All submissions

Solving Approach

How do you plan to solve it?

 

Code

module t_ff (
    input  CLK,
    input  T,
    output reg Q
);
// Write your code here

always @(posedge CLK) begin

    if(T==0) Q<=Q;

    else Q<=~Q;
end

endmodule

 

Testbench Code

`timescale 1ns/1ps

module tb_t_ff;
    // 1) Inputs
    reg CLK, T;
    // 2) Output
    wire Q;
    // 3) Expected output (prefixed "expected_")
    reg  expected_Q;
    // 4) Mismatch (HIGH when outputs != expected)
    wire mismatch;

    // DUT
    t_ff dut(.CLK(CLK), .T(T), .Q(Q));

    // Scoreboard mirrors DUT at posedge
    always @(posedge CLK) begin
        if (T) expected_Q <= ~expected_Q;
        else   expected_Q <= expected_Q;
    end

    assign mismatch = (Q !== expected_Q);

    // Counters / limits
    integer TOTAL_TEST_CASES        = 0;
    integer TOTAL_PASSED_TEST_CASES = 0;
    integer TOTAL_FAILED_TEST_CASES = 0;
    integer VCD_MAX_CASES           = 32;
    integer ERROR_MAX_CASES         = 32;

    integer i, j;

    // Free-running clock (10 time-unit period)
    initial begin
        CLK = 1'b0;
        forever #5 CLK = ~CLK;
    end

    // VCD — Inputs -> Outputs -> Expected -> mismatch; start at #0
    initial begin
        $dumpfile("tb_t_ff.vcd");
        $dumpvars(0,
            tb_t_ff.CLK,
            tb_t_ff.T,
            tb_t_ff.Q,
            tb_t_ff.expected_Q,
            tb_t_ff.mismatch
        );
        $dumpon;
    end

    // Seed the flop to avoid permanent X (no reset in DUT)
    task seed_known_state;
    begin
        expected_Q = 1'b0;
        force tb_t_ff.dut.Q = 1'b0; // seed DUT state
        #1;
        release tb_t_ff.dut.Q;
        @(posedge CLK); #1;         // re-sample a known state
    end
    endtask

    // Drive T on negedge; check after next posedge
    task drive_and_check;
        input [127:0] name;
        input t_val;
    begin
        @(negedge CLK);
        T = t_val;
        @(posedge CLK); #1;

        TOTAL_TEST_CASES = TOTAL_TEST_CASES + 1;
        if (!mismatch) begin
            TOTAL_PASSED_TEST_CASES = TOTAL_PASSED_TEST_CASES + 1;
        end else begin
            TOTAL_FAILED_TEST_CASES = TOTAL_FAILED_TEST_CASES + 1;
            if (TOTAL_FAILED_TEST_CASES <= ERROR_MAX_CASES)
                $display("[FAIL] %0s  T=%b  Q=%b expected_Q=%b  t=%0t",
                         name, T, Q, expected_Q, $time);
        end

        if (TOTAL_TEST_CASES == VCD_MAX_CASES) $dumpoff;
    end
    endtask

    // Compact edge table (from current state)
    task print_edge_table;
        integer tv;
        reg curQ, nxtQ;
    begin
        curQ = expected_Q;
        $display(" T | EXP_Q_after_↑CLK");
        $display("---------------------");
        for (tv=0; tv<2; tv=tv+1) begin
            nxtQ = (tv[0]) ? ~curQ : curQ;
            $display(" %0d |        %0d", tv[0], nxtQ);
        end
    end
    endtask

    initial begin
        // Initialize inputs
        T = 1'b0;

        // Seed DUT/scoreboard to a known state (no reset in module)
        seed_known_state();

        // Directed
        drive_and_check("hold"   , 1'b0);
        drive_and_check("toggle" , 1'b1);
        drive_and_check("toggle2", 1'b1);
        drive_and_check("hold2"  , 1'b0);

        // Two-step sequences
        for (i=0; i<2; i=i+1) begin
            drive_and_check("prev_edge", i[0]);
            for (j=0; j<2; j=j+1)
                drive_and_check("next_edge", j[0]);
        end

        // Random stress
        for (i=0; i<10; i=i+1)
            drive_and_check("rand", $random);

        // Edge table
        print_edge_table();

        // Summary
        $display("TOTAL_TEST_CASES=%0d",        TOTAL_TEST_CASES);
        $display("TOTAL_PASSED_TEST_CASES=%0d", TOTAL_PASSED_TEST_CASES);
        $display("TOTAL_FAILED_TEST_CASES=%0d", TOTAL_FAILED_TEST_CASES);
        $display("ALL_TEST_CASES_PASSED=%s",    (TOTAL_FAILED_TEST_CASES==0) ? "true" : "false");

        #2 $finish;
    end
endmodule