Jag läste den här sidan http://www.asic-world.com/verilog/verilog_one_day3.html när jag stötte på följande:
Vi måste normalt återställa flip-flops, alltså varje gång klockan gör övergång från 0 till 1 (posedge) kontrollerar vi om återställning är påstått (synkron återställning), sedan fortsätter vi med normal logik. Om vi tittar noggrant ser vi att när det gäller kombinationslogik hade vi ”=” för tilldelning och för det sekventiella blocket hade vi operatören ”< =”. Tja, ”=” blockerar tilldelning och ”< =” är tilldelning utan blockering. ”=” kör kod sekventiellt inuti en början / slut, medan icke-blockering ”< =” körs parallellt.
Jag var ganska säker på att icke-blockerande uppdrag var sekventiella medan blockeringsuppgifter var parallella. När allt kommer omkring kan du göra blockeringsuppgifter med tilldelningsuttalanden utanför alltid block, och de går alla parallellt. Är detta ett misstag, eller är beteendet annorlunda i ett alltid block? Och om beteendet ÄR annorlunda i ett alltid block, kan icke-blockerande tilldelningar göras utanför ett alltid block?
Svar
var ganska säker på att icke-blockerande tilldelningar var sekventiella medan blockeringstilldelningar var parallella.
Blockering av tilldelning körs ”i serie” eftersom en blockeringstilldelning blockerar körning av nästa uttalande tills den är klar. Därför kan resultatet av nästa uttalande bero på att det första slutförts.
Tilldelning som inte blockerar utförs parallellt eftersom det beskriver tilldelningar som alla sker samtidigt. Resultatet av ett uttalande på andra raden beror inte på resultatet av uttalandet på första raden. Istället kommer den andra raden att köras som om den första raden inte hade hänt än.
Kommentarer
Svar
Tilldelningsuttalanden är varken ”blockerande” eller ”icke-blockerande”, de är ”kontinuerliga”. Utsignalen från ett tilldelningsuttal är alltid lika med den angivna funktionen för dess ”ingångar.” Blockering ”och” nonblocking ”-tilldelningar finns bara inom alltid block.
En blockeringstilldelning påverkar omedelbart den behandlas. En tilldelning som inte blockerar sker vid slutet av bearbetningen av det aktuella ”tidsdeltaet”.
alltid kan block användas för att modellera antingen kombinatorisk eller sekventiell logik (systemverilog har alltid_komb och alltid_ff för att göra detta uttryckligt). kombinatorisk logik är det vanligtvis effektivare att använda = men det spelar vanligtvis ingen roll.
När du modellerar sekventiell logik (t.ex. alltid @ (posedge clk)) använder du normalt icke-blockerande uppgifter. Detta gör att du avskräcka ”tillståndet efter klockkanten” i termer av ”tillståndet före klockkanten”.
Det är ibland användbart att använda blockeringstilldelningar i sekventiella block alltid som ”variabler”. Om du gör detta då det finns två viktiga regler att tänka på.
- Få inte åtkomst till a reg som är inställt med blockerande tilldelningar inuti ett sekventiellt block alltid från det alltid block som det tilldelas i.
- Blanda inte blockerings- och nonblocking-tilldelningar till samma reg.
Att bryta mot dessa regler kommer sannolikt att leda till syntesfel och / eller beteendeskillnader mellan simulering och syntes.
Kommentarer
- ” ” Få inte åtkomst till en reg som är inställd med blockeringstilldelningar inuti ett sekventiellt blockera alltid från utsidan alltid blockera det tilldelas. ” ” Kan du förklara det?
- Olika sekventiella block alltid inte har en definierad ordning. Så att läsa en ” reg ” inställd med en blockerande bedömning i ett alltid block från ett annat alltid block kommer att leda till oförutsägbart beteende.
- Och även om det verkar fungera i simulering, bör ett syntesverktyg titta på det och säga ” nej ”. Jag använder lokala regs för de mellanliggande varorna och ser till att de alltid tilldelas varje klocka innan de läses, så att ingen ’ lagring ’ är underförstådd.
- IIRC åtminstone i kvartal anses det bara vara en varning inte som ett fel.
- Du bör inte använda icke-blockerande tilldelning i kombinationslogik, det kan låsa simuleringen. Mer information finns i detta svar: electronics.stackexchange.com/a/506047/238188
Svar
Termen Blockeringstilldelning förvirrar människor eftersom ordet blockering verkar antyda tidssekventiell logik. Men i syntetiserad logik betyder det inte detta , för allt fungerar i parallell .
Kanske skulle en mindre förvirrande term vara omedelbar tilldelning , som fortfarande skulle skilja mellanresultaten av kombinationslogik från ingångar till icke-transparenta minneselement (till exempel klockade register), som kan ha försenad tilldelning .
Ur en legalistisk synvinkel fungerar allt mycket snyggt. Du kan faktiskt betrakta =
som en blockering (tidssekvens) även inom always_comb
sekvenser. Men skillnaden mellan tidssekventiell och parallell gör absolut ingen skillnad i detta fall eftersom always_comb
-blocket definieras för att upprepas tills instruktionssekvensen konvergerar i ett stabilt tillstånd – vilket är exakt vad hårdvarukretsarna kommer att göra (om det uppfyller tidskraven).
Den syntetiserbara delmängden Verilog (och särskilt SystemVerilog) är extremt enkelt och lätt att använda – när du väl känner till de nödvändiga idiomen. Du måste bara komma förbi den smarta användningen av terminologi som är associerad med de så kallade beteendemässiga elementen i språket.
Kommentarer
- I beteende kodningsstilar ( jämfört med RTL ) kan skillnaden mellan blockering och icke-blockering vara relevant. I vissa fall kan syntesverktyget kunna leda funktionellt motsvarande RTL från beteendekomponentdesigner.
- Naturligtvis procedurella läge för SystemVerilog, särskilt tillämpligt på
initial
uttalanden inomprogram
block, använder (tidssekventiell) blockeringstilldelning uteslutande. Detta är användbart för testbänk -design, men i allmänhet inte för RTL-specifikation.
assign
uttalanden förekommer utanför alltid block och används vanligtvis för att beskriva för kombinatoriska (ospärrade ) logik (medan block alltid, med vissa undantag, beskriver sekventiell logik). AFAIK,assign
uttalanden kör alltid ” parallellt ” när deras LHS har en värdeförändring .