Domanda

Ho fatto una simulazione del comportamento del mio codice, e funziona perfettamente. I risultati sono come previsto. Quando ho sintetizzare il mio codice e caricarlo su un FPGA 3e spartano e cercare di analizzare utilizzando chipscope, i risultati non sono nemmeno vicino a quello che mi sarei aspettato. Che cosa ho fatto in modo errato? http://pastebin.com/XWMekL7r

È stato utile?

Soluzione

Il tuo problema è con le linee 13-16, in cui si imposta i valori iniziali per i registri di stato:

 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; 

Si tratta di un equivalente a scrivere una dichiarazione "iniziale" l'assegnazione di questi valori, che non è sintetizzabile - non v'è alcuna cosa come un valore predefinito in hardware. Quando si mette il disegno all'interno di un FPGA, tutti questi registri assumerà valori casuali.

Al contrario, è necessario inizializzare questi contatori / stati sempre all'interno del vostro blocco, quando di reset è alto.

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

risposta alle domande di follow-up:

Quando si inizializza il codice del genere, nulla accade a livello hardware - si viene completamente ignorato, proprio come se hai messo in un comunicato $ display. Lo strumento di sintesi salta su tutta la simulazione solo costrutti, mentre di solito si dà una sorta di avvertimento su di esso (che in realtà dipende lo strumento).

Ora, il blocco e non-blocking domanda richiede una risposta molto lunga :). Io vi guiderà a questa carta dal comodo-2000, che è probabilmente la migliore carta mai scritto sull'argomento. Esso risponde alla tua domanda, così come molti altri sul tema. In seguito, si capisce perché utilizzando le istruzioni di blocco in logica sequenziale è considerata cattiva pratica, e perché il codice funziona bene con il blocco dichiarazioni in ogni caso.

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


Ulteriori risposte:

Il solito "pattern" per creare logica come la vostra è di avere due blocchi, uno sempre definire la logica, e uno che definiscono i flop. Nel primo, si utilizza il blocco istruzioni per implementare la logica, e in quest'ultimo si fermo (o reset) il valore generato. Quindi, qualcosa di simile:

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;

Si noti che sto usando un reset sincrono, ma è possibile utilizzare asincrona, se necessario.

Altri suggerimenti

Le linee 13-16 sono corrette. "Reg [6: 0] fib_number_cnt = 1;" non è lo stesso di istruzione using "iniziale". Leggi Xilinx guida di sintesi per la descrizione più dettagliata di come inizializzare i registri.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top