`timescale 1 ns / 1 ps
module TrafficLight
(
input button,
input clk,
output reg red1,
output reg green1,
output reg yellow1,
output reg red2,
output reg green2,
output reg yellow2,
output reg red3,
output reg green3,
output reg yellow3,
output reg red4,
output reg green4,
output reg yellow4
);
parameter RED_TIME1 = 6; // Thoi gian den do
parameter RED_TIME2 = 4;
parameter GREEN_TIME = 6; // Thoi gian den xanh
parameter YELLOW_TIME = 4; // Thoi gian den vang
parameter YELLOW_BLINK_TIME1 = 1;
parameter YELLOW_BLINK_TIME2 = 1;
reg [1:0] state1 = 2'b00;
reg [1:0] state2 = 2'b00;
reg [3:0] counter = 4'b0000;
// Dinh nghia trang thai cua he thong
parameter [1:0] RED_STATE1 = 2'b00;
parameter [1:0] RED_STATE2 = 2'b01;
parameter [1:0] GREEN_STATE = 2'b10;
parameter [1:0] YELLOW_STATE = 2'b11;
parameter [1:0] YELLOW_BLINK_STATE1 = 2'b00;
parameter [1:0] YELLOW_BLINK_STATE2 = 2'b01;
// Dinh nghia trang thai button
parameter MODE1 = 1'b0;
parameter MODE2 = 1'b1;
always @(posedge clk) begin
case (button)
MODE1: begin
case (state1)
RED_STATE1: begin
counter <= counter + 1;
if(counter == ((RED_TIME1 * 1) - 1)) begin
counter <= 0;
state1 <= RED_STATE2;
end
end
RED_STATE2: begin
counter <= counter + 1;
if(counter == ((RED_TIME2 * 1) - 1)) begin
counter <= 0;
state1 <= GREEN_STATE;
end
end
GREEN_STATE: begin
counter <= counter + 1;
if(counter == ((GREEN_TIME * 1) - 1)) begin
counter <= 0;
state1 <= YELLOW_STATE;
end
end
YELLOW_STATE: begin
counter <= counter + 1;
if(counter == ((YELLOW_TIME * 1) - 1)) begin
counter <= 0;
state1 <= RED_STATE1;
end
end
endcase
end
MODE2: begin
case (state2)
YELLOW_BLINK_STATE1: begin
counter <= counter + 1;
if(counter == ((YELLOW_BLINK_TIME1 * 1) - 1)) begin
counter <= 0;
state2 <= YELLOW_BLINK_STATE2;
end
end
YELLOW_BLINK_STATE2: begin
counter <= counter + 1;
if(counter == ((YELLOW_BLINK_TIME2 * 1) - 1)) begin
counter <= 0;
state2 <= YELLOW_BLINK_STATE1;
end
end
endcase
end
endcase
end
always @(*) begin
case (button)
MODE1: begin
case (state1)
RED_STATE1: begin
red1 <= 1; red2 <= 0;
red3 <= 1; red4 <= 0;
yellow1 <= 0; yellow2 <= 0;
yellow3 <= 0; yellow4 <= 0;
green1 <= 0; green2 <= 1;
green3 <= 0; green4 <= 1;
end
RED_STATE2: begin
red1 <= 1; red2 <= 0;
red3 <= 1; red4 <= 0;
yellow1 <= 0; yellow2 <= 1;
yellow3 <= 0; yellow4 <= 1;
green1 <= 0; green2 <= 0;
green3 <= 0; green4 <= 0;
end
GREEN_STATE: begin
red1 <= 0; red2 <= 1;
red3 <= 0; red4 <= 1;
yellow1 <= 0; yellow2 <= 0;
yellow3 <= 0; yellow4 <= 0;
green1 <= 1; green2 <= 0;
green3 <= 1; green4 <= 0;
end
YELLOW_STATE: begin
red1 <= 0; red2 <= 1;
red3 <= 0; red4 <= 1;
yellow1 <= 1; yellow2 <= 0;
yellow3 <= 1; yellow4 <= 0;
green1 <= 0; green2 <= 0;
green3 <= 0; green4 <= 0;
end
endcase
end
MODE2: begin
case (state2)
YELLOW_BLINK_STATE1: begin
red1 <= 0; red2 <= 0;
red3 <= 0; red4 <= 0;
yellow1 <= 1; yellow2 <= 0;
yellow3 <= 1; yellow4 <= 0;
green1 <= 0; green2 <= 0;
green3 <= 0; green4 <= 0;
end
YELLOW_BLINK_STATE2: begin
red1 <= 0; red2 <= 0;
red3 <= 0; red4 <= 0;
yellow1 <= 0; yellow2 <= 1;
yellow3 <= 0; yellow4 <= 1;
green1 <= 0; green2 <= 0;
green3 <= 0; green4 <= 0;
end
endcase
end
endcase
end
endmodule
module SevenSegment (
input button,
input [3:0] time_led,
output [6:0] seg_display1,
output [6:0] seg_display2
);
reg [6:0] seg_data1; // Mang du lieu 7 doan
reg [6:0] seg_data2;
// Dinh nghia trang thai button
parameter MODE1 = 1'b0;
parameter MODE2 = 1'b1;
always @(*) begin
case (button)
MODE1: begin
// Chuyen doi thoi gian thanh du lieu 7 doan
case (time_led[3:0])
4'b0000: seg_data1 = 7'b0010000; // 9
4'b0001: seg_data1 = 7'b0000000; // 8
4'b0010: seg_data1 = 7'b1111000; // 7
4'b0011: seg_data1 = 7'b0000010; // 6
4'b0100: seg_data1 = 7'b0010010; // 5
4'b0101: seg_data1 = 7'b0011001; // 4
4'b0110: seg_data1 = 7'b0110000; // 3
4'b0111: seg_data1 = 7'b0100100; // 2
4'b1000: seg_data1 = 7'b1111001; // 1
4'b1001: seg_data1 = 7'b1000000; // 0
default: seg_data1 = 7'b1111111;
endcase
case (time_led[3:0])
4'b0000: seg_data2 = 7'b0010010; // 5
4'b0001: seg_data2 = 7'b0011001; // 4
4'b0010: seg_data2 = 7'b0110000; // 3
4'b0011: seg_data2 = 7'b0100100; // 2
4'b0100: seg_data2 = 7'b1111001; // 1
4'b0101: seg_data2 = 7'b1000000; // 0
4'b0110: seg_data2 = 7'b0110000; // 3
4'b0111: seg_data2 = 7'b0100100; // 2
4'b1000: seg_data2 = 7'b1111001; // 1
4'b1001: seg_data2 = 7'b1000000; // 0
default: seg_data2 = 7'b1111111;
endcase
end
MODE2: begin
seg_data1 = 7'b1111111;
seg_data2 = 7'b1111111;
end
endcase
end
assign seg_display1 = seg_data1; // Ket qua dau ra cua module la du lieu 7 doan
assign seg_display2 = seg_data2;
endmodule
`timescale 1 ms / 1 ms
module TrafficLight_tb;
reg button, clk;
wire red1, green1, yellow1, red2, green2, yellow2, red3, green3, yellow3, red4,
green4, yellow4;
reg [3:0] time_led = 0;
reg [4:0] time_mode = 0;
wire [6:0] seg_display1; // Output cua module LED 7 doan
wire [6:0] seg_display2;
TrafficLight UUT (
.button(button),
.clk(clk),
.red1(red1), .green1(green1), .yellow1(yellow1),
.red2(red2), .green2(green2), .yellow2(yellow2),
.red3(red3), .green3(green3), .yellow3(yellow3),
.red4(red4), .green4(green4), .yellow4(yellow4)
);
SevenSegment seg_display_module (
.button(button),
.time_led(time_led),
.seg_display1(seg_display1),
.seg_display2(seg_display2)
);
initial begin
clk = 0;
button = 0;
#500;
forever #500 clk = ~clk;
end
always @(posedge clk) begin
time_mode <= time_mode + 1;
if(time_mode == 19) begin
time_mode <= 0;
button = ~button;
end
$display("Time = %t: Red1 = %b, Green1 = %b, Yellow1 = %b, Red2 = %b,
Green2 = %b, Yellow2 = %b, Red3 = %b, Green3 = %b, Yellow3 = %b, Red4 = %b,
Green4 = %b, Yellow4 = %b",
$time, red1, green1, yellow1, red2, green2, yellow2, red3, green3, yellow3,
red4, green4, yellow4);
time_led <= time_led + 1;
if(time_led == 9) begin
time_led <= 0;
end
$display("Time = %t: 7-Segment Display 1: %b, 7-Segment Display 2: %b",
$time, seg_display1, seg_display2);
end
initial begin
#50000; // Thời gian kết thúc testbench
$finish;
end
endmodule