Ich habe einen Verilog-Code geschrieben und die RTL-Simulation funktioniert einwandfrei. Danach habe ich das Design mit dem XST-Tool in Xilinx ISE 13.2 synthetisiert. Die Post-Synthese-Simulation zeigt einige unerwartete Ergebnisse. Ich weiß nicht, was schief gelaufen ist, da es während der Simulation keine Warnungen gab. Was sollte ich jetzt tun? Gibt es eine Möglichkeit, die Netzliste auf Post-Synthese-Ebene zu debuggen? Woher weiß ich, was mein Synthesetool (XST) mit meinem Design macht? Ich habe einen Teil meines Quellcodes beigefügt. Es dient zur Steuerung des FSM meines Designs.
always @ (posedge clock)
begin
case (state) // s0, s1, s2, s3, s_reset are parameters
s_reset:
begin
if(start_proc)
state <= s0;
else
state <= s_reset;
end
s0: begin
pixel_value <= dataOut_bigimage;
pixel_ref <= dataOut_smallimage;
j <= j+1;
if(j==1'b1)
i <= i+1;
if ({i,j} == 2'b11)
if(base_col == 3'b101)
begin
base_row_prev <= base_row;
base_col_prev <= base_col;
base_col <= 3'b000;
base_row <= base_row+1;
end
else
begin
base_col <= base_col+1;
base_col_prev <= base_col;
base_row_prev <= base_row;
end
state <= s1;
end
s1: begin
if (pixel_value <= pixel_ref)
accumulator <= accumulator+1;
else
accumulator <= accumulator;
if({i,j} == 2'b00)
state <= s2;
else state <= s0;
end
s2: begin
if (accumulator > 2'b01)
begin
matchcount <= matchcount+1;
rowmatch[matchcount] <= base_row_prev;
colmatch[matchcount] <= base_col_prev;
end
accumulator <= 2'b00;
if (base_row == 2'b11)
state <= s3;
else
state <= s0;
end
s3: begin
task_done <= 1'b1;
state <= s3;
end
Alles innerhalb des Always-Blocks ist vom Reg-Datentyp und wird ordnungsgemäß in einem separaten Anfangsblock initialisiert
Vielen Dank im Voraus
Fügen Sie ein Reset-Signal hinzu (und verwenden Sie es).
Xilinx FPGAs verfügen über ein globales Set/Reset (GSR)-Signal, das alle Register in ihren Standardzustand oder wie in der Registerdeklaration angegeben versetzt (dies ist im XST-Benutzerhandbuch am Anfang von Kapitel 5 dokumentiert). AFAIK, der @initial Block wird ignoriert.
Beim Start des FPGAs geht es allerdings chaotisch zu, denn:
Die anfänglichen Flip-Flop-Werte nach dem GSR reichen also nicht aus.
Erstellen Sie ein Modul, das ein Reset-Signal für jede Taktdomäne generiert. Sie können es erstellen, indem Sie relevante asynchrone Rücksetzsignale UND-verknüpfen, z. B. einen externen Rücksetzstift, PLL/DCM-verriegelte Signale, und es wie folgt mit einem Synchronisierer verwenden:
(Quelle: Wie setze ich mein FPGA zurück? )
Hier ist ein Teil Ihres Codes, der jemandem, der neu bei Verilog ist, ein Bein stellen könnte:
j <= j+1;
if(j==1'b1)
i <= i+1;
if ({i,j} == 2'b11)
...
In diesem Code j
wird für den Vergleich ( if(j==1'b1)
) der alte Wert von verwendet j
, nicht der neu inkrementierte Wert. Aber ich vermute, Sie wussten das bereits, und wenn dies Ihr Problem wäre, hätten Sie es auf jeden Fall in der Verhaltenssimulation gesehen (es sei denn, Sie hätten eine blockierende Zuweisung verwendet, wie bei der Verhaltenssimulation j = j+1
).
Eine weitere seltsame Sache an Ihrem Code ist, dass Sie feststecken, sobald Sie Zustand 3 erreichen. Sie haben keinen Mechanismus bereitgestellt, um in den Reset-Zustand oder in den Zustand 0 zurückzukehren, was ein ungewöhnliches Design ist, aber auch nicht nach dem Problem klingt, nach dem Sie fragen.
Anscheinend gibt es eine werkzeugspezifische Funktion, mit der in Ihrem Fall erste Blöcke synthetisiert werden können. Das war mir nicht bewusst, als ich das geschrieben habe. Ich frage mich, warum sie dieses Feature hinzufügen würden, weil es nur einen schlechten Programmierstil fördern würde. Sinnvoller wäre eine Power-on-Reset-Megafunktion. Nehmen Sie diese Antwort also als allgemeinen Rat.
Alles innerhalb des Always-Blocks ist vom Reg-Datentyp und wird ordnungsgemäß in einem separaten Anfangsblock initialisiert
Anfängliche Blöcke sind normalerweise nicht synthetisierbar. Obwohl einige Tools den anfänglichen Block möglicherweise korrekt implementieren, ist es aus Gründen der Portabilität nicht ratsam, sich auf dieses Verhalten zu verlassen. Wenn Sie beispielsweise Werkzeuge wechseln, kann dies Ihr Design beschädigen. Sie sollten sie nicht in Blöcken verwenden, die Sie im Allgemeinen synthetisieren möchten, da das Verhalten vor und nach der Synthese möglicherweise nicht übereinstimmt.
Ihr Block hat kein Rücksetzsignal, und normalerweise bedeutet dies, dass keine Initialisierung in der Hardware erfolgt. Um dieses Problem zu beheben, fügen Sie Ihrem Code ein Reset-Signal und eine Reset-Bedingung hinzu. Platzieren Sie dann den Inhalt des Anfangsblocks in dem neuen Rücksetzbedingungsblock.
Ich würde Ihnen raten, einen kombinatorischen Block zu haben und die gesamte Steuerlogik dorthin zu verschieben und nur die Datenübertragungslogik im sequentiellen Block zu belassen. Ich habe Ihren Code nicht ausgeführt, aber ich habe das Gefühl, dass im Fall des Zustands s0 Ihre beiden if-Bedingungen (if j==1'b1) und (if {i,j} == 2'b11) sein könnten miteinander kollidieren. Bei einer normalen Verhaltenssimulation simuliert das Tool das Design ohne Verzögerungen. Nach der Synthese werden die Verzögerungen jedoch zum Design hinzugefügt und können das Problem des "zufälligen Ergebnisses" verursachen, das Sie sehen.
if
hervorgehobenen Aussagen verursacht werden könnte. Sie würden auf keine Weise, die ich sehen kann, "kollidieren".Ich habe im XTS-Benutzerhandbuch keine Erwähnung darüber gefunden, dass initial
Blöcke die richtige Methode zum Initialisieren von Registerwerten sind .
Andererseits fand ich auf Seite 109 folgende Aussage: "Da Initialblöcke während der Synthese ignoriert werden, werden immer nur Blöcke diskutiert".
Nun, es scheint, dass Ihr Synthese-Tool die Initialisierung von Registern in Blöcken nicht unterstützt initial
. Sie haben zwei Möglichkeiten:
reg [3:0] arb_priority = 4'b1011;
Generell rate ich dringend davon ab, initial
Statements zur Initialisierung von Werten zu verwenden (außer zur Initialisierung von SRAM-Inhalten und Initialisierung von Testbench-Signalen).
Tim
Akash Singh
Tim
Tim
Akash Singh
Tim