Bool
描述
Bool
类型对应于硬件设计中使用的布尔值(True 或 False)或单个位/线。虽然名称类似,但不应与 Scala Boolean 类型混淆,后者不描述硬件,而是描述 Scala 生成器代码中的真值。
An important concept and rule-of-thumb to understand is that the Scala Boolean type is used in places where elaboration-time HDL code-generation decision making is occurring in Scala code. Like any regular program it affects execution of the Scala program that is SpinalHDL at the time the program is being run to perform HDL code generation.
因此,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)