-
Notifications
You must be signed in to change notification settings - Fork 0
/
light_controller.vhd
152 lines (117 loc) · 3.87 KB
/
light_controller.vhd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
entity light_controller is
port (
clk : in std_logic;
enable : in std_logic;
nominal : in std_logic;
standby : in std_logic;
maintenance : in std_logic;
state_changed : in std_logic;
mod0 : in std_logic;
mod1 : in std_logic;
mod_auto : in std_logic;
mode_changed : in std_logic;
red : out std_logic;
yellow : out std_logic;
green : out std_logic
);
end entity light_controller;
architecture light_controller_behaviour of light_controller is
component counter is generic (N : integer);
port (
enable : in std_logic;
reset : in std_logic;
clk : in std_logic;
out_count : out std_logic_vector(N - 1 downto 0)
);
end component counter;
constant c_nominal : std_logic_vector(2 downto 0) := "100";
constant c_standby : std_logic_vector(2 downto 0) := "010";
constant c_maintenance : std_logic_vector(2 downto 0) := "001";
constant c_mod0 : std_logic_vector(2 downto 0) := "100";
constant c_mod1 : std_logic_vector(2 downto 0) := "010";
constant c_mod_auto : std_logic_vector(2 downto 0) := "001";
signal op_mode_int : std_logic_vector(2 downto 0) := (others => '0');
signal standby_mode_int : std_logic_vector(2 downto 0) := (others => '0');
signal out_count_int : std_logic_vector(3 downto 0) := (others => '0');
signal reset : std_logic := '1';
signal reset_int : std_logic := '1';
begin
op_mode_int <= nominal & standby & maintenance;
standby_mode_int <= mod0 & mod1 & mod_auto;
lights : process (state_changed, mode_changed, out_count_int) is
variable ticks : integer;
variable ryg : std_logic_vector(2 downto 0) := (others => '0');
begin
if (reset_int = '0') then
reset_int <= '1';
elsif (state_changed = '0' or mode_changed = '0') then
reset_int <= '0';
end if;
ticks := to_integer(unsigned(out_count_int));
ryg := (others => '0');
if (enable = '1') then
case (op_mode_int) is
when c_maintenance =>
ryg := "111";
when c_nominal =>
if (ticks >= 0 and ticks < 5) then
-- Red for 5 secs
ryg := "100";
elsif (ticks >= 5 and ticks < 8) then
-- Green 5 secs
ryg := "001";
elsif (ticks >= 8 and ticks < 10) then
-- Green + Yellow 2 secs at the end
ryg := "011";
end if;
if (ticks = 10) then
reset_int <= '0';
end if;
when c_standby =>
case (standby_mode_int) is
when c_mod0 =>
if (ticks >= 0 and ticks < 1) then
-- Yellow on 1 sec
ryg := "010";
elsif (ticks >= 1 and ticks < 3) then
-- Yellow off 2 sec
ryg := "000";
end if;
if (ticks = 3) then
reset_int <= '0';
end if;
when c_mod1 | c_mod_auto =>
if (ticks = 0) then
-- Red on for 1 sec
ryg := "100";
else
-- Green on for 1 sec
ryg := "001";
end if;
if (ticks = 2) then
reset_int <= '0';
end if;
when others =>
null;
end case;
when others => null;
end case;
end if;
red <= ryg(2);
yellow <= ryg(1);
green <= ryg(0);
end process lights;
counter_cmp : counter
generic map (
n => 4
)
port map (
enable => enable,
reset => reset_int,
clk => clk,
out_count => out_count_int
);
end architecture light_controller_behaviour;