Scheef_schaap
't schaap is de preut af, meestal vooralleer het spel hespe is! (of in het AN: Meestal zal het eerst mislukken voor alleer het lukt..)
Hallo,
Ik ben bezig met een PC-scope te maken met een FPGA. De FPGA is een Cyclone 2.
Hoe het nu werkt:
De PC stuurt via visual basic 1000 punten door, die 1 periode van een signaal bevat. De FPGA laat deze constant door een snelle DAC door het device under test sturen.
Vervolgens meten 2 ADC's synchroon de spanning & stroom, en worden 2 x 1000 punten terug naar de PC gezonden.
De ADC's geven geen probleem. Enkel geeft de DAC volgend signaal:
Slechte DAC zou je denken, maar vervolgens heb ik een VHDL programma geschreven dat gewoon een counter geeft op de input's van de DAC en dit is het resultaat:
Wat ik zou denken dat problemen kan geven:
Ik gebruik een dedicated RAM geheugen in de FPGA. Heel mijn systeem werkt op de falling edge van de klok, en m'n RAM op de rising edge. Dit omdat ik in één klokperiode m'n adres van m'n RAM kan verhogen & dus de data al klaar zetten op de DAC.
Quartus zegt dat fmax = 99,8Mhz. Ik werk echter aan 100Mhz. Dit MOET zo blijven.
Hoe kan ik dit probleem oplossen?
Dit is m'n code:
CODE
[Bericht gewijzigd door Scheef_schaap op (89%)]
Dat probleem los je meestal op door signalen extra te registeren en zo de wolken logica kleiner te maken.
Scheef_schaap
't schaap is de preut af, meestal vooralleer het spel hespe is! (of in het AN: Meestal zal het eerst mislukken voor alleer het lukt..)
Signalen tussen de verschillende logicablokken?
Ik dacht eerder aan zélf een geheugen te maken dat geen dedicated geheugen gebruikt, dit is misschien sneller?
Alleen hoe doe ik zoiets? Het is iets met een array waarschijnlijk, iemand code?
stecj366
Sonar is meer dan Ping...
Mwa, ik vind dat er toch ook wat ripple zit op de output van de DAC bij die counter. Dus lijkt mij dat er een foutje zit in het aansturen van de DAC? Hoe stuur je die aan? Wat voor een dac is dat? SPI?
Geef eens enkel de code van de DAC writer?
En is de quartus fitter op Optimise for Speed ingesteld?
[Bericht gewijzigd door stecj366 op (11%)]
rew
four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
Als ie 99.8 zou moeten halen volgens kwartus en je draait op 100, dan zou ik denken: Mwah. dat werkt wel.
Dus... om te helpen met foutzoeken.... draai eens op 50Mhz, en niet op 100. Dan zit je ruim binnen de grens wat zou moeten werken, en kijk of het dan werkt. Ik vermoed van niet.
Een dedicated RAM in de FPGA is VELE malen sneller dan een RAM die je zelf zou maken met logic cellen.
Als je niet met een tabel maar gewoon rekenend een sinus wilt maken kan dat zo:
x += y >> 8;
y -= x >> 8;Dit is in de taal C, jij zult dit naar VHDL o.i.d. moeten vertalen. Let op, je kan denken dat het beter is om de boel "tegelijk" te doen, maar dat is niet zo. Je moet ze achter mekaar doen, dus de oneven clocks de X aanpassen en de even clocks de Y. Je X is dan het uitgangssignaal....
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
falling edge ??? very bad my friend...
maak dat systeem eens op rising edge van de clock. de flipflops in de fpga zijn gemaakt om op rising edge te draaien.... je gooit overal rotzooi tussen zo.
en 100MHz is een peuleschil voor een cyclone. Mijn systeem hier rolt op 250MHz zonder verpinken (Cyclone 2C35)
Externe signalen lopen op 120MHz.
ook dat gebruik van beide clock edges is very bad. zet daar stomweg een pipeline tussen die de boel 1 cycle vertraagt. kost je alleen een tros flipflops om je data 1 clocktick te bewaren.
Bij dergelijke frequenties komt je boar dlayout wel om de hoek kijken. terminaties zijn belnagrijk. groudn plane is belangrijk. net lengte egalisatie is belangrijk.
ik heb de indruk dat de rotzooi die je ziet door je interconnecties komen ...
Trouwens , wat een idee om je commentaar in het spaans te schrijven.. als je denkt dat ik dat ga beginnen vertalen: forget it.
flipflop
"We cannot solve our problems with the same thinking we used when we created them" - Albert Einstein
Wat heb je als clock constraint staan? Die moet je een stukje boven de gewenste freq zetten zodat de synth extra z'n best doet om optimaler uit te komen. Niet TE hoog, want dan geeft ie het halverwege op en kom je juist slechter uit. Pak 110MHz of zo, of 105.
In het timing rapport kun je ook zien wat je worst case path is. Aan dat pad moet je beginnen te sleutelen door (bv) een extra flipflop ertussen te zetten. Of lagen logica ertussenuit. Op 100MHz moet je niet veel meer dan 10 lagen zien (even gevoelsmatig, de rapporten spreken de waarheid).
Henry S.
Moderator
Confucius says chà bù duo. Deze post is niet door ChatGPT gegenereerd. De 2019 CO labvoeding.
stecj366
Sonar is meer dan Ping...
Op 23 april 2009 19:30:37 schreef free_electron:
ook dat gebruik van beide clock edges is very bad. zet daar stomweg een pipeline tussen die de boel 1 cycle vertraagt. kost je alleen een tros flipflops om je data 1 clocktick te bewaren.
Waarom is dit een probleem? Waarom is het niet goed om 2 edges te gebruiken? DDR doet dat toch ook?
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
ja inderdaad ddr doet dat ook maar daar worden er 2 registers gerbuikt. 1 register reageert op srtijgende clokc een op dalende.
het mechanisme werkt anders. bij jou ga je er van uit dat de propagation delay+ setup time van je logica kleiner is dan de tijd tussen van rising edge en falling edge. 100MHz.. das 10nS.... en je verliest al 7 in de I/0 structuren ... verrekte klein ...
FPGA's zijn intern wel snel maar de i.o is traag ! vergeet dat niet.
stecj366
Sonar is meer dan Ping...
ok, maar ik ging dan ook er niet van uit (het is niet eens mijn topic...)
Ik dacht dat hij het hier over verschillende registers had die op de 2 flanken werken, vandaar dat ik naar meer uitleg vroeg.
terug OT: Als je echt hulp wil, ga je je code toch in kleinere blokken moeten aanbieden, niet zo een lange trits met spaanse commentaar dan nog. Geef eerst eens een overzicht van het hele systeem, een blokschema ofzo, dat we weten waar we naar moeten kijken. Dat maakt debuggen o zo eenvoudiger, want ik haak persoonlijk af bij die code.
Scheef_schaap
't schaap is de preut af, meestal vooralleer het spel hespe is! (of in het AN: Meestal zal het eerst mislukken voor alleer het lukt..)
Bedankt voor al jullie commentaar!
@ rew: Ik heb het gevoel dat jij weet wat mijn probleem is.
Ik heb vandaag eens gewerkt met een kloksnelheid van 25Mhz.
Hetzelfde probleem, net zoals jij beschreef.
Jullie stellen dus voor om het complete systeem te klokken op de positieve flank, en vervolgens met een bufferregister te werken die alles 1 klokpuls vertraagt. Ga ik dan niet moeten lezen én schrijven in dit register terzelfdertijd? Zal dit problemen geven?
Om het systeem uit te leggen (naast de spaanse commentaar):
Er zijn 4 parrallel lopende processen.
Het main process ontvangt de data van de computer, slaat deze op in het DAC-RAM geheugen, en laat vervolgens dit continu naar de ADC lopen. Na 20 cycly laat dit process de 2 ADC's (voor spanning & stroom) ook lopen, en die meten elk 1000 punten van dit signaal (1 klokcycly, synchroon met de output van de DAC).
Deze 2 x 1000 punten worden opgeslagen in 2 x 14 bit registers.
Er zijn ook dipswitches, een display en LED's gebruikt om het systeem te debuggen.
Het Tx & Rx process is dus voor het ontvangen / verzenden van data & het ADC process om te sampelen.
Het probleem zit hem dus voor 100% in het main process, aangezien de ADC & transmissie perfect werken. Daar hoeft er dus niet naar gekeken te worden.
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 zou dat als volgt maken
- een DPram in de cyclone met 1 schrijf poort en 1 lees poort. so ben je van synchro miserie vanaf.
- de leespoort krijgt een vaste counter
- de counter heeft een reset pin en een enable pin
- de schrijfpoort heeft ook een counter en een reset pin
- de dprams in de altera zijn synchrone machines van hun eigen. de write strobe van de dpram en de clk van de schrijf counter knoop je aan elkaar. bij elke write wordt automatisch de address counter opgehoogd. de dpram latcht de data en het address automatisch. Gans die zwik is nu synchroon en je kan vol gas gaan omdat je altijd op het laatste moment clockt.
bon, dat is je dac controller.
voor je adc : 2 registers elk van x breed. die krijgen de 'sample clock' en dienen om de signalen die van de adc komen te syncen met interne logica.
ook daar gebruik je weer een dpram. de uitgang van de syncregisters knoop je aan data in. de syncclock knoop je aan de addresscounter clk en aan de dpram write clock.
De uitgangen van de dpram geven je data terug.
al wat je nu nog nodig hebt is een kleine state machine die vanuit een uart kan lezen / schrijven.
ik zou de boel zo maken dat je een van de handshake lijnen gebruikt om te schakelen tusen command / data mode.
als je de handshake op hoog brengt kan je 1 karakter versturen. dat is het 'commando'
als d elijn laag is doe je exchange.
klein statemachientje doet de rest.
je hebt 1 masterclock die je dac en adc en de daaraan vasthangende santeboetiek clocken.
je hebt ook een uartclock die de statemachiene stuurt en de dprams kan lezen en schrijven.
je bent van alle scynhro meuk vanaf. de dprams vangen alles op.
ik zou het geneens in hdl maken. schematje volstaat om de samplers en de dprams aan elkaar te knopen. een klein blokje met een statemachientje van 5 lijntjes code en je bent vooruit.
rew
four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
Op 24 april 2009 00:35:04 schreef Scheef_schaap:
Jullie stellen dus voor om het complete systeem te klokken op de positieve flank, en vervolgens met een bufferregister te werken die alles 1 klokpuls vertraagt. Ga ik dan niet moeten lezen én schrijven in dit register terzelfdertijd? Zal dit problemen geven?
Dat register is een voorstel wat soms nodig is en moet je niet als een wet van meden en perzen zien.
Ja, in een FPGA kan je tegelijk in een register schrijven als dat een ander deel van de schakeling het resultaat nog gebruikt. Dat heeft met setup-en-hold tijden te maken. De hold tijd is tegenwoordig vaak nul. Dus ZODRA de klok veranderd, hoef je de signalen aan de uitgang niet langer stabiel te houden. En je register kan natuurlijk nooit VOOR de klok gaan veranderen.
Maak maar eens een counter of een schuifregister. Dan maak je hier gebruik van.
Volgens mij kan quartus niet met negatief geklokte flipflops werken. Dus als hij zegt 100, dan bedoelt hij 50. Ook dat nog.
[edit] Oh ja. Als je nu even een paaar van die spaansecommentaar regels naar de volgende regel verhuist zodat de langste regel een stuk korter wordt, dan leest het weer een beetje normaal....
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
rew
four NANDS do make a NOR . Kijk ook eens in onze shop: http://www.bitwizard.nl/shop/
Zo bedoel ik het niet. Je zult in geval van negatief geclockte FFs dus een door een "uitgerekend signaal" geclockte flipflop krijgen. Daar heeft quartus moeite mee om dat in de timing mee te nemen.
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
Dat is juist. probleem is dat de boel verandert bij placement.
Ik draai voor het ogenblik vrij dicht tegen de limiet van wat kan in de speedgrade die ik gebruik. als ik de boel zelfstandig laat draaien werkt het niet.
Ik heb het design mooi gepartitioneerd, zelf de placement gedaan, ( ik gebruik het logiclock feature en incremental compilation)
in bepaalde kritishce stukken staan directives dat hij niet mag minimisen ( ik heb zelf al de boel zo gemaakt dat de looptijden egaal zijn in het combinatorisch blok, kwestie van race condities te elimineren)
boeltje compileert telkens vlekkeloos. maar dat lukt niet met een 'kwak het er in' approach ...
Scheef_schaap
't schaap is de preut af, meestal vooralleer het spel hespe is! (of in het AN: Meestal zal het eerst mislukken voor alleer het lukt..)
Bedank allemaal voor de reacties!
Ik heb het probleem gevonden, we sampelden de ADC's met een verkeerd kloksignaal. Beide ADC's krijgen dezelfde CLK van de FPGA, maar de ADC's geven nog eens een DCLK out, en op de rising edge van DEZE klok moet gesampled worden, en niet van de FPGA klok. 1 week achter gezocht!
Nu zit ik met het volgend probleem:
ADCV moet gesampled worden met DCLKV (V = voltage), en ADCI moet gesampled worden met DCLKI.
Aangezien ik in één proces niet met 2 kloksignalen kan werken, ben ik genoodzaakt om 2 processen bij te creeëren om m'n RAM te vullen met samples.
Ik zit hier met volgende problemen:
Ik heb een multiplexer gecreeërd voor de adres lijnen van m'n geheugen. Aangezien 1 proces deze gebruikt om data naar de Tx(RS232) te schrijven, en een ander proces dit geheugen gebruikt om de samples in op te slaan.
Ik heb m'n 2 kloksignalen gemultiplexed, alsook m'n adres lijnen.
Hier gaat het weer fout. Quartus creeërd nu een dual-port ram, waar hij de 2 input adres lijnen parrallel aan elkaar hangt.
Huh ?
M'n PC ontvangt mooi 4000 bytes, het signaal dat ik ontvang is iets raar, bevat een deel juiste samples, en soms allemaal '00000000' ertussen.
Is er iets fout met de code voor deze mux (hij zou combinatorisch moeten werken).
--------------------------------------------
-- Memory Controller Process --
-- Used to multiplex 2 adress lines to 1 --
-- RAM block and use the correct CLK --
--------------------------------------------
ADCV_process: process(MUX_ADCV,add_mem_ADCV_CLK,add_mem_ADCV_DCLK,clk,DCLK_ADCV)
begin
if MUX_ADCV = '0' then
add_mem_ADCV <= add_mem_ADCV_CLK; -- Adress line used to read RAM
RAM_ADCV_CLK <= clk; -- FPGA clock is used
elsif MUX_ADCV = '1' then
add_mem_ADCV <= add_mem_ADCV_DCLK; -- Adress line to write to RAM
RAM_ADCV_CLK <= DCLK_ADCV; -- ADC clock is used to synchronise on data ready
end if;
end process;
--------------------------------------------
ADCI_process: process(MUX_ADCI,add_mem_ADCI_CLK,add_mem_ADCI_DCLK,clk,DCLK_ADCI)
begin
if MUX_ADCI = '0' then
add_mem_ADCI <= add_mem_ADCI_CLK; -- Adress line used to read RAM
RAM_ADCI_CLK <= clk; -- FPGA clock is used
elsif MUX_ADCI = '1'then
add_mem_ADCI <= add_mem_ADCI_DCLK; -- Adress line to write to RAM
RAM_ADCI_CLK <= DCLK_ADCI; -- ADC clock is used to synchronise on data ready
end if;
end process;
en dit is hoe ik m'n ADC sample
ADCV_sample_circuit: process(DCLK_ADCV, reset)
variable state_ADCV: integer range 0 to 2;
variable cont_datos: integer range 0 to NUM_PUNTOS+1;
variable cnt_divider: std_logic_vector(23 downto 0);
begin
if reset = '0' then
state_ADCV := 0;
cont_datos := 0;
else
if rising_edge(DCLK_ADCV) then
case state_ADCV is
when 0 =>
READY_ADCV <= '0';
if START_ADCV = '1' then
state_ADCV := 1;
cnt_divider:="000000000000000000000000";
cont_datos := 0;
else
state_ADCV := 0;
end if;
when 1 =>
if cnt_divider=divider2 & divider1 & divider0 then
cnt_divider:="000000000000000000000000";
add_mem_ADCV_DCLK<= cont_datos;
data_mem_in_ADCV<= in_ADCV;
cont_datos:=cont_datos+1;
if cont_datos=NUM_PUNTOS + 1 then
state_ADCV:=2;
cont_datos := 0;
end if;
else
cnt_divider:=cnt_divider+1;
end if;
when 2 =>
READY_ADCV <= '1';
if MUX_ADCV = '0' then
state_ADCV := 0;
cont_datos := 0;
else
state_ADCV := 2;
end if;
end case;
end if;
end if;
end process;
[Bericht gewijzigd door Scheef_schaap op (19%)]
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
als je een dualport ram gebruikt heb je geen multiplexer nodig op je address bus ... je doet iets fout.
je bent tussen verschillende clok domeinen aan het draaien. dat is miserie vragen...