SpinalHDL之语义(Semantic)(二)
本文作为SpinalHDL学习笔记第七十篇,介绍SpinalHDL的When/Switch/Mux。
目录:
1.When
2.Switch
3.本地声明(Local declaration)
4.Mux
⼀、When
when(cond1) {
//当cond1真时执⾏操作
}.elsewhen(cond2) {
//当cond1假但cond2真时执⾏操作
}.otherwise {
//cond1和cond2同假时执⾏操作
}
注意:如果otherwise关键字和花括号的后半部分}在同⼀⾏, .可以省略。
when(cond1) {
//当cond1真时执⾏操作
} otherwise {
//cond1和cond2同假时执⾏操作
}
但如果.otherwise在另⼀⾏, 需要.
when(cond1) {
//当cond1真时执⾏操作
}
.otherwise {
//cond1和cond2同假时执⾏操作
}
⼆、Switch
就像在VHDL和Verilog, 当信号得到固定值的时候可以条件执⾏运算:
switch(x) {
is(value1) {
//当x===value1执⾏
}
is(value2) {
//当x===value2执⾏
}
default {
//当之前的条件都没有符合执⾏
}
}
is⼦句可以⽤is(value1, value2)这种逗号分割的⽅式书写。
举例:
switch(aluop) {
is(ALUOp.add) {
immediate := instruction.immI.signExtend
}
is(ALUOp.slt) {
immediate := instruction.immI.signExtend
}
is(ALUOp.sltu) {
immediate := instruction.immI.signExtend
}
is(ALUOp.sll) {
immediate := instruction.shamt
}
is(ALUOp.sra) {
immediate := instruction.shamt
}
}
上述代码等价于:
switch(aluop) {
is(ALU0p.add, ALU0p.slt, ALU0p.sltu) {
immediate := instruction.immI.signExtend
}
is(ALU0p.sll, ALU0p.sra) {
immediate := instruction.shamt
}
}
三、本地声明(Local declaration)
也可以在when/switch描述内定义新的信号:
val x, y = UInt(4 bits)
val a, b = UInt(4 bits)
when(cond) {
val tmp = a + b
x := tmp
y := tmp + 1
} otherwise {
x := 0
y := 0
}
备注:SpinalHDL会检查信号是否只在该区域内被定义。
四、Mux
如果你只需要带有Bool选择信号的Mux, 有两种等价的语句形式:
val cond = Bool
val whenTrue, whenFalse = UInt(8 bits)
val muxOutput = Mux(cond, whenTrue, whenFalse)
val muxOutput2 = cond ? whenTrue | whenFalse
五、Bit级选择(Bitwise selection)
bit级的选择看起来像VHDL中when语句。
val bitwiseSelect = UInt(2 bits)
val bitwiseResult = bitwiseSelect.mux(
0 -> (io.src0 & io.src1),
1 -> (io.src0 | io.src1),
2 -> (io.src0 ^ io.src1),
default -> (io.src0)
)
同样, 如果条件是完备的, 不需要些default:
val bitwiseSelect = UInt(2 bits)
val bitwiseResult = bitwiseSelect.mux(
0 -> (io.src0 & io.src1),
1 -> (io.src0 | io.src1),
2 -> (io.src0 ^ io.src1),
3 -> (io.src0)
)
或者, 如果未覆盖的值并不重要, 他们可以⽤muxListDc使其不赋值。
muxLists(...)是另⼀种bit级选择器, 该选择器以元组作为输入, 下图是⼀个把128 bits分割成32 bits的例⼦。
val sel = UInt(2 bits)
val data = Bits(128 bits)
//把宽bit类型分成⼩块, 可以⽤mux:
val dataWord = sel.muxList(for (index <- until 4) yield (index, data(index*32+32-1 downto
index*32)))
//⼀种书写更短的⽅式书写上述代码:
val dataWord = data.subdivideIn(32 bits)(sel)