Altera_Forum
Honored Contributor
11 years agoCyclone V - Counter not counting correctly
Hi,
I don't know if this is the correct section for this issue since it could also be a VHDL problem, but because I think my source code is correct, I post it here. My (serious) problem is that I use a counter that I declared as follows in my design to generate SPI "states" (clock, mosi bits, read miso data, etc . . . ) for an ADS1158 AD converter.
signal state_register : unsigned(7 downto 0) := (others => '0');
I use this signal as a "state counter" which I increment throughout a SPI data transfer cycle by using the following expression:
state_register <= state_register + 1;
The "state_regsiter" signal is the expression in a case statement that looks like this:
case to_integer(state_register) is
when 0 => is_ads_n_cs <= '1'; -- IDLE State
is_spi_clk <= '0';
current_mosi_bit <= '0';
t_cssc_counter <= 0;
if(write_ads_registers = '1' or read_ads_registers = '1') then
is_ads_n_cs <= '0';
state_register <= state_register + 1;
elsif(read_ads_channel_data = '1' and
(ads_n_dready = '0' or (ads1158_component_status(1) = '1' and cyclic_processing_write_read_flag = '0')) and
kilo_sample_flag = '1' and
ads1158_component_status(0) = '0') then
if(ads1158_component_status(1) = '1' and cyclic_processing_write_read_flag = '0') then
ads_command_byte <= ADS_COMMAND_PULSE_CONVERT;
end if;
is_ads_n_cs <= '0';
state_register <= state_register + 1;
elsif(read_ads_channel_data = '1' and ads1158_component_status(0) = '1' and kilo_sample_flag = '1') then
state_register <= x"61";
end if;
when 1 => if(t_cssc_counter < 7) then
t_cssc_counter <= t_cssc_counter + 1;
if((write_ads_registers = '1' or read_ads_registers = '1') or ads1158_component_status(1) = '1') then
current_mosi_bit <= ads_command_byte(ads_data_byte_ptr); -- 7
end if;
else
state_register <= state_register + 1;
end if;
when 2 => is_spi_clk <= '1'; -- 1st rising edge of spi_sclk
read_status_byte(ads_data_byte_ptr) <= spi_miso;
state_register <= state_register + 1;
when 3 => ads_data_byte_ptr <= ads_data_byte_ptr - 1; -- 6
state_register <= state_register + 1;
when 4 => is_spi_clk <= '0'; -- 1st falling edge of spi_sclk
state_register <= state_register + 1;
when 5 => if((write_ads_registers = '1' or read_ads_registers = '1') or ads1158_component_status(1) = '1') then
current_mosi_bit <= ads_command_byte(ads_data_byte_ptr); -- 6
end if;
state_register <= state_register + 1;
......
This "state machine" counts up to 99 for a whole 3 Byte data read transfer from the ADS1158. I use this kind of "state machine" because there are several "spots" during the data transfer where I would like to peek into the data already read from the ADS (like status and channel ID). Otherwise I would have implemented a "real" state machine where I would have defined some kind of state types. Anyway, my problem is that, according to modelsim, this state counter works as expected: It increments by "1" after each current "state" is processed. If I synthesize this with Quartus II V13.1 or 14.0, it happens from time to time that the counter does not increment by "1", but by a random number. I confirmed that by using Signal Tap II (see attachment). The signal tap screenshot shows a value of 33 right after 0 which in my opinion is not possible if one looks at the source code. I also observed other values like 64 or 65. From this "little" error on, everything works as described in the vhdl code until the next error of this kind occurs. The errors occur randomly in time, but svereral times a second (I sample 8 differential channels of the ADC with 1kHz). The design is fully timing constrained with a sdc file for my own QSYS components and the additional QSys generated sdc files. The timing reports show no errors or hints for this behaviour (I have to admit that I'm not a Timequest expert, though). The clock I use in this component is the h2f_user0_clk running at 100MHz. The FMax report of Timequest shows me that this clock can work up to 106MHz. The case statement runs in a synchronized process (synchronized to this h2f_user0_clk). I really don't understand what is going on here . . . I use a simple counter in a fully constrained design and modelsim is telling me that the logic is correct. Why the hell do I experience this kind of counting error? Any help is very much appreciated. I will also post additional informations about my design if requested. Regards, Maik