logo

Verilog blochează întotdeauna

În Verilog, blocul întotdeauna este unul dintre blocurile procedurale. Instrucțiunile din interiorul unui bloc always sunt executate secvenţial.

Un bloc întotdeauna se execută întotdeauna, spre deosebire de blocurile inițiale care se execută o singură dată la începutul simulării. Blocul întotdeauna ar trebui să aibă o listă sensibilă sau o întârziere asociată cu acesta

Lista sensibilă este cea care spune blocului întotdeauna când să execute blocul de cod.

Sintaxă

The Verilog blocați întotdeauna următoarea sintaxă

str la int
 always @ (event) [statement] always @ (event) begin [multiple statements] end 

Exemple

apelați o funcție js din html

Simbolul @ după cuvântul rezervat mereu , indică faptul că blocarea va fi declanșată la condiția din paranteză după simbolul @.

 always @ (x or y or sel) begin m = 0; if (sel == 0) begin m = x; end else begin m = y; end end 

În exemplul de mai sus, descriem un mux 2:1, cu intrare x și y. The acest este intrarea selectată și m este ieșirea mux.

În orice logică combinațională, ieșirea se modifică ori de câte ori intrarea se schimbă. Când această teorie este aplicată la blocurile întotdeauna, atunci codul din interiorul blocurilor întotdeauna trebuie să fie executat ori de câte ori variabilele de intrare sau de ieșire se modifică.

NOTĂ: Poate conduce tipuri de date reg și întregi, dar nu poate conduce tipuri de date wire.

Există două tipuri de liste sensibile în Verilog, cum ar fi:

  1. Sensibilă la nivel (pentru circuite combinate).
  2. Sensibilă la margini (pentru flip-flops).

Codul de mai jos este același 2:1 mux, dar rezultatul m este acum o ieșire 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 &apos;x&apos; or &apos;y&apos; 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&apos;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 &apos;clk&apos; 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></=>

Nevoia listei de sensibilitate

Blocul întotdeauna se repetă continuu pe parcursul unei simulări. Lista de sensibilitate aduce un anumit sentiment de sincronizare, adică de fiecare dată când se schimbă orice semnal din lista de sensibilitate, blocul întotdeauna este declanșat.

mouse și tipuri de mouse

Dacă nu există instrucțiuni de control al timpului într-un bloc mereu, simularea se va bloca din cauza unei bucle infinite cu întârziere zero.

De exemplu, blocați întotdeauna încercările de a inversa valoarea semnalului clk. Instrucțiunea este executată după fiecare 0 unități de timp. Prin urmare, se execută pentru totdeauna din cauza absenței unei întârzieri în declarație.

 // 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; 

Dacă lista de sensibilități este goală, ar trebui să existe o altă formă de întârziere. Timpul de simulare este avansat printr-o instrucțiune de întârziere în construcția always.

 always #10 clk = ~clk; 

Acum, inversarea ceasului se face după fiecare 10 unități de timp. De aceea, adevăratul cod de proiectare Verilog necesită întotdeauna o listă de sensibilități.

NOTĂ: Întârzierile explicite nu sunt sintetizate în porți logice.

Utilizări de întotdeauna bloc

Un bloc întotdeauna poate fi utilizat pentru a realiza elemente combinaționale sau secvențiale. Un element secvenţial precum flip flop devine activ atunci când este prevăzut cu un ceas şi resetat.

În mod similar, un bloc combinațional devine activ atunci când una dintre valorile sale de intrare se modifică. Aceste blocuri hardware funcționează toate simultan, independent unul de celălalt. Legătura dintre fiecare este cea care determină fluxul de date.

Un bloc mereu este realizat ca un proces continuu care este declanșat și efectuează o anumită acțiune atunci când un semnal din lista de sensibilitate devine activ.

numere blocate

În exemplul următor, toate instrucțiunile din blocul întotdeauna sunt executate la fiecare margine pozitivă a semnalului clk

kajal aggarwal
 // execute always block at the positive edge of signal &apos;clk&apos; always @ (posedge clk) begin [statements] end 

Proiectarea elementelor secvențiale

Codul de mai jos definește un modul numit tff care acceptă o intrare de date, ceas și resetare activ-low. Aici, blocul întotdeauna este declanșat fie la marginea pozitivă a clk sau marginea negativă a rstn .

1. Frontul pozitiv al ceasului

Următoarele evenimente au loc la frontul pozitiv al ceasului și se repetă pentru toate frontul pozitiv al ceasului.

Pasul 1: În primul rând, instrucțiunea if verifică valoarea resetare active-low rstn .

  • Dacă rstn este zero, atunci ieșirea q ar trebui resetata la valoarea implicită de 0.
  • Dacă rstn este unul, atunci înseamnă că resetarea nu este aplicată și ar trebui să urmeze comportamentul implicit.

Pasul 2: Dacă pasul anterior este fals, atunci

  • Verificați valoarea lui d și, dacă se constată că este una, atunci inversați valoarea lui q.
  • Dacă d este 0, atunci menține valoarea lui 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></=>