2017-09-12 8 views
0

Ich schreibe den Verilog-Code für einen UART, der auf einem FPGA implementiert werden soll, und ich habe Probleme mit der Synchronisierung auf das START-Bit von Bytes nach dem ersten.Verilog Falling Edge Detection

Mein Manager schlug vor, mein empfangenes Signal zu synchronisieren und eine Art Interrupt zu verwenden, um der FSM mitzuteilen, dass ein Start erkannt wurde.

Ich habe über Techniken für die steigende Flanke Erkennung lesen, und ich fühle mich wie ich etwas tun könnte:

module StartDetectionUnit (
    input clk, state, signal_in, 
    output trigger 
    ); 

    reg signal_d; 

    always @(posedge clk) 
     begin 
      signal_d <= signal_in; 
     end 
    assign trigger = signal_in & (!signal_d); 

endmodule  

In meinem Verständnis, wie diese eine Beschreibung eine ansteigende Flanke erkennt, nicht eine abfallende Flanke, aber "START" ist eine logische "0" in der RS-232-Kommunikation.

Plus, ich möchte tatsächlich die Flagge nur zuweisen, wenn im IDLE-Zustand [Hardcoded als 000], aber verrückte Gating auf den endgültigen Aufgaben klingt nicht-hardware für mich.

TLDR, zwei Ausgaben

  1. eine gattungsgemäße abfallende Flanke eines asynchronen Eingangssignal
  2. dabei in einem einzigen, bestimmten Zustand eines FSM

durch ein Bündel zu erfassen, i‘ m neu zu Verilog und irgendwie neu zu HDL'ing

Antwort

1

Wenn Ihr Signal signal_in von außerhalb Ihres Entwurfs kommt, wird es nicht richtig synchronisiert. In Ihrem Design verwenden Sie nur einen D-Latch, zwei sind erforderlich.

reg signal_d; 
always @(posedge clk) 
    begin 
     signal_d <= signal_in; 
    end 

Dadurch wird nur ein D-Latch synthetisiert. So synchronisieren Signal korrekt müssen Sie ein zweites Signal für zwei D-Latch-Instanziierung erklären:

reg signal_d; 
reg signal_sync; 
always @(posedge clk) 
    begin 
     signal_d <= signal_in; 
     signal_sync <= signal_d; 
    end 

Und signal_d sollte nicht in Ihrem Design verwendet werden. Dann Kantenerkennung zu machen, müssen Sie ein drittes Signal, wie es erklären:

reg signal_d; 
reg signal_sync; 
reg signal_sync_old; 
always @(posedge clk) 
    begin 
     signal_d <= signal_in; 
     signal_sync <= signal_d; 
     signal_sync_old <= signal_sync; 
    end 

Und für einen fallenden Flanke Erkennung tun:

assign trigger = signal_sync_old & (!signal_sync); 

Eine gute Website für weitere Informationen über die Synchronisation: https://www.doulos.com/knowhow/fpga/synchronisation/

Wie ich verstehe, ist Ihr Signal "Zustand" in 3 Bits codiert, dann können Sie tun:

assign trigger = (state == 3'b000) ? (signal_sync_old & (!signal_sync)):0; 
+0

zu klären: "signal_in" ist das Bit ich von meiner USB-To-UART-Brücke oder Testumgebung während der Simulation erhalten würde. Modul StartDetectionUnit ( Eingang Clk, Zustand, Signal_in, Ausgang Auslöser ); reg signal_d; immer @ (pagedge clk) beginnen signal_d <= signal_in; Ende zuweisen Trigger = (! Signal_in) & Signal_d & (! Zustand); endmodule Ich schrieb es so, und es scheint von meinen ersten paar Simulationen Iterationen richtig zu funktionieren. Der Status, in dem ich arbeiten muss, ist als "000" codiert. –

+0

Asynchrones externes Eingangssignal kann nicht simuliert werden. Es wird immer in der Simulation funktionieren. – FabienM

+0

Sogar durch eine Testbench? –

-3

Für den synchronen Entwurf kann die Erkennung der fallenden Flanke auf diese Weise erfolgen.

Hier ist das Zustandsdiagramm und die Berechnungen für die obige Logik.

Falling Edge Detection - Synchronous

Die fallende Flanke Erkennung kann auf die folgende Art und Weise durchgeführt werden.

assign sout = !(sin | (!sin)); 
+0

Dies funktioniert nicht im synchronen Design. – FabienM

+0

Ja. Dank dafür. Ich habe die Antwort aktualisiert. –