#systemverilog# usage 之 always_comb 、always_iff

本文详细探讨了SystemVerilog中的`always_comb`和`always_ff`块。`always_comb`用于组合逻辑,其特性包括内部覆盖性和对外原子性,区分了unique case(并行比较)和priority case(串行比较)。`always_comb`中的if和for语句会被解释为条件判断和循环展开。而`always_ff`则专门用于描述触发器的行为。
摘要由CSDN通过智能技术生成

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

感谢大佬分享!!

(4条消息) System Verilog 语法_踩坑记录-CSDN博客

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值