risc-v中文社区

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

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

[复制链接]

347

主题

564

帖子

2237

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
2237
发表于 2022-6-6 16:18:50 | 显示全部楼层 |阅读模式
书接上文,SpinalHDL在Bool的基础上,定义了Bits数据类型,本篇就Bits的初始化及使用方式结合SpinalHDL Doc做一个总结。

   

Bits:初始化

       Bits意味这一组有Bool类型组成的向量,类似与我们在Verilog中的多比特位宽变量。在SpinalHDL中,声明一个Bits变量可采用如下形式(“[]”中为可选项):
    相较于Veriog,Bits变量的初始化给了更多灵活的方式用于针对不同的场景:

// Declarationval myBits  = Bits()     // the size is inferredval myBits1 = Bits(32 bits)val myBits2 = B(25, 8 bits)val myBits3 = B"8'xFF"   // Base could be x,h (base 16)                         //               d   (base 10)                         //               o   (base 8)                         //               b   (base 2)val myBits4 = B"1001_0011"  // _ can be used for readability
// Elementval myBits5 = B(8 bits, default -> True) // "11111111"val myBits6 = B(8 bits, (7 downto 5) -> B"101", 4 -> true, 3 -> True, default -> false) // "10111000"val myBits7 = Bits(8 bits)myBits7 := (7 -> true, default -> false) // "10000000" (For assignment purposes, you can omit the B)

操作符

    针对Bits变量,SpinalHDL提供了一系列的操作运算符,如下表所示:
    这里值得注意的是:&、|、^操作符中x,y的宽度必须保持一致,否则在生成RTL代码时将提示不能正常编译(可使用resized方法自动扩展剪裁位宽),相当于把RTL中的位宽不匹配警报消除在设计阶段。
    对于逻辑右移操作,同时x>>y,y变量类型的不同所产生的结果也不同,看下述代码:

class BitsInst extends  Component {  val data_in1=in Bits(16 bits)  val data_out1=out Bits()  val data_out2=out Bits()  data_out1:=data_in1>>3  data_out2:=data_in1>>U(3)}
    其生成的RTL代码为:

module BitsInst (  input      [15:0]   data_in1,  output     [12:0]   data_out1,  output     [15:0]   data_out2);  assign data_out1 = (data_in1 >>> 3);  assign data_out2 = (data_in1 >>> 2'b11);endmodule
    可以看到 ,data_out1位宽为13个bit,而data_out2位宽为16个比特。结合定义,对比可以看出:若y为Int类型(scala原生类型),所谓的移位操作更像是截断处理,而若y为UInt类型,则和Verilog中的移位操作含义基本相同。此外,虽然生成的RTL代码里采用的是>>>,但由于是无符号数,故而与逻辑右移相同。
    由于SpinalHDL会检测":="左右两侧位宽是否相同,所以若在编写时使用错误在生成rtl时即可发现,不会等到仿真时摸不着头脑。
      

比较操作符

    比较操作符Bits变量和Bool变量相同:

when(myBits === 3) {}
when(myBits_32 =/= B"32'x44332211") {}

类型转换

    Bits类型可以与其他类型之间进行相互转换,SpinalHDL提供的方法如下:

val mySInt = myBits.asSInt// create a Vector of boolval myVec = myBits.asBools// Cast a SInt to Bitsval myBits = B(mySInt)

部分赋值/提取操作符

    与Verilog/Systemverilog相同,Bits也支持部分读取/赋值操作:

val myBool = myBits(4)val myBits2= Bits(2 bits)// assignmyBits(1) := TruemyBits2:=myBits(2,2 bits)myBits2:=myBits(U(2),2 bits)// Rangeval myBits_8bits = myBits_16bits(7 downto 0)val myBits_7bits = myBits_16bits(0 to 6)val myBits_6bits = myBits_16Bits(0 until 6)
myBits_8bits(3 downto 0) := myBits_4bits
    对于x(offset,width bits),其意味着从offset比特位开始,向上截取width比特位宽,上述示例第5行等效于myBits2:=myBits(3 downto 2)。

其他方法

    为方便代码设计,SpinalHDL针对Bits也提供了一些其他方法:

myBool := myBits.lsb  // Equivalent to myBits(0)
// ConcatenationmyBits_24bits := bits_8bits_1 ## bits_8bits_2 ## bits_8bits_3
// Subdivideval sel = UInt(2 bits)val myBitsWord = myBits_128bits.subdivideIn(32 bits)(sel)    // sel = 0 => myBitsWord = myBits_128bits(127 downto 96)    // sel = 1 => myBitsWord = myBits_128bits( 95 downto 64)    // sel = 2 => myBitsWord = myBits_128bits( 63 downto 32)    // sel = 3 => myBitsWord = myBits_128bits( 31 downto  0)
// If you want to access in reverse order you can do: val myVector   = myBits_128bits.subdivideIn(32 bits).reverse val myBitsWord = myVector(sel)
// ResizemyBits_32bits := B"32'x112233344"myBits_8bits  := myBits_32bits.resized       // automatic resize (myBits_8bits = 0x44)myBits_8bits  := myBits_32bits.resize(8)     // resize to 8 bits (myBits_8bits = 0x44)myBits_8bits  := myBits_32bits.resizeLeft(8) // resize to 8 bits (myBits_8bits = 0x11



本帖来源微信公从号:Spinal FPGA

网页地址:链接

回复

使用道具 举报

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

本版积分规则



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

GMT+8, 2024-4-26 23:46 , Processed in 0.016596 second(s), 17 queries .

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

Copyright © 2018-2021, risc-v open source

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