A Synthesizable For loop és a Generate kérdés:

A Verilog nyelvet és a Zedboard-ot használom céltáblaként.

Ha jól tudom , a for ciklus szintetizálható, és a szintézis eszköz a for ciklust duplikált utasítások sorozataként fordítja le, mint például a hurok kibontása.

Például

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; 

Ezért ha jól tudom, a for ciklus akkor használható, ha az erőforrás rendelkezésre áll a több, de azonos célú kapu kikövetkeztetésére.

Úgy tűnik azonban, hogy a Verilogban a generálás használható nemcsak a több példányra, hanem a for ciklushoz hasonló több utasításra is.

Megértem, hogy a generálás csak a modul több példányát jelentheti, és a for ciklus nem használható erre a célra.

Akkor mi a különbség a ciklus és csak a hurok generálása között? Azt hiszem, mindkettő úgy működik, mint a hurok kibontása. Van-e észrevehető különbség? Ha nincs különbség, melyik a preferált kódolási stílus a hurok kibontásának előidézésére?

Megjegyzések

  • Az egyértelműség kedvéért ' s: Úgy értem, ön következtet. például. a RAM-ot a Verilog / VHDL-re utalja, a szintézis szoftver arra a következtetésre jut, hogy a RAM a Verilog / VHDL-ből származik. Nagyon gyakori hiba, érdemes megtanulni.

Válasz

A Verilog for-ciklusok bizonyos körülmények között tökéletesen szintetizálhatók:

  • A cikluson belül bármilyen eljárási utasítást használhat (pl. if-else).
  • A ciklusok száma előre meghatározottnak kell lennie .
    • A korlátozó kifejezésnek a ciklusváltozó és egy konstans vagy egy paraméter összehasonlítása kell, hogy legyen.
    • A lépéskiosztásnak a hurok értékét állandó összeggel kell növelnie.
  • Az egyes ciklusokban ugyanahhoz a változóhoz különböző értéket rendelhet (pl. index kiszámítása a ciklusváltozóból).
  • Szintézis céljából a ciklust kiértékelik nulla idő alatt – azaz ha számlálót próbálna készíteni, akkor csak a végső értéket látná.

Ugyanezek a szabályok érvényesek, függetlenül attól, hogy egy for-ciklust használ az eljárási blokkban, vagy egy generáló blokkban.

Ha egy eljárási blokkban készen áll, initial és always, használhatja a ciklus egy tömb elemeinek megváltoztatásához (pontosan úgy, mint a példádban), vagy ugyanazt az értéket többször is megváltoztathatja, például:

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 

Ebben a példában a kapott hardver összeadó lánc lesz, összeadva az értékeket négy tömbindexből.

A legfontosabb az, hogy nem hozhat létre új változót vagy modult a ciklus procedurális részében. Ez a szabály általában az eljárási blokkokra vonatkozik, nem csak a ciklusokra (azaz “nem deklarálhatunk változót az eljárási blokkban”).

 

A generáló blokkok viszont lehetővé teszik a változók létrehozását és a modulok példányosítását. Ez azt jelenti, hogy egy generáló blokkban a ciklus létrehozásával használhatja a modulok következtetését. Ez nagyjából az egyetlen különbség.

A ciklusok létrehozásához egy genvar -t kell használni ciklusváltozóként (azaz az értéket, amelyet az egyes ciklusokon keresztül számlálsz). A for ciklusnak nevet is kell adnia:

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

Ez a név minden olyan hardverhez elő van készítve, amelyet a ciklusban példányosít. Tehát, ha létrehoz egy bob nevű példányt, a fenti hurok példányokat hoz létre:

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

Ennek eredményeként több egyedi névvel rendelkező példányok.

 

A ciklusok generálása és az eljárási eljárás is végrehajtja a ciklus feltekerését, ahogyan mondja. A különbség egyszerűen abban rejlik, hogy miként tudja használni őket. A procedurális lehet eljárási blokkokban használni (például memória inicializálásához). A generálás csak generációs blokkokban használható.

Mindkettő hasznos és előnyös. Az egyik nem helyettesítheti a másikat.

Kommentárok

  • A generálás gondolkodásának másik módja egyfajta előprocesszor, a verilog fordító ' ' dolgokat generál blokkokban abban a pontban, ahol ' végrehajtja a blokkot tartalmazó blokkot a generál – ezek nem ' nem futási időben történnek (ellentétben az eljárási ciklusokkal)
  • @Taniwha eljárási ciklusok don ' t futtatáskor is végrehajtják. A fordító kigöngyöli őket. Végül az egész hardverré válik. Ne tévessze össze az előfeldolgozót a generációs utasításokkal sem, nem azok, amelyek ' ugyanaz a koncepció – a Verilognak van egy előfeldolgozója, amely if-else típusú utasításokat tartalmaz.
  • @TomCarpenter Nagyra értékelem a választ. Megértettem az összes pontot, kivéve a loop for generációt.Úgy tűnik, hogy kezdődik: valamit hozzá kell adni közvetlenül a for ciklus előtt, de nem értem, hogyan működik a modulok példányosítása. A loopName változó vagy csak karakterlánc? És hogyan lehet indexelni őket [1] – [4].
  • @JaeHyukLee loopName csak szöveg, például egy példánynév vagy egy jelnév. Ez bármi lehet.
  • @TomCarpenter – a fordítótól függ – ha ' újból összeállítja a kapukat, akkor kibontják őket, ha ' A szimulációhoz szükséges kód fordítása valószínűleg nem (felelősség kizárása, írtam egy Verilog fordítót)

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük