DanielBakker
Quidquid latine dictum sit, altum viditur
ik ben sinds kort de gelukkige eigenaar van een DE1, en ik ben nu begonnen met de meegeleverde cursus, maar er is 1 ding waar ik niet uit kom. de vraag is: selecteer met 2 schuifschakelaars het teken op het 7-segment display. dit doe ik door met een aantal multiplexers een constante waarde in een register te selecteren en naar het display te sturen. alleen, als ik het compileer negeert quartus die registers, en stuurt de ingangen van de schakelaars als input naar de multiplexers!
ik mag alleen het commando assign gebruiken, vandaar dat het er op het eerste gezicht een beetje vreemd uitziet.
de code:
module part4 (SW, HEX0);
input [1:0]SW;
output [6:0]HEX0;
reg [6:0]d;
reg [6:0]E;
reg [6:0]one;
reg [6:0]clear;
wire [6:0]res;
wire [6:0]res1;
wire sel;
assign d = 7'b1000010;
assign E = 7'b1100000;
assign one = 7'b1001111;
assign clear = 7'b1111111;
assign sel = SW[0] & SW[1];
assign res[0] = (~SW[0] & d[0]) | (SW[0] & E[0]);
assign res[1] = (~SW[0] & d[1]) | (SW[0] & E[1]);
assign res[2] = (~SW[0] & d[2]) | (SW[0] & E[2]);
assign res[3] = (~SW[0] & d[3]) | (SW[0] & E[3]);
assign res[4] = (~SW[0] & d[4]) | (SW[0] & E[4]);
assign res[5] = (~SW[0] & d[5]) | (SW[0] & E[5]);
assign res[6] = (~SW[0] & d[6]) | (SW[0] & E[6]);
assign res1[0] = (~SW[1] & res[0]) | (SW[1] & one[0]);
assign res1[1] = (~SW[1] & res[1]) | (SW[1] & one[1]);
assign res1[2] = (~SW[1] & res[2]) | (SW[1] & one[2]);
assign res1[3] = (~SW[1] & res[3]) | (SW[1] & one[3]);
assign res1[4] = (~SW[1] & res[4]) | (SW[1] & one[4]);
assign res1[5] = (~SW[1] & res[5]) | (SW[1] & one[5]);
assign res1[6] = (~SW[1] & res[6]) | (SW[1] & one[6]);
assign HEX0[0] = (~sel & res1[0]) | (sel & clear[0]);
assign HEX0[1] = (~sel & res1[1]) | (sel & clear[1]);
assign HEX0[2] = (~sel & res1[2]) | (sel & clear[2]);
assign HEX0[3] = (~sel & res1[3]) | (sel & clear[3]);
assign HEX0[4] = (~sel & res1[4]) | (sel & clear[4]);
assign HEX0[5] = (~sel & res1[5]) | (sel & clear[5]);
assign HEX0[6] = (~sel & res1[6]) | (sel & clear[6]);
endmodule
wat quartus ervan maakt:
Jochem
If you want to succeed, double your failure rate.
Kun je de opdracht eens precies geven? En wat is een schuifschakelaar?
Kun je ook eens in poorten uittekenen hoe JIJ in gedachte had dat het eruit kwam te zien? Ik ben geen verilog-kenner, maar ik zie zo niet iets anders dan dat ik uit die code zou verwachten.
DanielBakker
Quidquid latine dictum sit, altum viditur
een schuifschakelaar is, zoals de naam al zegt, zo'n schakelaar die je omhoog en omlaag schuift.
hoe het moet worden is niet heel ingewikkeld, SW 0 en 1 zijn de ingangen van een 7 bits wijde 3 to 1 multiplexer.
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 zie geen probleem (afgezien van het feit dat je een draak van een verilog code hebt )
je maakt een basisfout.
reg betekent niet 'register' in de zin van 'een flipflop'.
reg betekent 'een variabele'
als een reg in ee niet geclockt process gebruikt wordt dan wordt dat puur combinatorische logica !
module part4 ( input [1:0] SW, output [6:0] HEX0);
`define d 7'b1000010
`define E 7'b1100000
`define one 7'b1001111
`define clear 7'b1111111
case (SW)
2'b00 : HEX0 = `d;
2'b01 : HEX0 = `E;
2'b10 : HEX0 = `one;
2'b11 : HEX0 = `clear;
endcase
endmodule
i rest case ...
Jochem
If you want to succeed, double your failure rate.
Op 30 januari 2009 14:48:30 schreef danielbakker:
ik mag alleen het commando assign gebruiken
Wel aan de opdracht houden he 
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
Jochem
If you want to succeed, double your failure rate.
Ah, ik kan me wel wat indenken bij stap-voor-stap. En of je dan bij een weinig gebruikte assign begint of niet maakt dan niet zoveel uit.
DanielBakker
Quidquid latine dictum sit, altum viditur
de doel van het alleen assign gebruiken, is dat je eerst leert in logica te denken. als je direct met case e.d. gaat werken, heb je als beginneling geen idee wat quartus er precies van maakt. als je precies moet vertellen welke poortjes waar moeten komen, moet je veel meer nadenken.
maar ik ga dat define 's proberen.
DanielBakker
Quidquid latine dictum sit, altum viditur
helaas pindakaas, als ik een define gebruik mag ik bijv. niet d[3] zeggen, dat lust 'ie niet. andere suggesties?
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 30 januari 2009 21:28:54 schreef danielbakker:
de doel van het alleen assign gebruiken, is dat je eerst leert in logica te denken. als je direct met case e.d. gaat werken, heb je als beginneling geen idee wat quartus er precies van maakt. als je precies moet vertellen welke poortjes waar moeten komen, moet je veel meer nadenken.
maar ik ga dat define 's proberen.
niet juist.
een case is niets anders dan een multiplexer in dit geval.
het doel van HDL is net de poortjes achterlaten en je concentreren op wat het moet doen in plaats van hoe je het in poortjes aan elkaar lijmt.
met een define lukt dat niet als je de rest niet aanpast.
module part4 ( input [1:0] SW, output [6:0] HEX0);
`define d 7'b1000010
`define E 7'b1100000
`define one 7'b1001111
`define clear 7'b1111111
wire [7:0] res,res1;
assign res = SW[0] ? `d : `E;
assign res1 = SW[1] ? `one , `res;
assign sel = SW[0] & SW[1];
assign HEX0 = sel ? `clear , `res1;
endmodule
voila. allemaal met assigns.
der is geen enkele reden om al dat spul te gaan ontplooien en met al die losse bits gaan werken. stel u voor dat dat ding een 64 bit databus is ... we gaan niet met 5000 lijnen iets gaan schrijven wat met 4 ook kan he ... (even op mijn tong bijten... )
ook dat aanmaken van al die intermediare signalen is ook verwarrend. het kost mij 5 minutne om uit te vlooien hoe dat selectie mechanism nu eigenlijk juist werkt. met dat case statement zie je dat in 1 oogopslag. ik mijdt assigns als de pest.
het syntheseresultaat is toch hetzelfde. gans die worst wordt platgeklopt tot een tros booleaanse vergelijkingen en dan weggeminimaliseerd.
dat schem wat quartus daar produceert is perfect juist. alles is al compleet weggeminimaliseed.
Het ziet er naar uit dat je rtl na synthesis daar opgevraagd hebt.
vraag eens gewoon de RTL op. dan zal je daar wel multiplexers getekend zien staan.
flipflop
"We cannot solve our problems with the same thinking we used when we created them" - Albert Einstein
Niks mis met een assign hoor. "Worden bijna nooit gebruikt"???? Kom op zeg. Ik heb aardig wat Verilog gezien de afgelopen 5 jaar. Laten we zeggen dat op elk A4tje gemiddeld zo'n 5 assigns stonden. Ik vond het best handig op z'n tijd.
Maar toegegeven, in het geval TS is het niet handig. Niet leesbaar en (inderdaad) je ziet niet direkt wat het doet.
DanielBakker
Quidquid latine dictum sit, altum viditur
free toch, zo leer ik toch niks
maar wel heel erg bedankt. ik heb even goed bekeken wat je geschreven hebt, en het zou inderdaad moeten werken (wel even wat hoge kommaatjes weggehaald die er niet hoorden) maar als ik het aan quartus voer zegt hij dat hij aan het eind van iedere assign regel i.p.v. een ; een : of een ? of een binaire operator verwacht. wat doen we ermee?
Jochem
If you want to succeed, double your failure rate.
Op 30 januari 2009 22:11:44 schreef free_electron:
[...]
(even op mijn tong bijten... )

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 30 januari 2009 22:54:57 schreef danielbakker:
free toch, zo leer ik toch niksmaar wel heel erg bedankt. ik heb even goed bekeken wat je geschreven hebt, en het zou inderdaad moeten werken (wel even wat hoge kommaatjes weggehaald die er niet hoorden) maar als ik het aan quartus voer zegt hij dat hij aan het eind van iedere assign regel i.p.v. een ; een : of een ? of een binaire operator verwacht. wat doen we ermee?
Dat zijn die hoge commatjes die je net moet laten staan ... zijn trouwens geen afkappingstekens !!!!
geen ' maar ` <- goed opletten dus !
Op een US klavier staat dat teken under de ~ toets ( linksboven dus vlak onder de ESc toets. geen idee waar dat staat op een (cr)a(p)zerty keyboard. ( ALT 96 geeft je ook dat teken.)
@flipflop. Je plaatst dat ergens een heel enkele keer. Ik vermijd assigns als de pest. Je moet altijd op 25 plaatsen in de code duiken om uit te vlooien wat een of ander ding nu doet en of het nu om ene ingang of een interne wire gaat.
Als je een define gebruikt daarvoor werkt dat even goed en je ziet in 1 oogopslag dat dit iets is wat ergens als 'define' staat. ( je moet het immers aanroepen via dat ` teken. als je de regel leest zie je aan dat ` teken : dit is een symbool wat ergens gedefinieerd is en geen in of uitgang)
wire test
assign test = a | b
...
y = x & test
z = ~x & test
is vervangbaar door
`define test (a|b)
y = x & `test
z = ~x & `test
Het heeft geen enkel nut om daar zelf expliciet een wire aan te maken , daar een logische vergelijking aan te assignen. Je verkort daar niks mee. Je spaart ook geen enkel gate mee uit. En voor je compile time doet het ook al niks. De synthesizer gaat in de laatste stap gans die bollewinkel platkloppen. De sint (nee niet sinterklaas) is snugger genoeg om uit te vlooien : he, deze term wordt door meerdere blokken gebruikt . Ik kan die 1 keer maken. Trouwens zelfs dat is niet gegarandeerd. Als er geen routing channels meer zijn smijten ze die blok daar toch 2 keer in. in een FPGA zijn er niet echt losse poorten. het zit allemaal als LUT's verwerkt. In plaats van dat heen en weer te routen smijt je dat als 2 bits bij in de locale LUT en klaar.
Laat dat 'prutswerk' over aan de synthesizer. Je gebruikt een HDL taal voor iets.
Das even zot als in een HDL een netlist uit te schrijven gemaakt met losse and ,or en not poorten. Ja het kan, maar dan teken je dat beter als schema. Dat leest nog vlotter dan een hoop instances die and1 and2 and3 noemen met een tros symbolische namen die draad1 draad2 draad3 noemen. Daar geraakt geen kat wijs uit. ( je kan dan beter je kat de code laten maken. als je dat beest een tros breiwol geeft heb je binnen 3 seconden dergelijke netlist/breiwol kluwen)
Of als je iets hebt waar je dingen kan overriden met andere assigns. Maar dan herstructureer je de code beter en los je dat op met een always_comb blok en gooit daar if-then-else of een case tegenaan.
Mijn ervaring is dat assigns gebruikt worden als duct-tape oplossing, bah.
De enige keer dat je zulke knettergekke dingen doet is als je daar een 'no-minimise' clause aan vast knoopt omdat je ergens met je timing aan het roefelen bent.
Ik heb een speciale multiplexer die als no-minimise getekend is en dan met de hand geplaced is in de fpga . Dat ding is zo gemaakt dat de looptijd in alle takken identiek is. Tussen de takken zitten dan telkens 2 LCELLs met elk 1 buffer. Op manier heb ik een 64 tap delay line warbij elke stap exact 410 picoseconden is. Der zitten drie van die blokken in mijn systeem, vlak voor de I/O pinnen van de FPGA. Wordt gebruikt om de skew veroorzaakt door het bord en de connector weg te werken .... FPGA ziet op een moederbord waar verschillende dochterkaarten in kunnen. die zijn niet allen gelijk qua signaallengte. om niet telkens aan die layout te moeten sleutelen is de skew dynamisch programmeerbaar.
Dat je dan gaat zotte dingen doen, ja.
Maar anders ? Tis 2009 en de computer is er om mij te dienen. Niet omgekeerd
. We zitten niet meer in het stenen tijdperk he. 10 jaar terug moest je dat met pen en p[apier doen want er was niks anders. Nu zijn de tools er : gebruik ze. Laat die machiene de boel platkloppen en ontplooien. Daar dient dat ding voor. Minder werk voor mij : meer werk voor de synthesizer, zo wordt die 4e core ook nog benut, anders staat die toch maar te slapen.
DanielBakker
Quidquid latine dictum sit, altum viditur
bedankt voor alle hulp!
als ik exact aan quartus voer wat jij geschreven hebt, geeft hij naast de eerder genoemde errors ook nog de warning dat de tekstmacro's res en res1 niet gedefinieerd zijn. klopt ook, want er staat dat je ze als wire gebruikt, en dan gebruik je ze als tekst macro. wat moet het dan worden?
ik heb trouwens de goeie ` gebruikt hoor, gewoon een US qwerty hier.
flipflop
"We cannot solve our problems with the same thinking we used when we created them" - Albert Einstein
Op 31 januari 2009 01:13:45 schreef free_electron:
@flipflop. Je plaatst dat ergens een heel enkele keer. Ik vermijd assigns als de pest. Je moet altijd op 25 plaatsen
JIJ plaatst ze een enkele keer, anderen maken er gewoon zonder problemen gebruik van hoor. Zoals ik al zei hierboven.
Voorbeeldje, tristate bus:
wire output
assign output = out_enable ? out_val : 'hzz;
of zo:
wire output = out_enable ? out_val : 'hzz;
of een read-or tree:
assign bus0 = cpudata & {bus0_en,8}; //8x bus_en, hoe was die syntax ook weer?!
assign bus1 = dmadata & {bus1_en,8};
assign bus2 = testdata & {bus2_en,8};
assign readbus = bus0 | bus1 | bus3;
Is toch prima te lezen zo? Of wil je dat per-se in een always block stoppen? Wordt niet echt overzichtelijker lijkt me.
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
juist. IK hou er niet van. het is ook nergens voor nodig. ik schrijf codeop een andere manier.
ergens in het begon van mijn code zet ik output = 1'hzz;
en dan later , waar nodig, override ik dat gewoon.
output = 1'bzz;
blablalaba
if (out_enable) output = outval;
die or-tree maak ik anders :
case {bus_en0,bus_en1,bus_en2}
3'b100 : readbus = cpudata;
3'b010 : readbus = dmadata;
3'b001 : readbus = testadat;
default : readbus = &hDEADBEEF;
endcase
of ingeval je dit wilt combineren met de tristate bus :
case {bus_en0,bus_en1,bus_en2}
3'b100 : readbus = cpudata;
3'b010 : readbus = dmadata;
3'b001 : readbus = testadat;
default : readbus = 4'hzz;
endcase
FPGA's hebben voor busstructuren veelal speciale multiplexers zitten. Die dingen werken met one-hot encoding. Als je het op bovenstaande manier schrijft dan pikt de synthesizer direct die one-hot op en ben je zeker dat het daar op landt ( als je fpga dat heeft ) anders kan het gebeuren dat de synthesizer het niet door heeft en dan landt het in normale LUTs.
hetzelfde met state machienes ook. Probeer die ook altijd als one-hot te schrijven. Quartus heeft een synthese control vlag die hem automatisch laat herstructureren naar een one-hot systeem. Je moet dan wel je machine splitsen.. das weer teveel werk en ik vind het moeilijker leesbaar ( je moet weer op 2 plaatsen gaan zien wat het ding doet. 1 keer in het state assignment blok en een keeer in het blok waar de rest staat. ) als je direct one-hot encoding toepast is dat allemaal niet nodig.
ik heb in mijn code altijd voorop een always_comb blok zitten waar al dat spul instaat. ik hou er niet van om statements hier en daar rond te strooien. Het is altijd een soep om in 5 paginas iets terug te vinden.(of meer .. ik heb 1 blok code wat bijna 9000 lijnen lang is ( is 1 process ... klok , data / address wr/rd in en een tros dingen uit.) als je dan overal stuff begint rond te strooien ...). Ik bookmark dat always_comb blok. als ik iets moet terugvindnen spring ik gewoon naar daar en keer dan terug.
[Bericht gewijzigd door Henry S. op (12%)]
DanielBakker
Quidquid latine dictum sit, altum viditur
bedankt voor alle hulp!
als ik exact aan quartus voer wat jij geschreven hebt, geeft hij naast de eerder genoemde errors ook nog de warning dat de tekstmacro's res en res1 niet gedefinieerd zijn. klopt ook, want er staat dat je ze als wire gebruikt, en dan gebruik je ze als tekst macro. wat moet het dan worden?
flipflop
"We cannot solve our problems with the same thinking we used when we created them" - Albert Einstein
In free zijn voorbeeld zijn res1/2 toch wires? Dan moet je ze ook zo declareren, anders weet de synth niet wat het is.
@free: ja duidelijk dat het ook anders kan. Maar wat ik nou juist wilde met die read-or is een rits ANDs en 1 OR erachter maken. Dat krijg je met mijn code wel, maar met de jouwe niet. Functioneel is het wel een goede oplossing natuurlijk. Maar verder is er niks mis met assigns en ze worden ook veelvuldig toegepast in Verilog designs.
Het is al eerder gezegd: pas op met je persoonlijke mening als "waarheid" neer te zetten op een forum waar veel beginners zitten.
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 1 februari 2009 09:23:53 schreef flipflop:
In free zijn voorbeeld zijn res1/2 toch wires? Dan moet je ze ook zo declareren, anders weet de synth niet wat het is.@free: ja duidelijk dat het ook anders kan. Maar wat ik nou juist wilde met die read-or is een rits ANDs en 1 OR erachter maken. Dat krijg je met mijn code wel, maar met de jouwe niet.
volledig accoord : maar kijk eens wat de synthesizer daar uiteindelijk van maakt ? dat wordt allemaal getransformerd naar de ,voor de FPGA, beste oplossing. Als je echt op silicium level werkt ga ik volledig accoord. daar heb je flexibiliteit om dat effectief in gate level te laten uitmappen zoals jij dat uitschrijft. in FPGA wordt dat allemaal geherstructureerd naar de beste oplossing voor de cell. In FPGA en CPLD bestaan losse poorten helemaal niet. het zijn allemaal lookup tabellen met x ingangen en y uitgangen. poorten worden gemaakt door stomweg een waarheidstabel in te vullen. ( een LUT is niks anders dan een ROM waarbij de ingangssignalen als addresslijn gebruikt worden en de uitgang gewoon de data_out is. door 1tjes en nulletjes te plaatsen krijg je daar 'ge-emuleerde' logica uit.)
Is gene kwestie van persoonlijke waarheid : ik ben het zo aangeleerd. Ga de cursus van Altera volgen. Ze tonen verschillende manieren en geven dan op wat er best werkt voor hun synthesizers. Synopsys heeft ook zo een document voor hun FPGA compiler. Xilinx ook (XST documentatie)
Ook andere bronnnen raden af van bepaalde constructies nog te gebruiken. Coding efficiency en re-use is belangrijk vandaag de dag. Een tros assign statements ondersteboven gaan gooien als er een modificatie komt is veel lastiger en tijdrovender dan 1 lijn in te voegen in een case statement.
Nog eens: als je op silicium niveau werkt en je probeert 2 millimeter uit te sparen ga ik volledig akkoord : die and-or tree inderdaad de beste oplssing. Op FPGA hanteer je best datgene waar de tools op 'trippen' en de special functions kunnen voor mappen. ene tros assigns is voor de synthesizer ondoorzichtig. een case statement 'tript' de synthesizer direct : multiplexer !.
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
@Ts hier zijn de 'gefixte' voorbeelden:
noot : je moet wel quartus in Verilog 2005 mode zetten he !
module part4 ( input [1:0] SW, output [6:0] HEX0);
`define d 7'b1000010
`define E 7'b1100000
`define one 7'b1001111
`define clear 7'b1111111
always_comb case (SW)
2'b00 : HEX0 = `d;
2'b01 : HEX0 = `E;
2'b10 : HEX0 = `one;
2'b11 : HEX0 = `clear;
endcase
endmodule
andere implementatie
module part4 ( input [1:0] SW, output [6:0] HEX0);
`define d 7'b1000010
`define E 7'b1100000
`define one 7'b1001111
`define clear 7'b1111111
wire [7:0] res, res1;
assign res = (SW[0]) ? `d : `E;
assign res1 = (SW[1]) ? `one : res;
assign sel = SW[0] & SW[1];
assign HEX0 = (sel) ? `clear : res1;
endmodule
DanielBakker
Quidquid latine dictum sit, altum viditur
bedankt! om het toch nog even leerzaam te maken, wat is nu de functie van het tussen haakjes zetten?
Jochem
If you want to succeed, double your failure rate.
Mijn niet-verilog-kenner-gok: Hier niet nodig, maar een goede gewenning om je statement(s) voor het vraagteken altijd tussen () te zetten, zodat hij altijd het juiste evalueert.
DanielBakker
Quidquid latine dictum sit, altum viditur
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 2 februari 2009 07:35:16 schreef Jochem:
Mijn niet-verilog-kenner-gok: Hier niet nodig, maar een goede gewenning om je statement(s) voor het vraagteken altijd tussen () te zetten, zodat hij altijd het juiste evalueert.
juist.