Bool
描述
Bool
类型对应于硬件设计中使用的布尔值(True 或 False)或单个位/线。虽然名称类似,但不应与 Scala Boolean 类型混淆,后者不描述硬件,而是描述 Scala 生成器代码中的真值。
需要理解的一个重要概念和经验是,Scala Boolean 类型用于在实例细化时决定如何生成 HDL 代码。与任何常规程序一样,在运行 SpinalHDL 程序以执行 HDL 代码生成时,它会影响 Scala 程序的执行。
因此,Scala Boolean 的值无法从硬件中观察到,因为它仅在 HDL 代码生成时存在于 SpinalHDL 程序中,这在硬件仿真/运行之前。
在您的设计中可能需要这样做,例如从 Scala 向硬件设计中传递一个值(该值可能作为参数化常量输入),您可以使用构造函数 Bool(value: Boolean) 将其类型转换为 Bool 。
同样,SpinalHDL Bool 的值在代码生成时无法看到,所有可以看到和操作的都是有关 wire 的 HDL 构造以及它如何路由(通过模块/组件)、驱动(源)并连接(汇据点)。
赋值运算符 := 的信号方向由 SpinalHDL 管理。在赋值运算符 := 左侧或右侧使用 Bool 实例指示它是给定赋值的源(提供状态)还是接收器(捕获状态)。
允许多次使用赋值运算符,因此信号线作为源(提供值以驱动 HDL 状态)连接并驱动其他 HDL 结构的多个输入是很正常的。 当 Bool 实例用作源时,赋值语句在 Scala 中出现或执行的顺序并不重要,而当它用作汇(捕获状态)时则不同。
当多个赋值操作符驱动 Bool(Bool 位于赋值表达式的左侧)时,最后一个赋值语句将赢得胜利;并开始生效。 最后一个将在 Scala 代码中最后执行。 此事会影响 SpinalHDL Scala 代码的布局和排序,以确保在硬件设计中获得正确的优先顺序,以便在硬件中为 Bool 赋值新状态。
将 Scala/SpinalHDL Bool 实例作为对 net-list 中 HDL net 的引用,可能有助于理解这一概念。 其中,赋值 := 操作符将 HDL 结构加入到同一个网中。
声明
声明布尔值的语法如下:([]之间的所有内容都是可选的)
语法 |
描述 |
返回类型 |
---|---|---|
Bool() |
创建Bool值 |
Bool |
True |
创建一个分配有 |
Bool |
False |
创建一个Bool值并赋值为 |
Bool |
Bool(value: Boolean) |
创建一个 Bool,并分配一个 Scala 布尔类型(true、false)的值。这显式地转换为 |
Bool |
val myBool_1 = Bool() // Create a Bool
myBool_1 := False // := is the assignment operator (like verilog <=)
val myBool_2 = False // Equivalent to the code above
val myBool_3 = Bool(5 > 12) // Use a Scala Boolean to create a Bool
运算符
以下运算符可用于 Bool
类型:
逻辑运算
运算符 |
描述 |
返回类型 |
---|---|---|
!x |
逻辑非 |
Bool |
x && y
x & y
|
逻辑与 |
Bool |
x || y
x | y
|
逻辑或 |
Bool |
x ^ y |
逻辑异或 |
Bool |
~x |
逻辑非 |
Bool |
x.set[()] |
将 x 设置为 True |
Unit (none) |
x.clear[()] |
将 x 设置为 False |
Unit (none) |
x.setWhen(cond) |
当 cond 为 True 时设置 x 为 True |
Bool |
x.clearWhen(cond) |
当 cond 为 True 时设置 x 为 False |
Bool |
x.riseWhen(cond) |
当 x 为 False 并且 cond 为 True 时设置 x 为 True |
Bool |
x.fallWhen(cond) |
当 x 为 True 并且 cond 为 True 时设置 x 为False |
Bool |
val a, b, c = Bool()
val res = (!a & b) ^ c // ((NOT a) AND b) XOR c
val d = False
when(cond) {
d.set() // equivalent to d := True
}
val e = False
e.setWhen(cond) // equivalent to when(cond) { d := True }
val f = RegInit(False) fallWhen(ack) setWhen(req)
/** equivalent to
* when(f && ack) { f := False }
* when(req) { f := True }
* or
* f := req || (f && !ack)
*/
// mind the order of assignments! last one wins
val g = RegInit(False) setWhen(req) fallWhen(ack)
// equivalent to g := ((!g) && req) || (g && !ack)
边缘检测
所有边缘检测函数都将通过 RegNext 实例化一个附加寄存器,以获取相关 Bool
的延迟值(一拍)。
此功能不会重新配置 D 型触发器以使用其他 CLK 时钟,它使用串联链中的两个 D 型触发器(两个 CLK 引脚都继承默认的 ClockDomain)。它具有组合逻辑,可根据输出 Q 状态进行边缘检测。
运算符 |
描述 |
返回类型 |
---|---|---|
x.edge[()] |
当 x 状态改变时返回 True |
Bool |
x.edge(initAt: Bool) |
与 x.edge 相同但具有重置后的初始值 |
Bool |
x.rise[()] |
当 x 在上一个周期为低电平且现在为高电平时返回 True |
Bool |
x.rise(initAt: Bool) |
与 x.rise 相同但具有重置后的初始值 |
Bool |
x.fall[()] |
当 x 在上一个周期为高且现在为低时返回 True |
Bool |
x.fall(initAt: Bool) |
与 x.fall 相同但具有重置后的初始值 |
Bool |
x.edges[()] |
返回捆绑包(上升、下降、切换) |
BoolEdges |
x.edges(initAt: Bool) |
与 x.edges 相同但具有重置后的初始值 |
BoolEdges |
x.toggle[()] |
在每个边缘返回 True |
Bool |
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
}
比较运算
运算符 |
描述 |
返回类型 |
---|---|---|
x === y |
等价性判断 |
Bool |
x =/= y |
不等价判断运算 |
Bool |
when(myBool) { // Equivalent to when(myBool === True)
// do something when myBool is True
}
when(!myBool) { // Equivalent to when(myBool === False)
// do something when myBool is False
}
类型转换
运算符 |
描述 |
返回类型 |
---|---|---|
x.asBits |
二进制转换为 Bits |
Bits(1 bit) |
x.asUInt |
二进制转换为 UInt |
UInt(1 bit) |
x.asSInt |
二进制转换为SInt |
SInt(1 bit) |
x.asUInt(bitCount) |
二进制转换为 UInt 并调整大小,将 Bool 值放入 LSB 并用零填充。 |
UInt(bitCount bits) |
x.asBits(bitCount) |
二进制转换为位并调整大小,将布尔值放入 LSB 并用零填充。 |
Bits(bitCount bits) |
// Add the carry to an SInt value
val carry = Bool()
val res = mySInt + carry.asSInt
杂项
运算符 |
描述 |
返回类型 |
---|---|---|
x ## y |
连接Bits,x->高位,y->低位 |
Bits(w(x) + w(y) bits) |
x #* n |
n次重复x并合并 |
Bits(n bits) |
val a, b, c = Bool()
// Concatenation of three Bool into a single Bits(3 bits) type
val myBits = a ## b ## c
掩码布尔值
具有掩码的布尔型允许任意值(don’t care)。它们通常不单独使用,而是通过 MaskedLiteral 使用。
// first argument: Scala Boolean value
// second argument: do we care ? expressed as a Scala Boolean
val masked = new MaskedBoolean(true, false)