# Forum: FPGA, VHDL & Verilog Issue implementing counter in VHDL

Rate this post
 0 ▲ useful ▼ not useful
Hi everyone,

I have just started using VHDL and I am trying to understand a piece of
code I code I was handed. The counter must count up to 0xBEBC200 (which
is equal to 200,000,000) and whenever there is a change in the clock
signal, the program will enter the process statement to assess wether
the counter has reached 0xBEBC200 and reset the counter and if not,
increase the counter by 1. However, my friend has put the increment
statement inside the if statement assessing whether 0xBEBC200 has been
reached or not. For me this makes no sense since this means the counter
will not be incremented unless it is equal to 0xBEBC200. He has told me
the code is alright but could someone please tell me if the code is
right or not ? Thanks.

P.d. The clock is 100MHz and this section of the code acts as delay in a
larger system.

Rate this post
 1 ▲ useful ▼ not useful
Hi Jefazo

if I understand you right, you want to program a simple counter.
If you want to stop the delay at 200 000 000, then you must use
 if rising_edge(clk) then if counter < X"BEBC200" - X"01" then delay <= '0'; --if low active counter <= counter + X"01"; else counter <= X"00"; delay <= '1'; --if low active end if; end if; 

Why
 counter < X"BEBC200" - X"01"
You must set delay <= '1' before the last clock (199 999 999) because
the new signal value is only available at the next clock (200 000 000).

: Edited by User

Rate this post
 0 ▲ useful ▼ not useful
Hi oberheld,

Thank you for your reply but could the program use this somehow:

 process(clk) begin if rising_edge(clk)then if(counter <=X"BEBC200" ) then delay<='0'; counter_2000ms <=counter+x"000001"; else delay<='1'; counter<=x"000000"; end if; end if; end process; 

Testing if the value of counter is equal to X"BEBC200" and incrementing
from inside the condition ? Or is that part wrong ?
Also I not understanding why the next signal value is available from 200
000 000, could you elaborate more on it please ? Thanks in advance.

: Edited by User

Rate this post
 1 ▲ useful ▼ not useful
I don't know what you are doing with counter_2000ms
but now you assign the value of counter + 1 to "counter_2000ms".
With this code the signal "counter" does not increment itself.

Jefazo J. wrote:
> Testing if the value of counter is equal to X"BEBC200" and incrementing
> from inside the condition ? Or is that part wrong ?

It is right to increment the counter inside the if statement but your if
condition is not right.
 if(counter <=X"BEBC200" ) then 

Jefazo J. wrote:
> Also I not understanding why the next signal value is available from 200
> 000 000, could you elaborate more on it please ?

I hope you can understand my little sketch ;D
clk is your 100mhz clock. counter and delay show the current values at
the BEGINNING of each clk. So if you want to stop the delay in clk 2,
you must set delay to 1 before clk 2 starts.
  clk 0 clk 1 clk 2 (last clk) _____ _____ _____ clk | |_____| |_____| |_____ counter | 199999998 | 199999999 | 0 | delay | 0 | 0 | 1 | 

Rate this post
 0 ▲ useful ▼ not useful
Hi oberheld,

Again, thanks a lot for your reply. It was all very clearly explained
above. Just one little thing more about the counter, the next signal
value is available from 200 000 000 since the counter starts at a value
of 0 and when counter is equal 199 999 999, it actually means 200 000
000 cycles have already passed, right ? Apologies if my question seems
too simple or dumb. Thanks.

: Edited by User

Rate this post
 0 ▲ useful ▼ not useful
If clk 2 starts, then already 2 seconds have passed. Therefore you reset
the counter in clk 1 and restart counting in clk 2. So at the Beginning
of clk 3 the counter value is 1 again.

: Edited by User

Rate this post
 0 ▲ useful ▼ not useful
If you use this desgin you get a continuous counter.
To disable the counter after 2 sec you have to create something like an
enable signal.

 if rising_edge(clk) then if En = '1' and counter < X"BEBC200" - X"01" then delay <= '0'; --if low active counter <= counter + X"01"; else counter <= X"00"; delay <= '1'; --if low active end if; end if; 

: Edited by User

Rate this post
 0 ▲ useful ▼ not useful
Hi oberheld,

As always thank you for your great explanations. I understood it
perfectly now. The only issue is trying to link the state machine with
the delays. I am not sure if there is a keyword in VHDL. Please would
you mind telling me if there is somthing like that ? I have attached the
VHDL code for the state machine. Thanks.

: Edited by User

Rate this post
 0 ▲ useful ▼ not useful
Jefazo J. wrote:
> The counter must count up to 0xBEBC200
an integer for the counter? That leads to a much more readable code for
human beings:
 library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; : : signal counter : integer range 0 to 199999999 := 0; process(clk) begin if rising_edge(clk)then if counter < 200000000-1 then -- 0..199999999 are 200000000 steps delay<='0'; counter <= counter+1; else delay<='1'; counter <= 0; end if; end if; end process; 

-- start the process when clk when edge is detected.
The sensitivity list is only for the simulator. Any change on any of the
signals in that list leads to a recalculation of the process.
For generating hardware for the FPGA the synthesizer simply ignores
that list and invokes all of the necessary signals to implement the
described hardware. Only a info/warning about "simulation does not match
hardware due to incomplete sensitivity list" may be given.

-- if rising edge detected
The rising edge is not "detected", thats not a kind of passvie "wating
for anything happening". Instead the text these must be "due to a rising
edge", because exactly that rising edge does something with the
flipflops.

--reset the counte immediately
There is no such a thing linke "immediately" to signals inside a
process. In the simulator all signals inside a process keep their old
value till the end of the process or the next wait statement.
In real hardware you must see, what you describe: logic and flipflops.

--and restart the process
There is no way to "restart" a process. Forget this "starting" at all.
See it more like a process is "triggered" due to a change of any signal
in its sensitivity list (as already said). And forget about finfing a
process on a real FPGA: there is only logic (= LUTs) and flipflops to
build the hardware doing what you describe with your process.

Jefazo J. wrote:
> I have attached the VHDL code for the state machine.
This is no state machine, as the synthesizer invokes no flipflop,
because no clock is used inside the description. It may be the
combinatorial part of a state machine, but a complete FSM needs
flipflops for storing its state. A flipflop would be generated if there
would be some 'event or rising_edge() or falling_edge() in the code.
Where did you find that FSM coding style? Why not doing it like all the
others with a one-process or two-process description?

> Delay.txt
> STATEMACHINE.txt
Pls attach your VHDL code as *.vhd or *vhdl files. You will get some
kind of magic called "syntax highlighting" as a bonus.
BTW: each VHDL description starts with "library ieee;" and the few lines
behind

• $formula (LaTeX syntax)$