Stap 16: VM 3.3: geavanceerde instantiëren onderwerpen
(Afbeelding oorspronkelijk gemaakt door Digilent Inc.; gewijzigd door mij voor dit deze tutorial)
De vorige module geïntroduceerd, en hopelijk reed naar huis, het concept van instantiëren in Verilog. Nu zullen wij een blik bij een paar gevorderde onderwerpen (tweede onderwerp binnenkort worden toegevoegd) met betrekking tot module instantiëren.
Teller gecontroleerde instantiëren:
Wat als we nodig hadden voor het genereren van een bos (neem 50 als voorbeeld) van DFFs die werden allemaal met elkaar verbonden in een klok scheidingslijn circuit... We weten al hoe te maken van een algemene DFF module, dus nu moeten we instantiëren het 50 keer en verbinding maken met de pin klok van elkaar op de uitgang van de DFF thats sequentieel voordat het verbinding opnieuw ingesteld op een mondiale reset, en de D-pin aan de inverse van de DFF de productie (Q). Gebruik de bijgevoegde diagram voor verwijzing.
Dit zou een heleboel instanties voor u te schrijven (50 instanties tijden 6 lijnen per instantiëren is 300 lijnen!) met de hand. Maar in Verilog kunnen we een teller-controller gebruiken herhalen, in het bijzonder een "for"-lus, om objecten te maken (genereren) alle van deze modules (met uitzondering van de eerste shape) voor ons in zeer weinig coderegels. Maar er een waarschuwing is; We moeten zorgvuldig plannen van ons ontwerp, zodat we een "genereren lus" goed gebruiken kunnen.
Merk op dat de manier waarop wij elke DFF verbinden met de volgende uniform en voorspelbaar. Natuurlijk, zal de eerste DFF klok de klok input van onze hoogste niveau-module, en de output van de laatste DFF gaat ergens in de module van het hoogste niveau, maar we kunnen omgaan met die individueel; tijdens de generatie, elke interne draad in het ontwerp met uitzondering van de eerste klok die we zullen handmatig instelt en de laatste output draad expliciet krijgt een bron en een afvoer. De software weet dat de twee overige draden ofwel een bron moeten (eerst klok) of afvoer (laatste gegevens) en het is de verantwoordelijkheid van de ingenieur om een.
Zoals eerder vermeld, hebt u het ontwerp behoorlijk om te gebruiken een lus genereren instellen. Wat houdt dit in? Nou, is het zinvol dat aangezien elke DFF's gonna hebben een klok in afhankelijk van het vorige voorbeeld (niet met inbegrip van de eerste shape!) dat we deze vergelijkbare signalen in een bus kunt groeperen! Dit laat ons verwijst naar signaal groepen zoals een array in C/C++ en oproep individuele draden door index met de operator [].
De resetpin voor elke DFF zal komen uit een gemeenschappelijk reset, aangezien elke DFF moet kunnen instellen op hetzelfde moment.
Zonder de specifieke kenmerken van een lus genereren nog weten, kunnen we nog steeds onze bus die zal worden gebruikt in het ontwerp maken. Wat voor soort bus zullen we maken? Aangezien deze zijn alleen bezig met een signaal van een bron aan een afvoer, zullen we draden.
draad uit [49:0] //50 bits breed bus voor DFF-uitgang/ingang
We kunnen ook onze eerste DFF instantiëren. Met behulp van de module DFF van Tutorial Module 3.2, en ervan uitgaande dat de scheidslijn van onze klok heeft een input clk (een klok-pin), een input rst (een Resetpin) en een output uit (laten we zeggen dat het een LED, het creëren van een knipperend effect zal rijden).
DFF dff0)
.CLK(CLK),
.RST(RST),
. D(~out[0]),
. Q(out[0])
);
Nu, de genereren lus. Het is vergelijkbaar met een lus in C/C++, maar heeft zijn eigen nuances. We moeten eerst een teller-variabele maken. In Verilog type van de variabele "genvar" wordt genoemd en het wordt gebruikt om een variabele te declareren, noem het "y", als volgt:
genvar y;
De lus genereren met het trefwoord "generate" begint en eindigt met "endgenerate".
Opmerking: U moet alle variabelen van de genvar buiten de werkingssfeer van de lus genereren declareren.
Dat hebben we nu:
genvar y; endgenerate
genereren
Onmiddellijk na het sleutelwoord "genereren" is de werkelijke lus. Haar verklaring is als een lus in C/C++, maar in Verilog, we hebben niet de luxe van links en rechts krullend accolades ({en}) maar we hebben het Verilog-equivalent: beginnen en eindigen. Bovendien Verilog biedt geen ondersteuning voor postfix operaties, dus we kunnen niet zeggen "y ++" en in plaats daarvan vermeldt "y = y + 1". Wanneer het construeren van de for-lus, houd er rekening mee dat we reeds de eerste DFF (DFF0 gemaakt) zodat we zullen genereren van 1 tot en met 49 (kleiner dan 50).
genvar y; einde
genereren
voor (y = 1, y < 50; y = y + 1) //spaces kan worden weggelaten
beginnen
endgenerate
Met een lus genereren, we gaan 'begin' een lus instantiëren en moet dit proces een naam geven. Wij zullen niet gebruiken deze naam voor enig ander doel en zal niet verwijzen naar het verderop in ons ontwerp (het wordt intern gebruikt in de synthesizer). We doen dit door toevoeging van een verklaring naar aanleiding van de indeling ":" en plaats deze op dezelfde regel als de "begin" voor goede stijl. Laten we noemen dit "dff_generation":
genvar y; einde
genereren
voor (y = 1, y < 50; y = y + 1) //spaces kan worden weggelaten
beginnen: dff_generation
endgenerate
Nu is het cruciaal en moeilijkste deel: het instantiëren model maken. Dit ziet er net als elke andere instantiatie behalve dat de draden passeer de module mag gebruik maken van de genvar als een waarde of de waarde modifier. Herinneren dat de genvar de waarde door een in dit geval na elke instantiëren zal veranderen.
In plaats van lopen door elke regel van de instantiatie, ik geef u het hele codeblok en wijzen van de dingen die je niet kan herkennen. Moet u verwijzen naar de geleverde afbeelding om te zien hoe dit circuit wordt uitgevoerd.
genvar y;
genereren
voor (y = 1, y < 50; y = y + 1) //spaces kan worden weggelaten
beginnen: dff_generation
de onderstaande aanleg naam doet er niet toe
DFF dff_insts)
.CLK(out[y-1]), //clk in van DFF "y" is uit "y-1"
.RST(RST), //each DFF krijgt het dezelfde resetten
. D(~out[y]), //input wordt gevoed de omgekeerde output
. Q(out[y]) //output
);
einde
endgenerate
Ik moedig u aan de hand van trace een paar herhalingen van de lus om te zien hoe de generatie proces werken. De synthesizer krijgt elk exemplaar het creëert een unieke geïndexeerde naam zoals "dff_insts1" en "dff_insts2".