如果隐含的敏感性列表更改,则SystemVerilog always_comb不会重新评估

问题描述 投票:0回答:1

这是一段代码,带有3个不同的always语句,应该是可合成的。问题如下:

always_comb
  begin
    c_cntr1 = cntr1;
    c_func_val1 = diff (0, c_cntr1);

    if (read)
       c_cntr1 = cntr1+1;

  end

我期望在c_cntr1更改时重新评估always_comb,并调用该函数并重新评估c_func_val1,但它没有。我是否错误地解释了LRM?

这是一个完整的测试用例,显示错误的行为,另外2个始终阻止产生正确的结果。我用NC跑了这个。我没有检查过其他模拟器或综合工具。

完整的测试案例

module test_always_comb();

reg clk, resetn, read;

initial 
  begin
    clk = 0;
    resetn = 0;
    forever #5 clk = ~clk;
  end

initial 
  begin
    resetn = 0;
    read = 0;
    @(posedge clk);
    @(posedge clk);
    resetn = 1;
    for (int i = 0; i < 10; i++)
      begin
        @(posedge clk);
        if (i%2 == 0)
          read= 1;
        else
          read= 0;
      end
    $finish;
  end

always@(posedge clk)
  if (resetn)
   begin
      $display("Value of c_func_val1 is %d, cntr is %d, c_cntr is %d\n", c_func_val1, cntr1, c_cntr1);
      $display("Value of c_func_val2 is %d, cntr is %d, c_cntr is %d\n", c_func_val2, cntr2, c_cntr2);
      $display("Value of c_func_val3 is %d, cntr is %d, c_cntr is %d\n", c_func_val3, cntr3, c_cntr3);
   end

// Synesizable Design Code


   function automatic [4:0] diff 
     (
      input [4:0] num1,
      input [4:0] num2
      );
      return num2;
   endfunction // diff

logic [4:0] c_cntr1, c_cntr2, c_cntr3, c_func_val1, c_func_val2, c_func_val3;
reg [4:0] cntr1, cntr2, cntr3;

always_comb
  begin
    c_cntr1 = cntr1;
    c_func_val1 = diff (0, c_cntr1);

    if (read)
       c_cntr1 = cntr1+1;

  end

always_comb
  begin
    c_cntr2 = cntr2;
    if (read)
      c_cntr2 = cntr2+1;
    c_func_val2 = diff (0, c_cntr2);
  end

always @(*)
  begin
    c_cntr3 = cntr3;
    if (read)
      c_cntr3 = cntr3+1;
    c_func_val3 = diff (0, c_cntr3);
  end

always_ff @(posedge clk or negedge resetn)
   begin
     if (~resetn)
       begin
        cntr1 <= 0;
        cntr2 <= 0;
        cntr3 <= 0;
       end
     else
       begin
        cntr1 <= c_cntr1;
        cntr2 <= c_cntr2;
        cntr3 <= c_cntr3;
       end
   end


endmodule

谢谢你的帮助。

system-verilog evaluation synthesis register-transfer-level
1个回答
0
投票

这是always @*always_comb之间的差异之一。 always_comb不会根据标准重新评估(总是@ *会)。

您描述了一种称为read before write的条件,这意味着在您写入变量之前,您会在块内部读取变量。

always @*可以在这种情况下产生毛刺或挂在零延迟循环中。 always_comb永远不会循环。

除了目视检查之外,检查它的唯一方法是运行打开相应规则的linting工具。

© www.soinside.com 2019 - 2024. All rights reserved.