tb_traffic_light_fsm

Modified

2025-11-11

Source: Lab3Extra/tb_traffic_light_fsm.sv (modified 2025-11-09 23:34)

// tb_traffic_light_fsm.sv
// Simple TB to verify the 5-second all-red intervals.

`timescale 1ns/1ps

module tb_TrafficLightFSM;

    // clock: 100MHz for TB convenience (10ns period)
    logic clk = 0;
    always #5 clk = ~clk;

    // reset
    logic rst_n;

    // DUT outputs
    logic [2:0] LA, LB;

    // Instantiate with tiny "seconds" for fast sim:
    // We define TICK_HZ = CLK_HZ / 10 so that each "second" == 10 cycles (i.e., 100ns)
    localparam int CLK_HZ_TB  = 100_000_000; // matches our 10ns period
    localparam int TICK_HZ_TB = CLK_HZ_TB / 10; // 10 cycles per "second"

    TrafficLightFSM #(
        .CLK_HZ   (CLK_HZ_TB),
        .TICK_HZ  (TICK_HZ_TB),
        .T_A_GREEN(4),   // "4 seconds"
        .T_A_YEL  (2),
        .T_B_GREEN(4),
        .T_B_YEL  (2),
        .T_ALL_RED(5)    // <-- critical: both-red for 5 "seconds"
    ) dut (
        .clk  (clk),
        .rst_n(rst_n),
        .LA   (LA),
        .LB   (LB)
    );

    // Stimulus
    initial begin
        // init reset
        rst_n = 0;
        repeat (5) @(posedge clk);
        rst_n = 1;

        // run long enough to see several cycles, including two ALL-RED intervals
        // Each "second" is 10 cycles; one full cycle ~ (4+2+5+4+2+5)=22 "seconds" => 220 cycles
        // Run for, say, 6000ns (~600 cycles) to be safe.
        #60000; // 60 us
        $finish;
    end

    // Optional: monitors
    initial begin
        $display("time\tLA\tLB");
        forever begin
            @(posedge clk);
            $display("%0t\t%b\t%b", $time, LA, LB);
        end
    end

endmodule