Come evitare i fermi durante la sintesi


9

Voglio progettare un blocco di logica combinatoria usando VHDL, ma a volte il risultato sintetizzato contiene un latch involontario.

Quali linee guida di codifica devo seguire per evitare che il sintetizzatore deduca i latch?

Esempio: nel piccolo segmento di codice, dovrei usare le istruzioni if-else?


Se uno potesse ottenere quello che cerco di chiedere, per favore informatemi

Non ero sicuro di cosa intendevi dal tuo esempio. Verifica che la riformulazione corrisponda al tuo intento originale.
W5VO,

@fatai, ho già commentato, esiste un metodo specifico per eliminare il tuo account disponibile su meta.stackexchange.com. Ho collegato l'ultima domanda su cui sono stato segnalato. I moderatori sul posto non hanno questo potere, mai. Ciò richiede contattare il team di sviluppo.
Kortuk,

Risposte:


13

Per evitare i latch, è necessario assicurarsi che tutti gli output siano assegnati a tutti i possibili rami del codice.

per esempio,

if a = '1' then
   b(0) <= '1';
else
   b(1 downto 0) <= "00";
end if;

genererebbe un latch, perché nella prima condizione, il valore di b (1) non è specificato, quindi il compilatore ha deciso che si desidera mantenere lì il valore precedente di b (1). Un modo per scrivere questo che non genererebbe un latch è:

if a = '1' then
   b <= prev_b;
   b(0) <= '1';
else
   b(1 downto 0) <= "00";
end if;

...

if rising_edge (clk)
    prev_b <= b;
end if;

Qui si afferma esplicitamente che b deve conservare il suo vecchio valore e quindi sovrascrivere b (0) con il nuovo valore.

Un altro modo è quello di fornire un valore predefinito ba, come nella risposta di @ TomiJ.

Se pubblichi il codice su cui stai ottenendo un latch, potremmo aiutarti a trovare il motivo specifico.


Non credo che il tuo approccio b <= beviterà un latch, in quanto richiede ancora di preservare lo stato del segnale.
Tomi Junnila,

Potresti avere ragione; Sono troppo abituato alla logica con clock. Lo modificherò.
fbo,

6

Se stai usando i processi per la logica combinatoria (e io sconsiglio per questo motivo), assicurati che ogni percorso attraverso il processo assegni qualcosa a ogni segnale che il processo guida. Nessuna delle uscite può dipendere da nessuna delle uscite dell'ultima volta in cui il processo è stato eseguito.

Altrimenti si inferisce un latch perché la prossima volta che il processo è pianificato deve mantenere il valore del segnale che non ha ottenuto un nuovo valore l'ultima volta.

Preferisco mantenere la logica puramente combinatoria come assegnazioni continue e utilizzare i processi per la logica con clock, quindi non ottengo blocchi.


5

Quattro regole per evitare i fermi:

  • Non leggere dai segnali a cui scrivi.
  • Avere un elenco di sensibilità corretto (tutti i segnali letti dovrebbero essere nell'elenco di sensibilità)
  • Assicurati che tutti i segnali a cui la tua scrittura sono assegnati in ogni percorso. (ad esempio: in ogni ramo di un'istruzione if-else)
  • Per i processi che utilizzano una variabile, assicurarsi che ogni variabile sia inizializzata con un valore predefinito prima di leggerlo (in un'altra variabile o segnale).

Inoltre, se hai diversi processi combinatori, assicurati di non creare un ciclo.

Diversi stili di codifica possono aiutarti a rispettare queste regole, ad esempio lo stile nella risposta di @ TomiJ. Come sottolinea @Martin Thompson, potrebbe essere meglio evitare la logica combinatoria tutti insieme. Metti invece tutto in un processo a tempo.


+1 Bel set di regole. Saresti d'accordo sul fatto che la tua regola n. 2 (sull'elenco di sensibilità) è in realtà importante per garantire risultati coerenti tra sintesi e simulazioni, ma non fa davvero la differenza sull'inferenza dei fermi?
Rick

@rick AFAIK, non vi è alcuna garanzia di cosa farà uno strumento di sintesi con liste di sensibilità incomplete. Lo standard IEEE per VHDL Synthesis (1076.6-1999) afferma che: "L'elenco di sensibilità del processo deve contenere tutti i segnali letti all'interno dell'istruzione di processo. I processi con elenchi di sensibilità incompleti non sono supportati." Detto questo, so che alcuni strumenti di sintesi (forse tutti?) Accettano elenchi di sensibilità incompleti, ma semplicemente ignorano tutti gli elenchi di sensibilità. Se dovessi fare affidamento su quel comportamento anziché sullo standard IEEE più rigoroso, immagino che la tua affermazione sarebbe corretta.
Philippe

Grazie, suona bene, renderebbe il mio modello non conforme a quello standard. Ho appena ottenuto la mia curiosità perché tutti gli strumenti di sintesi che ho visto finora ignorano l'elenco di sensibilità, ma ho sentito voci che alcuni potrebbero inferire i latch.
Rick

3

Come è stato sottolineato da @fbo e @Martin Thompson, è necessario assicurarsi che a ogni segnale guidato dal processo sia assegnato un valore in ogni ramo del processo e tale valore non deve dipendere dallo stato precedente di nessuna delle uscite del processo.

Il modo più semplice per garantire ciò è assegnare un valore predefinito a ciascun output all'inizio del processo, ad esempio (cooptando l'esempio di fbo):

COMBO: process(a)
begin
    b <= (others => '0'); -- Assign default value to b
    if a = '1' then
        b(0) <= '1';
    else
        b(1 downto 0) <= "00";
    end if;
end process COMBO;

1
Questo è un buon metodo che uso spesso. A volte, tuttavia, un avviso di blocco può indicare che hai dimenticato di assegnare alcuni bit, mentre questo metodo potrebbe rendere più difficile trovare il bug. Ad esempio, se si assegnassero tutti i bit di un segnale wide separatamente e si fosse accidentalmente contato male.
fbo,

2
Solo in un processo combinatorio. In un processo a tempo, si inferisce un flipflop, che potrebbe essere esattamente quello che si desidera.
Martin Thompson,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.