Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.
21615 Discussions

Cyclone V - Counter not counting correctly

Altera_Forum
Honored Contributor II
2,040 Views

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
0 Kudos
8 Replies
Altera_Forum
Honored Contributor II
1,060 Views

This post for other forum -- read first glued message, here is discussed HPS-FPGA relations! 

 

May recommend you to rewrite code with "equal" changes -- often this helps to avoid "strange" FPGA behavior through "dancing with tambourine" :) 

For example, change all "state_register <= state_register + 1" to direct "state_register <= 1", "state_register <= 2", ... etc., if exampled in "when 0 =>" with x"61". May be excluded summator and all will cured. 

Or declare variable "state_register_plus_1", each tact compute it as "state_register_plus_1 <= state_register + 1" and make "state_register <= state_register_plus_1" in appropriate places... 

May be bringing out of "case" all works with "state_register" and make there only bool sign "need_be_inc_state_register". 

100 competetive writies to register is very complex problem for multiplexor, may be split these state machine to 2, 3... 

Or choice with "traditional" writing "state_register + 1" or x"61" in "when 0 =>" to drive mad LUTs... 

 

...Please, don`t work with text tabs and not upload examples with its ! 

It is enough 2 spaces to show a visible ident !
0 Kudos
Altera_Forum
Honored Contributor II
1,060 Views

 

--- Quote Start ---  

This post for other forum -- read first glued message, here is discussed HPS-FPGA relations! 

--- Quote End ---  

 

 

Yeah, sorry, I really was not sure where to put this. 

 

 

--- Quote Start ---  

May recommend you to rewrite code with "equal" changes -- often this helps to avoid "strange" FPGA behavior through "dancing with tambourine" :) 

For example, change all "state_register <= state_register + 1" to direct "state_register <= 1", "state_register <= 2", ... etc., if exampled in "when 0 =>" with x"61". May be excluded summator and all will cured. 

--- Quote End ---  

 

This was my very first implementation of this. I had declared the state_register as integer and did always "state_register <= 1;", "state_register <= 2;", etc. With this I had the same problems. I tried to change to use the summator in order to fix it, but it gave the same results, so I started this thread in the forum. 

 

 

--- Quote Start ---  

Or declare variable "state_register_plus_1", each tact compute it as "state_register_plus_1 <= state_register + 1" and make "state_register <= state_register_plus_1" in appropriate places... 

--- Quote End ---  

 

I will try this . . . Thanks for the suggestion! 

 

 

--- Quote Start ---  

May be bringing out of "case" all works with "state_register" and make there only bool sign "need_be_inc_state_register". 

--- Quote End ---  

 

Sorry, I don't fully understand what you mean by this. 

 

 

--- Quote Start ---  

100 competetive writies to register is very complex problem for multiplexor, may be split these state machine to 2, 3... 

--- Quote End ---  

 

Do you mean, that even if my design is checked by timequest (and modelsim) that there is still the chance that the design fails, just because I want to count to 100....? That seems really weird to me, but it explains, why I have this problem, right now. Can I implement something similar that is not synthesized with multiplexers? Is there some source of information on this topic regarding synthesis/FPGA design? I'm really interested in designing a rock solid system and was not aware, that counting to 100 can be that problem for the FPGA . . . .  

 

 

 

--- Quote Start ---  

Or choice with "traditional" writing "state_register + 1" or x"61" in "when 0 =>" to drive mad LUTs... 

--- Quote End ---  

 

Sorry, I have also problems to understand this. 

 

Thanks for your answer. I'm pretty happy that somebody answered this. I already feared that this was so unusual that nobody would reply. 

 

Maik
0 Kudos
Altera_Forum
Honored Contributor II
1,060 Views

Reply with embedded quotes is bad on this site!.. 

 

--- Quote Start ---  

 

--- Quote Start ---  

I recommend declare variable May be bringing out of "case" all works with "state_register" and make there only bool sign "need_be_inc_state_register". 

--- Quote End ---  

Sorry, I don't fully understand what you mean by this. 

--- Quote End ---  

 

I recommend declare variable "need_be_inc_state_register", set it always instead "state_register <= state_register + 1", and make "if (need_be_inc_state_register) state_register <= state_register + 1;" only once below all code -- carry out brackets. 

Although Quertus optimizer may make the same. And need be use this with "state_register_plus_1". 

 

--- Quote Start ---  

Do you mean, that even if my design is checked by timequest (and modelsim) that there is still the chance that the design fails... 

--- Quote End ---  

 

I is programmer and know 2 rules: 

1. Each program contain at the least 1 error. 

2. If count of errors ==0, go to 1. :) 

All may be... With 75 MHz instead 100 in FPGA these errors continues ? 

 

--- Quote Start ---  

 

--- Quote Start ---  

Or choice with "traditional" writing "state_register + 1" or x"61" in "when 0 =>" to drive mad LUTs... 

--- Quote End ---  

Sorry, I have also problems to understand this. 

--- Quote End ---  

 

All your problems with transition from 0 not to 1, and to 33, 64 and 65 ? 

I see to "when 0 =>" and pull out version: may be conflict with summator working and constant setting. 

 

--- Quote Start ---  

I'm pretty happy that somebody answered this. I already feared that this was so unusual that nobody would reply. 

 

--- Quote End ---  

 

Unreplied questions -- often event, also dread is bad state, even if jump need in situ ! (Sorry my Lingvo 5.0 if translation from rus-deutch is bad :) In your company absent more FPGA-developers ? 

I cardinal would be divide 100 states to 8 groups with 8 separate state counters and in exactly unproblem way use 9+ assigments of each. 

And may else problem with inputs in 3rd state -- new FPGA interprete its different as older. If in "if" they used... 

...And will be set FPGA clock to 25 MHz, SignalTap to 200, cath 8 samples in "tact", if present tremor in inputs to versatile variants... 

May closely analyse conditions for "official" transition to 33, 64 and 65, try to change it...
0 Kudos
Altera_Forum
Honored Contributor II
1,060 Views

This could be a stupid question but are you using the right clock in Signaltap? Is it the same than in your process? 

Are all your input signals on that state machine correctly synchronized with the clock? If they come from a different clock domain or from outside the FPGA they could require proper synchronization using at least two registers in series to avoid metastability issues.
0 Kudos
Altera_Forum
Honored Contributor II
1,060 Views

Hi, 

 

I'm using just this one clock in my whole design because I do not feel ready (from the timequest point of view) to handle different clock domains. I've gone through this pain in a couple of previous designs and try to avoid this as far as possible in this design. 

The clock that this counter is synchronized to is also the clock that I use for signal tap. 

 

The only signals that come from outside the FPGA are the MISO and N_DREADY signals from the ADC. The N_DREADY signal is (as you can see in the signal tap attachment) the trigger to leave my "state 0" and to got to "state 1" which quiet often is not working well . . . . 

These signal are set to "false path" in my sdc.  

Do you think, that the cause for this can be found here? Should I observe this N_DREADY signal outside my state machine with a, say, edge detector and feed that information into the main SPI state machine with my errornous counter? 

 

Regards, 

Maik
0 Kudos
Altera_Forum
Honored Contributor II
1,060 Views

Hi Daixiwen, 

 

you pointed it out! 

 

Since I send the n_dready signal through 3(!) registers and wait for all to have '0' in them, it just works!!!!! 

 

Thanks to you and also to WitFed for your time and hints!!!! Gives me something to think about in my current and future designs! 

 

Maik
0 Kudos
Altera_Forum
Honored Contributor II
1,060 Views

You don't need to be that safe, this kind of solution is mostly used for debouncing switches. In your case I think that using 2-3 registers in series and directly take the output of the last register as input to your state machine should be enough. Try and search "metastability" and "FPGA" on the net and I think you'll find lots of information about that subject.

0 Kudos
Altera_Forum
Honored Contributor II
1,060 Views

Thanks back for your thanks! :) 

...And need be always add in your out-of-FPGA signals as MISO and N_DREADY in simulator any random delay ! :) 

And may we ask Altera to add warning on compilation in similar "bare-in" situations without triggers ? :)
0 Kudos
Reply