Mein Professor hat sich diesen Code gut 10 Minuten angeschaut, konnte das Problem aber nicht finden. Also hoffe ich, dass ein frisches Paar Augen etwas sehen wird, das wir beide verpasst haben. Für Hinweise bin ich wie immer dankbar.
Kontext: Ein Modul, das von FFF bis 000 zählt und sich dann wiederholt.
Problem: Nur die niedrigste 2 zeigt ein Dekrement an, überspringt mehrere Zahlen gleichzeitig und springt dann an einem scheinbar zufälligen Punkt zurück zu FF.
Annahmen: 1. Der SevenSegment-Treiber funktioniert ordnungsgemäß. Es wurde manuell überprüft und zeigt die ihm zugewiesene Hex-Zahl an. 2. Das ClockDivider-Modul funktioniert wie vorgesehen. Der Countdown verringert sich alle 1 Sekunde, wie es sollte (CLOCK_50 = 50 MHz)
Möglicher Hinweis: Verilog warnt, dass „cd“ ein abgeleiteter Latch ist und seinen Wert über einen oder mehrere Pfade im „always“-Block behält
module ClockDivider( input CLOCK_50, output reg[ 31:0] count );
parameter clockDivisor = 50_000_000;
always @( posedge CLOCK_50 )
if ( count == 0)
count <= clockDivisor;
else
count <= count - 1;
endmodule
module Test (
//////////// CLOCK //////////
input CLOCK_50,
//////////// SEG7 //////////
output [6:0] HEX0,
output [6:0] HEX1,
output [6:0] HEX2
);
//ClockDivider Output
wire [31:0] cout;
reg [11:0] cd;
ClockDivider a( CLOCK_50, cout);
always @(cout)
begin
if (cout == 32'h0)
if (cd == 12'h0)
cd <= 12'hFFF;
else
cd <= (cd - 12'h001);
end
SevenSegment C2( cd[11:8], 1'b0, HEX2 );
SevenSegment C1( cd[7:4], 1'b0, HEX1 );
SevenSegment C0( cd[3:0], 1'b0, HEX0 );
endmodule
Persönlich hatte ich Probleme mit immer @(cout) , das flockig sein kann.
Ich würde immer immer @(posedge CLOCK_50) verwenden . Meiner Meinung nach sind auf diese Weise korrekte Ergebnisse garantiert ...
BEARBEITEN: Klarerer Code für den obigen Vorschlag hinzugefügt
always @(cout) -> always @(posedge CLOCK_50)
cout sollte sich theoretisch nur mit der positiven Flanke der Uhr (oder des Codes) ändern, aber was tatsächlich passiert, ist vielleicht anders. Ihr Timing-Bericht informiert Sie über die Einrichtungszeit und den Puffer - und dies kann Ihr Problem sein. Ändern Sie Ihre Logik auf "synchron" und ich wette mit Ihnen, dass es funktioniert.
Außerdem sollten Sie den abgeleiteten Latch als bewährte Methode entfernen. alles, was dies erfordern würde, ist eine else-Anweisung:
if (cout == 32'h0)
if (cd == 12'h0)
cd <= 12'hFFF;
else
cd <= (cd - 12'h001);
else
cd <= cd;
EDIT: vorgeschlagener Arbeitscode
module ClockDivider(input CLOCK_50,
output reg[ 0:0] en
);
parameter clockDivisor = 50_000_000;
reg [31:0] i;
always @( posedge CLOCK_50 ) begin
if ( i == clockDivisor ) begin
en <= 1;
i <= 0;
end
else begin
en <= 0;
i <= i + 32'b1;
end
end
endmodule
//1Hz clock output
wire [0:0] en;
//Holds the countdown value FFF-000
reg [11:0] cd;
ClockDivider CLOCK_1Hz( CLOCK_50, en);
always @(posedge CLOCK_50)
if (en) begin
if (cd == 12'h0)
cd <= 12'hFFF;
else
cd <= (cd - 12'h001);
end
else
cd <= cd;
end
else cd <= cd;
erzeugt immer noch einen Latch; Alles, was Sie getan haben, ist, es explizit und nicht implizit zu machen. Im Allgemeinen sollten auf diese Weise erstellte kombinatorische Latches vermieden werden.always @(<xxx>)
von Ihnen empfohlenen hinzufügen würden.Dank ThePhoton und johnymopo konnte ich die Lösung herausfinden. Die Lösung bestand darin, ClockDivisor selbst als langsamere Uhr fungieren zu lassen. Der Code wird:
module ClockDivider( input CLOCK_50, output reg[ 0:0] count );
parameter clockDivisor = 50_000_000;
reg [31:0] i;
always @( posedge CLOCK_50 )
begin
i <= i + 32'b1;
if ( i == clockDivisor )
begin
count <= 1;
i <= 0;
end
else
count <= 0;
end
endmodule
In diesem Fall ist dies ein 1-Hz-Takt. Das Countdown-Dekrement kann dann mit der Pose dieser langsameren Uhr ausgelöst werden:
//1Hz clock output
wire [0:0] slowClock;
//Holds the countdown value FFF-000
reg [11:0] cd;
ClockDivider CLOCK_1Hz( CLOCK_50, slowClock);
always @(posedge slowClock)
begin
if (cd == 12'h0)
cd <= 12'hFFF;
else
cd <= (cd - 12'h001);
end
cd
ändert es sich einmal pro Sekunde, basiert aber immer noch auf dem 50-MHz-Takt und ist daher immer noch ein Latch - aber das scheint seltsam. Ich empfehle nach wie vor die Verwendung einer gemeinsamen Uhr für die gesamte Logik, wenn möglich.
Das Photon
Das Photon
cout
in der Empfindlichkeitsliste stehen, aber es erscheint nie rechts in einer der darunter liegenden Aufgaben.cout
Also was kann das Tool daraus schließen, außer dass man es als Taktsignal für Block verwenden möchte .Meridian