2015-07-13 13 views
6

Supponiamo di dover provare diversi bit su un file std_logic_vector. sarebbe meglio implementare un singolo processo, for-loops per ogni bit o istanziare processi "n" usando for-generate su cui ogni processo verifica un bit?Qual è la differenza pratica tra l'implementazione di FOR-LOOP e FOR-GENERATE? Quando è meglio usare l'uno sull'altro?

FOR-LOOP

my_process: process(clk, reset) begin 
    if rising_edge (clk) then 
    if reset = '1' then 
     --init stuff 
    else 
     for_loop: for i in 0 to n loop 
     test_array_bit(i); 
     end loop; 
    end if;  
    end if; 
end process; 

generare FOR-

for_generate: for i in 0 to n generate begin 
my_process: process(clk, reset) begin 
    if rising_edge (clk) then 
    if reset = '1' then 
     --init stuff 
    else 
     test_array_bit(i); 
    end if; 
    end if; 
end process; 
end generate; 

Quale sarebbe l'impatto sulla FPGA e ASIC implementazioni per questi casi? Che cosa è facile da gestire con gli strumenti CAD?

EDIT: Solo l'aggiunta di una risposta che ho dato a uno aiutando ragazzo, per rendere la mia domanda più chiaro:

Per esempio, quando sono andato un pezzo di codice utilizzando per-loop sul ISE, la sintesi di sintesi ha dato un risultato equo, mi ci vorrà molto tempo per calcolare tutto. quando ho ri-codificato il mio design, questa volta usando for-generate, e diversi processi, ho usato un po 'più di area, ma lo strumento è stato in grado di calcolare tutto in modo più veloce e il mio risultato di timing era anche migliore. Quindi, implica una regola, che è sempre meglio usare per-genera con un costo di area extra e una complessità inferiore o è uno dei casi che devo verificare ogni singola possibilità di implementazione?

risposta

3

Supponendo una logica relativamente semplice nelle funzioni di reset e test (ad esempio, nessuna interazione tra bit adiacenti) mi sarei aspettato che entrambi generassero la stessa logica.

Comprendere che poiché l'intero ciclo for viene eseguito in un singolo ciclo di clock, la sintesi lo srotolerà e genererà un'istanza separata di test_array_bit per ciascun bit di input. Pertanto è abbastanza possibile che gli strumenti di sintesi generino una logica identica per entrambe le versioni, almeno in questo semplice esempio.

E su questa base preferirei (marginalmente) la versione for ... loop perché localizza la logica del programma, mentre la versione "genera" la globalizza, ponendola al di fuori dello standard process. Se trovi la versione loop leggermente più facile da leggere, allora sarai d'accordo ad un certo livello.

Tuttavia, non si paga per essere dogmatici riguardo allo stile e l'esperimento lo dimostra: lo loop sintetizza su hardware inferiore. Gli strumenti di sintesi sono software complessi e imperfetti, come i compilatori altamente ottimizzanti e condividono molti degli stessi problemi. A volte mancano un'ottimizzazione "ovvia" e talvolta apportano una ottimizzazione complessa (ad es.nel software) funziona più lentamente perché la sua dimensione aumentata ha trascinato la cache.

Quindi è preferibile scrivere nello stile più pulito dove è possibile, ma con una certa flessibilità per aggirare limiti degli strumenti e occasionalmente difetti reali degli strumenti.

Diverse versioni degli strumenti rimuovono (e occasionalmente introducono) tali difetti. Potresti scoprire che l'opzione "usa il nuovo parser" di ISE (per le parti pre-Spartan-6) o Vivado o Synplicity si ottiene esattamente dove il parser più vecchio di ISE non lo fa. (Ad esempio, passando i segnali fuori dalle procedure, le vecchie versioni di ISE avevano dei bug seri).

Potrebbe essere istruttivo modificare l'esempio e vedere se la sintesi può "farlo bene" (produrre lo stesso hardware) per il caso più semplice e reintrodurre la complessità finché non si trova quale costrutto ha esito negativo.

Se scopri qualcosa di concreto in questo modo, vale la pena riportarlo qui (rispondendo alla tua stessa domanda). Xilinx veniva utilizzato per incoraggiare la segnalazione di tali difetti tramite il proprio sistema Webcase; alla fine furono persino riparati! Sembrano averlo fermato, tuttavia, negli ultimi due anni.

0

Il primo frammento sarebbe equivalente alla seguente:

my_process: process(clk, reset) begin 
    if rising_edge (clk) then 
    if reset = '1' then 
     --init stuff 
    else 
     test_array_bit(0); 
     test_array_bit(1); 
     ............ 
     test_array_bit(n); 
    end if;  
    end if; 
end process; 

Mentre la seconda genererà n+1processi per ogni i, insieme con la logica di reset e tutto (che potrebbe essere un problema come quello la logica tenterà di guidare gli stessi segnali da processi diversi).
In generale, i cicli for sono istruzioni sequenziali, contenenti istruzioni sequenziali (vale a dire che ogni iterazione viene eseguita in sequenza dopo la precedente). I loop for-generate sono istruzioni concorrenti, contenenti istruzioni concorrenti e questo è il modo in cui è possibile utilizzarlo per rendere diverse istanze di un componente, ad esempio.

+0

Ciao Eugene, grazie mille per aver risposto. Mi dispiace, ma avrei dovuto essere più chiaro sulla mia domanda. Conosco le basi della codifica e le implicazioni "logiche" dell'uso di entrambe le strutture. Il mio dubbio è sul risultato pratico del loro utilizzo. Ho usato l'esempio con un semplice vettore proprio come una vetrina, ma in pratica le cose sono molto più complicate. Quindi, riformulando: se ho un pezzo di codice che dovrebbe darmi una risposta in un ciclo di clock (o eseguire tutti i suoi contenuti in parallelo, se questo si adatta meglio) cosa, dal punto di vista fisico lvl, sarebbe la migliore implementazione strategia? –

+0

Ad esempio, quando eseguo un pezzo di codice usando for-loops su ISE, il sommario di sintesi mi ha dato un risultato equo, impiegando molto tempo per calcolare tutto. quando ho ricodificato il mio progetto, questa volta usando for-generate, e diversi processi, ho usato un po 'più di area, ma gli strumenti sono stati in grado di calcolare tutto in modo più veloce e anche il mio risultato di timing era migliore. Quindi, implica una regola, che è sempre meglio usare per-genera con un costo di area extra o è uno dei casi che devo verificare ogni singola possibilità di implementazione? –

+0

Il calcolo più veloce è il risultato della natura parallela della seconda implementazione. E, come sempre, c'è un compromesso con il numero di risorse utilizzate. Se osservate lo schema RTL di entrambe le implementazioni, vedrete la differenza. Personalmente sto usando i cicli 'generate' quando codifico la logica RTL, cioè quando specifichi la struttura hardware esatta ei loop' for' con descrizioni comportamentali (beh, quasi mai :)) –

Problemi correlati