Systemverilog中的iff事件控制

使用systemverilog已经有一段时间了,主要是其中的部分新特性能够简化代码的编写,比如interface、支持多维端口等。为了进一步深入学习systemverilog,最近抽空更广泛的学习了一些systemverilog的内容。本文记录一下Systemverilog中的事件控制和sequence控制相关内容的学习情况。

Systemverilog在@事件控制中添加了iff修饰词,只有当iff后的条件为真时,@事件才会触发。注意,iff可以在always和always_ff下使用,但是不能在always_comb、always_latch中使用

module tb(

    );

reg                 a;
reg                 en;
logic               outa;

initial begin
    a = 1'b0;
    en = 1'b0;
    #100 a = 1'b1;
    #20 a = 1'b0;
    #20 en = 1'b1;
    #10 a = 1'b1;
    #10 a = 1'b0;
end 

always @ (a iff en)
    outa <= a;

endmodule

上述代码的仿真结果如下,只有当en为真时,outa才会输出a的值。

Systemverilog中的iff事件控制_第1张图片

iff可以在组合逻辑中使用,同样也可以在时序逻辑中使用,iff是可综合的。以下是在时序逻辑中使用iff的例子。

localparam P        = 5.0;

reg                 clk=1'b0;
reg                 a;
reg                 en;
logic               outa;

initial forever clk = #(P/2) ~clk;

initial begin
    a = 1'b0;
    en = 1'b0;
    #100 a = 1'b1;
    #20 a = 1'b0;
    #20 en = 1'b1;
    #10 a = 1'b1;
    #10 a = 1'b0;
end 

always @ (posedge clk iff en)
    outa <= a;

这种情况下,outa的输出、a值的采样和en的识别都是在时钟边沿的驱动现进行的,其输出如下。

Systemverilog中的iff事件控制_第2张图片

虽然iff可以用在时序逻辑中,但是建议不要使用。因为不同的编译器可以综合出不同的电路,其结果也不总是我们期望的。比如以下的代码,outa是采用在时序always块中加入iff的方式使用en的;outb是采用在always块中使用if(enb)的方式应用enb的。

module top(
    input               clk,
    input               en,
    input               a,
    input               enb,
    input               b,

    output logic        outa,
    output logic        outb
    );

always @ (posedge clk iff en)
    outa <= a;

always @ (posedge clk)
    if(enb)
        outb <= b;

endmodule

以下是综合后的网表,可以看到使用iff时,outa的输出电路并不如预期。en和clk被送入一个LUT2来实现一个门控时钟,这种电路会降低电路的时序性能。而outb的输出电路中,en被直接接入了寄存器的CE端,不会出现门控时钟,显然是更优的综合结果。所以iff在仿真中可提供一些便捷,但是不建议在可综合代码中使用iff事件控制。

Systemverilog中的iff事件控制_第3张图片

你可能感兴趣的:(#,systemverilog)