学习SpinalHDL至今已有一段时间,算是有个初步的入门吧,从本篇开始将会从SpinalHDL的基础知识开始做一系列的文章笔记,在官方手册的基础上加上个人的理解,欢迎拍砖与交流。
认准是“Bool”
在电路设计中,其最基础的便是“0”、“1”代表这电路开关,可以说基于“0”,“1”我们搭建起了整个庞大的数字电路系统。为表示电路的0和1,SpinalHDL最基础的数据类型便是“Bool”。
由于SpinalHDL是基于Scala构建的,Scala本身自带类似变量Boolean,故在此要认准SpinalHDL中采用的是Bool而非Boolean:
Bool:True表示1,False表示0
Boolean:true表示1,false表示0
Bool变量声明四式
在SpinalHDL里,Bool类型变量的声明可以采用四种形式:
val myBool_1=BoolmyBool_1 := False // := is the assignment operatorval myBool_2 = False // Equivalent to the code aboveval myBool_3 = Bool(5 > 12) // Use a Scala Boolean to create a Bool
Bool变量逻辑运算
与Verilog相同,Bool类型变量也支持逻辑运算操作,其支持的逻辑运算符如下表所示: 可以看到,常用的逻辑操作符SpinalHDL均有提供: val res = (!a & b) ^ c // ((NOT a) AND b) XOR cval d = Falsewhen(cond) { d.set() // equivalent to d := True}val e = Falsee.setWhen(cond) // equivalent to when(cond) { d := True } 这里值得注意的是,由于Scala中一切操作均可以理解为函数操作,故而在使用过程中下面两行代码是不等价的:
val a=Boolval b=Boola:= !ba:=!b 在上述代码第三行(:=与!之间有空格)可正常编译通过,而第四行则无法正常编译,原因在于编译器认为:=!是一个函数操作而非两个,而SpinalHDL中并未定义该函数。
Bool变量逻辑运算
与verilog等传统HDL不同,SpinalHDL中Bool变量提供了丰富的边沿检测函数: 虽然这些函数我们在编写Verilog时也非常简单容易,但是一次两次还OK,总是做这种简单的重复劳动中而又认为理所当然是否合适呢……when(myBool_1.rise(False)) { // do something when a rising edge is detected}val edgeBundle = myBool_2.edges(False)when(edgeBundle.rise) { // do something when a rising edge is detected}when(edgeBundle.fall) { // do something when a falling edge is detected}when(edgeBundle.toggle) { // do something at each edge}
Bool变量比较与拼接
SpinalHDL里提供了用于Bool变量的比较操作符:
与普通的比较操作符没什么差别,不做过多解释。 而拼接操作符则能够使我们像在Verilog中一样进行变量拼接: // Concatenation of three Bool into a Bitsval myBits = a ## b ## c
Bool变量类型转换
在SpinalHDL中有一点个人觉得是一个不错的思想,那就是不会默认进行变量转换,哪怕相同类型变量即便位宽不同相互赋值也不被允许(SpinalHDL提供了方便的位宽截取功能),这相比于Verilog能够使我们在更早起避免些不必要的错误。 SpinalHDL中Bool类型支持的变量转换类型如下表所示:// Add the carry to an SInt valueval carry = Boolval res = mySInt + carry.asSInt
是val还是var?
熟悉scala的同学都知道val与var的区别及使用场景(看此文的大多数小伙伴应该对scala都了解不多),val是不可变类型变量,声明后变量内容不可更改,类似C中的const,而var是可变类型变量,声明后仍可重新赋值。而Scala是函数式编程,同样SpinalHDL中一切结尾对象,想象下我们声明了一个Bool类型像我们声明了一个wire对象,这个指向的对象在电路里是固定的,只不过我们可以改变这个对象的状态罢了(简单点所有的电路都是不可变类型,不能动态销毁与创建,val是唯一选择),这也是为什么SpinalHDL在声明时采用“=”,而在改变电路状态时用“:=”。
本帖来源微信公从号:Spinal FPGA
网页地址: 链接
|