2014-11-06 61 views
0

下面的代碼是我正在編寫的一個更簡單的例子。Verilog定時控制(模塊之間的同步)

模塊bar將根據operationa。問題是,我無法正確分配result(應該在輸出b之後指定foo1)。

我找到了解決辦法,只需在result = r1之前加上#1即可。我想知道在模塊之間進行同步的正確方法是什麼?

module foo1(
    input a, 
    output reg b 
); 
    [email protected](a) 
    b = a; 
endmodule 

module foo2(
    input a, 
    output reg b 
); 
    [email protected](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); 

    [email protected](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 

回答

1

您可能看不到結果的正確傳播的原因是因爲您的結果的敏感性列表不完整。你包括一個和你的操作,你真的需要包括r1和r2有正確的組合邏輯。如果將它們添加到敏感列表,應該按預期進行操作:

[email protected](operation or r1 or r2) begin 
    case (operation) 
    1'b0: 
     result = r1; 
    1'b1: 
     result = r2; 
    endcase 
end 

但是,它是最好的,如果你不能使用SystemVerilog的構造像always_comb至少使用Verilogs always @(*)做組合邏輯。那樣的話,你不用擔心這次會丟失敏感列表項目。

1

您的敏感列表要分配result不正確。 [email protected](a or operation)應該是[email protected](r1 or r2 or operation)always @*

Verilog除了放置在程序塊中的代碼(begin-end)之外,模擬一切不按順序。這意味着[email protected](a or operation)可以在r1r2更新之前執行。

對於組合邏輯,我推薦使用always @*(或相當於always @(*))。這是一個自動靈敏度列表(即找出適用於您的靈敏度列表的內容),它是IEEE Std 1364-2001中引入的所有現代仿真器都支持的。如果您需要遵循IEEE標準1364-1995,請使用[email protected](r1 or r2 or operation)