1 | /************************************************************************** |
---|
2 | Adaptation of Mead and Conway traffic light controller. |
---|
3 | |
---|
4 | A little used farm road intersects with a multi-lane highway; a traffic |
---|
5 | light controls the traffic at the intersection. |
---|
6 | The light controller is implemented to maximize the time the highway light |
---|
7 | remains green. A submodule implements a timer, which outputs "short" and |
---|
8 | "long" time outs. The highway light stays green for at least "long" time. |
---|
9 | Any time after "long" time, if there is a car waiting on the farm road, then |
---|
10 | the farm light turns green. The farm light remains green until there are no |
---|
11 | more cars on the farm road, or until the long timer expires. The yellow |
---|
12 | light for both directions stays yellow for "short" time. |
---|
13 | |
---|
14 | The timer has non-determinism in it. Liveness properties won't pass until |
---|
15 | fairness constraints are placed on the timer, so that it can't pause |
---|
16 | forever. |
---|
17 | |
---|
18 | Tom Shiple, 25 October 1995 |
---|
19 | |
---|
20 | ***************************************************************************/ |
---|
21 | |
---|
22 | /* |
---|
23 | * Symbolic variables. |
---|
24 | */ |
---|
25 | typedef enum {YES, NO} boolean; |
---|
26 | typedef enum {START, SHORT, LONG} timer_state; |
---|
27 | typedef enum {GREEN, YELLOW, RED} color; |
---|
28 | |
---|
29 | /* |
---|
30 | * Module main ties together the underlying modules. In addition, it |
---|
31 | * ORs together the start timer outputs of the farm road and highway |
---|
32 | * controllers. Note that only a single timer is used for both the farm |
---|
33 | * road and highway controllers. In theory, this could lead to conflicts; as |
---|
34 | * implemented, such conflicts are avoided. |
---|
35 | */ |
---|
36 | module main(clk); |
---|
37 | input clk; |
---|
38 | |
---|
39 | color wire farm_light, hwy_light; |
---|
40 | wire start_timer, short_timer, long_timer; |
---|
41 | boolean wire car_present; |
---|
42 | wire enable_farm, farm_start_timer, enable_hwy, hwy_start_timer; |
---|
43 | |
---|
44 | assign start_timer = farm_start_timer || hwy_start_timer; |
---|
45 | |
---|
46 | timer timer(clk, start_timer, short_timer, long_timer); |
---|
47 | sensor sensor(clk, car_present); |
---|
48 | farm_control farm_control(clk, car_present, enable_farm, short_timer, long_timer, |
---|
49 | farm_light, farm_start_timer, enable_hwy); |
---|
50 | hwy_control hwy_control (clk, car_present, enable_hwy, short_timer, long_timer, |
---|
51 | hwy_light, hwy_start_timer, enable_farm); |
---|
52 | |
---|
53 | |
---|
54 | endmodule |
---|
55 | |
---|
56 | |
---|
57 | /* |
---|
58 | * There is a single, coupled sensor that detects the presence of a car |
---|
59 | * in either direction of the farm road. At each clock tick, it non- |
---|
60 | * deterministically reports that a car is present or not. |
---|
61 | */ |
---|
62 | module sensor(clk, car_present); |
---|
63 | input clk; |
---|
64 | output car_present; |
---|
65 | |
---|
66 | wire rand_choice; |
---|
67 | boolean reg car_present; |
---|
68 | |
---|
69 | initial car_present = NO; |
---|
70 | |
---|
71 | assign rand_choice = $ND(0,1); |
---|
72 | |
---|
73 | always @(posedge clk) begin |
---|
74 | if (rand_choice == 0) |
---|
75 | car_present = NO; |
---|
76 | else |
---|
77 | car_present = YES; |
---|
78 | end |
---|
79 | endmodule |
---|
80 | |
---|
81 | |
---|
82 | /* |
---|
83 | * From the START state, the timer produces the signal "short" |
---|
84 | * after a non-deterministic amount of time. The signal "short" |
---|
85 | * remains asserted until the timer is reset (via the signal "start"). |
---|
86 | * From the SHORT state, the timer produces the signal "long" |
---|
87 | * after a non-deterministic amount of time. The signal "long" |
---|
88 | * remains asserted until the timer is reset (via the signal "start"). |
---|
89 | * The following Buchi fairness constraints should be used: |
---|
90 | * |
---|
91 | * !(timer.state=START); |
---|
92 | * !(timer.state=SHORT); |
---|
93 | */ |
---|
94 | module timer(clk, start, short, long); |
---|
95 | input clk; |
---|
96 | input start; |
---|
97 | output short; |
---|
98 | output long; |
---|
99 | |
---|
100 | wire rand_choice; |
---|
101 | wire start, short, long; |
---|
102 | timer_state reg state; |
---|
103 | |
---|
104 | initial state = START; |
---|
105 | |
---|
106 | assign rand_choice = $ND(0,1); |
---|
107 | |
---|
108 | /* short could as well be assigned to be just (state == SHORT) */ |
---|
109 | assign short = ((state == SHORT) || (state == LONG)); |
---|
110 | assign long = (state == LONG); |
---|
111 | |
---|
112 | always @(posedge clk) begin |
---|
113 | if (start) state = START; |
---|
114 | else |
---|
115 | begin |
---|
116 | case (state) |
---|
117 | START: |
---|
118 | if (rand_choice == 1) state = SHORT; |
---|
119 | SHORT: |
---|
120 | if (rand_choice == 1) state = LONG; |
---|
121 | /* if LONG, remains LONG until start signal received */ |
---|
122 | endcase |
---|
123 | end |
---|
124 | end |
---|
125 | endmodule |
---|
126 | |
---|
127 | |
---|
128 | /* |
---|
129 | * Farm light stays RED until it is enabled by the highway control. At |
---|
130 | * this point, it resets the timer, and moves to GREEN. It stays in GREEN |
---|
131 | * until there are no cars, or the long timer expires. At this point, it |
---|
132 | * moves to YELLOW and resets the timer. It stays in YELLOW until the short |
---|
133 | * timer expires. At this point, it moves to RED and enables the highway |
---|
134 | * controller. |
---|
135 | */ |
---|
136 | module farm_control(clk, car_present, enable_farm, short_timer, long_timer, |
---|
137 | farm_light, farm_start_timer, enable_hwy); |
---|
138 | input clk; |
---|
139 | input car_present; |
---|
140 | input enable_farm; |
---|
141 | input short_timer; |
---|
142 | input long_timer; |
---|
143 | output farm_light; |
---|
144 | output farm_start_timer; |
---|
145 | output enable_hwy; |
---|
146 | |
---|
147 | boolean wire car_present; |
---|
148 | wire short_timer, long_timer; |
---|
149 | wire farm_start_timer; |
---|
150 | wire enable_hwy; |
---|
151 | wire enable_farm; |
---|
152 | |
---|
153 | color reg farm_light; |
---|
154 | |
---|
155 | initial farm_light = RED; |
---|
156 | |
---|
157 | assign farm_start_timer = (((farm_light == GREEN) |
---|
158 | && ((car_present == NO) || long_timer)) |
---|
159 | || |
---|
160 | (farm_light == RED) && enable_farm); |
---|
161 | assign enable_hwy = ((farm_light == YELLOW) && short_timer); |
---|
162 | |
---|
163 | always @(posedge clk) begin |
---|
164 | case (farm_light) |
---|
165 | GREEN: |
---|
166 | if ((car_present == NO) || long_timer) farm_light = YELLOW; |
---|
167 | YELLOW: |
---|
168 | if (short_timer) farm_light = RED; |
---|
169 | RED: |
---|
170 | if (enable_farm) farm_light = GREEN; |
---|
171 | endcase |
---|
172 | end |
---|
173 | endmodule |
---|
174 | |
---|
175 | |
---|
176 | /* |
---|
177 | * Highway light stays RED until it is enabled by the farm control. At |
---|
178 | * this point, it resets the timer, and moves to GREEN. It stays in GREEN |
---|
179 | * until there are cars and the long timer expires. At this point, it |
---|
180 | * moves to YELLOW and resets the timer. It stays in YELLOW until the short |
---|
181 | * timer expires. At this point, it moves to RED and enables the farm |
---|
182 | * controller. |
---|
183 | */ |
---|
184 | module hwy_control(clk, car_present, enable_hwy, short_timer, long_timer, |
---|
185 | hwy_light, hwy_start_timer, enable_farm); |
---|
186 | input clk; |
---|
187 | input car_present; |
---|
188 | input enable_hwy; |
---|
189 | input short_timer; |
---|
190 | input long_timer; |
---|
191 | output hwy_light; |
---|
192 | output hwy_start_timer; |
---|
193 | output enable_farm; |
---|
194 | |
---|
195 | boolean wire car_present; |
---|
196 | wire short_timer, long_timer; |
---|
197 | wire hwy_start_timer; |
---|
198 | wire enable_farm; |
---|
199 | wire enable_hwy; |
---|
200 | |
---|
201 | color reg hwy_light; |
---|
202 | |
---|
203 | initial hwy_light = GREEN; |
---|
204 | |
---|
205 | assign hwy_start_timer = (((hwy_light == GREEN) |
---|
206 | && ((car_present == YES) && long_timer)) |
---|
207 | || |
---|
208 | (hwy_light == RED) && enable_hwy); |
---|
209 | |
---|
210 | assign enable_farm = ((hwy_light == YELLOW) && short_timer); |
---|
211 | |
---|
212 | always @(posedge clk) begin |
---|
213 | case (hwy_light) |
---|
214 | GREEN: |
---|
215 | if ((car_present == YES) && long_timer) hwy_light = YELLOW; |
---|
216 | YELLOW: |
---|
217 | if (short_timer) hwy_light = RED; |
---|
218 | RED: |
---|
219 | if (enable_hwy) hwy_light = GREEN; |
---|
220 | endcase |
---|
221 | end |
---|
222 | endmodule |
---|