2017-05-07 4 views
0

Ich habe ein Problem mit meinem Verilog-Code. Ich habe 2 Uhren - eine 100 kHz, Sekunde 10 kHz. Ich möchte nur LED mit 100kHz Frequenz umschalten, wenn 10kHz HIGH ist. Aber meine Leistung ist immer noch niedrig. Dies ist mein Code:Verilog Wartefunktion Erklärung

module LED_toggle(
    input clock_100kHz, 
    input clock_10kHz, 

    output reg LED_PIN, 
); 
    initial begin   
     LED_PIN <= 1'b0; 
    end 

    always begin 
     if(clock_10kHz) begin 
      LED_PIN = 1'b1; 
      @(posedge clock_100kHz);    
      LED_PIN = 1'b0; 
      @(posedge clock_100kHz); 
     end 
     else begin 
      LED_PIN = 1'b0; 
     end 
    end 

endmodule 

Ich weiß, dass ich dies auf andere Weise (wie Trigger auf 100kHz Rand und Zustand ot 10kHz überprüfen) tun können, aber ich versuche zu verstehen, warum @ (posedge clock_100kHz); handle nicht wie ich es erwarte. Ich versuch auch zu warten (clock_100kHz), aber das funktioniert auch nicht.

Ich bin sicher, dass meine Uhren richtig konfiguriert sind, da dieser Code funktioniert wie ich erwarten:

module LED_toggle (
    input clock_100kHz, 
    input clock_10kHz, 

    output reg LED_PIN, 
); 
    initial begin   
     LED_PIN <= 1'b0; 
    end 

    always begin 
     if(clock_10kHz) begin 
      LED_PIN = ~LED_PIN; 
     end 
     else begin 
      LED_PIN = 1'b0; 
     end 
    end 

endmodule 

aber ich versuche zu verstehen, was mit meiner Warte Bedingungen falsch ist.

Antwort

2

Es wäre wahrscheinlich am besten, wenn Sie das mehr wie HW anstelle von SW bauen. Ihre Blöcke, die immer beginnen, verhalten sich eher wie ein Verhaltensmodell als eine HW-Repräsentation.

Es sieht so aus, dass basierend auf dem ersten Snippet, das Sie tatsächlich wollen, die LED mit 50kHz laufen soll (da Sie die LED-Ausgabe auf jeder Seite der 100kHz umschalten)? Das wäre was ich tun würde, für 100kHz:

assign LED_PIN = clock_10kHz & clock_100Hz; 

Für

50kHz
always @(posedge clock_100kHz) begin 
    if(clock_10kHz) LED_PIN <= ~LED_PIN 
    else   LED_PIN <= 1'b0; 
end 

Was der erste Schnipsel tut, ist nur die 10kHz Uhr als Gate verwenden und im Grunde direkt die 100kHz Uhr treibt die LED .

Das zweite Snippet verwendet immer noch den 10-kHz-Takt als Gatter, aber es ist ein Register eingebaut, das mit dem 100-kHz-Takt getaktet wird, der den LED_PIN-Ausgang ansteuert. Dadurch wird die LED 50kHz anstelle der 100kHz, die Sie beschrieben/gewünscht haben, umgeschaltet. Dies entspricht jedoch Ihrem Verhalten in Ihrem ersten Snippet. Ich nehme an, dass diese Uhren synchron sind, aber eigentlich sollte dieses Gatter in die 100kHZ-Taktdomäne synchronisiert werden, aber das ist ein anderes Thema.

immer beginnen ist wirklich ein Verhaltenskonstrukt. Es ist im Wesentlichen etwas, das sagt "mach das immer und tu es so schnell wie ich sage". In Ihrem Beispiel bin ich mir nicht sicher, wie der Simulator nicht gerade weggelaufen ist, als der Takt 10 kHz niedrig war. Viele Simulatoren würden keine Zeitangabe (wie z. B. eine # Verzögerung oder @()) sehen und versuchen, dies so oft wie möglich zu berechnen, oder einfach einen Fehler, wenn es schlau genug wäre, eine Endlosschleife zu sehen. Denken Sie daran, dass Verilog eine ereignisbasierte Sprache ist. In Ihrem Code gibt es Fälle, in denen Sie keine "Ereignisse" haben, nur Aktionen, die passieren sollten. Dies kann und wird dir etwas Kummer bereiten. Wenn Sie andere Programmiersprachen verwendet haben und Verilog starten, ist das normalerweise der schwierigste Teil, den Sie verstehen sollten, aber wenn Sie das tun, ist es viel sinnvoller.

Hoffentlich hilft das!