Ich habe derzeit ein Spartan-6-FPGA in einem Digilent Nexus 3-Board. Ich verwende Xilinx 14.6 Project Navigator, um den Code zu schreiben und das FPGA zu programmieren.
Mein Code für das oberste (und einzige) Modul lautet wie folgt:
21 module blinker(
22 input clk,
23 output reg led_state
24 );
25
26 reg [31:0] count;
27 wire count_max = 32'd50000000;
28
29 assign count_next = (count_next > count_max) ? 32'd00000000 : count + 32'd00000001;
30 assign led_next = (count == count_max) ? ~led_state : led_state;
31
32 always @(posedge clk)
33 begin
34 count <= count_next;
35 led_state <= led_next;
36 end
37
38 endmodule
Laut Nexus 3-Referenzhandbuch hat das Board einen 100-MHz-Oszillator an Pin V10, und so habe ich in meiner Benutzerbeschränkungsdatei den V10-Pin dem clk-Eingangssignal meines Moduls zugeordnet.
Da der Oszillator bei 100 MHz liegt, setze ich count_max auf 50.000.000, sodass der led_state alle 50 x 10 ^ 6 clk-Flanken oder jede halbe Sekunde bei 100 MHz invertieren sollte.
Als ich versuchte, eine Synthese mit XST im Projektnavigator durchzuführen, erhalte ich diese Warnmeldungen:
WARNING:HDLCompiler:413 - "C:\Users\Public\Documents\Xilinx Projects\blinker\blinker.v" Line 29: Result of 32-bit expression is truncated to fit in 1-bit target.
WARNING:Xst:2404 - FFs/Latches <count<31:1>> (without init value) have a constant value of 0 in block <blinker>.
WARNING:Xst:2170 - Unit blinker : the following signal(s) form a combinatorial loop: n0011<0>.
Ich kann jedoch immer noch die .bit-Datei erstellen und das Nexus 3 programmieren. Das Ergebnis ist jedoch, dass die LED, die ich durch den Ausgang bezeichnet habe, einfach die ganze Zeit an blieb (es sei denn, sie blinkt). so schnell, dass ich nicht bemerke, dass es blinkt).
Ich dachte, dass es vielleicht mit der Warnung zu tun hat, wo der Synthesizer den Ausdruck in Zeile 29 abgeschnitten hat, also habe ich versucht, count_next als 32-Bit-Vektor [31:0] zu deklarieren, sowohl als Reg als auch als Wire, und ihn auch zu initialisieren Wert. Versuchte den Synthesizer und ich bekomme stattdessen Fehler.
Das Deklarieren und Initialisieren von count, led_state, count_next, led_next hat auch nicht funktioniert.
Ich habe mich gefragt, ob sich jemand das ansehen und mir sagen kann, was mit dem Code nicht stimmt. Es gibt auch eine kombinatorische Schleife für das Signal "n0011<0>", die ich nicht kenne.
Das Problem, das ich sehe, ist, count_max
dass Sie einen 1 Bit breiten Draht deklariert haben und ihm dann eine 32-Bit-Konstante zuweisen - dies wird im Wesentlichen auf 1 Bit gekürzt.
Dies bedeutet dann, dass Sie in Zeile 29 Additionen und Vergleiche zwischen 32-Bit- und 1-Bit-Werten durchführen, sodass Sie das Problem erhalten, dass 32-Bit auf 1-Bit verkürzt werden.
Dann werden Ihre Berechnungen durch Erweiterung auf einen einzigen 1-Bit-Wert optimiert (im Wesentlichen läuft es auf ab if >0, set to 0, else add 1
), der immer nur 0 oder 1 sein wird und daher Ihre count[31:1]
(beachten Sie nicht das LSB, Bit 0) im Always-Konstrukt unverändert bleiben - weil Sie zuweisen sie auf immer 0.
Auch eine count_next
spezifische Deklaration würde helfen - Sie weisen einem nicht vorhandenen Draht zu, sodass ein Draht für Sie erstellt wird. Bei manchen Tools zB Modelsim wäre das ein Fehler, bei anderen zumindest eine Warnung. Der einfachste Weg, dies zu tun, wäre das Ersetzen assign count_next
durch wire [31:0] count_next
.
Wie Brian in den Kommentaren zu Recht betont, ist Ihre Bedingung schließlich falsch. Sie verwenden es count_next
als Teil seiner eigenen Assign-Anweisung, was einfach schlecht ist. Dies ist mit getakteten Registern problemlos möglich , da kein Risiko besteht, ein Design zu erstellen, das mit sehr hohen Frequenzen schwingt und möglicherweise das FPGA beschädigt. Ich glaube was du meinst ist (count >= count_max)
. Beachten Sie, dass ich auch zu >= geändert habe, das liegt daran, dass Ihre Zählung Null enthält - sagen Sie count_max = 5, Sie möchten, dass Ihr Zähler 0,1,2,3,4,0 geht - beachten Sie, wie 5 Taktzyklen benötigt werden von 0 bis 4 zählen und dann wieder auf 0 zurückgehen?
Ihre count_next-Leitung wird implizit deklariert. Das bedeutet, dass es ein Bit breit ist, daher wird count [31: 1] nie zugewiesen und Sie erreichen nie Ihre maximale Anzahl, die auch als 32 Bit und nicht als 1 Bit deklariert werden muss, wie Tom betonte.
wire [31:0] count_next;
localparam count_max = 32'd50000000; //you can use a wire but a parameter is a better description for a run time constant.
Es gibt mehrere andere Probleme, wie von anderen erwähnt.
Initialisieren Sie Ihre Zählregistrierung auf Null und geben Sie die richtige Breite für den count_next-Draht an. Sollte gut funktionieren, sobald Sie diese Änderungen vorgenommen haben.
user_1818839
count_next
den Ausdruck nicht verwenden, umcount_next
. Das ist, genau wie die Fehlermeldung sagt, eine kombinatorische Schleife. Ich bin mir ziemlich sicher, dass Sie hier verwenden wolltencount
.