Ik heb een groot, complex blok logica draaiend op een Altera Cyclone FPGA, op een eigen board.

In een bepaalde fase van de state machine worden er samples gemeten en opgeslagen in een RAM. De relevante code staat hier onder.

Het gaat om de variabele sps_cnt. Deze wordt gebruikt om te bepalen hoeveel samples er al opgeslagen zijn, en zorgt ervoor dat de BIG FSM naar de volgende sequentiestap gaat (doorsturen van de opgeslagen data) en dat de sample FSM terug in idle mode gaat. Dit werkt allemaal mooi.

Het probleem is echter, dat de sps_cnt niet altijd mooi met 1 verhoogt wordt, zoals gehoopt. De Signaltap probe bevestigt dit: soms gaat hij bv van 7423 (0b1110011111111) niet naar 7424 (1110100000000), maar naar 1110110000000. Er blijft dus een bitje 'hangen'. Dit gebeurt ook regelmatig op andere bitgrenzen, maar het probleem zit dus op die plaats ergens.

Heeft er iemand een idee vanwaar dit "springen" kan komen, en beter nog, hoe dit kan worden opgelost? De code is volledig synchroon, alles zit binnen 1 proces dat op 1 clock (60MHz) en 1 reset draait.

De volledige code kan doorgemaild worden, maar ze is nogal lang en hier posten heeft dan niet veel zin imho. In de code hieronder is wel wat weg gelaten, daar waar de ... staan. Het gaat om andere signalen die worden geset/gereset en dergelijke, maar niets wat met die teller te maken heeft.

Oh ja, ik heb nog een vergelijkbaar probleem gehad met de State machines, die sprongen ook op een gekke manier. Ik heb deze dan op gray encoding gezet, en het probleem was opgelost. Eventueel dat ik de counter encoding ook op gray kan zetten? Kan dit in quartus?

[code=VHDL]
case STM_MEAS is
when ms_idle =>
-- We init the measurement and just hop to the measurement state when CLK_ADC is high
-- cause we store when CLK_ADC is low...
sps_cnt <= 0;
...

-- Enable write clock for the RAMs and init Adress:
-- The ram is storing the data from now on on the defined adress:
...
stor_chan <= 1;

if(CLK_ADC = '1') then
STM_MEAS <= ms_doMeas;
end if;

when ms_doMeas =>
-- This is the measurement state, we measure for n_sps_meas_int samples
-- If the CLK_ADC is 0, we go to the wait state, to prepare for storage
stor_chan <= 1;

meas_enveloppe <= '1';
if(CLK_ADC = '0') then
sps_cnt <= sps_cnt + 1;
STM_MEAS <= ms_wait;
end if;

when ms_wait =>
-- Wait unil next sample becomes available. If enough samples are read go to next BIG state
-- We also can store the result here to the RAMS at the write speed

if(sps_cnt >= n_sps_meas_int) then

-- We have stored all the nescesary samples, clean up and write data now...
...

STM_Meas <= ms_idle;
STM_Big <= write_data;

-- reset ram addres counter:
...
-- Also init the Ram OE
...

elsif(CLK_ADC = '1') then
-- CLK_ADC is 1, we need to return to the measurement state:
STM_MEAS <= ms_doMeas;

else

case stor_chan is
-- Here we write the data to the ram...
-- This is channel decoding, is lots of repetitive code...

...
end case;
end if;

when ms_slowRam =>
-- insert a wait state to write at 30MHz instead of 60MHz...
EN_RAM_WE <= '0';
STM_MEAS <= ms_wait;
when others =>

end case;
[/code]