Gokje: Onderwater is een Cyclone II haast een Stratix.
Gokje: Onderwater is een Cyclone II haast een Stratix.
Ik heb de VGA driver ook gemaakt voor de Terasic DE1 board. De Terasic DE1 board .qar file kun je hier downloaden
Er is wel een extra functie bijgevoegd. Zo worden er 16 leds van de board aangestuurd en de status van deze 16 leds wordt ook op de VGA monitor weergegeven.
Er is ook een clear screen functie toegevoegd. Maar als je deze uitvoerd ben je natuurlijk alle teksten kwijt. De teksten van de leds worden in deze versie niet opnieuw gezet op het scherm, de status aanduidingen van de leds lopen echter wel verder.
Wissen scherm is met de rechter drukknop.
De tijd wordt ook op het scherm geplaatst en kan worden ingesteld door 5 schuifschakelaars. Normale werkingstoestand is allemaal naar beneden anders wordt iedere seconde elke digit verhoogt!
Deze nieuwe functie van led aanduidingen is ook gemaakt voor de BlueBird FPGA board.
De BlueBird FPGA VGA .qar file kun je hier downloaden. Ook hier zit een wis functie bij met de MS1 drukknop. De 16 leds worden ook op de board aangestuurd en op het VGA scherm.
Alle files zijn ook bereikbaar via de link van de download pagina in mijn signature.
Tip: Voor veel data, kan je in rs232.v (het RS232 <-> usb voorbeeld) de PLL aanpassen dat ie op 95.8 MHz draait. Dat doe je in de megawizard.
code:
wire clk_96m;
reg clk48m;
pll_baudrate baud1(
.inclk0 (OSC),
.c0 (clk_96m) // nodig voor 115.200 bauds
);
wire clk_uart = clk_48m; // delen door 16 = 3M bauds
always @ (posedge clk_96m)
begin
clk_48m <= ~ clk_48m;
end
De baudrate wordt dan 3Mbaud. Onder linux kan je dan met
code:
setserial /dev/ttyUSB0 spd_cust
setserial /dev/ttyUSB0 divisor 8
stty -F /dev/ttyUSB0 38400
ook die van de ftdi op 3M zetten.
Ik wou dit net testen op 3 Mbit speed maar mijn "advance serial monitor" trail versie is net vervallen.
Heeft iemand weet van een andere gratis tool om serial iets over de USBlijn in te lezen?
Ik gebruik c-kermit, maar dat schijnt het ook onder windows te doen. http://www.columbia.edu/kermit/ck80.html
en met gui:
http://www.columbia.edu/kermit/k95gui.html
[Bericht gewijzigd door rew op 12 november 2007 15:04:30 (21%)
Zonder GUI interface op PC zie ik dit niet te doen....
Ik kan enkel nog met de muis klikken...
Update:
Ik heb hyperterminal ingesteld op de PC. Die heb ik even op 115200x4 = 460800 baud geplaatst en ja dat werkt. Nu nog even op 921600 plaatsen..... En ja ook dit gaat. Daarvoor moet je enkel de prescaler aanpassen:
wire clk_uart = baud_clk_cnt[0];
En hij staat op 921600. Voorlopig kan het niet hoger geselecteerd worden in de standaard menu maar dit is toch ook bijna 1Mbit als speed. Ook niet slecht zou ik zeggen, zonder tools.
Beste fotoopa,
Ik bewonder je mooie werk hier. Helaas ben ik 'nog' niet de gelukkige bezitter van een mooi FPGA/CPLD board.
Ik heb wel een simpel printje met een EPM7064, ik weet het erg weinig LE's. Nou wilde ik dit project wat eigenlijk voor een EPM7128 is gebruiken voor de EPM7064. Heb jij misschien tips om het wel te laten passen? Of doe ik iets wat veel efficiënter kan? Ik zou het graag ook 'echt' testen op mn printje, ik heb zelf nog niet de know-how voor het optimaliseren.
@SMD lover,
Je maakt het mij wel heel moeilijk, vooral als je weet dat ik geen VHDL gebruik.
Maar na analyse van je program zie ik dat je 50% van de LE's moet besparen en dat is heel veel. Je hebt 2 modules die vrij veel LE's gebruiken maar daar zitten zeer grote counters in. Ik zie daar 400.000 en als je dit echt nodig hebt kun je daar moeilijk veel LE's gaan besparen. het enige zou zijn ergens een lagere clock gebruiken maar zo laag zal het ook weer niet gaan om voldoende te besparen.
Je moet heel lange tijden wachten en dan nog eens lange tijden meten. Ik denk dat je niet snel tot zo een beperking gaat komen. ik heb ook timer modules die lopen per decade van 1sec tot 1us en die verbruiken ook ongeveer 90 LE's.
Het enige is een trage delay extern maken en die als input binnen nemen om die te tellen. vb een binaire deler zoals de 4020 reeks. Dan gaan je beide modules kunnen werken met minder LE's.
Maar dan nog die counter dat is 19 LE, dan moet je nog 5 LE besparen. Hmm zou kunnen, maar zal wel met veel pijn en moeite gepaard gaan..
Silicon Member
een Verilog ( en ook VHDL ) Tip :
het maken van volledig synchrone designs.
Synthesizers werken bottom up.
met andere woorden de prioriteit groet naarmate je dichter naar beneden gaat.
een voorbeeld :
code:
module teller (input clk,reset,preset,output einde);
reg [8:0] teller;
always @(posedge clk)
if(reset) teller <=0;
else if (preset) teller <=7;
else if (teller !=0) teller <= teller -1;
end
endmodule
bovenstaande code is 'redelijk' duidelijk .
bij elke klok : als er een reset binnekomt : teller op nul. als er geen reset binnekomt maar er komt een preset binnen : teller op 7. als er gene reset of preset binnenkomt en teller groter dan nul : teller naar beneden.
er is echter 1 conditie die niet afgehandeld wordt ... met name wat geberut er als geen enkele van deze conditie het geval is ? ( teller staat op nul ). de meeste compilers genereren een warning ( die in veel gevallen niet gelezen wordt door beginners maar die enorme fouten kan veroorzaken.
in bovenstaand voorbeeld is dat redelijk duidelijk maar bij complexe geneste if then else if statements wordt het een soep. vooral om ervoor te zorgen dat alle paden bewandeld worden en dat de boel niet als een latch geimplementeerd wordt. een pad wat niet volledig bewandeld wordt , of ene conditie die niet in alle gevallen evalueert kan ongewenste latches opleveren in het design.
daarom stipuleert IEEE1364 het volgende : concurrent staments : de signalen gaan van UITGANG naar INGANG. ELKE compiler MOET dat zo implementeren.
we passen de teller aan. nu zijn er een aantal paralelel statements.
code:
teller <= teller;
if (reset) teller <=0;
if (preset) teller <=7;
if (teller !=0) teller <=teller -1;
de synthesizer doet het volgende :
code:
reset
teller --|0\ preset
| |--|0\ teller >0
0---|1/ | |-----|0\ ____
7-|1/ | |---|d q|-- teller
(teller-1)--|1/ |> |
met andere woorden dit spul bouwt een nest multiplexers. ( die perfect mappen in FPGA. fpga is immers intern met multiplexers gemaakt en niet met losse AND en OR poortjes )
als alle condities evalueren naar logisch nul staan alle multiplexers naar boven. de teller stockeert dus bij elke clockpuls zijn huidige toestand.
als (teller != 0) staat de multiplexer het dichts bij de flipflop naar beneden. dus de flifplops stockren teller -1. op dat ogenblik spelen al die andere termen absoluut geen rol.
je kan nu dus door de volgorde van de IF statements te veranderen opdrukken wie de hoogste prioriteit heeft !
stel je wilt een teller waar PRESET voorang heeft op CLR.
code:
teller <= teller;
if (teller !=0) teller <=teller -1;
if (reset) teller <=0;
if (preset) teller <=7;
PRESET staat het laagst dus heeft hogere prioriteit dan CLR.
je moet dit zien als een 'EXCEPT' in plaats van een 'ELSE' methode.
code:
teller <= teller; // de teller blijft staan
if (teller !=0) teller <=teller -1; // BEHALVE als de teller verschillend is van nul
if (reset) teller <=0; // bovenstaande mag deaan worden BEHALVE als er een RESET binnenkomt
if (preset) teller <=7; // bovenstaande mag gedaan worden BEHALVE als er een preset binnenkomt
tis een andere manier van denken , maar in het geval van complexe if then else statements kan het je probleem heel elegant oplossen.
het kan je ook helepn te vermijden om overal else clauses te gaan toevoegen. stel je hebt een tristate bus. in plaats van overla die '<= z' te gaan invullen in je exception handlers schrijf je vlak voor je finale 'end'
output <=z;
dat heeft dus absolute prioriteit. je hoeft dan in je if then else nergens nog een z neer te poten. ze heeft prioriteit. het maakt je logica simpeler om te schrijven. en het is GEGARANDEERD dat dan alle paden bewandeld worden en dat je van die smerige latches vanaf bent.
wat is die website van terasic traag zeg , ik ben al 4 uur aan het proberen om mijn bord te bestellen, maar ik kom niet verder als het knopje checkout klikken.
Gr. Rik
Bedankt voor alle reacties!
Op 12 november 2007 20:14:10 schreef fotoopa:Maar na analyse van je program zie ik dat je 50% van de LE's moet besparen
Ik dacht dat het minder was? Bij het compileren kwam ik uit op 91 LE's wat er maximaal 64 kunnen zijn.
Misschien is het geheel ook wel op een andere manier aan te pakken.
Wat het programma moet doen is dit:
In stand-by telt een countertje continue. Wanneer op de knop wordt gedrukt, dan wordt de huidige waarde van de counter ingelezen. Deze waarde wordt gebruikt om een random-tijd te genereren. De punt in het 7-seg-display gaat aan. Na de random tijd gaat de punt weer uit. Op het moment dat de punt dooft, gaat er een timer lopen die de tijd (10 ms en 100 ms) meet tot de gebruiker de knop voor de tweede keer indrukt. Daarna wordt direct de gemeten tijd op het 7-seg gezet (doe dit x100 ms). Daarna moet de gebruiker weer op de knop drukken om het 2e deel van de gemeten tijd (x10 ms) te laten tonen. Tel deze waarden bij elkaar op en je hebt je reactietijd. Is deze tijd langer als 1 sec. dan kan deze tijd niet worden weergegeven op het 7-seg. Daarom wordt in dat geval een - getoond. De gebruiker moet nu weer op de knop drukken om de reactie-teller weer in de standby stand te zetten, waarna het gehele proces kan worden herhaald.
Ik hoor het graag als iemand vindt dat ik een totaal verkeerde oplossing heb gemaakt, als het maar minder LE's opleverd
Op 12 november 2007 23:36:54 schreef kofi:
De bestel site werk niet met firefox.
toch wel, net bordje besteld, dus zal eind deze week er wel zijn . Wellicht had vanmiddag iedeneen ineens een FPGA bord nodig
hoe wist je dat ik firefox gebruik
Gr. Rik
Ik heb op een CPLD boardje met een Xilinx XC9572 een osc van 50 MHz.
Nu wil ik graag een klok hebben van 25 MHz.
Hoe kan ik dit met verilog voor elkaar krijgen?
moet ik een nieuwe module maken in een nieuwe verilog file?
zoja, wat moet daar dan in staan? ik zal iets met een teller moeten doen, elke keer als die teller een bepaalde waarde bereikt heeft zal de output even hoog moeten worden, lieft met een duty cycle van 50%
wie o wie kan mij op weg helpen!
@Jeroen: ik kan je niet goed helpen vrees ik, ben nog steeds een grote noob in de wereld van Verilog Maar als je nou eens met schema-entry een deler maakt en dat dan door Quartus om laat zetten naar Verilog en het daar af kijkt? edit: oh, wacht, Xilinx.. Nou, die zullen wellicht ook zo'n optie hebben in hun pakket?
@free: in software gebruik ik in zo'n geval liever case statements, maar jij zegt dus eigenlijk dat een compiler dit beter zal verwerken?
Wat betreft onafgedekte condities: je kunt in een if-elseif-elseif-elseif... constructie natuurlijk ook gewoon altijd een else op het einde zetten waarin je default staat. In dat geval werkt de prioriteits-volgorde net andersom natuurlijk.
Maar er is wel wat voor jouw constructie te zeggen. Vanuit software-oogpunt gezien lijkt het in eerste instantie erg vreemd, omdat je tig keer een waarde gaat toekennen. Dat is natuurlijk net de truuk van het anders denken als je met VHDL/Verilog bezig gaat: alles gaat parallel, dus de volgorde van opeenvolgende if-statements met "dubbele" toekenningen weerspiegelt gewoon een prioriteit; ze worden niet sequentieel afgehandeld zoals in software.
@SMD lover,
Het is idd maar 91-64 macrocellen maar toch een vrij groot verschil. Nu ik goed je bedoelingen weet is er wel veel kans dat het gaat. Straks probeer ik het en heb ik nog een oplossing voor de middag dan zie je het wel. Deze namiddag ben ik niet vrij.
@Rikkepic,
Die site is idd traag maar de levering gaat snel. Enkel als student moet je eventueel nog eens de checking meerekenen om die korting te bekomen.
@Jeroen Boere,
Dit is enkel een deler zoals dit:
code:
reg clk25;
always @ (posedge clk50)
clk25 <= !clk25;
Je clk25 heeft een duty cycle van 50%. Gewoon deze 3 regels bijvoegen aan de bestaande verilog code.
@free_electron,
Weer iets dat we weten. Als je iedere week zo een tip geeft worden we met tijd allemaal ervaren gebruikers ( enfin als we het nog leren toepassen). Al die tips zijn zeker welkom.
Re: Fotoopa @ jeroen....
En dan kan je "clk25" elders wel weer als clock gebruiken, maar volgens mij vind FreeElectron dat je dat beter niet kunt doen. (tot nu toe doe ik (en fotoopa) het wel, en het werkt prima)
De reden is dat deze clk25 uit logica komt, en mogelijk glitches kan bevatten. Een teller kan dan zomaar terwijl dat niet moet toch een stappie doen.... Omdat dit wel vaker gedaan wordt, zal Altera er wel een beetje op letten in de quartus software, en het proberen te voorkomen. Wat meer meetelt is dat de FPGA 1 of 2 "clock distributie netten" heeft. Deze zijn er op gemaakt dat alle LEs tegelijk een clock signaal krijgen. Hierdoor heb je dus even veel tijd voor berekeningen van LE-A naar LE-B als andersom. Als een clock 2 ns later bij B is kan je dus krijgen dat je in de ene richting 6 en in de andere richting maar 4 ns "rekentijd" tot je beschikking hebt. Uiteindelijk kan je design dan minder hard.
Dus in plaats van
code:
always @ (posedge clk25)
begin
...
zou je volgens FE moeten doen:
code:
always @ (posedge clk50)
begin
if (clk25)
...
De algemene "clk50" wordt dan op het clock-netwerk gezet, en het gedeelte achter de if (clk25) gebeurt maar 25M keer per seconde.
FE, heb ik het goed begrepen?
Je hebt dat wel goed begrepen, maar in dit geval is dat niet echt nodig. het zal allemaal wel als flipflop worden geimplementeerd: de synthesiser zal de Q_Niet uitgang terugkoppelen naar de D ingang, en de 50Meg clock aan de clockingang hangen. Dit omdat alle mogelijke combinaties aan bod komen in het process.
Omdat het hier over slechts 1 FF gaat zullen er geen glitches ontstaan. Altera zal automatisch deze clock promoten tot hoofdclock en daarbij de goede distributie lijn gebruiken. Met grotere delers kun je idd wel glitches hebben maar in dat geval zal ik ze altijd terug op 1 hoge distriebutie clk gaan synchroniseren. Maar gezien jeroen aar heel weinig macro elementen heeft blijft er niet veel meer over om dergelijke oplossingen te gebruken.
Waar je wel moet mee rekening houden is dat de clk25 naijlt op de clk50. Gebruik je beide clokken dan kunnen er wel problemen ontstaan maar hoe je het ook schrijft de clk25 zal altijd blijven naijlen op je clk50.
Als schema entry zou je enkel een TFF hebben (of een DFF met geinverteerde uitgang naar zijn ingang), de clk50 op de FF clock en de clk25 is de FF uitgang. Glitches kunnen hier bijgevolg niet ontstaan.
oef ... stecj366 was mij voor!
Ik vraag me ook al een tijdje af wat de beste methode is om een klok te maken (afgezien van PLLs). Glitches heb je volgens mijn met zo'n synchrone deler niet, maar je krijgt wel een nieuwe clock domain erbij.
Zo'n if() constructie met de deelklok in de enable is wel een oplossing, maar betekent dat niet dat de timing constraints voor dat stuk code nog steeds binnen de 50Mhz klok vallen? Met andere woorden zelfs als je er een 1 Hz klok aan hangt (via een if) moet het stuk code nog steeds binnen 1 periode van de 50MHz klok uit te voeren zijn?
Inderdaad krijg je hier hoogstwaarschijnlijk geen last van glitches. Ik kan het me wel voorstellen in dingen als:
code:
always @ (posedge clk_50)
begin
if (clk_1us_cnt == 49) clk_1us_cnt <= 0;
else
begin
clk_1us_cnt <= clk_1us_cnt + 1;
if (clk_1us_cnt == 0) clk_1us_reg <= 1;
if (clk_1us_cnt == 25) clk_1us_reg <= 0;
end
end
hoewel ie hier ook netjes registered is. Dat zal dus wel meevallen. Maar je moet met je implementatie van je langzamere klok dus uitkijken.
Verder kan ie maar 1 of 2x de boel naar het hoofd-klok-netwerk omschakelen. Fotoopa heeft 1M, 100k, 10k, 1k, 100, 10 en 1 Hz. De neiging bestaat om die dan ook te gebruiken, en dan zijn er niet genoeg hardware clocknetten....
@madwizard: Ja.
Optie is dus om bijvoorbeeld 1 langzamere clock te maken (bijvoorbeeld 1MHz), en als die dan naast de 50MHz op een centraal clocknet kan, heb je daar een ruime 1000ns de tijd voor combinatoriek....
[Bericht gewijzigd door rew op 13 november 2007 10:33:24 (12%)
Ja dat klopt. Vandaar dat je vrij gemakkelijk timingsfouten krijgt van de compiler. Daar heb ik ook veel problemen mee. En 50 Mhz is tenslotte maar 20 nsec.
Bij 2 clock domainen ga ik ze wel gaan hersynchroniseren. Dan weet je dat de signalen binnen die tijd stabiel zijn.
Maar wie weet zal F_E nog wel andere duidelijke oplossingen hebben.
@rew:
Bij de cyclone zijn er 2x4 global clocks mogelijk. Die toekenning zie je in je rapport verschijnen. Maar ik geef toe dat ik ook nog veel vraagtekens heb voor de ideale clockmodule in een range van 1us tot 1s.
... 2x4 global clocks
Je hebt gelijk, en hij promote ook een paar signalen om die te gebruiken.
code:
Info: Automatically promoted some destinations of signal
"clk_uart" to use Global clock
Info: Destination "clk_uart" may be non-global or
may not use global clock
Info: Automatically promoted signal "clock_module:sys_clocks|
clk_1ms" to use Global clock
Info: Automatically promoted signal "clock_module:sys_clocks|
clk_10us~reg0" to use Global clock
Info: Automatically promoted signal "clock_module:sys_clocks|
clk_10ms" to use Global clock
Ik krijg trouwens, altijd een aantal timing violations bij de voorbeeld designs, maar het werkt wel. Is dat bij jou ook zo?
Ik heb toch ook al gemerkt dat de tools nogal kwistig zijn met het melden van timing fouten... Simuleren op gate level wil dan wel eens uitsluitsel geven, en anders gewoon testen of het kan...