FPGA Synchronized Digit Counter goes Asynchronous!

I'm trying to implement one digit counter from 0 to 9 using an FPGA board. The digit is incremented when the signal "pulse" is set. The "pulse" signal is set every fixed number N of clock cycles. The clock frequency is 5 MHz. However the counter jumps inconsistently depending on the "pulse" period. For example when it's set to 1000000, the counter works fine and the digit is incremented every 1/5 of a second. When the period is different, it does not behave as expected. Even if the period is set longer, every 5000000 clock cycles, it jumps from 0 to 1 to 0..., the increment is 10!

Here's the VHDL code that increments the counter based on the pulse.

process(clk, reset)
begin
if (reset = '1') then
digit_reg <= (others => '0');
elsif rising_edge(clk) then
digit_reg <= next_digit;
end if;
end process;

process(pulse, digit_reg)
begin
if (pulse = '1') then
if (digit_reg >= 9) then
next_digit <= (others => '0');
else
next_digit <= digit_reg + 1;
end if;
end if;
end process;


Any idea what the problem might be?

Thanks.

• You mean when you simulated it ? – Mitu Raj Mar 24 '18 at 17:41
• Are you sure pulse is high for only one clock cycle? If not you need to make sure of that. – C_Elegans Mar 24 '18 at 17:42
• No, when synthesized. – Joseph Mar 24 '18 at 17:42
• First your next_digit is a latch. It gets set if pulse='1' but otherwise you haven not given it a value. I have no idea where 'pulse' comes from. Is it generated of the same clock? I think we need to see more code from that. – Oldfart Mar 24 '18 at 17:43
• remove digit_reg from the sensitivity list and check. – Mitu Raj Mar 24 '18 at 18:02

Add an else branch to fix the broken combinatoric process description:

process(pulse, digit_reg)
begin
if (pulse = '1') then
if (digit_reg >= 9) then
next_digit <= (others => '0');
else
next_digit <= digit_reg + 1;
end if;
else
next_digit <= digit_reg;
end if;
end process;


Your implementation will not fit good to any existing FPGA hardware because it uses an asynchronous and synchronous reset.

This is how to describe a fully synchronous counter modulo 9 with synchronous reset and clock enable (pulse):

process(clk)
begin
if rising_edge(clk) then
if ((reset = '1') or (digit_reg >= 9)) then
digit_reg <= (others => '0');
elsif (pulse = '1') then
digit_reg <= digit_reg + 1;
end if;
end if;
end process;

• You have completely misread the question. The OP is not trying to implement a mod-9 counter on "clk". He wants to count using the generated clock pulse. – Mitu Raj Mar 24 '18 at 18:47
• Actually the counter rotates after 9 it restarts from 0, hence a mod-9 counter. Sorry for not clarifying this in the OP. – Joseph Mar 24 '18 at 18:51
• @joseph Seems like your question itself is misleading. If you are trying to implement a mod 9 counter on clk ( I thought pulse ) this is the correct solution indeed. Then why do you even describe like your functionality was met when it incremented every 1/5 seconds, at first place. – Mitu Raj Mar 24 '18 at 18:59
• OP never clarifies whether pulse is a generated clock of 5x10^6 clk cycles or a pulse of "clk period" that occurs every 1/5 seconds. I answered thinking the first way and you answered thinking the latter way – Mitu Raj Mar 25 '18 at 0:26
• "You still haven't understood how VHDL works and how VHDL or any other HDL is translated to hardware " -- misleading question created your misconceptions. I don't claim to be pro expert with 25+ industrial experience but knows enough to help people out here. – Mitu Raj Mar 25 '18 at 0:32