Lär dig Verilog: En kort Tutorial serie på Digital elektronik Design med FPGAs och Verilog HDL (19 / 21 steg)
Steg 19: VM 4.2: blockera kontra icke-blockerande Verilog uttalanden
Det kan verka konstigt att vi växla från att diskutera alltid block för att blockera/icke-blockerande men detta är en perfekt tid att införa ett nytt koncept.När vi skriver kod i C/C++, vår kod körs rad för rad i tur och ordning tills programmet berättas att avvika från detta mönster (t.ex. hoppa till en viss rad). En rad körs och endast efter det ytskikt kör är nästa rad avrättades. Mest av praktiska skäl märker vi inte varje försening i enkel Konsolapplikationer. Men i digital design, denna försening från utförande en linje till nästa kan få mycket negativa och märkbara konsekvenser. Även förseningar på mindre än en nanosekund skulle kunna orsaka problem; buggar att vara exakt.
En glitch definieras formellt som en momentan och oönskade förändringar i produktionen av en krets på grund av en ingång in ett övergående tillstånd och att ha minst två vägar genom kretsen utan motsvarande gate förseningar mellan vägar-ingången.
Tänk dig att du har två växlar (sw0 och sw1) som var både en logik 0, och den resulterande produktionen av en enda LED var en logik en om båda växlar var en logik 0 (LED = ~(sw0 & sw1)), bland annat önskas utgångar. Men säger du vänder sw1 till en logic hög. Tänk om bara för en bråkdel av en sekund att LED var fortfarande en logik en medan spänningen från sw1 källan "ripples" väg "nedströms" logik Gates i dess olika vägar innan den kommer till den sista gate i kretsen? Däri ligger en bråkdel av en sekund där lysdioden är en logik en när teoretiskt det borde vara en logik noll. din krets bröt reglerna för sin egen logik ekvationer!
Poängen med denna modul är att täcka Hur fixar buggar i din logik uttalanden, är poängen att även fint bildade logik ekvationer för kretsar som är "glitch gratis" potentiellt kan skapa en glitch om du använder en blockerande uttalande där du borde ha använt en icke-blockerande uttalande och vice versa.
Hur sker detta och varför skulle uttrycket fel Verilog orsaka detta?
En blockerande uttalande är en tilldelning (det behöver inte nödvändigtvis använda nyckelordet "tilldela") uttalande som använder operatorn "=". Blockerande uttalanden utförs som kod i C/C++: sekventiellt och i ordning. En icke-blockerande uttryck är ett tilldela uttryck som använder den "< =" operatör. Icke-blockerande uttalanden i samma tillämpningsområde koden med andra icke-blockerande uttalanden kommer att köras samtidigt.
Re Läs ovanstående definitioner eftersom de är mycket viktiga.
En gemensam tanke studenter kan ha är "Verilog-koden är ett hårdvarubeskrivande språk, så det inte borde roll vilken typ av uttalande jag skriver eftersom det kommer att syntetisera i samma fysiska krets och beter sig på samma sätt." Detta är inte nödvändigtvis sant, eftersom den komplexa Verilog kompilatorn måste skapa olika transistor mönster för att passera olika signaler till olika platser och du måste ange om detta måste ske samtidigt eller vid andra tidsintervaller. Kan det vara mer effektivt att bygga en krets med blockering uttalanden som kan direkt signaler samtidigt bekvämt att gå runt men ofta är det viktigt att två eller flera output förändringar äger rum samtidigt i huvudsak.
Ser du hur en rad blockerande uttalanden kan ha negativa effekter av krets beteende? Top level tilldela uttalanden blockerar eftersom bara "exekveras deklarationerna" en gång, men något liknande en avkodare som kan "alltid" omvärdera villkor måste förändra utgångar samtidigt. Tänk de problem en ingenjör skulle ha om deras dekoder utdata GS och utsignaler EO ändrats vid olika tillfällen!
Ta en titt på några enkla exempel ("om" uttalanden skall ingå i nästa modulen!):
Example #1
alltid @ (sw0, sw1)
börja
om (sw0 == 1' b1)
börja
alla dessa utgångar tilldelas sina
värden på samma gång
RESULTAT1 < = 1' b0;
output2 < = 1' b1;
output3 < = 1' b0;
slutet
slutet
Exempel #2
alltid @ (sw0, sw1)
börja
om (sw0 == 1' b1)
börja
den första produktionen kommer att tilldelas, då två
kommer att tilldelas samtidigt
RESULTAT1 = 1' b0;
output2 < = 1' b1;
output3 < = 1' b0;
slutet
slutet
Exempel #3
alltid @ (sw0, sw1)
börja
om (sw0 == 1' b1)
börja
den första produktionen kommer att tilldelas, då två kommer att
tilldelas en efter en
RESULTAT1 = 1' b0;
output2 = 1' b1;
output3 = 1' b0;
slutet
slutet
Aldrig lagt ett blockerande uttalande i en strukturell logik block. Med andra ord aldrig sätta en "=" insidan av en alltid blockera. Även om du bara ändrar en utgång är det dålig praxis att använda ett blockerande uttalande.
Använd alltid ett blockerande uttalande när du använder nyckelordet "tilldela". Dessa uttalanden kommer alltid äga rum utanför en alltid blockera. Exempel användning skulle vara att förklara en reg vars värde du ändra insidan av en alltid block, sedan tilldela en utgång tråd "=" till den reg värde.
Tips: du kommer vanligtvis ge en reg ett värde med hjälp av formuläret: < namn på reg >< = < värde >;
Extra tips (dubbla): du kan bara ange värden för en reg i en alltid blockera, ingen tilldela värden för att ange tråd. Du kan, men senare tilldela kabeln för att motsvara den reg värde.