Vraag over Synthesizable For-lus en Genereer

Ik gebruik de Verilog-taal en Zedboard als doelbord.

Voor zover ik weet kan de for-lus worden gesynthetiseerd, en de synthesetool vertaalt de for-lus als een reeks gedupliceerde instructies, zoals het afrollen van de lus.

Bijvoorbeeld

for ( i = 0; i < 4; i=i+1) begin mem[i] = i; end will be translated to mem[0] = 0; mem[1] = 1; mem[2] = 2; mem[3] = 3; 

Daarom kan, voor zover ik weet, de for-lus worden gebruikt als de bron beschikbaar is om de meerdere maar dezelfde beoogde poorten af te leiden.

Het lijkt er echter op dat de genereren in Verilog kan worden gebruikt om niet alleen de meerdere instanties te impliceren, maar ook de meerdere instructies hetzelfde als de for-lus.

Ik begrijp dat het genereren alleen de meerdere instanties van de module kan impliceren en de for-lus kan niet worden gebruikt voor dat doel.

Wat is dan het verschil tussen de lus genereren + for en de lus alleen for? Ik denk echter dat beide werken als het afrollen van de lus. Is er een merkbaar verschil? Als er geen verschil is, welke codeerstijl heeft dan de voorkeur om het uitrollen van de lus te induceren?

Reacties

  • Voor de duidelijkheid, het is ' s: Ik bedoel, u concludeert. bijv. je impliceert een RAM in Verilog / VHDL, de synthesesoftware leidt dat RAM af van je Verilog / VHDL. Veelgemaakte fout, de moeite waard om te leren.

Antwoord

Verilog for-loops zijn perfect te synthetiseren onder bepaalde voorwaarden:

  • U kunt elke procedurele instructie binnen een lus gebruiken (bijv. if-else).
  • Het aantal lussen moet vooraf bepaald zijn.
    • De beperkende uitdrukking moet een vergelijking zijn tussen de lusvariabele en een constante of een parameter.
    • De staptoewijzing moet de luswaarde met een constante hoeveelheid verhogen.
  • U kunt in elke lus een andere waarde toewijzen aan dezelfde variabele (bijv. een index berekenen op basis van de lusvariabele).
  • Voor synthesedoeleinden wordt de lus geëvalueerd in tijd nul – dat wil zeggen dat als je probeerde een teller te maken, je alleen de uiteindelijke waarde zou zien.

Diezelfde regels zijn van toepassing, of je nu een for-loop in een procedureel blok gebruikt, of in een genereerblok.

Als je klaar bent in een procedureel blok, initial en always, kun je een for gebruiken loop om elementen in een array te wijzigen (precies zoals in uw voorbeeld), of u kunt dezelfde waarde meerdere keren wijzigen, bijvoorbeeld:

for (idx = 0; idx < 4; idx=idx+1) begin a = a + b[idx]; c = c + 2; //You can change more than one variable in a for loop end 

In dat voorbeeld, de resulterende hardware zal een reeks optellers zijn, waarbij de waarden van vier array-indices worden opgeteld.

Het belangrijkste is dat je geen nieuwe variabelen of modules kunt maken in een procedurele for-lus. Deze regel is van toepassing op procedurele blokken in het algemeen, niet alleen op loops (dwz je kunt “geen variabele declareren in een procedureel blok).

 

Genereer blokken aan de andere kant staat het aanmaken van variabelen en de instantiatie van modules toe. Dat betekent dat je in een Genereer blok een Genereer for-lus kunt gebruiken om modules af te leiden. Dat is vrijwel het enige verschil.

Voor het genereren van lussen moet u een genvar gebruiken als de lusvariabele (dwz de waarde die u gebruikt om door elke lus te tellen). Je moet de for-lus ook een naam geven:

for (loopVal = 0; loopVal < 4; loopVal = loopVal + 1) begin : loopName 

Deze naam wordt toegevoegd aan elk stuk hardware dat je in de lus instelt. Dus als u een instantie maakt met de naam bob, zou de bovenstaande lus instanties creëren:

loopName[0]|bob loopName[1]|bob loopName[2]|bob loopName[3]|bob 

Dit resulteert in meerdere instanties met unieke namen.

 

Zowel het genereren als procedureel voor lussen zullen het uitrollen van lussen uitvoeren zoals je zegt. Het verschil is simpelweg hoe u ze kunt gebruiken. Procedureel kan worden gebruikt in procedurele blokken (bijvoorbeeld voor het initialiseren van een geheugen). Generate kan alleen worden gebruikt om blokken te genereren.

Ze zijn zowel nuttig als de voorkeur. De ene kan de andere niet vervangen.

Reacties

  • een andere manier om te denken aan genereren is als een soort pre-processor, je verilog-compiler ' voert ' dingen uit in het genereren van blokken op het punt waar het ' s instantiëren van het blok met de genereert – ze vinden niet ' plaats tijdens runtime (in tegenstelling tot procedurele lussen)
  • @Taniwha procedurele lussen don ' worden ook niet uitgevoerd tijdens runtime. Ze worden uitgerold door de compiler. Uiteindelijk komt het allemaal neer op hardware. Verwar de preprocessor ook niet met het genereren van instructies, ze zijn niet hetzelfde concept – Verilog heeft een preprocessor inclusief if-else type statements.
  • @TomCarpenter Ik waardeer een geweldig antwoord. Ik kon al je punten begrijpen, behalve het genereren voor lus.Het lijkt erop dat begin: iets moet worden toegevoegd vlak voor de for-lus, maar kan niet begrijpen hoe het werkt in instantiemodules. Is de loopName een variabele of slechts een string? En hoe ze kunnen worden geïndexeerd door [1] tot [4].
  • @JaeHyukLee loopName is gewoon tekst, zoals een instantienaam of een signaalnaam. Het kan alles zijn wat je maar wilt.
  • @TomCarpenter – het hangt af van de compiler – als je ' poorten opnieuw compileert, ja ze worden uitgerold, als je ' opnieuw compileren van code voor simulatie waarschijnlijk niet (disclaimer, ik ' heb een Verilog-compiler geschreven)

Geef een reactie

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