Hihi. Ik houd van compactere code... :-)

Dus ook de "ustate <= ustate" hoef ik niet expliciet /voor/ de case te zetten om hem z'n waarde te laten houden? Ik had dat geloof ik al geprobeerd, maar toen werkte het voor geen meter. Ik geloof dat een "inout" alleen als output gebruiken HELEMAAL niet werkt, en dat het daar aan lag.

Voor de "regelmaat" hou ik er zelf van om toch de begin/end in stand te houden, omdat ik zo her en der meer dan 1 statement nodig heb. Maar goed dat is programmeer stijl, en ieder z'n lol. Zo kan ik me ook voorstellen dat er mensen zijn die liever inderdaad nog expliciet de "else state<=0" laten staan. Maar het is fijn dat ik weet dat ik het kan vereenvoudigen. Thanks!

jep. ik schrijf ook altijd die begin-end constructie normaliter ( in een case ). het leest ook iets gemakkelijker. en als er later een lijn bijkomt moet je ze er toch gaan inprakken.

met dat expliciet zetten van ustate <=ustate garandeer je dat er geen latches gemaakt worden. als je de boel dan als concurrent if's schrijft heb je gegarandeerd een flifplop te pakken. de minimizer kan er dan niet onderuit.
voor simpel spul maakt het niks uit. bij state machines wel !

flifplop is (c)(r)(tm) f_e (ik moet een dezer dagen eens echt leren typen ... )

Op 30 november 2007 01:57:04 schreef free_electron:
met dat expliciet zetten van ustate <=ustate garandeer je dat er geen latches gemaakt worden.

In een geklokt process krijg je nooit een latch, dus daar maakt het niet uit. Dus zolang je maar always@(posedge clk) schrijft wordt het altijf een FF. Je kunt die state<=state dan best weglaten. De FF houdt z'n oude stand totdat je een nieuwe assignment doet.


case (ustate)       
    0:	ustate <= data_available;
    1:  blabla

Nog een opmerking over deze code (sry, moet even): dit vindt ik wel gevaarlijk worden. Het is alleen toevallig hetzelfde als wanneer je de if(data_available) er omheen zet. Met de if blijft de FF in dezelfde stand staan zolang data_avail 0 is. In bovenstaand geval klok je er 0 in in dat geval. In dit specifieke voorbeeld is dat hetzelfde, maar het gaat fout zodra je het gebruikt in een andere state. Een keer copy/past en je hebt je bug te pakken. Gewoon de if gebruiken, dan schrijf je ook precies functioneel op wat je wilt hebben.

hihi mee eens. je moet het zien als een obfuscating vereenvoudiging, die in dit geval als "syntax voorbeeld" dienst doet. Thanks voor de verduidelijking.

(state is een multi-bit variabele. data_available is 1 bit. Dat gaat kennelijk automatisch goed. Ik blijk voor een busje bij de declaratie de busbreedte vergeten te zijn, dan gaat het ook vanzelf fout.... Zucht.)

[Bericht gewijzigd door rew op (41%)]

Op 30 november 2007 14:30:34 schreef rew:
state is een multi-bit variabele. data_available is 1 bit. Dat gaat kennelijk automatisch goed

Ja, da's de ellende met Verilog. In VHDL wordt zoiets gelijk afgestraft. Een VHDL designer maakt zulke fouten ook niet.

IK heb mij bijna 2 dagen suf gezocht op volgende foute if:


  if ((dim_puls_reg == 2'b01) & dim_dir);

syntax gezien geen probleem maar er staat ten onrechte een ";" juist achter die if en die had ik niet gezien.

Daar kun je heel lang overkijken zonder te snappen waarom die if niet echt zijn werk doet :)

Op 30 november 2007 15:02:49 schreef flipflop:
[...]
Ja, da's de ellende met Verilog. In VHDL wordt zoiets gelijk afgestraft. Een VHDL designer maakt zulke fouten ook niet.

dat is helemaal geen fout. als je het compiler rapport leest zul je zien dat er variable smashing gebeurd is. die MOET je er uit halen.
laat variable smashing / stretching NOOIT over aan de synth !

trouwens er is meer aan de hand dan dat alleen.
het wordt heel gevaarlijk als je rtl gaat porteren naar andere tools / hardware ( fpga , asic )

het gebeurt vaak dat een blok wat perfect werk op asic niet werkt op fpga en vice versa. ik heb ook al problemen gezien bij xilinx <> altera .. soms stomweg omdat bepaald primitives anders zijn en extra delay veroorzaken.

ook voor high-speed design zitten er addertjes onder het gras.
om dat soort miserie te vermijden : concurrent if statements. Dat mapt mooi naar een combinatorische wolk voor een register.
en nooit ofte nooit combinatorische dingen naar buiten brengen.

ik was gisteren bezig op een timing probleem... FPGA draait op 240 MHz intern. ding wekt een seriele datatroom op ( ook de clock wordt opgewekt )

timing van de output is altijd goed. lezen gaat continue verkeerd. tot ik de interne clock ook terug naar buiten bracht en daar keek. er zat meer dan 1 periode delay in de io cell zelf.

fpga's zijn intern soms zeer snel ( tot 400 .. 600 MHz ) maar de pin to in delay is soms wel 5 tot 10 nS ..

de delay aan de output en de delay aan de input cel zorgden dat de data dus altijd een clock te laat kwamen ...

Op 30 november 2007 15:11:24 schreef fotoopa:
IK heb mij bijna 2 dagen suf gezocht op volgende foute if:


  if ((dim_puls_reg == 2'b01) & dim_dir);

syntax gezien geen probleem maar er staat ten onrechte een ";" juist achter die if en die had ik niet gezien.

Is die enkele '&' bewust gedaan of bedoel je '&&'? Kan namelijk ook een vervelend verschil maken, maar is in dit geval toevallig hetzelfde.

Op 30 november 2007 16:19:10 schreef madwizard:
[...]
Is die enkele '&' bewust gedaan of bedoel je '&&'? Kan namelijk ook een vervelend verschil maken, maar is in dit geval toevallig hetzelfde.

"&" gebruik ik altijd voor 1 bit variabelen. Het resultaat van een compaire is toch altijd een 1 bit. Ik hoop dat dit correct is want heb het altijd wat moeilijk gehad met "&" of "&&"
De fout hier was een lege if door de misplaatste ";"
"&&" zou ik gebruiken voor meerdere and bits. Die veronderstel ik test eigenlijk voor nul of geen nul van de overeenkomnede bits in je woord. Maar die heb ik heel zelden nodig.

Zelfde onduidelijk verhaal is een beetje met het gebruik van"!" of het "~" teken. Daar geraak ik ook niet zo best uit en zou een verduidelijking welgekomen zijn. Uit de handboeken geraak ik ook niet veel wijzer.

Op 30 november 2007 16:31:07 schreef fotoopa:
"&" gebruik ik altijd voor 1 bit variabelen. Het resultaat van een compaire is toch altijd een 1 bit. Ik hoop dat dit correct is want heb het altijd wat moeilijk gehad met "&" of "&&"

& is bitwise AND, && is logical AND. Bitwise is het best te vergelijk met wat een AND poort doe. Je geeft twee bitvectors, op elke 2 bits wordt de AND operatie uitgevoerd, en het resultaat is een even lange bitvector met de resultaten:

1011 &
1101
====
1001

Logical AND is de 'en' die in vergelijkingen en combinaties gebruikt worden. Enigszins vergelijkbaar met spreektaal 'en', 'of' e.d. maar daar moet je erg mee oppassen, in spreektaal heeft het vaak een andere betekenis dan in de logica. Maar het gaat er wel om of bepaalde dingen waar of onwaar zijn.
Logical AND (&&) kijkt of de linkerkant niet 0 is, en of de rechterkant niet 0 is. Wat het verder voor waarde is maakt niet uit. Als beide kanten niet 0 zijn is de uitkomst 1, anders 0. Je hebt dus altijd 0 of 1 als uitkomst.

1011 &&
1101
====
   1

0000 &&
0101
====
   0

Het verschil wordt belangrijk als je verschillende waarden gaat ANDen die uit meer bits bestaan:


0100 &
0010 
====
0000

-maar-

0100 &&
0010
====
   1

Kort gezegd: & gebruik je als je de AND van twee waarden wilt berekenen. Dus als het resultaat belangrijk is.
&& gebruik als je twee waardes op waarheid wilt controleren (linkerkant niet nul EN rechterkant niet nul).

|, ^ e.d. gaan op dezelfde manier.

De fout hier was een lege if door de misplaatste ";"

Dat snapte ik, maar dit viel me zo even op. Vooral als je geen C achtergrond hebt is zo'n fout namelijk snel gemaakt.

"&&" zou ik gebruiken voor meerdere and bits. Die veronderstel ik test eigenlijk voor nul of geen nul van de overeenkomnede bits in je woord. Maar die heb ik heel zelden nodig.

Bij een enkele bit is er geloof ik geen verschil nee, maar ook om duidelijk aan te geven wat je bedoeld zou ik && gebruiken. Het gaat immers om een logische AND (beide condities waar), niet of het resultaat van een AND operatie op 1 uit komt (wat stiekem hetzelfde betekent hier). Het verschil geeft de bedoelding ook aan.

Zelfde onduidelijk verhaal is een beetje met het gebruik van"!" of het "~" teken. Daar geraak ik ook niet zo best uit en zou een verduidelijking welgekomen zijn. Uit de handboeken geraak ik ook niet veel wijzer.

Dit is iets soorgelijks. ~ is een NOT op elke bit afzonderlijk (bitwise), en het resultaat krijg je terug. ! is kijken of de waarde 0 of niet is (logical), en het resultaat is respectievelijk 1 of 0.


~1010 = 0101
~0000 = 1111
~0001 = 1110

!1010 = 0
!0000 = 1
!0001 = 0

Dit kan duidelijk ook voor problemen zorgen bij meerdere bits.

Madwizard, weet je zeker dat Verilog hier dezelfde definities als C hanteert? (ook hier is dit een serieuze vraag en niet een sarcastische opmerking omdat ik denk dat het anders is.... )

Voor zover ik weet wel ja, behalve dat je ook nog Z en X hebt in verilog als bits maar los daarvan geloof ik dat het hetzelde werkt.

Bedankt madwizard voor de uitgebereide uitleg.

Een en ander is mij nu wel duidelijker. Eigenlijk ben ik weer te lui geweest. Ik kon dit zelf getest hebben. Om een en ander toch wat beter te memoriseren heb ik het toch in een routine geschreven die het resultaat direct op de 4x7 segments display plaatst. En dan zie je idd dat je uitleg klopt.

Op 30 november 2007 16:00:59 schreef free_electron:
dat is helemaal geen fout. als je het compiler rapport leest zul je zien dat er variable smashing gebeurd is. die MOET je er uit halen.
laat variable smashing / stretching NOOIT over aan de synth !

trouwens er is meer aan de hand dan dat alleen.
het wordt heel gevaarlijk als je rtl gaat porteren naar andere tools / hardware ( fpga , asic )

Dus het is toch wel een fout dan? Als je het MOET fixen? Ik wil in de code altijd precies zien wat je in hardware wilt hebben. Dus aan beide kanten van de assignment moet je evenveel bits hebben, anders wordt je afhankelijk van de compiler, hoe die het oplost. Nou is het in dit specifieke voorbeeld (vector<=bit) precies door Verilog gedefinieerd, maar netjes is het niet.

Over dat porten: dat probleem heb je dus ook alleen bij Verilog omdat die taal niet "ontworpen" is. Het is ontstaan uit bestaande tools. En je hebt ook alleen problemen als je zaken aan de compiler overlaat en dus niet precies opschrijft wat je wilt hebben. Zie weer die assignment.

Op 30 november 2007 17:47:07 schreef flipflop:
[...]
Dus het is toch wel een fout dan? Als je het MOET fixen? Ik wil in de code altijd precies zien wat je in hardware wilt hebben.

Over dat porten: dat probleem heb je dus ook alleen bij Verilog omdat die taal niet "ontworpen" is. Het is ontstaan uit bestaande tools.

Noch verilog noch VHDL zijn 'ontworpen' als synthese talen. ! men probeert daar die functionaleit op te kleven.
Ditto met SystemC. het enige wat echt gemaakt is om logica te 'schrijven' zijn zaken zoals ABEL en AHDL, maar dat is heel gelimiteerd.

Je hoeft het ook niet te fixen. Als je exact weet hoe je tool werkt mag je het laten staan. ( als je synth 1364 compliant is maakt het nisk uit. de vraag is alleen : hoe goed is de synth die je gebruikt )
vandaar : kuis de warnings op. Das net gelijk in 'c'. ze compileren en duwen een programma met 5000 warnings in prodcutie. en dan zijn ze verwonderd dat het af en toe vast loopt. 'tzal wel goed gaan' .... jaja.

Er zijn zaken die je heel mooi aan de syntesizer kan overlaten. 0 expanding etcetera. ook bij resizing is het vaak handig ( bespaart veel tikwerk en hoofdbreken. ) maar je moet wel weten wat je doet. en das het probleem. dat komt alleen met ervaring. vandaar : proper programmeren .

ze lachen ook af en toe met mij als ze mijn code zien. maar jongen das veel te 'uitvoerig geschreven'.
das allemaal goed , maar die gasten kennen de tool. ikke niet. ( heb er ook geen zin in )
32 bit register schrijven over 16 bit addressbus :


rega <= rega;
if (write) case (address)
   0 : rega <= {rega[31:16] , data_in  );
   1 : rega <= {data_in     , rega{15:0};
endcase

kan ook als dit geschreven worden


rega <= rega;
if (write) case (address)
   0 : rega[31:16] <= data_in;
   1 : rega[15:0]  <= data_in;
endcase

die concatenation hoeft helemaal niet. Ik vind het alleen 'visueel' leesbaarder en het werkt gegarandeerd. je moet niet op meerdere lijnen gaan lezen om uit te vlooien wat het doet.
en bij portering is er geen verwarring .
bij VHDL heb je die porteerproblemen ook. niet alle compilers zijn fully standard compliant...

een beetje extra tikwerk heb ik geen bezwaar tegen. maar de 'vhdl' uitvoerigheid is er teveel aan voor mij.

Tja, dan komen wederom op de eeuwige discussie uit: Wat is beter, VHDL of Verilog. Daar komen we dus nooit uit want dat is niet objectief te beoordelen.
Wel een paar opmerkingen:
- Van beide code snippets vind ik de laatste het best leesbaar. Geeft EXACT aan wat er gebeurt en wat je WILT dat er gebeurt.
- VHDL is wel degelijk voor synthese ontworpen. Beter, voor zowel simulatie als synthese.
- Uiteraard hebben beide talen een historie voordat ze in IEEE standaarden zijn vastgelegd. Je kunt echter niet ontkennen dat VHDL een veel meer een "pure" taal is waar de historie niet zo in te herkennen is. Verilog had al een heel lange historie in allerlei tools voordat het een standaard werd. Daarom is niet altijd alles even logisch opgezet. En het mist ook een aantal handige constructies. Of dat beter of slechter is mag iedereen zelf bepalen.
- Ik garandeer je dat een implementatie cycle niet of nauwelijks bepaald wordt door de lengte van je code. Dat VHDL dus meer regels code geeft, speelt geen rol. Het gaat erom of het duidelijk leesbaar is.

Nog iets om over na te denken: Vaak is er geen "waarheid". Jouw waarheid is niet de waarheid, de mijne ook niet. Voor andere lezers ook iets om even te onthouden bij het lezen van de posts.

hallo, ik heb inmiddels mijn DE-2 bord in gebruik, en nu ik met de quartus software aan t spelen was, ben ik mijn tabbladen kwijt geraakt (als je meerdere vensters opent). Weet iemand hoe ik deze terug kan halen?

Gr. Rik

Ik heb een probleem, of ja het is nog niet echt een probleem. Ik wou nu door middel van de expansion pinnen een 7 segment aansturen. (ik wou dit gemultiplexed doen), ik weet alleen niet zeker of dit mogelijk is?

Maar het grootste probleem is dat ik niet weet hoeveel stroom die expansion pinnen maximaal kunnen uitsturen.

Het is een Xilinx bordje. (ML403). Deze heb ik te leen gekregen, alleen ben ik niet van plan om deze op te blazen. Weet iemand wat de gangbare stroom is voor deze uitbreindingspinnen. In de documentatie kan ik het ook niet vinden.

Als die expansionpinnen rechtstreekts aan de fpga hangen (zal wel, anders kost het je snelheid) net zo veel als de fpga aan kan en dat staat hier: http://www.xilinx.com/support/documentation/data_sheets/ds302.pdf

Op blz 8, maar onderaan blz 1 staat ook nog iets:
"Current applied to an I/O pin, powered or unpowered ±100 mA
Total current applied to all I/O pins, powered or unpowered ±200 mA"

Als je dus zowel de anodes als de kathodes allemaal direct uit de fpga voedt, loopt er netto 0 A en kan het dus :P.

Nu serieus, als je de 'common' kant van de leds van stroom voorziet door een transistor, zou het wel heel moeten blijven.

Op 30 november 2007 22:03:02 schreef flipflop:
Dat VHDL dus meer regels code geeft, speelt geen rol. Het gaat erom of het duidelijk leesbaar is.

FYI, voor grote projecten, is "1 regel per uur" ongeveer wat je kunt halen. Ja, ook ik schrijf zo nu en dan in 8 uur 500 regels. Maar dat is "een klein project".

Op 6 december 2007 10:55:05 schreef rew:
[...]
FYI, voor grote projecten, is "1 regel per uur" ongeveer wat je kunt halen. Ja, ook ik schrijf zo nu en dan in 8 uur 500 regels. Maar dat is "een klein project".

Maar dat zal dan wel gaan om nuttige regels code. De overhead die de taal genereert hoef je niet mee te tellen volgens mij...

Op 5 december 2007 17:11:10 schreef Rikkepic:
tabbladen kwijt geraakt
Gr. Rik

Goed zoeken... ;-)

Je kunt ze terug halen door: tools->options->general
en dan aanvinken: Display tabs for child windows.

Klik op OK en je hebt je tabs weer terug!

"Current applied to an I/O pin, powered or unpowered ±100 mA
Total current applied to all I/O pins, powered or unpowered ±200 mA"

Nu serieus, als je de 'common' kant van de leds van stroom voorziet door een transistor, zou het wel heel moeten blijven.

In dit geval, wanneer de stroom een beperkende factor kan zijn, lijkt het me logischer om te gaan voor een FET.

Ik bedoelde dat je de common anode stuurt met een pnp transistor. (of npn voor common cathode)

De stromen zijn zo klein, dat kan elke fluttransistor (flut= for light usage transistor :P) nog wel.

Er kan één voordeel zijn als je common anode displays gebruikt, gevoedt door 5V, terwijl je fpga IO 3.3V is. Een gewone tor staat dan altijd aan, terwijl een juistgekozen P-FET dan precies dichtstaat.

Op 6 december 2007 10:55:05 schreef rew:
FYI, voor grote projecten, is "1 regel per uur" ongeveer wat je kunt halen. Ja, ook ik schrijf zo nu en dan in 8 uur 500 regels. Maar dat is "een klein project".

Dat is echt niet zo. Het hangt namelijk helemaal af over welke taal je het hebt. Je hebt gelijk dat, als je het goed bij houdt, je zo'n regel op kunt stellen. Das dan weer handig voor volgende projecten. Echter, de tijd gaat hoofdzakelijk zitten in het nadenken. Wat doe je anders in de rest van dat uur? 1 regel kost 10 seconden, dus 59 minuten en 50 seconden nadenken. Stel nu dat ik in VHDL werk, dan kost het me 10 seconden extra (stel) om hetzelfde te typen. Dat kost me heus geen uur extra nadenken. Dus of het nu 10 of 20 seconden typen is, maakt niets uit. Valt weg tov het nadenken (of noem het ontwerpen).
Anders gezegd, je kunt twee keer zoveel VHDL regels code maken dan Verilog per uur.