In this session, we will design and discuss a traffic light controller using Verilog and finite state machine approach. Consider a controller for traffic at the intersection of a main street and a side street as shown in the figure beside.
To understand and get the same perception, consider the following specifications:
- The traffic signal for the main street gets highest priority because car are continuously present on the main street. Thus, the main street signal remains green by default.
- Occasionally, cars from the side street arrive at the traffic signal. The traffic signal for the side street must turn green only long enough to let the cars on the side street go.
- As soon as there are no cars on the side street, the side street traffic signal turns yellow and then red and the traffic signal on the main street turns green again.
- There is a sensor to detect cars waiting on the side street. The sensor sends a signal X as input to the controller. X = 1 if there are cars on the side street; otherwise, X = 0.
- There are delays on transitions from S1 to S2, from S2 to S3, and from S4 to S0. The delays must be controllable.
Verilog Description
The traffic controller module can be designed with behavioral Verilog constructs as follow:
// Traffic Signal Controller
----------------------------------------------------------------------------
`define TRUE 1'b1';
`define FALSE 1'b0';
//Delays
`define Y2R_DELAY 3 // Yellow to red delay
`define R2G_DELAY 2 // Red to green delay
module sig_control(main_s, side_s, X, clock, clear);
// I/O ports
output [1:0] main_s, side_s; //2-bit output for 3 signal states (green, yellow, red)
reg [1:0] main_s, side_s; // declared output signals are registers
intput X; // if TRUE, indicates there is car on the side street, otherwise FALSE
input clock, clear;
parameter RED = 2'd0, YELLOW = 2'd1, GREEN = 2'd2;
// State definition MAIN_S SIDE_S
parameter S0 = 3'd0, //GREEN RED
S1 = 3'd1, //YELLOW RED
S2 = 3'd2, //RED RED
S3 = 3'd3, //RED GREEN
S4 = 3'd4, //RED YELLOW
// Internal state variable
reg [2:0] state;
reg [2:0] next_state;
// State changes only at positive edge of clock
always@(posedge clock) `define FALSE 1'b0';
//Delays
`define Y2R_DELAY 3 // Yellow to red delay
`define R2G_DELAY 2 // Red to green delay
module sig_control(main_s, side_s, X, clock, clear);
// I/O ports
output [1:0] main_s, side_s; //2-bit output for 3 signal states (green, yellow, red)
reg [1:0] main_s, side_s; // declared output signals are registers
intput X; // if TRUE, indicates there is car on the side street, otherwise FALSE
input clock, clear;
parameter RED = 2'd0, YELLOW = 2'd1, GREEN = 2'd2;
// State definition MAIN_S SIDE_S
parameter S0 = 3'd0, //GREEN RED
S1 = 3'd1, //YELLOW RED
S2 = 3'd2, //RED RED
S3 = 3'd3, //RED GREEN
S4 = 3'd4, //RED YELLOW
// Internal state variable
reg [2:0] state;
reg [2:0] next_state;
// State changes only at positive edge of clock
if (clear)
state <= S0; //Controller starts in S0 state
else
state <= next_state; //State change
// Compute values of main signal and side signal
state <= S0; //Controller starts in S0 state
else
state <= next_state; //State change
// Compute values of main signal and side signal
always@(state)
endmodule
begin
main_s = GREEN; //Default Light Assignment for Main_s light
side_s = RED; //Default Light Assignment for Side_s light
case@(state)
S0 = ; //No change, used default
S1: main_s = YELLOW;
S2: main_s = RED;
S3: begin
main_s = RED;
side_s = GREEN;
main_s = RED;
side_s = `YELLOW;
end
// State machine using case statements
always@(state or X)
begin
case@(state)
S0: if(X)
next_state = S1;
else
next_state = S0;
S1: begin //delay some positive edges of clock
repeat (`Y2R_DELAY)@(posedge clock);
next_state = S2;
repeat (`R2G_DELAY)@(posedge clock);
next_state = S3;
next_state = S3;
else
next_state = S4;
S4: begin //delay some positive edges of clock
repeat (`Y2R_DELAY)@(posedge clock);
next_state = S0;
end
main_s = GREEN; //Default Light Assignment for Main_s light
side_s = RED; //Default Light Assignment for Side_s light
case@(state)
S0 = ; //No change, used default
S1: main_s = YELLOW;
S2: main_s = RED;
S3: begin
main_s = RED;
side_s = GREEN;
end
S4: begin main_s = RED;
side_s = `YELLOW;
end
endcase end
// State machine using case statements
always@(state or X)
begin
case@(state)
S0: if(X)
next_state = S1;
else
next_state = S0;
S1: begin //delay some positive edges of clock
repeat (`Y2R_DELAY)@(posedge clock);
next_state = S2;
end
S2: begin //delay some positive edges of clock repeat (`R2G_DELAY)@(posedge clock);
next_state = S3;
end
S3: if(X)next_state = S3;
else
next_state = S4;
S4: begin //delay some positive edges of clock
repeat (`Y2R_DELAY)@(posedge clock);
next_state = S0;
end
default next_state = S0;
endcase default next_state = S0;
end
Stimulus can be applied to check if the traffic signal transitions correctly when cars arrive on the side street. The stimulus below instantiates the traffic signal controller and checks all possible states of the controller.
Reference:
- Verilog HDL, A guide to Digital Design and Synthesis, 2nd edtion, Samir Palnitkar, SunSoft Press - A Prentice Hall Title.
Very true....
ReplyDeleteWhen traffic lights display mixed signals, the results can be costly.
We regularly depend on just three colors for the safe navigation of the world’s freeways, highways and suburban thoroughfares. Red, yellow and green. It couldn't be any simpler. And yet, the reality is that the underlying technology and programming behind the display of these three colors is far from simple.
www.sealimited.com