2016-10-14 5 views
2

Ich möchte ein Eingangssignal um einen kompletten Taktzyklus verzögern.
Ich habe den Code unten, der grundsätzlich versucht, das Signal an der Uhr zu ändern.
Der Prüfstand zeigt jedoch, dass er nicht immer um 1 Zyklus verzögert wird.
In einigen Fällen ändert sich gleichzeitig das Eingangssignal.
Verilog: Wie verzögert man ein Eingangssignal um einen Taktzyklus?

Gibt es eine Möglichkeit, diese Art von Problem zu lösen? Hier

module delay_one_cycle(
    input clk, 
    input[3:0] original_signal, 
    output reg[3:0] delayed_signal 
); 

    always @(posedge clk) begin 
    delayed_signal <= original_signal; 
    end 


endmodule 

module delay_one_cycle_tb(); 
    reg clk; 
    reg[3:0] original_signal; 
    wire[3:0] delayed_signal; 

    delay_one_cycle doc_inst (clk, original_signal, delayed_signal); 

    // Initial setup 
    initial begin 
    clk     = 0; 

    original_signal  = 4'd9; 
    #5 original_signal = 4'd10; 
    #5 original_signal = 4'd11;  
    #4 original_signal = 4'd12; 
    #3 original_signal = 4'd13; 

    // finish the simulation 
    #5 $finish; 
    end 

    // clock 
    always begin 
    #1 clk = !clk; 
    end 
endmodule 

ist die Wellenform: enter image description here Die Wellenform zeigt, zum Beispiel, wenn die Eingangssignaländerungen an der Taktflanke bis 1010, Ausgabe auch zur gleichen Zeit ändert.
Das verzögerte Signal wird nicht wirklich auf den nächsten Zyklus verzögert!

Antwort

2

Diese Frage ist ganz ähnlich wie Ihre Frage Why is my D Flip Flop not waiting for the positive edge of the clock?

Vielleicht möchten Sie diese Konvention versuchen Race-Bedingung zu vermeiden:

@(posedge clk); 

Versuchen Eingangssignale auf Ihren RTL-Code mit blockierenden Zuweisungen zu vermeiden Einstellung. Verwenden Sie stattdessen nicht blockierende Zuweisung als das, was @Morten Zilmer vorschlägt.

Ihr Prüfstand sollte irgendwie etwas wie folgt aussehen:

module delay_one_cycle(
    input clk, 
    input[3:0] original_signal, 
    output reg[3:0] delayed_signal 
); 

    always @(posedge clk) begin 
    delayed_signal <= original_signal; 
    end 


endmodule 

module delay_one_cycle_tb(); 
    reg clk; 
    reg[3:0] original_signal; 
    wire[3:0] delayed_signal; 

    delay_one_cycle doc_inst (clk, original_signal, delayed_signal); 

    // Initial setup 
    initial begin 

    original_signal  <= 4'd9; 
    repeat (5) @(posedge clk); 
    original_signal <= 4'd10; 
    repeat (5) @(posedge clk); 
    original_signal <= 4'd11; 
    repeat (4) @(posedge clk); 
    original_signal <= 4'd12; 
    repeat (3) @(posedge clk); 
    original_signal <= 4'd13; 

    // finish the simulation 
    repeat (5) @(posedge clk); 
    $finish; 
    end 

    initial begin 
    clk     = 0; 
    forever begin 
     #1 clk = !clk; 
    end 
    end 
endmodule 

Hoffnung, das hilft.

2

Problem ist ein Verilog race condition.

Also, wenn original_signal zur gleichen Zeit zu ändern, wo eine ansteigende Flanke der clk auftritt, dann wird original_signal den neuen Wert vor der Aktualisierung auf Basis von clk, und das Ergebnis ist, dass Sie nicht die gewünschte Verzögerung erhalten.

Verwenden Sie die nicht blockierende Zuweisung (<=) anstelle der blockierenden Zuweisung (=) in den Blöcken.

Nutzen Sie auch die clk Änderung von Stimuli Daten steuern mit repeat (5) @(posedge clk); wie @ e19293001 weist darauf hin, um einen robusten Prüfstand für ein sequentielles Design zu erhalten.

Lesen Sie mehr über das Problem in der obigen Suche und in diesem Nonblocking Assignments in Verilog Synthesis.

+0

1) Was bedeutet die einzelne Aussage @ (posedge clk); machen? Ich habe nur Syntax wie gesehen: immer @ (posedge clk) beginne .... Ende. 2) Welche Art von Konstrukt ist es und wie es mit Wiederholung oben funktioniert? Zum Beispiel: wiederhole (5) @ (posedge clk); 3) Sind beide wiederholen (5) @ (posedge clk); und nicht-blocking (<=) benötigt, um die richtige Simulation zu erhalten? – user3330840

Verwandte Themen