Jak interpretować zadania blocking vs non blocking w Verilog?

Jestem trochę zdezorientowany tym, jak interpretuje się zadania blokujące i nieblokujące, jeśli chodzi o rysowanie diagramu sprzętowego. Czy musimy wnioskować, że nie blokujące zadanie daje nam rejestr? Więc zgodnie z tym stwierdzeniem c <= a+b , c byłoby prawem rejestru, ale nie a i b?

module add (input logic clock,  
output logic[7:0] f);   

logic[7:0] a, b, c;  

always_ff @(posedge clock)  
begin   
  a = b + c;   
  b = c + a;   
  c <= a + b;  
end   

assign f = c;  

endmodule
Author: Greg, 2011-01-11

6 answers

To zdecydowanie trochę trudne, aby zrozumieć różnice między blokowaniem i nieblokowaniem zadań na początku. Ale bez strachu-jest poręczna zasada:

Jeśli chcesz wywnioskować logikę combo za pomocą bloku always, Użyj przypisań blokujących (=). Jeśli chcesz logiki sekwencyjnej, użyj taktowanego always bloku z niezablokowanymi przypisaniami (<=). I postaraj się nie mieszać tych dwóch.

Twój powyższy kod prawdopodobnie nie jest najlepszym przykładem. Bez wiedzy jaką strukturę adder/flipflop próbowałeś zbudować, istnieje niebezpieczeństwo posiadania ścieżek sprzężenia zwrotnego combo (które są złe). A ponieważ nie masz magistrali wejściowych, zasadniczo próbujesz skonstruować a, b & c znikąd!

Ale aby odpowiedzieć na twoje pytanie, każda zmienna przypisana do bloku taktowanego {[1] } wywnioskuje flipflop, chyba że jest przypisana za pomocą operatora blokującego (=) i użyta jako rodzaj zmiennej lokalnej.

module add
  (
   input clock,
   input [7:0] in1,
   input [7:0] in2,
   output logic [7:0] f1, f2, f3, f4, f5
   );   


   // f1 will be a flipflop
   always_ff @(posedge clock) begin
      f1 = in1 + in2;
   end


   // f2 will be a flipflop
   always_ff @(posedge clock) begin
      f2 <= in1 + in2;
   end


   // f3 will be a flipflop
   // c1 will be a flipflop
   logic [7:0] c1;
   always_ff @(posedge clock) begin
      c1 <= in1 + in2;
      f3 <= c1 + in1;
   end


   // f4 will be a flipflop
   // c2 is used only within the always block and so is treated
   // as a tmp variable and won't be inferred as a flipflop
   logic [7:0] c2;
   always_ff @(posedge clock) begin
      c2 = in1 + in2;
      f4 = c2 + in1;
   end


   // c3 will be a flipflop, as it's used outside the always block
   logic [7:0] c3;
   always_ff @(posedge clock) begin
      c3 = in1 + in2;
   end

   assign f5 = c3 + in1;

endmodule

Wielki powód do podążania za zasada, aby nie mieszać blokowania i nieblokowania zadań w obrębie always bloku, jest taka, że mieszanie zadań może spowodować poważne niedopasowanie symulacji między RTL sims i gate-sims / real hardware operation. Symulator verilog traktuje = i <= zupełnie inaczej. Blokowanie przypisań oznacza "przypisz wartość do zmiennej od razu w tej chwili". Niezablokowane przydziały oznaczają "dowiedzieć się, co przypisać do tej zmiennej i zapisać ją, aby przypisać w przyszłości". Dobry papier do przeczytania, aby lepiej to zrozumieć to: Zobacz też: http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA.pdf

 26
Author: Marty,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-11 13:55:26

Konwencjonalna mądrość Veriloga ma to wszystko źle. Nie ma problemu z użyciem przydziałów blokujących dla zmiennej local. Jednak nigdy nie powinieneś używać blokowania przydziałów do komunikacji synchronicznej, ponieważ jest to nieeterministyczne.

Nieblokujące przypisanie w bloku clocked always zawsze wywnioskuje flip-flop, zgodnie z semantyką.

To, czy blokowanie w taktowanym bloku zawsze wywiera wpływ na klapkę, czy nie zależy całkowicie od jak jest stosowany. Jeśli jest możliwe, że zmienna zostanie odczytana przed przypisaniem, wywnioskowany zostanie flip-flop. W przeciwnym razie jest to zmienna tymczasowa i spowoduje to logikę kombinatoryczną.

 41
Author: Jan Decaluwe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-23 14:56:43

Chcę tylko dodać do odpowiedzi Jana Decaluwe. Wydaje się, że na wolności jest bardzo mało kodu, który faktycznie używa tego, co opisuje Jan Decaluwe, mimo że jest to absolutnie słuszne. Mieszanie blokujących i nieblokujących wypowiedzi jest teraz tabu, dzięki Panu Cummings.

Problem w tym, że większość miejsc unika blokowania poleceń dla zmiennych lokalnych, a w bezpośredniej przestrzeni wyszukiwania Google jest bardzo mało kodu, który wygląda na przykład, jak to się robi. Na jedynym miejscem, gdzie znalazłem styl kodowania, o którym wspomniał Jan, jest zwycięski kod w tym artykule . I to, natknąłem się przypadkowo

 2
Author: Akaberto,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-15 05:35:26

Też miałem z tym problem.

Ale po pierwsze, powinieneś zrozumieć, że nie Blokowanie lub blokowanie nie ma w rzeczywistości nic wspólnego z tym, czy zostanie utworzony zatrzask/ff!

Dla ich różnicy możesz to zrozumieć po prostu (na początku) w tym punkcie: i. jeśli używasz blokowania, zdania po nim nie mogą być wykonane, dopóki zdanie blokowe LHS nie przypisało wartości, ponieważ to, co zmieniło się na LHS, może być zaktualizowane i użyte, jeśli zmienna jest używana. Jednak w przypadku nieblokowania nie blokuj kolejne zdanie jak równolegle z następnym(właściwie obliczenia RHS powinny być wykonane najpierw, ale to nie ma znaczenia, zignoruj je, gdy pomylisz). LHS nie zmienia się/aktualizuje dla wykonania tego czasu (aktualizowane następnym razem, gdy zawsze blok wyzwalany ponownie). Po zdaniu używaj starej wartości, zaktualizowanej pod koniec cyklu wykonawczego.

a = 0; b= 0;
a = 1;
b = a;
--> output a = 1, b = 1;
a = 0; b= 0;
a <= 1;
b = a;
--> output a = 1, b = 0;

Jednym z kluczowych punktów jest sprawdzenie, czy w kodzie (zawsze blokowym) jest jakaś zmienna case, która nie ma przypisanej wartości, ale może się zdarzyć. Jeśli nie przekażesz do niego wartości i tak się stanie, wtedy zostanie utworzony latch/ff, aby zachować wartość.

Na przykład,

always @(*) begin
    if(in) out = 1;
    else out = 0;
end
--> this end without latch/ff
always @(*) begin
    if(in) out = 1;
end
--> this end with one latch/ff to keep value when in = 0, as it might happen and you didn't assign value to out as in=1 do. 

NastÄ ™ pujÄ ... ce moĹźe rĂłwnieĹź utworzyÄ ‡ latch/ff:

always @(*) begin
    if(in) a = 1;
    else b = 1;
end

--> latch/FFS stworzony dla in = 1, B no assignment, in = 0 a no assignment.

Ponadto, gdy wyczujemy posedge z clk always @(posedge clk), jest on związany z zakończeniem zatrzaskiem / ff. Ponieważ dla clk musi istnieć ujemna krawędź, a ty nic nie robisz, latch / ffs są tworzone, aby zachować wszystkie stare wartości!

 1
Author: Steve,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-25 17:33:20

Proszę zawsze możesz zinterpretować verilog w domenie cyfrowej tylko musisz zrozumieć, co się stanie, jeśli ten sam kod, który napisałeś, zostanie przekonwertowany na poziomie bramy, ja osobiście nie przestrzegam zasady, że aby używać non blocking w seq lub używać blocking w combinational, to ograniczy twoje myślenie . trzymaj się tylko cyfrowej strony kodu oto, co się stanie, jeśli twój kod zostanie przekonwertowany na poziom bramy, po prostu zobacz, że chcesz tego tylko

  1. najpierw pełny adder zostanie zrobiony -- wejścia a i b
    1. Wyjście przejdzie do flip flop tworząc wyjście a posiadające synchronizację z clk
    2. teraz, ponieważ przypisanie jest blokowane, więc nowe a zostanie zastosowane do następnego pełnego dodawania mając nowe a i c jako wejście, wyjście z niego przejdzie do dffcsync do clk tworząc nowe b
    3. teraz, ponieważ b = c + a; jest tam, co blokuje statement więc b jest aktualizowany do tego nowego B
    4. teraz jego c
    5. następnie zostanie utworzony dff, ponieważ stare c nie nowe zostało utworzone przez instrukcję non blocking, a wyjście tego DFF sync to clk przechodzi do a i A zostaje zaktualizowane

Dzięki pozdrawiam Rahul jain

 0
Author: Rahul Jain,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-10-12 15:40:21

Mogę odpowiedzieć na twoje pytanie, ale myślę, że jedna praca byłaby najlepsza do tego, więc polecam przeczytać tę pracę Clifforda Cummings. Rozwiąże wszystkie Twoje wątpliwości, a dodatkowo wzmocni twoje zrozumienie verilog.

Http://www.sunburst-design.com/papers/CummingsSNUG2000SJ_NBA_rev1_2.pdf

 0
Author: Karan Shah,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-12-09 03:13:59