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)