SpinalHDL中关于M"00--1---"的使用与casez的使用
SpinalHDL中的switch
在之前的文章中曾提到过SpinalHDL中switch的使用:
通常情况下,switch对应着我们日常Verilog代码中的case。像下面的代码:
其生成的RTL代码为:
没什么大的问题。但我们知道,在Verilog中,存在case,casez,casex三种语法(本篇不做三种语法的区分与讨论,对此感兴趣的小伙伴可以自行百度)。像下面的这种代码:
case (sel)
000 : y = a;
001 : y = b;
010,011 : y = c;
100,101,110,111 : y = d;
endcase
我们在写Verilog代码时还是很少会直接这么来写的,往往通常采用casez来进行描述:
casez (sel)
000: y = a;
001: y = b;
01?: y = c;
1??: y = d;
endcase
那么在SpinalHDL中,我们是否也可以这么描述呢?
SpinalHDL中的don't care
像Verilog代码中,casez里我们常常采用?表示我们不关心的位,而在SpinalHDL中,也存在这么一种表示方式。
SpinalHDL整体的数据结构如下图所示:
针对BitVector及其子类,SpinalHDL定义了一种特殊的类型用于在比较中表示不关心的bit:
val myBits = Bits(8 bits)
val itMatch = myBits === M"00--10--" // - don't care value
像上面的例子里只要myits的bit7,bit6,bit2为0,bit3为1那么itMatch即为True。
而通过这种形式,我们即可在switch中实现类似casez的功能:
其对应的Verilog代码为:
module test3 (
input [7:0] io_dataIn,
output reg [2:0] io_result
);
always @(*) begin
casez(io_dataIn)
8'b1??????? : begin
io_result = 3'b010;
end
8'b01?????? : begin
io_result = 3'b001;
end
default : begin
io_result = 3'b000;
end
endcase
end
endmodule
可以看到,在生成的Verilog代码里,这里换成了casez。
使用需谨慎
像上面在switch中使用M"----1----"没有什么问题,然而在其他地方,使用则需谨慎。像下面的代码逻辑:
case class test2() extends Component{
val io=new Bundle{
val dataIn=in UInt(8 bits)
val result=out Bool()
}
io.result:=io.dataIn===M"1---1---"
}
其在生成RTL代码时会采用下面的逻辑:
module test2 (
input [7:0] io_dataIn,
output io_result
);
assign io_result = ((io_dataIn & 8'h88) == 8'h88);
endmodule
从资源的利用角度来讲反而增加了面积开销,还是老老实实的采用常规形式比较好:
case class test2() extends Component{
val io=new Bundle{
val dataIn=in UInt(8 bits)
val result=out Bool()
}
io.result:=io.dataIn.msb & io.dataIn(3)
}
☆ END ☆
作者:玉骐
原文链接:https://mp.weixin.qq.com/s/e5-PNsvjiofYvA9d7blczg
微信公众号:
推荐阅读
更多SpinalHDL技术干货请关注Spinal FPGA专栏。