flipflop
"We cannot solve our problems with the same thinking we used when we created them" - Albert Einstein
Mag niet gebeuren.
Ik had geloof ik nog een opmerking gemaakt over het gebruik van latches. In FPGA's in het nogal not-done om ze te gebruiken omdat het de kans op glitches sterk vergroot. Immers, de gate staat de halve clock cycle open en alles wat op de ingang rammelt, rammelt gelijk door naar de uitgang.
However, daar waar power (stroomverbruik) een rol gaat spelen wordt nog wel met latches gewerkt. Latches zijn kleiner en dus zuiniger.
Tegenwoordig wordt er vooral synchroon met FFs gewerkt. Alle tools zijn daarop ingericht. Alleen bij "extreem designs" bij Intel & Co (en bij bepaalde HDD fabrikanten) worden nog wel asynchrone designs gemaakt.
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. de heel snelle designs worden zelfs asynchroon gedaan en drijven op de delay van de gates. in fpga is dat haast ondoenbaar omdat je moet weten hoe de boel gerouted wordt ( je moet ook de routing delay kennen en dergelijke ) het kan , maar tis zeer moeilijk.
fpga is synchroon desgin. een latch is goed om hold-times te verlengen. anders : niet gebruiken. zoals flipflop zegt : rotzooi in is rotzooi out bij die dingen. ( alhoewel flipflops ook metastabiel kunnen zijn , zeker als je setup time violations hebt ...
Kan mij iemand vertellen wat het onderstaande in VHDL is?
always @(posedge vga_clk or negedge reset_n)
begin
if (reset_n == 0)
sync_n <= 0;
else if (1)
sync_n <= vga_start ? (vsync_temp ~^ hsync_temp) : sync_n_init;
end
Zelf dacht is iets van:
[code_]
process (vga_clk, reset_n)
begin
if reset_n = '0' then
sync_n <= std_logic'('0');
elsif vga_clk'event and vga_clk = '1' then
if (std_logic_vector'("00000000000000000000000000000001")) /= std_logic_vector'("00000000000000000000000000000000") then
sync_n <= Vector_To_Std_Logic(A_WE_StdLogicVector((std_logic'(vga_start) = '1'), (vsync_temp xnor hsync_temp), (std_logic_vector'("0000000000000000000000000000000") & (A_TOSTDLOGICVECTOR(sync_n_init)))));
end if;
end if;
Ik weet alleen niet zeker of de (vsync_temp xnor hsync_temp) wel klopt.
[Bericht gewijzigd door Jeroen Boere op (0%)]
Maak als je blieft als eerste die code eens kleiner het
past niet meer op mijn scherm.
Je zegt "else if (1)" moet dat niet zijn "else if (reset_n = 1)"?
Zoja dan is de code: (en anders ook...)
process(vga_clk,reset_n)
begin
if rising_edge(vga_clk) or falling_edge(reset_n) then
if vga_start = '1' then
sync_n <= vsync_temp xnor hsync_temp;
else
sync_n <= sync_n_init;
endif;
if reset_n = '0' then --concurrent if, deze heeft voorang op wat hierboven staat
sync_n <= '0';
endif;
endif;
end process;
maar pin me er niet op vast VHDL is niet mijn sterkste kant...
En alle signalen moeten std_logic zijn
flipflop
"We cannot solve our problems with the same thinking we used when we created them" - Albert Einstein
Hmm, da's niet een heel gebruikelijke manier om een FF te modelleren. Zoals neptunus het doet is het goed. Mooi clean.
Ik vind het gedoe met die std_logic_vector(00000) het nogal oneverzichtelijk maken. Ik heb het ooit ook zo gedaan, maar het hangt ervan af welke libraries je gebruikt. Ik heb het zo niet paraat, maar als je een andere lib gebruikt hoef je niet zo moeilijk te doen. Je kunt dan gelijk schijven:
if (X="0000000001") then
Mooier is nog om die vector in een constante te zetten zodat je code wat compacter wordt.
rew
four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
Ik zie
if (1) ...
in iets ingewikkelds vertaald worden door Neptunus. Volgens mij kan dat gewoon weg. Zowel in VHDL als in Verilog. Of is er iets wat ik over het hoofd zie?
Verder snap ik helemaal niet waarom er ineens 32bit binaire constanten moeten komen als het enkelbits variabelen zijn. Nu kan ik dat niet echt weten, want ook in verilog ontbreken de declaraties.
Verder vraag ik me af of het handig is om
if rising_edge(vga_clk) or falling_edge(reset_n) then
te schrijven. Je krijgt dan, denk ik, een constructie die beide signalen als clock gaat gebruiken, terwijl "vga_clk" bedoeld is als echte clock, terwijl "reset_n" gewoon een synchrone reset kan zijn. En volgens mij hebben de LEs van Altera gewoon een synchrone reset, dus dat mapped dan ook makkelijk op de hardware.
Even voor de duidelijkheid: Je kunt "ik vraag me af of... " lezen als "ik zou zeggen dat je niet... " maar dat bedoel ik niet. Ik stel gewoon de vraag....
Zelf heb ik het volgende probleem:
always @ (posedge alivectr[23])
begin
if (nRESET == 0)
begin
state <= 0;
addr <= 0;
end
//ledsreg[15:8] <= 8'hAA;
CLE <= 0;
CEn <= 0;
WEn <= 1;
REn <= 1;
//io <= 8'bZ;
ALE <= 0;
WPn <= 1;
oe <= 0;
ledsreg[15:11] <= state;
case (state)
0: ...
1: ...
....
het stuk /voor/ de case zijn de defaults. Dat zijn de waarden die de pennetjes "meestal" moeten hebben, de uitzonderingen zijn "soms" in enkele states, dus dan staan ze daar.
Dit lijkt redelijk te werken in de praktijk. Maar volgens de simulator blijft m'n state gewoon nul.
Duh! Teddybeer effect. Probeer je je probleem uit te leggen, kom je er zelf achter wat er mis is. Ik moet natuurlijk in de simulator WEL even "@posedge (alivectr[23])" veranderne in "@posedge (myclck)" Dat is ook wat ie uiteindelijk moet worden, maar om hem met de ledjes te kunnen debuggen had ik hem even 2^24 langzamer gezet....
Goed die is opgelost. State blijft zeker 2^23 gelijk aan nul. Dat klopt.
Nu deze:
always @ (posedge myclk)
begin
if (nRESET == 0)
begin
alivectr <= 0;
end
alivectr <= alivectr + 1;
end
Duh! Teddybeer twee! In de simulator gaat "alivectr" meteen tellen, ook al is de reset actief. De concurrent statements heeft de laatste "alivectr ophoog" voorrang (en dus altijd!) boven de "reset conditie". Ik moet ze dus omdraaien of er een "else" tussen zetten. Problem solved!
Grmlb.... Heb ik een dag op zitten staren, kon het maar niet vinden.....
Op 23 november 2007 00:15:33 schreef rew:
Ik zieif (1) ...Verder vraag ik me af of het handig is om
if rising_edge(vga_clk) or falling_edge(reset_n) thente schrijven. Je krijgt dan, denk ik, een constructie die beide signalen als clock gaat gebruiken, terwijl "vga_clk" bedoeld is als echte clock, terwijl "reset_n" gewoon een synchrone reset kan zijn.
DAt doet i in Verilog ook hoor, hij kijkt naar beide inputs en als er iets gebeurd gaat i kijken of hij van hoog naar laag ging of andersom. Tis idd een async reset.
flipflop
"We cannot solve our problems with the same thinking we used when we created them" - Albert Einstein
Maar da's wel een benadering vanuit de simulator gezien. Voor synthes moet het duidelijk zijn wat de clk is en wat de reset. Nou is dat in jou (Surge) ook wel duidelijk in dit geval. Toch vindt ik de constructie van TS beter. Dit dus:
process (vga_clk, reset_n)
begin
if reset_n = '0' then
sync_n <= '0';
elsif vga_clk'event and vga_clk = '1' then
sync_n <= X;
end if;
end process
Dit wordt door ALLE synthese tools onvoorwaardelijk als FF gezien. Je hardware wordt dan ALTIJD exact hetzelfde als in je simulatie.
Jeroen Boere
IF you can't convince them, then confuse them!
ik wil met behulp van een Xilinx XC9572 CPLD een parallel in, serial out shiftregister maken.
eerst had ik dit middels schematic entry willen doen, echter bestaat er voor een schuifregister zoals ik dit wil maken geen symbool.
uiteraard bestaat de mogelijkheid om deze dan maar met Verilog (oid) te maken.
maar mijn vraag is anders van strekking:
waarom bestaat dit symbool niet.
het is niet een wereldvreemd/exotisch component.
ser in par uit bestaat wel.... dus zou ik ook par in ser uit verwachten.
wie o wie heeft hier een antwoord op.
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
in quartus zitten alle 74xx erin .. in xilinx niet. dus pech..
in verilog "
module shift (input [7:0] d_in,
input clk , load,
ouput sdo)
reg [7:0] shifter;
always @(posedge clk)
if(load)
shifter <=d_in;
else
shifter <= {1'b0,shifter [7:1]};
assign sdo = shifter[0];
endmodule
voila. synchrone load.
ding schuift naar rechts uit.
als ie naar links moet schuiven :
module shift (input [7:0] d_in,
input clk , load,
ouput sdo)
reg [7:0] shifter;
always @(posedge clk)
if(load)
shifter <=d_in;
else
shifter <= {shifter [6:0],1'b0};
assign sdo = shifter[7];
endmodule
Op 25 november 2007 04:53:40 schreef free_electron:
in quartus zitten alle 74xx erin .. in xilinx niet. dus pech..
Dit is een van de redenen waarom het met Altera een stuk eenvoudiger is om te starten. Voor een professionele eindgebruiker maakt dit minder verschil maar voor de hobby is dit heel duidelijk dat Altera met Quartus het je een heel stuk gemakkelijker maakt.
En zoals reeds eerder gemeld moet de support voor starters ook gegeven worden door meer ervaren gebruikers (vooral voor het opstarten van de tools en hun gebruik). Dan ben je weer afhangkelijk van Xilinx of Altera gebruikers.
Dan heb ik nog eeen vraag van het formaat schuif register:
module shift_reg_3(
//inputs
input wire clk,
input wire reset,
input wire input_data,
//outputs
output reg [63:0]led_select,
output reg [7:0]floor_select);
reg [2:0]floor_counter;
always@(posedge clk)
begin
if(led_select[63])
begin
led_select <= 'b1;
floor_counter <=floor_counter+1;
end
else
begin
led_select <= led_select << 1;
end
if(input_data)
begin
case(floor_counter)
3'd0:
begin
floor_select <= 8'd1;
end
3'd1:
begin
floor_select <= 8'd2 ;
end
3'd2:
begin
floor_select <= 8'd4 ;
end
3'd3:
begin
floor_select <= 8'd8 ;
end
3'd4:
begin
floor_select <= 8'd16 ;
end
3'd5:
begin
floor_select <= 8'd32 ;
end
3'd6:
begin
floor_select <= 8'd64 ;
end
3'd7:
begin
floor_select <= 8'd128;
end
default:
begin
floor_select <= 8'd0;
end
endcase
end
else
floor_select <= 8'd0;
if(reset)
begin
floor_counter <= 'b0;
floor_select <= 'b0;
led_select <= 'b1;
end
end //end always
endmodule
Dit moet een led cubes (8*8*8) gaan ansturen waar led_select het ledje is dat aan moet gaan, en floor_select de betreffende hoogte is waar het aan moet gaan.
Wat de code moet doen is een 64 bits breede uitgang steeds bit voor bit hoog laten worden en als het 64ste bit hoog geworden is dan moet bit 0 weer hoog worden en floor_counter moet opgehoogd worden zodat de volgende vloer doorlopen kan worden.
Daarnaast hebben we data in, deze wordt ge-and met het signaal naar de vloer, als deze input_data hoog is dan wordt de vloer naar ground getrokken, en dan gaat 1 van de 64 ledjes branden. Andersom als input_data laag is komt de vloer niet in geleiding en gaat het ledje niet branden.
NU MIJN VRAAG:
De schakeling werkt geheel niet...
Zelfs als ik reset hoog zet wordt led_select niet hoog...
Ziet iemand wat ik verkeerd doe?
rew
four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
Probeer eens;
led_select <= {led_select [62:0],led_select[63]};
ipv die If contstructie.
De "reset conditie" wordt dan natuurlijk wel "0000....001".
Als het werkt, dan kan je er voor kiezen om te zeggen: - Ok dan doe ik het zo.. of - Hmm. maar waarom werkt het eerste dan niet?
@ REW
je bent de derde optie vergeten... waarom werkt dit ook niet? 
Helaas ik heb dit:
if(led_select[63])
begin
led_select <= 'b1;
floor_counter <=floor_counter+1;
end
else
begin
led_select <= led_select << 1;
end
vervangen door dit
led_select <= {led_select [62:0],led_select[63]};
floor_counter <=floor_counter + led_select[63];
En het resultaat is helaas het zelfde....
rew
four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
flipflop
"We cannot solve our problems with the same thinking we used when we created them" - Albert Einstein
Wat zegt je simulatie?
Mijn gevoel zegt me dat je dat stadium maar hebt overgeslagen terwijl het m.i. toch een heel essentieel deel van het ontwerpen is. Als ik iets implementeer, dan werkt het ook 9 van de 10 keer niet in een keer. Meestal door iets stoms wat ik vergeten ben (waardoor bv signalen op "undifined" blijven staan. Dat zie je in een oogopslag in je sim.
Ook deze code die je gemaakt hebt heb je in een uurtje (of minder) in een testbench hangen, hoeft niet heel complex te zijn in dit geval. Gaat je een hoop tijd en ergernis schelen.
[edit] oh, toch sim? Dan kun je toch makkelijk zoeken waar het fout zit?
rew
four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
De simulator is soms een beetje "anal" over hoe niet gedefinieerde signalen door kunnen rippelen naar je registers. Dus bijvoorbeeld zou het kunenn zijn dat je schema werkt, maakt niet uit nul of 1 van je ingangssignaal, dat als hij zomaar doorrekent met "kweenie" dat hij dan ergens uitkomt met dat het niet meer werkt.
Kan je even de tweede helft weghalen, en kijken wat het dan doet? En dan stukje bij beetje weer toevoegen?
Mijn eerste indruk was dat je een led_select <= ... in het if (data_in) stuk had staan, maar /ik/ zie hem niet. Simulator wel?
flipflop
"We cannot solve our problems with the same thinking we used when we created them" - Albert Einstein
De simulator doet PRECIES wat jij in hardware opschrijft. Het laat dus nooit signalen door-ripplen die niet relevant zijn. Sims zijn in feite domme uitvoerders, denken niet na maar doen precies wat je ze voorschotelt.
Over die code: ik zie zo niet wat er fout zit. Wat ik zou willen zien in de sim is het hoog worden van het 1e bit in led_select. In je testbench MOET je daarvoor de reset actief hebben gedurende de eerste klok puls. Je hebt een synchrone reset gemaakt namelijk. Loopt je klok wel netjes in je simulatie? Da's namelijk ook een bron van "niets werkt". Als ie op undefined staat, gaat alles op rood.
rew
four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
Als jij bijvoorbeeld XOR (A , NOT(A)) uitrekent, wordt dat altijd 1. De simulator rekent NOT ('X') uit en zegt dat het "X" wordt. Vervolgens is XOR ("X", "X") == "X".
Maar goed. Ook bij mij werkte het niet zoals ik had gehoopt, totdat ik het opschreef zodat de compiler me ook kon begrijpen....
Op 25 november 2007 12:32:19 schreef flipflop:
Over die code: ik zie zo niet wat er fout zit. Wat ik zou willen zien in de sim is het hoog worden van het 1e bit in led_select. In je testbench MOET je daarvoor de reset actief hebben gedurende de eerste klok puls. Je hebt een synchrone reset gemaakt namelijk. Loopt je klok wel netjes in je simulatie? Da's namelijk ook een bron van "niets werkt". Als ie op undefined staat, gaat alles op rood.
Jup clock werkt prima, en reset is hoog geduurende de eerste clock cycle (ook meerdere clock cycles maakten niets uit)
Echter ik heb alles weggehaald en alleen die reset statement laten staan.
Vandaar heb ik het overnieuw opgebouwd en steeds als ik iets toevoegde heb ik de boel gesimuleerd om te kijken of het nog liep.
De problemen kwamen toen ik het signaal input_data introduceerde als input en er verder niets mee deed... Na een kijkje genomen te hebben in de RTL view, was ik nog verbaasder omdat dit signaal nergens aan vast zat en toch invloed had op de uitgang...
Nu heb ik twee apparte if statments genomen met daarin wat er moet gebeuren als input_data 1 is en als hij 0 is...
En waarrempel hij doet het!
Blijkbaar kan Quartus niet goed overweg met inputs waar geen logica aan vast zit en met concurrent if statements met daarin een else....
Ik blijf het vreemd vinden waarom hij dat niet kan maar goed gelukkig doet hij het nu wel.
@REW en flipflop Bedankt voor al het medenken
rew
four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
Hoi Surge,
Ik denk eerder dat wij verilog nog niet genoeg snappen dan dat quartus het verkeerd doet. Ik hoop dat bijvoorbeeld Free ons nog wat kan leren als ie uit z'n bed komt... 
flipflop
"We cannot solve our problems with the same thinking we used when we created them" - Albert Einstein
Free weet ook niet alles. (Ik ook niet overigens)
Kun je dat stukje code waar het fout begint te gaan eens posten? (ter leering ende vermaeack) Ik kan me namelijk ook niet voorstellen dat de Quartus simulator zo ernstig de fout in zou gaan. Dan zou je nooit een stabiel design kunnen maken. Er moet een duidelijke reden zijn waarom het fout gaat.