Frage

Ich habe eine Verhaltenssimulation von meinem Code, und es funktioniert perfekt. Die Ergebnisse werden als vorhergesagt. Wenn ich meinen Code synthetisieren und es zu einem spartanisch 3e FPGA laden und versuchen zu analysieren Chipscope verwendet, sind die Ergebnisse nicht einmal in der Nähe zu dem, was ich erwartet hätte. Was habe ich falsch gemacht? http://pastebin.com/XWMekL7r

War es hilfreich?

Lösung

Ihr Problem ist mit den Linien 13-16, wo Sie Anfangswerte für Zustandsregister gesetzt:

 reg    [OUTPUT_WIDTH-1:0] previousstate = 0;              
 reg    [OUTPUT_WIDTH-1:0] presentstate = 1;
 reg    [6:0] fib_number_cnt = 1;  
 reg    [OUTPUT_WIDTH-1:0] nextstate = 1; 

Dies ist eine äquivalent eine „initial“ Anweisung zum Schreiben dieser Werte zuweisen, die nicht synthetisierbaren ist - es gibt nicht so etwas wie einen Standardwert in der Hardware. Wenn Sie Ihr Design innerhalb eines FPGA gesetzt, alle diese Register auf Zufallswerte nehmen.

Stattdessen müssen Sie diese Zähler / Zustände in Ihrem immer blockieren, initialisieren, wenn Reset hoch ist.

always @(posedge clk or posedge reset)
  if (reset) begin
     previousstate <= 0;
     presentstate <= 1;
     ... etc ...
  end

Antwort auf die Folgefragen:

Wenn Sie Code so zu initialisieren, nichts passiert in der Hardware - es völlig ignoriert wird, so als ob Sie in einer $ Display-Anweisung gesetzt haben. Die Synthese-Tool überspringt alle simulations nur Konstrukte, während Sie in der Regel eine Art von Warnung darüber zu geben (das auf das Werkzeug wirklich abhängt).

Nun, Sperrung und nicht blockierende Frage erfordert eine sehr lange Antwort :). Ich werde Sie in dieses Papier von SNUG-2000 lenken, die wahrscheinlich das beste Papier ist jemals zu diesem Thema geschrieben. Es beantwortet Ihre Frage, wie auch viele andere zum Thema. Danach werden Sie verstehen, warum in sequentieller Logik blockiert Aussagen verwendet, ist eine schlechte Praxis betrachtet wird, und warum Ihr Code funktioniert gut mit Aussagen ohnehin blockiert.

http://cs.haifa.ac.il /courses/verilog/cummings-nonblocking-snug99.pdf


Weitere Antworten:

Das übliche „Muster“ Logik wie das Ihre zu schaffen, ist immer zwei Blöcke zu haben, eine der Logik definiert und eine Definition der Flops. Im ersteren Anweisungen verwenden blockieren Sie Logik zu implementieren, und im letzteren Sie einrasten (oder Reset) den generierten Wert. So etwas wie folgt aus:

wire some_input;

// Main logic (use blocking statements)
reg state, next_state;
always @*
  if (reset) next_state = 1'b0;
  else begin
    // your state logic
    if (state) next_state = some_input;
    else next_state = 1'b0;
  end

// Flops (use non-blocking)
always @(posedge clock)
  if (reset) state <= 1'b0;
  else state <= next_state;

Beachten Sie, dass ich ein synchrones Reset bin mit, aber Sie können async verwenden, wenn nötig.

Andere Tipps

Die Linien 13-16 sind korrekt. "Reg [6: 0] fib_number_cnt = 1;" ist nicht das gleiche wie „initial“ Anweisung. Lesen Xilinx Synthese Leitfaden für detailliertere Beschreibung, wie die Register zu initialisieren.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top