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.

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

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.

@ flipflop,

wat is niet een gebruikelijke manier om een flipflop te realiseren?

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 zie


if (1) ...

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.

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.

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.

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.

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?

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? :p

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....

OK...

Waar werkt het niet. Simulator of "real life"?

simulator

Ik heb helaas de hardware nog niet om het te testen

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?

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?

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.

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

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... :-)

@ REW dat zou best wel eens kunnen... :)

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.