risc-v中文社区

 找回密码
 立即注册
查看: 847|回复: 0

[原创] SpinalHDL—数据类型:Bool

[复制链接]

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
发表于 2022-6-6 16:16:13 | 显示全部楼层 |阅读模式
学习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

网页地址:链接

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



Archiver|手机版|小黑屋|risc-v中文社区

GMT+8, 2024-4-26 10:59 , Processed in 0.027714 second(s), 17 queries .

risc-v中文社区论坛 官方网站

Copyright © 2018-2021, risc-v open source

快速回复 返回顶部 返回列表