Verschil tussen blokkerende en niet-blokkerende toewijzing Verilog

Ik was deze pagina aan het lezen http://www.asic-world.com/verilog/verilog_one_day3.html toen ik het volgende tegenkwam:

Normaal gesproken moeten we flip-flops resetten, dus elke keer dat de klok de overgang van 0 naar 1 (posedge), we controleren of reset wordt beweerd (synchrone reset), dan gaan we verder met normale logica. Als we goed kijken, zien we dat we in het geval van combinatielogica “=” hadden voor toewijzing, en voor het sequentiële blok hadden we de “< =” operator. Nou, “=” blokkeert toewijzing en “< =” is niet-blokkerende toewijzing. “=” voert code opeenvolgend uit binnen een begin / einde, terwijl non-blocking “< =” parallel wordt uitgevoerd.

Ik was er vrij zeker van dat niet-blokkerende opdrachten opeenvolgend waren, terwijl blokkeringsopdrachten parallel waren. Je kunt immers blokkeringsopdrachten maken met toewijzingsinstructies buiten always blocks, en die lopen allemaal parallel. Is dit een vergissing, of is het gedrag anders binnen een altijd blok? En als het gedrag anders IS binnen een always block, kunnen dan non-blocking opdrachten worden gemaakt buiten een always block?

Answer

was er redelijk zeker van dat niet-blokkerende opdrachten opeenvolgend waren, terwijl blokkerende opdrachten parallel waren.

Blokkeringstoewijzing wordt “in serie” uitgevoerd omdat een blokkeertoewijzing de uitvoering van de volgende instructie blokkeert totdat deze is voltooid. Daarom kunnen de resultaten van de volgende instructie afhangen van de eerste die wordt voltooid.

Niet-blokkerende toewijzing wordt parallel uitgevoerd omdat het toewijzingen beschrijft die allemaal tegelijkertijd plaatsvinden. Het resultaat van een verklaring op de 2e regel hangt niet af van de resultaten van de verklaring op de 1e regel. In plaats daarvan zal de 2e regel worden uitgevoerd alsof de 1e regel nog niet is gebeurd.

Opmerkingen

  • Hoe zit het met het toewijzen van uitspraken? Bevinden ze zich gewoon in een hele eigen klasse?
  • Ja, assign -instructies komen voor buiten always-blokken en worden over het algemeen gebruikt om te beschrijven naar combinatorische (niet-vergrendeld ) logica (terwijl blokken altijd, met enkele uitzonderingen, sequentiële logica beschrijven). AFAIK, assign -instructies worden altijd ” parallel ” uitgevoerd wanneer hun LHS een waardeverandering heeft .
  • Oké … ik ‘ begin de indruk te krijgen dat Verilog niet het meest ‘ is elegant ontworpen taal. Dit zal lijken op het leren van C.
  • Verilog is ontworpen om ” ” hardware te beschrijven die al bestaat. Het gebruiken als een taal om hardware te ontwerpen (synthetiseren) is een hack.
  • als Verilog ” zoals het leren van C ” is een probleem, kijk eens naar VHDL. Sommige mensen hebben vrij sterke voorkeuren voor de een of de ander. Voor sommigen is VHDL gewoon te uitgebreid. Voor mij is het ‘ veel beter doordacht. (semantiek van signaal / variabele toewijzing is veel duidelijker dan bijvoorbeeld blokkeren / niet). stackoverflow.com/questions/13954193/… en sigasi .com / content / vhdls-crown-jewel Misschien geef je er de voorkeur aan of haat je het. Maar het ‘ is het bekijken waard.

Antwoord

Assign statements zijn noch “blokkerend” noch “niet-blokkerend”, ze zijn “continu”. De output van een assign statement is altijd gelijk aan de gespecificeerde functie van zijn inputs. ‘Blokkerende’ en ‘niet-blokkerende’ toewijzingen bestaan alleen binnen altijd blokken.

Een blokkeringstoewijzing wordt onmiddellijk van kracht nadat deze is verwerkt. Een niet-blokkerende toewijzing vindt plaats aan het einde van de verwerking van de huidige ‘tijdsverschil’.

blokken kunnen altijd worden gebruikt om combinatorische of sequentiële logica te modelleren (systemverilog heeft always_comb en always_ff om dit expliciet te maken). combinatorische logica is meestal efficiënter om = te gebruiken, maar het doet er meestal niet toe.

Bij het modelleren van sequentiële logica (bijv. always @ (posedge clk)) gebruikt u normaal gesproken niet-blokkerende bewerkingen. Dit stelt u in staat om bepaal de “toestand na de klokflank” in termen van “de toestand vóór de klokrand”.

Het is soms handig om blokkeringsopdrachten in opeenvolgende blokken altijd als “variabelen” te gebruiken. Als je dit doet dan er zijn twee belangrijke regels om in gedachten te houden.

  1. Gebruik geen reg die is ingesteld met blokkerende toewijzingen binnen een opeenvolgend altijd blok van buiten het altijd blok waarin het is toegewezen.
  2. Meng geen blokkerende en niet-blokkerende toewijzingen aan dezelfde reg.

Het overtreden van deze regels zal waarschijnlijk resulteren in mislukte synthese en / of gedragsverschillen tussen simulatie en synthese.

Opmerkingen

  • ” ” Krijg geen toegang tot een reg die is ingesteld met blokkeringstoewijzingen binnen een opeenvolgend blok altijd van buitenaf, blokkeer het altijd is toegewezen in. ” ” Kunt u het uitleggen?
  • Verschillende opeenvolgende blokken hebben geen gedefinieerde bestellen. Dus het lezen van een ” reg ” set met een blokkerende assingment in het ene altijd blok van het andere altijd blok zal leiden tot onvoorspelbaar gedrag.
  • En zelfs als het in simulatie lijkt te werken, zou een synthesetool daarnaar moeten kijken en ” nee ” moeten zeggen. Ik gebruik lokale regs voor die tussenliggende variabelen en zorg ervoor dat ze altijd op elke klok worden toegewezen voordat ze worden gelezen, zodat er geen ‘ opslag ‘ wordt geïmpliceerd.
  • IIRC wordt het in ieder geval in quartus alleen als een waarschuwing beschouwd en niet als een fout.
  • Je moet geen niet-blokkerende toewijzing gebruiken in combinatielogica, het kan vastlopen de simulatie. Raadpleeg dit antwoord voor meer details: electronics.stackexchange.com/a/506047/238188

Antwoord

De term Blokkeringstoewijzing brengt mensen in verwarring omdat het woord blokkeren tijdsequentiële logica lijkt te suggereren. Maar in gesynthetiseerde logica betekent dit niet dit , omdat alles werkt in parallel .

Misschien is een minder verwarrende term onmiddellijke toewijzing , die de tussenresultaten van combinatielogica nog steeds zou onderscheiden van de invoer naar niet-transparante geheugenelementen (bijvoorbeeld geklokte registers), die een vertraagde toewijzing kunnen hebben.

Vanuit een legalistisch standpunt komt het allemaal erg goed uit. U kunt de = zelfs beschouwen als een blokkerende (tijdsequentiële) bewerking, zelfs binnen always_comb sequenties. Echter, maakt het onderscheid tussen tijdsequentieel en parallel absoluut geen verschil in dit geval omdat de always_comb blok is gedefinieerd om te herhalen totdat de instructiesequentie convergeert naar een stabiele toestand – en dat is precies wat de hardwarecircuits zullen doen (als het voldoet aan de timingvereisten).

De synthetiseerbare subset van Verilog (en vooral SystemVerilog) is extreem simpel en gemakkelijk te gebruiken – als je eenmaal de nodige idiomen kent. Je hoeft alleen maar voorbij te gaan aan het slimme gebruik van terminologie die is gekoppeld aan de zogenaamde gedragsmatige elementen in de taal.

Opmerkingen

  • In gedragsmatige coderingsstijlen ( in vergelijking met RTL ), kan het onderscheid tussen blokkeren en niet-blokkeren relevant zijn. In sommige gevallen kan de synthesetool functioneel equivalente RTL afleiden uit ontwerpen van gedragscomponenten.
  • Natuurlijk is de procedureel modus van SystemVerilog, met name van toepassing op initial instructies binnen program blokken, gebruikt (tijdsequentiële) blokkeringstoewijzing exclusief. Dit is handig voor testbench -ontwerp, maar over het algemeen niet voor RTL-specificatie.

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *