16 Jun 12:25
module top (
input wire CLK_PCB,
input wire nRST_PCB,
input wire ROAD_DET,
output wire ROAD_RED,
output wire ROAD_YELLOW,
output wire ROAD_GREEN,
input wire PED_BUTT,
output wire PED_RED,
output wire PED_GREEN,
output wire [3:0] LED,
output wire buzzer
);
reg car, ped;
always @(posedge CLK) begin
car <= ROAD_DET;
ped <= PED_BUTT;
end
reg buzzer_en = 1;
wire [1:0] car_light, ped_light;
wire CLK = CLK_PCB;
wire RST_PCB = ~nRST_PCB;
wire RST_async, RST_sync, RST;
assign RST_async = RST_PCB;
assign RST_sync = RST_async;
assign RST = RST_sync;
reg [31:0] heartbeat_clk;
always @(posedge CLK or posedge RST)
if (RST) heartbeat_clk <= 0;
else heartbeat_clk <= heartbeat_clk + 1;
assign LED = ~{ROAD_DET, PED_BUTT, RST, heartbeat_clk[27]};
assign ROAD_RED = (car_light == 2'b00 || car_light == 2'b11);
assign ROAD_YELLOW = (car_light == 2'b01 || car_light == 2'b11);
assign ROAD_GREEN = (car_light == 2'b10);
assign PED_RED = (ped_light == 2'b00);
assign PED_GREEN = (ped_light == 2'b10 || ped_light == 2'b11);
traffic_lights uut(
.clk(CLK),
.rst(RST),
.car(car),
.ped(ped),
.buzzer_en(buzzer_en),
.car_light(car_light),
.ped_light(ped_light),
.buzzer(buzzer)
);
endmodule
module traffic_lights (
input wire clk,
input wire rst,
input wire car,
input wire ped,
input wire buzzer_en,
output reg [1:0] car_light,
output reg [1:0] ped_light,
output reg buzzer
);
localparam CLK_FREQ = 50_000_000;
localparam GREEN_TIME = 5 * CLK_FREQ;
localparam YELLOW_TIME = 2 * CLK_FREQ;
localparam BLINK_TIME = 1 * CLK_FREQ;
localparam S0 = 3'd0;
localparam S1 = 3'd1;
localparam S2 = 3'd2;
localparam S3 = 3'd3;
localparam S4 = 3'd4;
localparam S5 = 3'd5;
localparam S6 = 3'd6;
localparam S7 = 3'd7;
reg [2:0] state, next_state;
reg [31:0] timer;
reg blink;
always @(posedge clk or posedge rst) begin
if (rst) begin
state <= S0;
timer <= 0;
blink <= 0;
end else begin
state <= next_state;
case (state)
S2: begin
if (timer == 0) begin
blink <= ~blink;
timer <= BLINK_TIME;
end else begin
timer <= timer - 1;
end
end
S5, S6: begin
if (timer > 0) timer <= timer - 1;
end
default: begin
timer <= 0;
blink <= 0;
end
endcase
end
end
always @(*) begin
case (state)
S0: next_state = ped ? S1 : (car ? S4 : S0);
S1: next_state = S2;
S2: next_state = blink ? S3 : S2;
S3: next_state = S4;
S4: next_state = S5;
S5: next_state = (timer == 0) ? S6 : S5;
S6: next_state = (timer == 0) ? S7 : S6;
S7: next_state = S1;
default: next_state = S0;
endcase
end
always @(*) begin
car_light = 2'b00;
ped_light = 2'b00;
buzzer = 0;
case (state)
S0: begin car_light = 2'b00; ped_light = 2'b00; end
S1: begin car_light = 2'b00; ped_light = 2'b10; end
S2: begin
car_light = 2'b00;
ped_light = blink ? 2'b11 : 2'b00;
buzzer = (buzzer_en && blink);
end
S3: begin car_light = 2'b00; ped_light = 2'b00; end
S4: begin car_light = 2'b11; ped_light = 2'b00; end
S5: begin car_light = 2'b10; ped_light = 2'b00; end
S6: begin car_light = 2'b01; ped_light = 2'b00; end
S7: begin car_light = 2'b00; ped_light = 2'b00; end
endcase
end
always @(posedge clk or posedge rst) begin
if (rst) begin
timer <= 0;
end else begin
if (state != next_state) begin
case (next_state)
S2: timer <= BLINK_TIME;
S5: timer <= GREEN_TIME;
S6: timer <= YELLOW_TIME;
default: timer <= 0;
endcase
end
end
end
endmodule