I am trying to implement something as simple as the controller for one single traffic light by using two counters (one for green/red and one for yellow), but I don't seem to be getting the timing right.
My first counter looked something like
entity counter is generic ( max_count : integer := 50 ); port ( clk : in std_ulogic; rst : in std_ulogic; count_value : out integer := '0'; flag : out std_ulogic := '0' ); end entity; architecture behav of counter is signal count : natural := 0; begin count_value <= count process (rst, clk) begin if rst = '0' then flag <= '0'; count <= 0; elsif rising_edge(clk) then count <= (count + 1) mod max_count; if count = 0 then -- set flag value for one cycle flag <= '1'; else flag <= '0'; end if; end if; end process; end architecture behav;
which also sets the flag value when it starts to count.
When I tried to implement the traffic light (simply a state machine) by means of this counter, I got stuck. When I just start the red/green counter
c_redgreen once, i.e. the counter is never reset. The problem with this approach is of course that the time where the traffic light is yellow is not taken into account (e.g. the light starts with red and stays in that state for 50 cycles, then it becomes yellow for 5 cycles, but then there are only 45 cycles green, because the counter was not paused during the yellow time etc...). I thought this could be simply worked around by resetting
c_redgreen while the light is yellow, but immediately after the reset, the flag is immediately set and therefore I can't use something like
if rising_edge(rg_flag) then ..., because the rising edge comes immediately (because the counter sets the flag as it starts).
After these troubles, I thought it would be better to reformulate my counter as follows
... elsif rising_edge(clk) then temp := (count + 1) mod max_count; count <= temp if temp = 0 then ...
to avoid the flag being set when starting, but when I start the clock (in the testbench) with 0, the first red light does not last 50 cycles, but only 49. Also I am not sure whether it is a good idea for a counter to do nothing until it has reached
My question is thus how I can combine two counters (with or without start-flag) so that I can make my red/green lights shine for
n cycles and my yellow light for
m cycles. I hope I have been clear enough. If the code for my traffic light would be necessary, I can add it (I just didn't want to make this question even longer). I also don't necessarily need a traffic light, I just want to have these counters running in parallel in some way. Thanks in advance