In Verilog, il blocco sempre è uno dei blocchi procedurali. Le istruzioni all'interno di un blocco sempre vengono eseguite in sequenza.
Un blocco sempre viene sempre eseguito, a differenza dei blocchi iniziali che vengono eseguiti solo una volta all'inizio della simulazione. Il blocco sempre dovrebbe avere un elenco sensibile o un ritardo ad esso associato
L'elenco sensibile è quello che indica al blocco sempre quando eseguire il blocco di codice.
Sintassi
rom
IL Verilog blocca sempre la seguente sintassi
always @ (event) [statement] always @ (event) begin [multiple statements] end
Esempi
Il simbolo @ dopo la parola riservata Sempre , indica che il blocco verrà attivato A la condizione tra parentesi dopo il simbolo @.
always @ (x or y or sel) begin m = 0; if (sel == 0) begin m = x; end else begin m = y; end end
Nell'esempio sopra descriviamo un mux 2:1, con input xey. IL Questo è l'input selezionato e M è l'output del mux.
In qualsiasi logica combinatoria, l'output cambia ogni volta che cambia l'input. Quando questa teoria viene applicata a sempre blocchi, il codice all'interno di sempre blocchi deve essere eseguito ogni volta che cambiano le variabili di input o output.
NOTA: può gestire tipi di dati reg e interi ma non può gestire tipi di dati wire.
Esistono due tipi di elenchi sensibili in Verilog, ad esempio:
- Sensibile al livello (per circuiti combinatori).
- Sensibile ai bordi (per infradito).
Il codice seguente è lo stesso mux 2:1, ma l'output M è ora un'uscita flip-flop.
always @ (posedge clk ) if (reset == 0) begin m <= 0; end else if (sel="=" 0) begin m <="x;" pre> <h4>NOTE: The always block is executed at some particular event. A sensitivity list defines the event.</h4> <h3>Sensitivity List</h3> <p>A sensitivity list is an expression that defines when the always block executed, and it is specified after the @ operator within the parentheses ( ). This list may contain either one or a group of signals whose value change will execute the always block.</p> <p>In the code shown below, all statements inside the always block executed whenever the value of signals x or y change.</p> <pre> // execute always block whenever value of 'x' or 'y' change always @ (x or y) begin [statements] end </pre> <p> <strong>Need of Sensitivity List</strong> </p> <p>The always block repeats continuously throughout a simulation. The sensitivity list brings a certain sense of timing, i.e., whenever any signal in the sensitivity list changes, the always block is triggered.</p> <p>If there are no timing control statements within an always block, the simulation will hang because of a zero-delay infinite loop.</p> <p>For example, always block attempts to invert the value of the signal clk. The statement is executed after every 0-time units. Hence, it executes forever because of the absence of a delay in the statement.</p> <pre> // always block started at time 0 units // But when is it supposed to be repeated // There is no time control, and hence it will stay and // be repeated at 0-time units only and it continues // in a loop and simulation will hang always clk = ~clk; </pre> <p>If the sensitivity list is empty, there should be some other form of time delay. Simulation time is advanced by a delay statement within the always construct.</p> <pre> always #10 clk = ~clk; </pre> <p>Now, the clock inversion is done after every 10-time units. That's why the real Verilog design code always requires a sensitivity list.</p> <h4>NOTE: Explicit delays are not synthesizable into logic gates.</h4> <h3>Uses of always block</h3> <p>An always block can be used to realize combinational or sequential elements. A sequential element like flip flop becomes active when it is provided with a clock and reset.</p> <p>Similarly, a combinational block becomes active when one of its input values change. These hardware blocks are all working concurrently independently of each other. The connection between each is what determines the flow of data.</p> <p>An always block is made as a continuous process that gets triggered and performs some action when a signal within the sensitivity list becomes active.</p> <p>In the following example, all statements within the always block executed at every positive edge of the signal clk</p> <pre> // execute always block at the positive edge of signal 'clk' always @ (posedge clk) begin [statements] end </pre> <h3>Sequential Element Design</h3> <p>The below code defines a module called <strong> <em>tff</em> </strong> that accepts a data input, clock, and active-low reset. Here, the always block is triggered either at the positive edge of the <strong> <em>clk</em> </strong> or the negative edge of <strong> <em>rstn</em> </strong> .</p> <p> <strong>1. The positive edge of the clock</strong> </p> <p>The following events happen at the positive edge of the clock and are repeated for all positive edge of the clock.</p> <p> <strong>Step 1:</strong> First, if statement checks the value of active-low reset <strong> <em>rstn</em> </strong> .</p> <ul> <li>If <strong> <em>rstn</em> </strong> is zero, then output q should be reset to the default value of 0.</li> <li>If <strong> <em>rstn</em> </strong> is one, then it means reset is not applied and should follow default behavior.</li> </ul> <p> <strong>Step 2:</strong> If the previous step is false, then</p> <ul> <li>Check the value of d, and if it is found to be one, then invert the value of q.</li> <li>If d is 0, then maintain value of q.</li> </ul> <pre> module tff (input d, clk, rstn, output reg q); always @ (posedge clk or negedge rstn) begin if (!rstn) q <= 0; else if (d) q <="~q;" end endmodule pre> <p> <strong>2. Negative edge of reset</strong> </p> <p>The following events happen at the negative edge of <strong> <em>rstn</em> </strong> .</p> <p> <strong>Step 1:</strong> First, if statement checks the value of active-low reset <strong> <em>rstn</em> </strong> . At the negative edge of the signal, its value is 0.</p> <ul> <li>If the value of <strong> <em>rstn</em> </strong> is 0, then it means reset is applied, and output should be reset to the default value of 0.</li> <li>And if the value of <strong> <em>rstn</em> </strong> is 1, then it is not considered because the current event is a negative edge of the <strong> <em>rstn</em> </strong> .</li> </ul> <h3>Combinational Element Design</h3> <p>An always block can also be used in the design of combinational blocks.</p> <p>For example, the digital circuit below represents three different logic gates that provide a specific output at signal o.</p> <img src="//techcodeview.com/img/verilog-tutorial/39/verilog-always-block.webp" alt="Verilog Always Block"> <p>The code shown below is a module with four input ports and a single output port called o. The always block is triggered whenever any of the signals in the sensitivity list changes in value.</p> <p>The output signal is declared as type <strong> <em>reg</em> </strong> in the module port list because it is used in a procedural block. All signals used in a procedural block should be declared as type <strong> <em>reg</em> </strong> .</p> <pre> module combo (input a, input b, input c, input d, output reg o); always @ (a or b or c or d) begin o <= ~((a & b) | (c^d)); end endmodule < pre> <p>The signal o becomes 1 whenever the combinational expression on the RHS becomes true. Similarly, o becomes 0 when RHS is false.</p> <hr></=></pre></=></pre></=>
Necessità di elenco di sensibilità
Il blocco sempre si ripete continuamente durante una simulazione. L'elenco di sensibilità apporta un certo senso di tempistica, ovvero ogni volta che cambia un segnale nell'elenco di sensibilità, viene attivato il blocco sempre.
Se non sono presenti istruzioni di controllo temporale all'interno di un blocco sempre, la simulazione si bloccherà a causa di un ciclo infinito con ritardo zero.
Ad esempio, blocca sempre i tentativi di invertire il valore del segnale clk. L'istruzione viene eseguita dopo ogni unità di 0 volte. Pertanto, viene eseguito per sempre a causa dell'assenza di un ritardo nell'istruzione.
// always block started at time 0 units // But when is it supposed to be repeated // There is no time control, and hence it will stay and // be repeated at 0-time units only and it continues // in a loop and simulation will hang always clk = ~clk;
Se l'elenco di sensibilità è vuoto, dovrebbe essere presente qualche altra forma di ritardo. Il tempo di simulazione viene anticipato da un'istruzione di ritardo all'interno del costrutto sempre.
always #10 clk = ~clk;
Ora, l'inversione dell'orologio viene eseguita ogni 10 unità di tempo. Ecco perché il vero codice di progettazione Verilog richiede sempre un elenco di sensibilità.
NOTA: i ritardi espliciti non sono sintetizzabili in porte logiche.
Usi di bloccare sempre
Un blocco sempre può essere utilizzato per realizzare elementi combinatori o sequenziali. Un elemento sequenziale come il flip flop diventa attivo quando viene dotato di un orologio e ripristinato.
Allo stesso modo, un blocco combinatorio diventa attivo quando uno dei suoi valori di ingresso cambia. Questi blocchi hardware funzionano tutti contemporaneamente indipendentemente l'uno dall'altro. La connessione tra ciascuno è ciò che determina il flusso di dati.
Un blocco sempre viene creato come un processo continuo che viene attivato ed esegue alcune azioni quando un segnale all'interno dell'elenco di sensibilità diventa attivo.
Nell'esempio seguente, tutte le istruzioni all'interno del blocco sempre vengono eseguite ad ogni fronte positivo del segnale clk
// execute always block at the positive edge of signal 'clk' always @ (posedge clk) begin [statements] end
Progettazione di elementi sequenziali
Il codice seguente definisce un modulo chiamato tff che accetta un input di dati, un orologio e un ripristino attivo-basso. In questo caso il blocco sempre viene attivato sul fronte positivo di clk o il fronte negativo di prima .
1. Il fronte positivo dell'orologio
I seguenti eventi si verificano sul fronte positivo del clock e si ripetono per tutto il fronte positivo del clock.
Passo 1: Innanzitutto, l'istruzione if controlla il valore del ripristino attivo-basso prima .
- Se prima è zero, l'uscita q deve essere ripristinata al valore predefinito di 0.
- Se prima è uno, significa che il ripristino non è applicato e dovrebbe seguire il comportamento predefinito.
Passo 2: Se il passaggio precedente è falso, allora
- Controlla il valore di d e, se risulta essere uno, inverti il valore di q.
- Se d è 0, mantieni il valore di q.
module tff (input d, clk, rstn, output reg q); always @ (posedge clk or negedge rstn) begin if (!rstn) q <= 0; else if (d) q <="~q;" end endmodule pre> <p> <strong>2. Negative edge of reset</strong> </p> <p>The following events happen at the negative edge of <strong> <em>rstn</em> </strong> .</p> <p> <strong>Step 1:</strong> First, if statement checks the value of active-low reset <strong> <em>rstn</em> </strong> . At the negative edge of the signal, its value is 0.</p> <ul> <li>If the value of <strong> <em>rstn</em> </strong> is 0, then it means reset is applied, and output should be reset to the default value of 0.</li> <li>And if the value of <strong> <em>rstn</em> </strong> is 1, then it is not considered because the current event is a negative edge of the <strong> <em>rstn</em> </strong> .</li> </ul> <h3>Combinational Element Design</h3> <p>An always block can also be used in the design of combinational blocks.</p> <p>For example, the digital circuit below represents three different logic gates that provide a specific output at signal o.</p> <img src="//techcodeview.com/img/verilog-tutorial/39/verilog-always-block.webp" alt="Verilog Always Block"> <p>The code shown below is a module with four input ports and a single output port called o. The always block is triggered whenever any of the signals in the sensitivity list changes in value.</p> <p>The output signal is declared as type <strong> <em>reg</em> </strong> in the module port list because it is used in a procedural block. All signals used in a procedural block should be declared as type <strong> <em>reg</em> </strong> .</p> <pre> module combo (input a, input b, input c, input d, output reg o); always @ (a or b or c or d) begin o <= ~((a & b) | (c^d)); end endmodule < pre> <p>The signal o becomes 1 whenever the combinational expression on the RHS becomes true. Similarly, o becomes 0 when RHS is false.</p> <hr></=></pre></=>=>=>