DFF with Synchronous Reset

Solving Approach

How do you plan to solve it?

As it is synchronous so in sensitivity list only add clk and rst in case statements in always block.

Code

module dff_sync_reset (
    input  CLK,
    input  RST,
    input  D,
    output reg Q
);
    // Write your code here
    always @(posedge CLK) begin
        if(RST)
            Q = 1'b0;
        else
            Q <= D;
    end
    
endmodule

 

Upvote
Downvote

Testbench Code

`timescale 1ns/1ps

module tb_dff_sync_reset;
    // 1) Inputs
    reg CLK, RST, D;
    // 2) Outputs
    wire Q;
    // 3) Expected outputs (prefixed "expected_")
    reg  expected_Q;
    // 4) Mismatch (HIGH when outputs != expected)
    wire mismatch;

    // DUT
    dff_sync_reset dut(.CLK(CLK), .RST(RST), .D(D), .Q(Q));

    // Scoreboard: same sampling as DUT
    always @(posedge CLK) begin
        if (RST) expected_Q <= 1'b0;
        else     expected_Q <= D;
    end

    // 4-state compare
    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 — only Inputs -> Outputs -> Expected -> mismatch; start at #0
    initial begin
        $dumpfile("tb_dff_sync_reset.vcd");
        $dumpvars(0,
            tb_dff_sync_reset.CLK,
            tb_dff_sync_reset.RST,
            tb_dff_sync_reset.D,
            tb_dff_sync_reset.Q,
            tb_dff_sync_reset.expected_Q,
            tb_dff_sync_reset.mismatch
        );
        $dumpon;
    end

    // Drive inputs on negedge, check after next posedge
    task drive_and_check;
        input [127:0] name;
        input rst_v, d_v;
    begin
        @(negedge CLK);
        RST = rst_v;
        D   = d_v;
        @(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  RST=%b D=%b  Q=%b expected_Q=%b  t=%0t",
                         name, RST, D, Q, expected_Q, $time);
        end
        if (TOTAL_TEST_CASES == VCD_MAX_CASES) $dumpoff;
    end
    endtask

    // Optional between-edge change (no check; Q must hold)
    task change_between_edges;
        input rst_v, d_v;
    begin
        @(negedge CLK);
        RST = rst_v;
        D   = d_v;
    end
    endtask

    initial begin
        // Start with unknown expected like real silicon; first edge defines it
        RST = 1'b0; D = 1'b0; expected_Q = 1'bx;
        @(posedge CLK); #1;

        // Directed sequences
        drive_and_check("reset_clears" , 1'b1, 1'b1);
        drive_and_check("reset_still"  , 1'b1, 1'b0);
        drive_and_check("capture_one"  , 1'b0, 1'b1);
        drive_and_check("capture_zero" , 1'b0, 1'b0);

        // Show that between-edge changes don't affect until next edge
        change_between_edges(1'b0, 1'b1);
        drive_and_check("capture_after_change", 1'b0, 1'b1);

        // Exhaustive two-step edges over {RST,D}
        for (i=0; i<4; i=i+1) begin
            drive_and_check("prev_vec", i[1], i[0]);
            for (j=0; j<4; j=j+1)
                drive_and_check("next_vec", j[1], j[0]);
        end

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

        // 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