A finite state machine-based traffic light controller for NS & EW intersections with pedestrian signals and night mode — implemented in Verilog HDL.
Design and implement a Traffic Light Controller using Verilog HDL handling vehicle and pedestrian signals for North-South (NS) and East-West (EW) directions, including night mode and vehicle sensor input to optimize real-time traffic flow.
Priyanka Gandhi A & Monica Gandhi A
ECE Student, Avinashilingam University
This is an independent project exploring digital design using hardware description language and finite state machine principles.
clk system clock · rst reset
night_mode blink trigger
sensor_NS / sensor_EW vehicle detection
ped_NS / ped_EW pedestrian requests
light_NS[2:0] — 3-bit NS traffic signal
light_EW[2:0] — 3-bit EW traffic signal
ped_signal_NS / ped_signal_EW
Pedestrian crossing indicators
| State | NS Signal | EW Signal | Ped NS | Ped EW | Duration |
|---|---|---|---|---|---|
G1 | GREEN 100 | RED 001 | if ped_NS | — | 100 clk |
Y1 | YELLOW 010 | RED 001 | — | — | 30 clk |
R1 | RED 001 | RED 001 | — | — | 20 clk |
G2 | RED 001 | GREEN 100 | — | if ped_EW | 100 clk |
Y2 | RED 001 | YELLOW 010 | — | — | 30 clk |
R2 | RED 001 | RED 001 | — | — | 20 clk |
BLINK | YELLOW 010 | YELLOW 010 | — | — | 10 clk loop |
Start the system and initialize the control logic.
If reset is active → set initial state to G1 (NS Green) and set internal timer to 0. Otherwise → proceed to clock cycle operations.
On each clock cycle monitor the timer. If timer ≥ threshold for current state → transition to next_state and reset timer. Otherwise → increment timer.
Set output signals per state: G1 (NS Green, ped_NS active) → Y1 → R1 → G2 (EW Green, ped_EW active) → Y2 → R2, then loop back.
If Night Mode is active → override state and transition to BLINK. Both light_NS and light_EW set to Yellow continuously.
Repeat all steps on every clock pulse to maintain real-time traffic control.
module traffic_light_controller( input wire clk, rst, night_mode, input wire sensor_NS, sensor_EW, input wire ped_NS, ped_EW, output reg [2:0] light_NS, light_EW, output reg ped_signal_NS, ped_signal_EW ); // State encoding parameter G1=3'd0, Y1=3'd1, R1=3'd2, G2=3'd3, Y2=3'd4, R2=3'd5, BLINK=3'd6; reg [2:0] state, next_state; reg [7:0] timer; // Timing parameters parameter GREEN_TIME=8'd100, YELLOW_TIME=8'd30; parameter RED_TIME=8'd20, BLINK_TIME=8'd10; // Clocked state machine always @(posedge clk or posedge rst) begin if (rst) begin state <= G1; timer <= 0; end else begin if (timer >= (night_mode ? BLINK_TIME : (state==G1&&sensor_NS)||(state==G2&&sensor_EW) ? GREEN_TIME : (state==Y1||state==Y2) ? YELLOW_TIME : RED_TIME)) begin state <= next_state; timer <= 0; end else timer <= timer + 1; end end // Combinational output logic always @(*) begin light_NS=3'b001; light_EW=3'b001; ped_signal_NS=0; ped_signal_EW=0; next_state=state; case (state) G1: begin light_NS=3'b100; light_EW=3'b001; // Green NS if(ped_NS) ped_signal_NS=1; next_state=Y1; end Y1: begin light_NS=3'b010; next_state=R1; end R1: next_state=G2; G2: begin light_EW=3'b100; // Green EW if(ped_EW) ped_signal_EW=1; next_state=Y2; end Y2: begin light_EW=3'b010; next_state=R2; end R2: next_state=G1; BLINK: begin light_NS=3'b010; light_EW=3'b010; // Both Yellow next_state=BLINK; end default: next_state=G1; endcase if(night_mode) next_state=BLINK; end endmodule
`timescale 1ns / 1ps module tb_traffic_light; reg clk, rst, sensor_NS, sensor_EW; reg ped_NS, ped_EW, night_mode; wire [2:0] light_NS, light_EW; wire ped_signal_NS, ped_signal_EW; traffic_light_controller uut ( .clk(clk), .rst(rst), .sensor_NS(sensor_NS), .sensor_EW(sensor_EW), .ped_NS(ped_NS), .ped_EW(ped_EW), .night_mode(night_mode), .light_NS(light_NS), .light_EW(light_EW), .ped_signal_NS(ped_signal_NS), .ped_signal_EW(ped_signal_EW) ); // 100 MHz clock always #5 clk = ~clk; initial begin $dumpfile("traffic_wave.vcd"); $dumpvars(0, tb_traffic_light); clk=0; rst=1; sensor_NS=0; sensor_EW=0; ped_NS=0; ped_EW=0; night_mode=0; #20 rst=0; // Day simulation #50 sensor_EW=1; #100 sensor_EW=0; #50 ped_NS=1; #100 ped_NS=0; #50 ped_EW=1; #100 ped_EW=0; // Night mode test #200 night_mode=1; #1000 night_mode=0; #500 $finish; end endmodule