always_comb
always_comb内部每条语句都是阻塞赋值语句。不能出现电路语句(assign)
always_comb有以下性质:
内部覆盖性
对外原子性
always_comb begin
a = 1'b1;
b = a;
a =1'b0;
c = a;
end
// 电路输入:1'b1;1'b0; // 右边(1'b1;1'b0; a)除去左边(a,b,c)
// 电路输出:(a,b,c)//左边
// 运行结果 a=1'b0, b=1'b1, c=1'b0,
assign a = b;
always_comb begin
b = 1'b1;
c = a;
b = 1'b0;
end
// 先 always_comb 得: c = a, b = 1'b0; 再assign得:a = b = 1'b0; c = a = 1'b0
// 于是 a=1'b0, b=1'b0, c=1'b0,
assign a = b;
always_comb begin
b = 1'b1;
c = b;
b = 1'b0;
end
// 先 always_comb 得: c = b = 1'b1; b = 1'b0 再assign得:a = b = 1'b0;
// 于是 a=1'b0, b=1'b0, c=1'b1,
always_comb case
unique case
case块内没有优先级,并行比较.
// unique case
always_comb begin
b = 1'b0;
unique case (a[3:0])
4'd1: begin b = 1'b1; end
4'd0: begin b = 1'b0; end
default: begin end
endcase
end
priority case
case块内有优先级,串行比较 (依次比较)
always_comb begin
priority case (1'b1)
a[3]: begin end
a[2]: begin end
default: begin end
endcase
end
// 相当于:
/*
always_comb begin
if(a[3]) begin
end else if(a[2]) begin
end else if() begin end
end
*/
always_comb if 和 for
if
if和else用于条件判断
always_comb begin
b = 1'b0;
if (a[3]) begin b = 1'b1; end
else if (a[2]) begin b = 1'b0; end
else begin end
end
for
for在always_comb中,会被解释为循环展开。
logic [15:0]a;
logic [3:0] b;
always_comb begin
b = '0;
for (int i = 15; i >= 0; i--) begin
if (a[i]) begin
b = i[3:0];
break;
end
end
end
always_comb begin
for (int i = 0 ; i < 16; i ++) begin
if (i >= n) break;
end
end
always_comb begin
for (int i = 0; i < 16; i++) begin
a[i] = b[i] & (c[i] == d[i] | e[i]); // 编译器不认为i是常数,a[i:i+3]非法
end
end
for (genvar i = 0; i < 16; i++) begin // genvar assign
assign a[i] = b[i] & (c[i] == d[i] | e[i]); // 编译器认为i是常数,a[i:i+3]合法
always_comb begin
end
end
always_ff
always_ff用于描述触发器。
always_ff @(posedge clk) begin
if (~resetn) begin
q <= '0; // 触发器非阻塞赋值
end else if (en) begin
q <= d;
end
end
logic [3:0] a, a_nxt;
// always_ff只写触发器部分 非阻塞赋值
always_ff @(posedge clk) begin
if (~resetn) begin
a <= '0;
end else if (en) begin
{a, b} <= {a_nxt, b_nxt};
end
end
always_comb begin
a_nxt = a;
// 不属于触发器的逻辑,写在always_comb 阻塞赋值
unique case(a)
4'd3: begin
a_nxt = 4'd2;
end
default: begin
end
endcase
end
感谢大佬分享!!