Ich habe mit Verilog einen einfachen Zähler von 0 bis 9 erstellt. Der Ausgang sind 4 LEDs, die eingeschaltet werden, wenn ihr entsprechendes Bit 1 ist. Der Code synthetisiert gut, aber auf dem FPGA leuchtet nur eine LED wiederholt ein und aus. Die anderen drei LEDs leuchten überhaupt nicht. Hier ist mein Code:
module counter(
input wire clock,
input wire reset,
output wire [3:0] o_number
);
reg [3:0] cur_state;
reg [3:0] next_state;
always @(posedge clock or posedge reset) begin
if (reset) cur_state <= 4'b0;
else
cur_state <= next_state;
end
// Next state function
always @(*) begin
if (cur_state == 4'b1001) next_state = 4'b0000;
else next_state = cur_state + 4'b0001;
end
// Output function
assign o_number = cur_state;
endmodule
module display(
input wire [3:0] inumber,
output wire [3:0] LEDs
);
assign LEDs = inumber;
endmodule
Keine der LEDs ist defekt, da sie alle leuchten, wenn sie einzeln getestet werden. Die Uhr wurde so eingestellt, dass ihre Periode etwa 2 Sekunden beträgt.
Bitte hilf mir. Danke schön.
Ich habe das Zählermodul überarbeitet. Hier sind alle Dateien, die ich verwendet habe:
oben.v
module top ( input wire clock, input wire reset, output wire [3:0] LEDs);
counter c1 (.clock(clock), .reset(reset), .o_number(number));
display d1 (.inumber(number), .LEDs(LEDs));
endmodule
Zähler.v
module counter ( input wire clock, input wire reset, output wire [3:0] o_number);
reg [3:0] cur_state;
always @ (posedge clock or posedge reset) begin
if (reset) cur_state[3:0] <= 4'b0000;
else begin
if (cur_state[3:0]==4'b1001) cur_state[3:0] <= 4'b0000;
else cur_state[3:0] <= cur_state[3:0] + 4'b0001;
end
end
assign o_number[3:0]=cur_state[3:0];
endmodule
Anzeige.v
module display( input wire[3:0] inumber, output wire [3:0] LEDs);
assign LEDs[3:0] = inumber[3:0];
endmodule
top.ucf
NET "LEDs[0]" LOC = K12;
NET "LEDs[1]" LOC = P14;
NET "LEDs[2]" LOC = L12;
NET "LEDs[3]" LOC = N14;
NET "clock" LOC = T9;
NET "reset" LOC = L14;
Es gab ein Problem mit dem oberen Modul. Ich habe den Draht, der zum Verbinden des Anzeige- und Zählermoduls verwendet wird, nicht deklariert.
Hier ist die überarbeitete top.v:
module top ( input wire clock, input wire reset, output wire [3:0] LEDs);
wire [3:0] number;
counter c1 (.clock(clock), .reset(reset), .o_number(number));
display d1 (.inumber(number), .LEDs(LEDs));
endmodule
Die LEDs leuchten jetzt je nach Zustand korrekt.
Ich vermute, das Problem kann in der Verwendung cur_state
und next_state
ohne Indizes liegen. Versuchen
always @(posedge clock or posedge reset) begin
if (reset) cur_state[3:0] <= 4'b0;
else begin
cur_state[3:0] <= next_state[3:0];
end
always @(*) begin
if (cur_state[3:0] == 4'b1001) next_state[3:0] <= 4'b0000;
else next_state[3:0] <= cur_state[3:0] + 4'b0001;
end
Und
assign o_number[3:0] = cur_state[3:0];
Und
assign LEDs[3:0] = inumber[3:0];
Beachten Sie, dass ich [3:0]
überall hinzufüge und im zweiten Konstrukt =
zu ändere .<=
always
Das Ziel kann durch eine viel einfachere Konfiguration erreicht werden:
module counter(
input wire clock,
input wire reset,
output wire [3:0] LEDs
);
reg [3:0] cur_state;
wire reset_n=~reset;
assign LEDs[3:0] = cur_state[3:0];
always @(posedge clock or negedge reset_n) begin
if (!reset_n) cur_state[3:0] <= {4{1'b0}};
else begin
if (cur_state[3:0] == 4'b1001) cur_state[3:0] <= {4{1'b0}};
else cur_state[3:0] <= cur_state[3:0] + 4'b1;
end
end
Update:LEDs[3:0]
Hat nicht geholfen - dann erstmal nur mit zuordnen 4'b1111
und schauen ob alle LEDs leuchten.
Die nächste mögliche Ursache für das Problem ist, always @(*) begin
dass es beim Ändern von Eingangsleitungen für das Inhaltskonstrukt ausgelöst wird always
. Das einzige Ereignis, das passiert, wenn Sie Reset ausgeben, cur_state
ändert sich auf 0 und wird somit zu cur_state
4'b0001 und behält diesen Wert.
Update 1: Sie haben also LSB, andere 3 Bits funktionieren nicht. Sie haben getestet, dass alle LEDs leuchten, wenn Sie 4'b1111 in die Drähte der LEDs schreiben. Ich denke, der Code ist korrekt, da ist etwas anderes falsch. Folgendes berücksichtigen:
vereinfachen den Wechsel von Dezimal zu Hexadezimal. In diesem Fall müssen Sie nur cur_state[3:0] <= cur_state[3:0] + 4'b1;
ohne Bedingungen nach Zustand #10 suchen
always @ (posedge clock or posedge reset) begin if (reset) cur_state[3:0] <= 4'b0000; else cur_state[3:0] <= cur_state[3:0] + 4'b0001; end
Überlegen Sie, was reset
während des Tests passiert. Bist du sicher, dass es konstant niedrig ist? Alternativ entfernen Sie es überhaupt aus der Konfiguration:
always @ (posedge clock) begin cur_state[3:0] <= cur_state[3:0] + 4'b0001; end
synthetisiere meinen obigen Code mit nur einem Modul und reset_n
um zu sehen, ob es auch nicht funktioniert.
versuchen Sie es mit anderen LEDs:
always @ (posedge clock) begin cur_state[3:1] <= cur_state[3:1] + 3'b001; end
always @(*)
. Sie können zwei Module behalten, aber es sollte keine Notwendigkeit bestehen, das erste Modul mit zwei Always-Konstrukten zu verkomplizieren. Die Implementierung sollte so prägnant und lesbar wie möglich sein – dies ist ein Ziel jeder Programmiersprache, einschließlich Verilog.always @(*)
anscheinend nicht das leistet, was Sie davon erwarten. RTFM darüber, was es tut und vor allem wann.always
sollte Ihre aktuelle Bedingung dazu führen, dass Operand(en) in der Bedingung nicht mit den entsprechenden Kanten in der umschließenden Ereignissteuerung des Always-Construct- Fehlers übereinstimmen können. Erklären Sie auch, wie es jetzt nicht funktioniert.
Makoto
HelferKönig
Makoto
HelferKönig
Makoto
HelferKönig
Greg
LEDs[3]
die einzige ist, die aufleuchtet. Wenn dies der Fall ist, versuchen Sie, Ihre Uhr auf 1/4 ihrer aktuellen Frequenz zu verlangsamen. Wenn das nicht funktioniert, überprüfen Sie die Zuordnung in Ihrer top.ucfGreg
or posedge reset
, um es zu einem synchronen Reset zu machen. Ich bezweifle, dass die Asynchronität das Problem ist, ich glaube, es ist die Taktfrequenz, die wahrscheinlich das Problem ist.