Goede avond,
sinds vorige week heb ik mijn Terasic bordje binnen (DE2-115). ik ben begonnen met wat simpele dingetjes zoals drukknop stuurt led etc.
Nu ben ik begonnen met wat timing gedoe, uit een post van fotoopa zag ik iets met een prescaler. Ik heb deze code aangepast zodat ik met 1 prescaler 2 klokwaardes kan maken (zie code).
Is dit een goede manier van werken (om resources te besparen) of is dit not done? Als visualisatie heb ik 2 maal 8 leds die "optellen".
module test (clk, uitgangen, uitgang2);
input clk; //kloksignaal (50Mhz)
output reg [7:0] uitgangen; //eerste set uitgangen (groene leds)
output reg [7:0] uitgang2; //tweede set uitgangen (rode leds)
reg [27:0] prescaler; //bepalen hoe "breed" onze prescaler is
assign clk_enc = prescaler[27]; //eerste klok is 28 bits
assign clk_enc2 = prescaler[23];//tweede klok is 24 bits
//We tellen constant eentje op bij de prescaler
always @ (posedge clk)
begin
prescaler <= prescaler + 1;
end
//28bits ==> 5,3sec
always @(posedge clk_enc) begin
uitgangen = uitgangen + 1;
end
//24bits ==> 0,33sec
always @(posedge clk_enc2) begin
uitgang2 = uitgang2 + 1;
end
endmodule
Hoe ga je tewerk als je bv een 74HC595 kloksignaal moet maken? is dit dan op dezelfde manier (behalve dat je dan een enkele uitgang hebt)?
alvast bedankt
PS: FPGA is cool^_^
Tijmerd
free_electron
Silicon Member
Professioneel ElectronenTemmer - siliconvalleygarage.com - De voltooid verleden tijd van 'halfgeleider' is 'zand' ... US 8,032,693 / US 7,714,746 / US 7,355,303 / US 7,098,557 / US 6,762,632 / EP 1804159 - Real programmers write Hex into ROM
je maakt eigenlijk 2 clockdomeinen aan. die dan op hun beurt weer aangedreven worden door het master clock domein.
voor kleine projectjes gaat dat , maar je gaat andere problemen krijgen op den duur.
beter is om in 1 domein te blijven draaien.
always @(posedge clk) begin
// event creation
event1 <=0;
event2 <=0;
prescaler <= prescaler +1;
if (prescaler == 32'h10000000) event1 <=1'b1;
if (prescaler == 32'h01000000) event2 <=1'b1;
// event handlers
if (event1) begin
uitgangen <= uitgangen +1;
end
if (event2) begin
uitgang2 <=uitgang2 +1;
end
end
ik maak gewoon events aan. een event wordt afgevuurd voor exact 1 clocktick van de master clock. alle flipflops draaien dus op die master clock. ik controller eignelijk alleen de 'enable pin' op cadans van de event generator.
nog een paar andere dingen :
gebruik <= en niet =
Schakel de compiler over naar SystemVerilog ( Verilog2005 ) project -> settings -> verilog settings
je kan veel korter scrijven en hoeft niet constant alles te herschrijven of twee keer te schrijven
module test ( input clk,
output reg [7:0] uitgang, uitgang2
);
reg [27:0] prescaler; //bepalen hoe "breed" onze
always_ff @ (posedge clk)
event1 <=0;
event2 <=0;
prescaler <= prescaler +1;
if (prescaler == 32'h10000000) event1 <=1'b1;
if (prescaler == 32'h01000000) event2 <=1'b1;
// event handlers
if (event1) begin
uitgangen <= uitgangen +1;
end
if (event2) begin
uitgang2 <=uitgang2 +1;
end
begin
end
endmodule
flipflop
"We cannot solve our problems with the same thinking we used when we created them" - Albert Einstein
Inderdaad. NOOIT meerdere domeinen aanmaken in een FPGA, tenzij het echt niet anders kan (bv als een externe interface op een andere clk werkt). Maakt je constraining alleen maar lastig en het is totaal niet nodig.
rew
four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
Even voor de goede orde: De code die FE heeft gepost zorgt dat voor ieder "rondje" van de prescaler op twee verschillende momenten "event1" en "event2" afgaan, maar niet dat ze op verschillende snelheden lopen. De TS wil dus iets als:
if (prescaler(23 downto 0) == 24'h123456) event2 <=1'b1;
(ik geloof dat FE Verilog schrijft, en dat ik hier half VHDL doorheen doe, je zult even uit moeten zoeken hoe dat in jou taaltje moet. )
[edit] Trouwens: Als je iets schrijft als:
prescaler1 <= prescaler1 + 1;
if (prescaler1 == <hier een waarde invullen>) {
event1 <=1'b1;
prescaler1 <= 0; // hier correcte syntax voor "0" invullen
}
dan kan je vrij willekeurige verhoudingen maken
[Bericht gewijzigd door rew op (25%)]
free_electron
Silicon Member
Professioneel ElectronenTemmer - siliconvalleygarage.com - De voltooid verleden tijd van 'halfgeleider' is 'zand' ... US 8,032,693 / US 7,714,746 / US 7,355,303 / US 7,098,557 / US 6,762,632 / EP 1804159 - Real programmers write Hex into ROM
Op 19 augustus 2011 07:14:55 schreef rew:
Even voor de goede orde: De code die FE heeft gepost zorgt dat voor ieder "rondje" van de prescaler op twee verschillende
ah inderdaad. dat was me even ontglipt. ik wou orginieel iets anders schrijven ( bitwise ands ) maar dacht ' dat zaait teveel verwarring bij de TS in 1 keer. en toen heb ik het maar met een comparator gedaan... en toen is de echte functionaliteit verloren gegaan.
zo los je dat dan op:
if (prescaler[27:0] == 28'h10000000) event1 <=1'b1;
if (prescaler[23:0] == 24'h01000000) event2 <=1'b1;
nu tellen de MSB's niet meer mee... en krijg je inderdaad verschillende frequenties.
Allright, ik dacht al dat er iets niet klopt met de eerste code van FE. Anyway nu werkt het, maar heb nog enkele vraagjes.
Is er een voorkeur voor always_ff boven always te kiezen? Heb gelezen dat dit eerder te maken had met simulatie software ofzoiets.
in mijn vorige code maakte via 2 assign statements mijn "kloksnelheid". nu wordt dit gedaan in een if structuur waar je de prescaler gaat "beperken" en dan vergelijken. Wat is het verschil dan precies? En waarom kan het mis gaan via een assign?
Is mijn code nu "beter" geschreven of zijn er nog opmerkingen rond?
module test (
input clk,
output reg [7:0] uitgangen, uitgang2
);
reg [27:0] prescaler;
reg event1, event2;
//We tellen constant eentje op bij de prescaler
always @ (posedge clk) begin
event1 <= 0;
event2 <= 0;
prescaler <= prescaler + 1;
if (prescaler[23:0] == 24'h00100000) event1 <=1'b1;
if (prescaler[27:0] == 28'h00010000) event2 <=1'b1;
// event handlers
if (event1) begin
uitgangen <= uitgangen +1;
end
if (event2) begin
uitgang2 <=uitgang2 +1;
end
end
endmodule
Iedereen bedankt voor het helpen:)
Tijmerd
flipflop
"We cannot solve our problems with the same thinking we used when we created them" - Albert Einstein
Ja, zo is het goed. Wat je nu hebt is dat alle FFs op dezelfde clk lopen, nl. "posedge clk". Dat heet synchrone logica, alles loopt synchroon met de clock.
Wat je eerst had was een prescaler waaruit 2 signalen kwamen. Elk van die signalen (uitgangen van FFs) werden ergens anders weer als clk gebruikt. Dus op punt a is het data, op punt b is het clk. Dat kan (bv als je erg zuinig wilt zijn) maar in een FPGA speelt power niet en dan geeft het alleen maar ellende.
free_electron
Silicon Member
Professioneel ElectronenTemmer - siliconvalleygarage.com - De voltooid verleden tijd van 'halfgeleider' is 'zand' ... US 8,032,693 / US 7,714,746 / US 7,355,303 / US 7,098,557 / US 6,762,632 / EP 1804159 - Real programmers write Hex into ROM
ik wil even iets verduidelijken wat flipflop schrijft.
het geeft ellende als je later iets gaat doen met een signaal wat op clock 1 loopt en een signaal wat op clock 2 loopt.
als er geen fase relatie is , of de delay random wordt , dan krijg je gegarandeerd vodden. je gaat de mist in met setup en hold times en dan is er niemand die weet wat het resultaat nu precies is.. je kan er evengoed ene random generator in vlammen dan...
ander punt is dat in ene fpga er slechts een paar fysieke 'clock netten' zijn. dat zijn speciale constructies waarvan gegarandeerd is dat de signalen overal tegelijkertijd aankomen. ( skew generators aan boord )
met gewone routing kanalen is dat niet het geval.
Natuurlijk kan het perfect. Ik heb een systeem waar 3 verschillende klokdomeinen in zitten.
De master clock is 48 MHz via ene PLL wordt die opgewerkt naar 200MHz.
er is dus niks relatie tussen die twee ( faserelatie ) . Dat valt op te lossen door synchronisatie mechanismes te stoppen daar waar signalen van het ene naar het andere moeten. ik gebruik een handshake mechanisme.
het snelle domein zet een vlag. wanneer het trage domein die vlag ziet zet dat op zijn beurt een tweede vlag. het snelle domein bewaakt de tweede vlag. als het die ziet hoog worden zet het vlag 1 uit. Er is dus terugkoppeling dat het trage domein het snelle domein gezien heeft. Pas als het trage domein de eerste vlag terug op nul ziet vallen wordt de actie uitgevoerd. Zo weet het trage domein dat het snelle domein gezien heeft dat het trage domein de informatie uit het snelle domein heeft overgenomen.
Ik heb nog een derde domein wat ook op 48 MHz loopt maar met een skew. ( uit de PLL gemaakt ) zo kan ik de delay in de I/O compenseren. Ik stuur data uit op de voorijlende clock. de naijlende clock leest die , verwerkt die en ramt die terug buiten. bij de volgende naijlende cloktick pak ik die dan weer binnen.
bespaart me een waitstate en werkt vlekkeloos.
Maar dergelijke grapjes moet je goed doordenken en vooral meten (lees : dikke logic analyser met state en timing analyse. )
flipflop
"We cannot solve our problems with the same thinking we used when we created them" - Albert Einstein
Op 20 augustus 2011 00:25:09 schreef free_electron:
...ik gebruik een handshake mechanisme.
het snelle domein zet een vlag. wanneer het trage domein die vlag ziet ...
Zo kan dat inderdaad, maar die flags moet je wel synchroniseren naar het domein waar ie gelezen wordt, anders heb je alsnog kans op meta-stabiliteit. Nou is die kans in een FPGA niet zo groot, maar het kan wel voorkomen.
rew
four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
vincent, volgens mij heb je je dag(en) niet...
Jij vergelijkt in:
if (prescaler[27:0] == 28'h10000000) event1 <=1'b1;
if (prescaler[23:0] == 24'h01000000) event2 <=1'b1;
precies met de eerste waarde die ie nooit kan halen..... Volgens mij zou de compiler daar van moeten maken: if (FALSE) event1 <= 1'b1; ----> nop;
Het is m.i. makkelijker om te vergelijken met de waarde "0". Dan zit je niet met dit gedoe.
Tijmerd is er bewust of niet achter gekomen, en heeft een paar nulletjes rechts weggehaald...
eagle987
Eerst waren het atomen, dan waren het protonen, neutronen, elektronen, nog later waren het quarks en nu blijken het snaren te zijn...
Waarom niet gewoon een rising edge detector bouwen? (dff, and en not-poort)
Daarna in het snelle circuit pollen wanneer er een flank binnenkomt van het trage circuit.
rew
four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
Ik heb een keer een statemachine gebouwd die een extern ding (FT245) aan moest sturen. Dat externe ding liep dus niet synchroon met de interne clock. Gevolg... De statemachine kwam in een niet-bestaande state. 
Als je dus in het langzame of het snelle domein direct zo'n signaal van de "andere kant" in een statemachine gebruikt moet je uitkijken.....
flipflop
"We cannot solve our problems with the same thinking we used when we created them" - Albert Einstein
Op 20 augustus 2011 18:34:49 schreef rew:
..Dat externe ding liep dus niet synchroon met de interne clock. Gevolg... De statemachine kwam in een niet-bestaande state.
Dat zou dus het gevolg van metastabiliteit kunnen zijn, maar het lijkt mij veel waarschijnlijker een design fout. Immers, je FSM is synchroon en gaat onder bepaalde voorwaarden over naar een volgende state. Ik zie niet hoe de "next state" beinvloedt kan worden door een asynchroon input signaal.
[edit] Dat kan natuurlijk wel degelijk. Immers, als je asynchrone signaal net "op" een clk flank veranderd, en die is van invloed op de state, dan kan het zijn dat sommige bits van het state register wel overgenomen worden en andere (nog) niet. Dan kun je inderdaad in een niet bestaande state uitkomen.
Overigens, altijd goed om ALLE states uit te coderen. Default ga je naar idle terug, of naar een error state. "Niet bestaand" mag niet bestaan eigenlijk.
@eagle. Ja, dat kan ook, maar dan kun je niet elk willekeurig deeltal maken. Overigens, pollen doen we niet in hardware 
[Bericht gewijzigd door flipflop op (16%)]
Tijmerd is er bewust of niet achter gekomen, en heeft een paar nulletjes rechts weggehaald...
Laat ons zeggen dat ik het zonder nadenken heb aangepast:) Aangezien ik nog niet zolang bezig ben met heel dit gebeuren is er nog veel chinees hier:). ik snap het nog niet zo goed van die clockdomeinen die dan plots nietmeer synchroon gaan lopen en "meta stabiliteit"?
anyway op dit moment loopt mijn "klokje" goed I guess. maar ik snap nog niet geheel waarom je zegt dat de 28bit klok niet zou werken. Heeft dit te maken met het "datatype" (28'h) ?
Ik heb ondertussen toch al redelijk wat bijgeleerd:)
Tijmerd
rew
four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
Op 20 augustus 2011 19:20:22 schreef flipflop:
Overigens, altijd goed om ALLE states uit te coderen. Default ga je naar idle terug, of naar een error state. "Niet bestaand" mag niet bestaan eigenlijk.
Ik codeer m'n statemachine zo van: "er zijn 5 states en die heten...", en laat de werkelijke codering aan de compiler over. Daarnaast zeg ik dan dat ie van alle "andere" states direct naar "idle" moet gaan. Dan zou je denken dat die een 5 uit 8 codering verzint. Maar dat is niet zo. Hij verzint een codering met 5 bits. Iedere state een eigen bitje. Dat is beter voor de logica die er omheen moet. En de optimalisator komt er achter dat alle "other" states dus nooit bereikt kunnen worden en optimaliseert die er uit.
Die optimalisator is trouwens best goed. Als je een input van je statemachine (nog) niet nodig hebt en vast aan de 0V hangt, dan optimaliseert ie gewoon de halve statemachine weg.
@tijmerd: Een 3bits variable kan 8 verschillende waardes aannemen: 000, 001,010, 011, 100, 101, 110, 111. Als je dan if (pietje == '1000') gaat doen, dan is dat NOOIT waar.
feit, ik was nog niet helemaal mee dat het in hex stond enz:-) Anyway, het lijkt nu toch redelijk deftig te werken ^_^
flipflop
"We cannot solve our problems with the same thinking we used when we created them" - Albert Einstein
Op 22 augustus 2011 06:53:02 schreef rew:
[...]
Ik codeer m'n statemachine zo van: "er zijn 5 states...Hij verzint een codering met 5 bits. Iedere state een eigen bitje.
1-hot codering. Er zijn bepaalde regels waarop ie een codering kiest. Bij veel states wordt het wel degelijk binair gecodeerd anders zou je wel een heel breed state register krijgen (stel je voor 50 states).
Als je een input van je statemachine (nog) niet nodig hebt en vast aan de 0V hangt, dan optimaliseert ie gewoon de halve statemachine weg.
Dat heet constant propagation. De synthese begint gewoon concequent bij een constante en gaat net zolang doorzoeken tot ie een circuit tegenkomt waar het niet meer constant is. Alles tot dat punt gaat (en kan zonder problemen) weg.
@TS, don't worry. Je hebt veel info niet erg hard nodig nog. Maar wat betreft die clk-domeinen... het is niet zo dat ze niet synchroon gaan lopen, maar ze zijn niet synchroon meer. De ene clk flank loopt iets achter de andere en zodoende mag je ze niet meer zomaar mixen want dan krijg je timing fouten. In een synchroon design liggen alle flanken exact op elkaar en alle FFs schakelen dan ook gelijk. Teken het maar in een timing diagram, dan zie het het misschien.
[Bericht gewijzigd door flipflop op (16%)]
rew
four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
Maar met het mixen van clock domeinen is gevaarlijk. In mijn geval ging het iets van 1 op tientallen miljoenen pas fout. Tja, ik wilde megabytes aan data oversturen, dus het ging gewoon in een paar seconden mis.... 
Die electronica gaat zodanig snel dat als het 1 op miljard fout gaat het nog snel fout gaat. (Als je met je auto naar je werk gaat is er een kans van meer dan 1:miljard dat je de avond niet haalt. Acceptabele kans om 2x per dag te doen. Maar als je FPGA 1:miljard een foutje maakt, kan het binnen een paar seconden al fout gaan...)
Lucky Luke
Eluke.nl | handgetypt | I'm a poor, lonesome cowboy, with a long, long way to go.
Op 22 augustus 2011 21:56:44 schreef flipflop:
1-hot codering. Er zijn bepaalde regels waarop ie een codering kiest. Bij veel states wordt het wel degelijk binair gecodeerd anders zou je wel een heel breed state register krijgen (stel je voor 50 states).
Leukste is nog (is mij verteld) dat het niet te bewijzen valt welke coderingsmogelijkheid de minste logica kost. De truc is er een stuk of 10 te proberen en de beste daarvan te nemen, die zal dan de "meest optimale" niet ver ontlopen.
Maarja, dat is voer voor wiskundigen of compilers/synthesetools.
rew
four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/