本文作为SpinalHDL学习笔记第五十四篇,介绍SpinalHDL的Bool数据类型。
SpinalHDL技术交流QQ群:
Note:
1.本群是个人技术交流群,不是什么官方答疑群;
2.提问是你的权利,但回答不是别人的义务;
3.可以潜水,不能灌水;
4.请文明交流,做这行的都算高层次人才,希望你有对应的高素质;
5.不强制改名,但希望统一格式:姓名(昵称也行)-公司/学校-岗位/专业
SpinalHDL语⾔提供了五种基本数据类型和两种复合类型。
基础类型:Bool, Bits, UInt⽆符号整型, SInt有符号整型, Enum
复合类型:Bundle和Vec
除了这些基础类型, Spinal还提供了以下的拓展:
Fixed-point数(部分⽀持)
Floating-point数(实验⽀持)
最后, 还有⼀种特殊类型能够检查BitVector和bit常量是否相等, 且可以添加⽆效位。如下所⽰:
val myBits = Bits(8 bits)
val itMatch = myBits === M"00--10--“ // - 为⽆效位
Verilog:
wire [7:0] myBits;
wire itMatch;
assign itMatch = ((myBits & 8'hcc) == 8'h08);
⼀、描述(Description)
Bool数据类型对应于布尔值(True/False)
⼆、声明(Declaration)
声明布尔值的语法如下所⽰:([]中的内容可填项)
Bool(value:Boolean) 创建⼀个值为Scala Boolean(true, false)的Bool量。
val myBool_1 = Bool() //创建⼀个Bool
myBool_1 := False //:=是赋值操作符
val myBool_2 = False //与上⼀⾏等价
val myBool_3 = Bool(5 > 12) //⽤Scala Boolean类型创建Bool
Verilog:
wire myBool_1;
wire myBool_2;
wire myBool_3;
reg [7:0] counter;
assign myBool_1 = 1'b0;
assign myBool_2 = 1'b0;
assign myBool_3 = 1'b0;
三、操作符(Operators)
下列操作符可以⽤Bool类型:
1. 逻辑运算(Logic)
val a, b, c = Bool()
val res = (!a & b) ^ c
val d = False
when(cond) {
d.set() //等价于d := True
}
val e = False
e.setWhen(cond) //等价于when(cond) { d := True }
val f = RegInit(False) fallWhen(ack) setWhen(req)
/*
*等价于
*when(f && ack) { f := False}
*when(req) {f := True}
*or
*f := req || (f && !ack)
*/
//注意赋值顺序!
val g = RegInit(False) setWhen(req) fallWhen(ack)
//等价于 g := ((!g) && req) || (g && !ack)
Verilog:
wire a;
wire b;
wire c;
assign res = (((! a) && b) ^ c);
reg d;
always @(*) begin
d = 1'b0;
if(io_cond0) begin
d = 1'b1;
end
end
reg e;
always @(*) begin
e = 1'b0;
if(cond) begin
e = 1'b1;
end
end
reg f;
assign when_MyTopLevel_l47 = (f && ack);
always @(posedge clk or posedge reset) begin
if(reset) begin
f <= 1'b0;
end else begin
if(when_MyTopLevel_l47) begin
f <= 1'b0;
end
if(req) begin
f <= 1'b1;
end
end
end
reg g;
assign when_MyTopLevel_l49 = (g && ack);
always @(posedge clk or posedge reset) begin
if(reset) begin
g <= 1'b0;
end else begin
if(req) begin
g <= 1'b1;
end
if(when_MyTopLevel_l49) begin
g <= 1'b0;
end
end
end
2. 边沿检测(Edge detection)
when(myBool_1.rise(False)) {
//当检测到上升沿时做点什么
}
val edgeBundle = myBool_2.edges(False)
when(edgeBundle.rise) {
//当检测到上升沿时做点什么
}
when(edgeBundle.fall) {
//当检测到下降沿时做点什么
}
when(edgeBundle.toggle) {
//当检测到边沿时做点什么
}
3. 比较操作(Comparison)
when(myBool) {
//等价于when(myBool === True)
}
when(!myBool) {
//等价于when(myBool === False)
}
4. 类型转换(Type cast)
//给SInt值进位
val carry = Bool()
val res = mySInt + carry.asSInt
Verilog:
reg [7:0] mySInt;
assign _zz_res_1 = carry;
assign _zz_res = {{7{_zz_res_1[0]}}, _zz_res_1};
assign res = ($signed(mySInt) + $signed(_zz_res));
5. Misc
val a, b, c = Bool
//把三个Bool拼接成Bits
val myBits = a ## b ## c
Verilog:
wire a;
wire b;
wire c;
wire [2:0] myBits;
assign myBits = {{a,b},c};