1 | -- Anmerkung:
|
2 | -- In der Praxis würde man diese Ampelsteuerung eher komplett in einem getakteten Prozess implementieren,
|
3 | -- anstatt die Logik in zwei Prozesse (1x getaktet und 1x ungetaktet) aufzusplitten.
|
4 | -- Durch diese hier gewählte Aufsplittung können einige Probleme entstehen ("race-conditions", "hazards").
|
5 | -- gez. Udo Siebertz
|
6 |
|
7 |
|
8 | library ieee;
|
9 | use ieee.std_logic_1164.all;
|
10 | use ieee.numeric_std.all;
|
11 |
|
12 | entity ampel is
|
13 | generic (
|
14 | CNT_OFL : positive := 50000000-1 -- Sekundentakt ofl
|
15 |
|
16 | );
|
17 |
|
18 | port (
|
19 | reset_n : in std_logic; -- Key3
|
20 | clk : in std_logic; --50 MHz
|
21 | taste : in std_logic; -- Key0: Taste an Fussgaengerampel
|
22 |
|
23 | ledg7_out : out std_logic; --LEDG[7]
|
24 | ledg30_out : out std_logic_vector(3 downto 0); -- LEDG[3…0]
|
25 |
|
26 | ledr93_out : out std_logic_vector(9 downto 3); -- LEDR[9…3]
|
27 | ledr0_out : out std_logic -- LEDR[0]
|
28 |
|
29 |
|
30 | );
|
31 | end entity ampel;
|
32 |
|
33 | architecture arch of ampel is
|
34 |
|
35 | -- signals
|
36 |
|
37 | signal cnt : unsigned(25 downto 0);
|
38 | signal time_s : unsigned(4 downto 0);
|
39 |
|
40 |
|
41 | type main_state_t is (wait_for_idle, idle, r_g_r, r_o_r, r_r_r, r_r_g, r_ro_r, reset);
|
42 | -- Bsp: r_g_r bedeutet: timer run, Verkehrsampel: grün, Fußgängerampel: rot
|
43 | signal main_state, next_main_state : main_state_t;
|
44 |
|
45 | type ampel_colour_t is (rot, gruen, orange, rot_orange);
|
46 | signal fa_colour, va_colour : ampel_colour_t; -- Fussgaengerampel, Verkehrsampel
|
47 |
|
48 |
|
49 | signal ledg7 : std_logic;
|
50 | signal ledg30 : std_logic_vector(3 downto 0);
|
51 | signal ledr93 : std_logic_vector(9 downto 3);
|
52 | signal ledr0 : std_logic;
|
53 |
|
54 |
|
55 | begin
|
56 |
|
57 | z_reg : process (reset_n, clk)--ERGÄNZE Sensitivitätsliste
|
58 | begin
|
59 | if (reset_n = '0') then
|
60 | cnt <= (others => '0');
|
61 | time_s <= (others => '0');
|
62 | main_state <= reset;
|
63 | elsif rising_edge(clk) then
|
64 | -- Update State Register
|
65 | main_state <= next_main_state;
|
66 |
|
67 | -- fast counter, overflow = 1s
|
68 | if cnt = to_unsigned(CNT_OFL, cnt'length) or main_state = idle then
|
69 | cnt <= (others => '0');
|
70 | else
|
71 | cnt <= cnt + 1;
|
72 | end if;
|
73 |
|
74 | -- Sekunden timer
|
75 | if main_state = reset then -- reset timer
|
76 | time_s <= (others => '0');
|
77 | elsif main_state /= idle and cnt = CNT_OFL then
|
78 | time_s <= time_s + 1;
|
79 | end if;
|
80 |
|
81 | end if;
|
82 |
|
83 |
|
84 | end process z_reg;
|
85 |
|
86 |
|
87 |
|
88 |
|
89 |
|
90 | ampel_control : process(time_s, taste) is --ERGÄNZE Sensitivitätsliste
|
91 |
|
92 | begin
|
93 |
|
94 |
|
95 | case main_state is -- timer VA FA
|
96 | -----------------------------------
|
97 |
|
98 | when reset => -- reset timer rot/orange rot
|
99 | --ERGÄNZE Ausgangszuweisung und Zustandsübergangsbedingung
|
100 | va_colour <= rot_orange;
|
101 | fa_colour <= rot;
|
102 |
|
103 | next_main_state <= wait_for_idle;
|
104 |
|
105 | when wait_for_idle => -- run grün rot
|
106 | --ERGÄNZE Ausgangszuweisung und Zustandsübergangsbedingung
|
107 | va_colour <= gruen;
|
108 | fa_colour <= rot;
|
109 |
|
110 | if (time_s < 7) then
|
111 | if (taste = 0) then
|
112 | next_main_state <= wait_for_idle;
|
113 | else
|
114 | next_main_state <= r_g_r;
|
115 | end if;
|
116 | else if (time_s = 7) then
|
117 | next_main_state <= idle;
|
118 | end if;
|
119 |
|
120 |
|
121 | when idle => -- stop grün rot
|
122 | --ERGÄNZE Ausgangszuweisung und Zustandsübergangsbedingung
|
123 | va_colour <= gruen;
|
124 | fa_colour <= rot;
|
125 |
|
126 | if (time_s = 7) then
|
127 | if (taste = 0) then
|
128 | next_main_state <= idle;
|
129 | else
|
130 | next_main_state <= r_g_r;
|
131 | end if;
|
132 | end if;
|
133 |
|
134 | when r_g_r => -- run grün rot
|
135 | --ERGÄNZE Ausgangszuweisung und Zustandsübergangsbedingung
|
136 | va_colour <= gruen;
|
137 | fa_colour <= rot;
|
138 |
|
139 | if (time_s < 10) then
|
140 | next_main_state <= r_g_r;
|
141 | else if (time_s = 10) then
|
142 | next_main_state <= r_o_r;
|
143 | end if;
|
144 |
|
145 |
|
146 | when r_o_r => -- run orange rot
|
147 | --ERGÄNZE Ausgangszuweisung und Zustandsübergangsbedingung
|
148 | va_colour <= orange;
|
149 | fa_colour <= rot;
|
150 |
|
151 | if (time_s < 12) then
|
152 | next_main_state <= r_o_r;
|
153 | else if (time_s = 12) then
|
154 | next_main_state <= r_r_r;
|
155 | end if;
|
156 |
|
157 |
|
158 | when r_r_r => -- run rot rot
|
159 | --ERGÄNZE Ausgangszuweisung und Zustandsübergangsbedingung
|
160 | va_colour <= rot;
|
161 | fa_colour <= rot;
|
162 |
|
163 | if (time_s < 13) then
|
164 | next_main_state <= r_r_r;
|
165 | else if (time_s = 13) then
|
166 | next_main_state <= r_r_g;
|
167 | else if (time_s < 20) then
|
168 | next_main_state <= r_r_r;
|
169 | else if (time_s = 20) then
|
170 | next_main_state <= r_ro_r;
|
171 | end if;
|
172 |
|
173 |
|
174 | when r_r_g => -- run rot grün
|
175 | --ERGÄNZE Ausgangszuweisung und Zustandsübergangsbedingung
|
176 | va_colour <= rot;
|
177 | fa_colour <= gruen;
|
178 |
|
179 | if (time_s < 18) then
|
180 | next_main_state <= r_r_g;
|
181 | else if (time_s = 18) then
|
182 | next_main_state <= r_r_r;
|
183 | end if;
|
184 |
|
185 |
|
186 | when r_ro_r => -- run rot/orange rot
|
187 | --ERGÄNZE Ausgangszuweisung und Zustandsübergangsbedingung
|
188 | va_colour <= rot_orange;
|
189 | fa_colour <= rot;
|
190 |
|
191 | if (time_s < 21) then
|
192 | next_main_state <= r_ro_r;
|
193 | else if (time_s = 21) then
|
194 | next_main_state <= reset;
|
195 | end if;
|
196 |
|
197 |
|
198 | end case;
|
199 |
|
200 | -- Fussgaengerampel
|
201 | if fa_colour = rot then
|
202 | ledr0 <= '1';
|
203 | ledg7 <= '0';
|
204 | elsif fa_colour = gruen then
|
205 | ledr0 <= '0';
|
206 | ledg7 <= '1';
|
207 | end if;
|
208 |
|
209 | -- Verkehrsampel
|
210 | if va_colour = rot then
|
211 | ledr93(9) <= '1';
|
212 | ledr93(8) <= '1';
|
213 | ledr93(7) <= '1';
|
214 | ledr93(6) <= '1';
|
215 | ledr93(5) <= '1';
|
216 | ledr93(4) <= '1';
|
217 | ledr93(3) <= '0';
|
218 | ledg30 <= (others => '0');
|
219 | elsif va_colour = orange then
|
220 | ledr93(9) <= '1';
|
221 | ledr93(8) <= '0';
|
222 | ledr93(7) <= '1';
|
223 | ledr93(6) <= '0';
|
224 | ledr93(5) <= '1';
|
225 | ledr93(4) <= '0';
|
226 | ledr93(3) <= '0';
|
227 | ledg30 <= (others => '0');
|
228 | elsif va_colour = rot_orange then
|
229 | ledr93(9) <= '1';
|
230 | ledr93(8) <= '1';
|
231 | ledr93(7) <= '1';
|
232 | ledr93(6) <= '0';
|
233 | ledr93(5) <= '1';
|
234 | ledr93(4) <= '0';
|
235 | ledr93(3) <= '1';
|
236 | ledg30 <= (others => '0');
|
237 | elsif va_colour = gruen then
|
238 | ledr93 <= (others => '0');
|
239 | ledg30 <= (others => '1');
|
240 | end if;
|
241 |
|
242 |
|
243 | ledg7_out <= ledg7;
|
244 | ledg30_out <= ledg30;
|
245 | ledr93_out <= ledr93;
|
246 | ledr0_out <= ledr0;
|
247 |
|
248 | end process ampel_control;
|
249 |
|
250 | end architecture arch;
|