Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Industrial programming >> Verilog

Verilog Blocking vs. Non-Blocking: belangrijkste verschillen uitgelegd

Blocking-toewijzing

Blocking-toewijzingsinstructies gebruiken = en worden sequentieel uitgevoerd in een proceduraal blok. Dit voorkomt niet dat statements in een parallel blok worden uitgevoerd.

module tb;
  reg [7:0] a, b, c, d, e;
  initial begin
    a = 8'hDA;
    $display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
    b = 8'hF1;
    $display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
    c = 8'h30;
    $display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
  end
  initial begin
    d = 8'hAA;
    $display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
    e = 8'h55;
    $display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
  end
endmodule

Er zijn twee initial-blokken die parallel uitgevoerd worden wanneer de simulatie start. Statements worden sequentieel uitgevoerd in elk blok en beide blokken zijn klaar op tijd 0ns. Preciezer: variabele a krijgt eerst een waarde, gevolgd door de display-instructie, en dan alle overige statements. Dit is zichtbaar in de output waar variabele b en c 8'hxx zijn in de eerste display-instructie. Dit is omdat de toewijzingen aan b en c nog niet uitgevoerd waren toen de eerste $display werd aangeroepen.

Simulatie-log

ncsim> run
[0] a=0xda b=0xx c=0xx
[0] a=0xda b=0xf1 c=0xx
[0] a=0xda b=0xf1 c=0x30
[0] d=0xaa e=0xx
[0] d=0xaa e=0x55
ncsim: *W,RNQUIE: Simulation is complete.

In het volgende voorbeeld voegen we een paar vertragingen toe aan dezelfde set statements om te zien hoe het zich gedraagt.

module tb;
  reg [7:0] a, b, c, d, e;
  initial begin
    a = 8'hDA;
    $display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
    #10 b = 8'hF1;
    $display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
    c = 8'h30;
    $display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
  end
  initial begin
    #5 d = 8'hAA;
    $display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
    #5 e = 8'h55;
    $display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
  end
endmodule

Simulatie-log

ncsim> run
[0] a=0xda b=0xx c=0xx
[5] d=0xaa e=0xx
[10] a=0xda b=0xf1 c=0xx
[10] a=0xda b=0xf1 c=0x30
[10] d=0xaa e=0x55
ncsim: *W,RNQUIE: Simulation is complete.

Non-blocking toewijzing

Non-blocking-toewijzing stelt toewijzingen in zonder de uitvoering van volgende statements te blokkeren en wordt aangeduid met het symbool <=. Het is interessant om te merken dat hetzelfde symbool gebruikt wordt als relationele operator in expressies, en als toewijzingsoperator in de context van een non-blocking toewijzing. Als we het eerste voorbeeld nemen en alle =-symbolen vervangen door de non-blocking toewijzingsoperator <=, zien we een verschil in de output.

module tb;
  reg [7:0] a, b, c, d, e;
  initial begin
    a <= 8'hDA;
    $display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
    b <= 8'hF1;
    $display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
    c <= 8'h30;
    $display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
  end
  initial begin
    d <= 8'hAA;
    $display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
    e <= 8'h55;
    $display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
  end
endmodule

Zie dat alle $display-instructies 'h'x printen. De reden voor dit gedrag ligt in de manier waarop non-blocking toewijzingen worden uitgevoerd. De RHS van elke non-blocking-instructie van een bepaalde tijdstap wordt vastgelegd, en de simulator gaat door naar het volgende statement. De vastgelegde RHS-waarde wordt pas aan de LHS-variabele toegewezen aan het einde van de tijdstap.

Simulatie-log

ncsim> run
[0] a=0xx b=0xx c=0xx
[0] a=0xx b=0xx c=0xx
[0] a=0xx b=0xx c=0xx
[0] d=0xx e=0xx
[0] d=0xx e=0xx
ncsim: *W,RNQUIE: Simulation is complete.

Als we de uitvoeringsstroom van het bovenstaande voorbeeld opsplitsen, krijgen we zoiets als hieronder.

|__ Spawn Blok1: initial
| |___ Tijd #0ns : a <= 8'DA, is non-blocking dus noteer waarde van RHS (8'hDA) en voer volgende stap uit
| |___ Tijd #0ns : $display() is blocking, dus voer deze statement uit: Maar a heeft nog geen nieuwe waarden dus a=8'hx
| |___ Tijd #0ns : b <= 8'F1, is non-blocking dus noteer waarde van RHS (8'hF1) en voer volgende stap uit
| |___ Tijd #0ns : $display() is blocking, dus voer deze statement uit. Maar b heeft nog geen nieuwe waarden dus b=8'hx
| |___ Tijd #0ns : c <= 8'30, is non-blocking dus noteer waarde van RHS (8'h30) en voer volgende stap uit
| |___ Tijd #0ns : $display() is blocking, dus voer deze statement uit. Maar c heeft nog geen nieuwe waarden dus c=8'hx
| |___ Einde van tijdstap en initial-blok, wijs vastgelegde waarden toe aan variabelen a, b, c
| |__ Spawn Blok2: initial
| |___ Tijd #0ns : d <= 8'AA, is non-blocking dus noteer waarde van RHS (8'hAA) en voer volgende stap uit
| |___ Tijd #0ns : $display() is blocking, dus voer deze statement uit: Maar d heeft nog geen nieuwe waarden dus d=8'hx
| |___ Tijd #0ns : e <= 8'55, is non-blocking dus noteer waarde van RHS (8'h55) en voer volgende stap uit
| |___ Tijd #0ns : $display() is blocking, dus voer deze statement uit. Maar e heeft nog geen nieuwe waarden dus e=8'hx
| |___ Einde van tijdstap en initial-blok, wijs vastgelegde waarden toe aan variabelen d en e
| |__ Einde van simulatie op #0ns

Nu laten we het tweede voorbeeld gebruiken en alle blocking-statements vervangen door non-blocking.

module tb;
  reg [7:0] a, b, c, d, e;
  initial begin
    a <= 8'hDA;
    $display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
    #10 b <= 8'hF1;
    $display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
    c <= 8'h30;
    $display ("[%0t] a=0x%0h b=0x%0h c=0x%0h", $time, a, b, c);
  end
  initial begin
    #5 d <= 8'hAA;
    $display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
    #5 e <= 8'h55;
    $display ("[%0t] d=0x%0h e=0x%0h", $time, d, e);
  end
endmodule

Opnieuw zien we dat de output anders is dan eerder.

Simulatie-log

ncsim> run
[0] a=0xx b=0xx c=0xx
[5] d=0xx e=0xx
[10] a=0xda b=0xx c=0xx
[10] a=0xda b=0xx c=0xx
[10] d=0xaa e=0xx
ncsim: *W,RNQUIE: Simulation is complete.

Als we de uitvoeringsstroom opsplitsen, krijgen we zoiets als hieronder.

|__ Spawn Blok1 op #0ns: initial
| |___ Tijd #0ns : a <= 8'DA, is non-blocking dus noteer waarde van RHS (8'hDA) en voer volgende stap uit
| |___ Tijd #0ns : $display() is blocking, dus voer deze statement uit: Maar a heeft nog geen nieuwe waarden dus a=8'hx
| |___ Einde van tijdstap : Wijs vastgelegde waarde toe aan variabele a, en a is nu 8'hDA
| |___ Wacht tot tijd vooruitgaat met 10 tijdseenheden naar #10ns
| | |___ Tijd #10ns : b <= 8'F1, is non-blocking dus noteer waarde van RHS (8'hF1) en voer volgende stap uit
| |___ Tijd #10ns : $display() is blocking, dus voer deze statement uit. Maar b heeft nog geen nieuwe waarden dus b=8'hx
| |___ Tijd #10ns : c <= 8'30, is non-blocking dus noteer waarde van RHS (8'h30) en voer volgende stap uit
| |___ Tijd #10ns : $display() is blocking, dus voer deze statement uit. Maar c heeft nog geen nieuwe waarden dus c=8'hx
| |___ Einde van tijdstap en initial-blok, wijs vastgelegde waarden toe aan variabelen b, c
| |__ Spawn Blok2 op #0ns: initial
| |___ Wacht tot tijd vooruitgaat met 5 tijdseenheden naar #5ns
| | |___ Tijd #5ns : d <= 8'AA, is non-blocking dus noteer waarde van RHS (8'hAA) en voer volgende stap uit
| |___ Tijd #5ns : $display() is blocking, dus voer deze statement uit: Maar d heeft nog geen nieuwe waarden dus d=8'hx
| |___ Einde van tijdstap : Wijs vastgelegde waarde toe aan variabele d, en d is nu 8'hAA
| |___ Wacht tot tijd vooruitgaat met 5 tijdseenheden naar #5ns
| | |___ Tijd #10ns : e <= 8'55, is non-blocking dus noteer waarde van RHS (8'h55) en voer volgende stap uit
| |___ Tijd #10ns : $display() is blocking, dus voer deze statement uit. Maar e heeft nog geen nieuwe waarden dus e=8'hx
| |___ Einde van tijdstap en initial-blok, wijs vastgelegde waarden toe aan variabele e, en e is nu 8'h55
| |__ Einde van simulatie op #10ns

Verilog

  1. Verilog beheersen: Complete tutorial voor digitale schakelingontwerp
  2. Verilog concatenatie beheersen: Een praktische gids
  3. Verilog-toewijzingen begrijpen: types, syntax en best practices
  4. Verilog-functies beheersen voor efficiënt RTL-ontwerp
  5. Verilog Tasks begrijpen: Functions vs Tasks, Syntax en Gebruik
  6. Verilog Clock Generator: Ontwerp & Implementatie Gids
  7. Verilog Math Functions beheersen voor efficiënt Hardware-ontwerp
  8. Verilog $timeformat beheersen: Precisie en Weergave-controle
  9. Verilog Timescales begrijpen en printen in elke Scope
  10. Verilog File I/O onder de knie: Openen, Lezen, Schrijven en Sluiten
  11. Beginner's Guide to Verilog: Hello World Voorbeeld