Verilog定时控制(模块之间的同步)

时间:2014-11-06 13:58:58

标签: synchronization verilog

以下代码是我写作的简单案例。

模块bar将根据aoperation执行某些操作。问题是,我无法正确分配result(应在b的输出foo1之后分配)。

我找到了一种解决方法,只需在#1之前添加result = r1即可。我想知道模块之间同步的正确方法是什么?

module foo1(
  input a,
  output reg b
);
  always@(a)
    b = a;
endmodule

module foo2(
  input a,
  output reg b
);
  always@(a)
    b = ~a;
endmodule

module bar(
  input a,
  input operation,
  output b
);
  reg result;
  assign b = result;

  wire r1, r2;
  foo1 submod1(a, r1);
  foo2 submod2(a, r2);

  always@(a or operation) begin
    case (operation)
      1'b0:
        result = r1;
      1'b1:
        result = r2;
    endcase
  end

  initial begin
    $dumpfile("foobar.vcd");
    $dumpvars(0, r1);
    $dumpvars(0, r2);
    $dumpvars(0, result);
    $dumpvars(0, operation);
  end
endmodule

module test;
  reg a, op;
  wire r;
  bar mod(a,op,r);

  integer i;
  initial begin
    a = 0;
    op = 0;
    for (i=0; i<8; i=i+1)
      #10 a = ~a;
  end
endmodule

2 个答案:

答案 0 :(得分:1)

您可能没有看到正确传播结果的原因是因为您的结果敏感度列表不完整。你包含一个和你的操作真的需要包括r1和r2才能拥有正确的组合逻辑。如果将它们添加到灵敏度列表中,它应该按预期运行:

always@(operation or r1 or r2) begin
  case (operation)
    1'b0:
      result = r1;
    1'b1:
      result = r2;
  endcase
end

但是,最好不要使用像always_comb这样的SystemVerilog结构来至少使用Verilogs always @(*)来组合逻辑。这样,你就不会像在这次一样冒险丢失敏感度列表项目。

答案 1 :(得分:1)

分配result的敏感度列表不正确。 always@(a or operation)应为always@(r1 or r2 or operation)always @*

除了放置在程序块(begin - end)中的代码之外,Verilog会模拟所有乱序。这意味着always@(a or operation)可以在r1r2更新之前执行。

对于组合逻辑,我建议使用always @*(或等效的always @(*))。这是IEEE Std 1364-2001中引入的所有现代模拟器支持的自动灵敏度列表(即计算出灵敏度列表中的内容)。如果您需要遵循IEEE Std 1364-1995,请使用always@(r1 or r2 or operation)