【SpinalHDL快速入门】4.2、基本类型之Bits

文章详细介绍了SpinalHDL中Bits类型的声明方法,包括默认声明、指定宽度和基于基数的声明。接着,文章列举了用于Bits类型的逻辑运算、比较、类型转换、部分赋值/提取操作以及一些特殊功能,如旋转、设置/清除、比较和掩码字面量。此外,还特别强调了位宽对齐和转换的重要性。

在这里插入图片描述

1.1、描述

Bits类型对应于一个不传达任何算术含义的位向量

1.2、声明

声明位向量的语法如下:(方括号中的所有内容都是可选项)

在这里插入图片描述

// Declaration
val myBits = Bits() // the size is inferred
val 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

// Element【这个赋值方式有点意思,之前其他语言都没见过】
val 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)

1.3、运算符

以下运算符可用于 Bits 类型:

1.3.1、逻辑运算(Logic)

在这里插入图片描述

// Bitwise operator
val a, b, c = Bits(32 bits)
c := ~(a & b) // Inverse(a AND b)

val all_1 = a.andR // Check that all bits are equal to 1

// Logical shift
val bits_10bits = bits_8bits << 2 // shift left (results in 10 bits)
val shift_8bits = bits_8bits |<< 2 // shift left (results in 8 bits)

// Logical rotation
val myBits = bits_8bits.rotateLeft(3) // left bit rotation

// Set/clear
val a = B"8’x42"
when(cond) {
	a.setAll() // set all bits to True when cond is True
}

注意:

  • 1、 这里值得注意的是:&、|、^操作符中x,y的宽度必须保持一致,否则在生成RTL代码时将提示不能正常编译(可使用resized方法自动扩展剪裁位宽),相当于把RTL中的位宽不匹配警报消除在设计阶段。

  • 2、对于逻辑右移操作:x>>y,y变量类型的不同所产生的结果也不同。y为UInt时和Verilog是比较符合的,移位前后位数不变。实验代码如下:

有点意思的东西,可以琢磨一下

SpinalHDL代码:

package test

import spinal.core._


case 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) //类型转换为UInt,默认是Int
}

object MyTopLevelApp extends App{
  SpinalConfig().generateSystemVerilog(BitsInst())
}

注意:直接写数字,代表Scala中的Int

// Generator : SpinalHDL v1.6.0    git head : 73c8d8e2b86b45646e9d0b2e729291f2b65e6be3
// Component : BitsInst



module BitsInst (
  input      [15:0]   data_in1,
  output     [12:0]   data_out1,
  output     [15:0]   data_out2
);

  assign data_out1 = (data_in1 >>> 3); //默认Int移位后进行截断,不会高位补0
  assign data_out2 = (data_in1 >>> 2'b11); //移位后还是原来的位数,高位补0

endmodule

1.3.2、比较(Comparison)

在这里插入图片描述

when(myBits === 3) {
}

when(myBits_32 =/= B"32’x44332211") {
}

1.3.3、类型转换(Type cast)

在这里插入图片描述

将 Bool、UInt 或 SInt 转换为 Bits,您可以使用 B(something):

// cast a Bits to SInt
val mySInt = myBits.asSInt

// create a Vector of bool
val myVec = myBits.asBools

// Cast a SInt to Bits
val myBits = B(mySInt)

1.3.4、部分赋值/提取操作符(Bit extraction)

在这里插入图片描述

对于x(offset,width bits),其意味着从offset比特位开始,向上截取width比特位宽

// get the element at the index 4
val myBool = myBits(4)

// assign
myBits(1) := True

// Range
val 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

有点意思的东西,可以琢磨一下

Range的三种表示范围

在这里插入图片描述

  • 简而言之:todownto是左右闭区间,until是左闭右开区间。

1.3.5、杂项(Misc)

在这里插入图片描述

注意:validRange仅适用于最小值和最大值适合于有符号32位整数的类型。 (这是由Scala范围类型给出的限制,它使用Int)

println(myBits_32bits.getWidth) // 32

myBool := myBits.lsb // Equivalent to myBits(0)

// Concatenation
myBits_24bits := bits_8bits_1 ## bits_8bits_2 ## bits_8bits_3

// Subdivide
val sel = UInt(2 bits)
val myBitsWord = myBits_128bits.subdivideIn(32 bits)(sel) //根据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)

// Resize(有点意思!!!)
myBits_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)

resized 有点意思的东西,可以琢磨一下

1.3.6、MaskedLiteral

MaskedLiteral值是带有“-”的位向量,表示不关心的值。【下面的M就表示MaskedLiteral】

val myBits = B"1101
val test1 = myBits === M"1-01" // True
val test2 = myBits === M"0---" // False
val test3 = myBits === M"1--1" // True
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ReCclay

如果觉得不错,不妨请我喝杯咖啡

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值