Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

Traffic lamp with blinking

Status
Not open for further replies.

kahlenberg

Junior Member level 3
Joined
Oct 26, 2009
Messages
29
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Location
AT
Activity points
1,543
Hi,
I want to design a traffic light controller with blinking green function.
There are 2 LED groups, each of which consists of 3 LEDs (red, orange, green) for cars, 2 LEDs (red, green) for pedestrians. Totally, there are 10 LEDs. There are 2 buttons as well.
The first button is night-mode button. When it is pressed, only orange LEDs should blink. The second button is for pedestrians. When it is pressed, after some certain time (lets say after 3 seconds) the green LED for pedestrians should light.

I haven't implemented pedestrian-button yet, I try to implement first night-mode button, but it doesn't work. When I press it, green LED is going off and never come back.

I want to implement this controller as a state machine.
Can you have a look and say what the problem is? And also, I would be appreciated if you have some suggestions for whole design.
Here is my code:




lights.png


Code:
library IEEE;
use IEEE.std_logic_1164.all;

package ampel_const is
    constant ACTIVE: std_logic := '1';
    type state is (R_R, RY_R, G_R, GB_R, Y_R, R_RY, R_G, R_GB, R_Y, YB_YB);
    type blink_state is (NONE, LIGHT_A, LIGHT_B);
    constant GREEN:  std_logic_vector(4 downto 0) := "10100";
    constant YELLOW: std_logic_vector(4 downto 0) := "01010";
    constant RED:    std_logic_vector(4 downto 0) := "01001";
    constant REDYEL: std_logic_vector(4 downto 0) := "01011";
    constant CAUTION: std_logic_vector(4 downto 0) := "00010";
    constant BLANK : std_logic_vector(4 downto 0) := "00000";
end ampel_const;
-------------------------------------------

library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
use ieee.numeric_std.all;
use work.ampel_const.all;
use work.my_constants.all;

entity ampel is
    port(
        clk : in std_logic;
        reset : in std_logic;
        timer_ack: inout std_logic;
        night_mode: in std_logic;
        lights_A: out std_logic_vector(4 downto 0);
        lights_B: out std_logic_vector(4 downto 0)
    );
end ampel;

architecture simple of ampel is

    constant BLINK_COUNTER : integer := 30000000; --to_integer(unsigned'(x"17d7840"));
    constant SHORT_STATE_COUNTER: integer := BLINK_COUNTER * 8;
    constant LONG_STATE_COUNTER: integer := SHORT_STATE_COUNTER * 4;
    signal phase, nextPhase: state;
    signal nextTimer_ack: std_logic;
    signal s_blink_puls: std_logic;
    signal s_blink: std_logic;
    signal s_change_state_puls: std_logic;
    signal s_blink_timer_reset: std_logic;
    signal s_lights_a, s_lights_b : std_logic_vector(4 downto 0);
    signal s_state_timer_max_count : unsigned(31 downto 0) := to_unsigned(LONG_STATE_COUNTER, 32);

    component counter is
        generic(COUNTER_WIDTH: integer := 16);
        port (clk: in std_logic; reset: in std_logic;  max_count: in unsigned(COUNTER_WIDTH-1 downto 0); overflow: out std_logic );
    end component;
begin
    state_timer: counter
        generic map(32)
        port map(clk, reset, s_state_timer_max_count, s_change_state_puls);
    blink_timer: counter
        generic map(32)
        port map(clk, s_blink_timer_reset, to_unsigned(BLINK_COUNTER, 32), s_blink_puls);

    lights_A <= s_lights_a;
    lights_B <= s_lights_b;

    syn_phase: process(clk, reset, nextPhase, nextTimer_ack)
    begin
        if reset = ACTIVE then
            phase <= R_R;
            timer_ack <= not ACTIVE;
        else
            if clk'event and clk = '1' then
                phase <= nextPhase;
                timer_ack <= nextTimer_ack;
            end if;
        end if;
    end process syn_phase;

    next_phase: process(phase, nextPhase, s_change_state_puls, timer_ack, night_mode)
    begin
        nextPhase <= phase;
        nextTimer_ack <= not ACTIVE;
--        if night_mode = ACTIVE then
--            nextPhase <= YB_YB;
--        end if;
        if s_change_state_puls = ACTIVE then
            nextTimer_ack <= ACTIVE;
            if timer_ack = not ACTIVE then

                case phase is
                    when R_R =>
                        nextPhase <= RY_R;
                    when RY_R =>
                        nextPhase <= G_R;
                    when G_R =>
                        nextPhase <= GB_R;
                    when GB_R =>
                        nextPhase <= Y_R;
                    when Y_R =>
                        nextPhase <= R_RY;
                    when R_RY =>
                        nextPhase <= R_G;
                    when R_G =>
                        nextPhase <= R_GB;
                    when R_GB =>
                        nextPhase <= R_Y;
                    when R_Y =>
                        nextPhase <= R_R;
                    when YB_YB =>
                        nextPhase <= YB_YB;
                    when others =>
                        nextPhase <= R_R;
                end case;
            end if;
        end if;
    end process next_phase;

    output: process(phase, s_blink_puls)
    begin
        case phase is
            when R_R =>
                s_lights_a <= RED;
                s_lights_b <= RED;
                s_blink_timer_reset <= ACTIVE;
                s_blink <= '0';
                s_state_timer_max_count <= to_unsigned(SHORT_STATE_COUNTER, 32);
            when RY_R =>
                s_lights_a <= REDYEL;
                s_lights_b <= RED;
                s_blink_timer_reset <= ACTIVE;
                s_blink <= '0';
                s_state_timer_max_count <= to_unsigned(SHORT_STATE_COUNTER, 32);
            when G_R =>
                s_lights_a <= GREEN;
                s_lights_b <= RED;
                s_blink_timer_reset <= ACTIVE;
                s_blink <= '0';
                s_state_timer_max_count <= to_unsigned(LONG_STATE_COUNTER, 32);
            when GB_R =>
                if s_blink_puls = '1' then
                    s_blink <= not s_blink;
                end if;
                s_lights_a <= (s_blink & "0" & s_blink & "00");
                s_lights_b <= RED;

                s_blink_timer_reset <= not ACTIVE;
                s_state_timer_max_count <= to_unsigned(SHORT_STATE_COUNTER, 32);

            when Y_R =>
                s_lights_a <= YELLOW;
                s_lights_b <= RED;
                s_blink_timer_reset <= ACTIVE;
                s_blink <= '0';
                s_state_timer_max_count <= to_unsigned(SHORT_STATE_COUNTER, 32);
            when R_RY =>
                s_lights_a <= RED;
                s_lights_b <= REDYEL;
                s_blink_timer_reset <= ACTIVE;
                s_blink <= '0';
                s_state_timer_max_count <= to_unsigned(SHORT_STATE_COUNTER, 32);
            when R_G =>
                s_lights_a <= RED;
                s_lights_b <= GREEN;
                s_blink_timer_reset <= ACTIVE;
                s_blink <= '0';
                s_state_timer_max_count <= to_unsigned(LONG_STATE_COUNTER, 32);
            when R_GB =>

                if s_blink_puls = '1' then
                    s_blink <= not s_blink;
                end if;

                s_lights_a <= RED;
                s_lights_b <= (s_blink & "0" & s_blink & "00");

                s_blink_timer_reset <= not ACTIVE;
                s_state_timer_max_count <= to_unsigned(SHORT_STATE_COUNTER, 32);
            when R_Y =>
                s_lights_a <= RED;
                s_lights_b <= YELLOW;
                s_blink_timer_reset <= ACTIVE;
                s_blink <= '0';
                s_state_timer_max_count <= to_unsigned(SHORT_STATE_COUNTER, 32);

            when YB_YB =>
                if s_blink_puls = '1' then
                    s_blink <= not s_blink;
                end if;
                s_lights_a <= ("000" & s_blink & "0");
                s_lights_b <= ("000" & s_blink & "0");

                s_blink_timer_reset <= not ACTIVE;
                s_state_timer_max_count <= to_unsigned(SHORT_STATE_COUNTER, 32);

            when others =>
                s_lights_a <= RED;
                s_lights_b <= RED;
                s_blink_timer_reset <= ACTIVE;
                s_blink <= '0';
                s_state_timer_max_count <= to_unsigned(SHORT_STATE_COUNTER, 32);
        end case;
    end process output;
end simple;
 

Just a thought here is a different approach -

**broken link removed**


Regards, Dana.
 

You have written plenty code neatly. But you must do simulation first and see it working as expected then move to hardware making sure it passes timing. Only then you can identify any issues.
 

Yes, I already simulated it. But as I wrote, night-mode button is not working, I don't know why.
 

Yes, I already simulated it. But as I wrote, night-mode button is not working, I don't know why.
Your problem isn't clear. If night button doesn't work is it in sim or hardware.?

Anyway my suspicion is that it is to do with priority logic.
The statements:
-- if night_mode = ACTIVE then
-- nextPhase <= YB_YB;
-- end if;
are at top in the process and will be over-driven by next statements...
Again you need to see night button in sim before going to hardware. You need proper testbench for that.
 

Hi,

With the simukation it should be simple to follow the "night mode" signal ..... in direction to the "not working" signal (whatever "not working" means).

Klaus
 

@kahlenberg ,
This is a straightforward design and if it is working in simulation it should work in hardware without much problems. You need to do functional verification thoroughly.
Can you show us a simulation screenshot of the night_mode signal transitions?
Can you also post the testbench?
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top