dakies/OSS_Verilog huggingface dataset:
module jk_flip_flop_behavioral (
    input       clk,        // Clock
    input       j,          // Inputs
    input       k,          // 
    output reg  q,          // Output
    output      qbar);      //

    // INTERNAL WIRES
    assign qbar = ~q;

    always @(posedge clk) begin
        case({j,k})
            2'b0_0 : q <= q;
            2'b0_1 : q <= 1'b0;
            2'b1_0 : q <= 1'b1;
            2'b1_1 : q <= ~q;
        endcase
    end

endmodule
module jk_flip_flop_pos_edge_sync_clear_behavioral (
    input       clk,        // Clock
    input       clrbar,     // Clear
    input       j,          // Inputs
    input       k,          // 
    output reg  q,          // Output
    output      qbar        //
);

    parameter  NOCHANGE   = 2'b0_0,
               RESET      = 2'b0_1,
               SET        = 2'b1_0,
               TOGGLE     = 2'b1_1;

    assign qbar = ~q;

    // JK FLIP-FLOP WITH SYNC CLEAR
    always @ (posedge clk) begin
        if (~clrbar) begin
            q <= 1'b0;
        end else begin
            case({j,k})
                NOCHANGE : q <= q;
                RESET    : q <= 1'b0;
                SET      : q <= 1'b1;
                TOGGLE   : q <= ~q;
            endcase
        end
    end

endmodule
module jk_flip_flop_pulse_triggered_gate (
    input       clk,        // Clock
    input       j,          // Inputs
    input       k,          // 
    output      q,          // Output
    output      qbar);      //

    // INTERNAL WIRES
    wire        clk2;
    wire        s1, r1;
    wire        s2, r2;
    wire        q1, q1bar;

    // JK FLIP FLOP 1 -----------------------------------

        // NAND7
        nand (s1, j, clk, qbar);

        // NAND8
        nand (r1, k, clk, q);

        // SR- LATCH -------------------------------------
        
        // NAND6
        nand (q1, s1, q1bar);

        // NAND6
        nand (q1bar, r1, q1);

    // JK FLIP FLOP 2 -----------------------------------

        // NAND3
        nand (s2, q1, clk2);

        // NAND4
        nand (r2, q1bar, clk2);

        // SR- LATCH -------------------------------------
        
        // NAND1
        nand (q, s2, qbar);

        // NAND2
        nand (qbar, r2, q);

    // CLOCK -------------------------------------------

        not (clk2, clk);

endmodule
module jk_flip_flop_pulse_triggered_dataflow (
    input       clk,        // Clock
    input       j,          // Inputs
    input       k,          // 
    output      q,          // Output
    output      qbar);      //

    // JK FLIP FLOP 1 -----------------------------------

        // NAND7
        assign s1 = ~(j & clk & qbar);

        // NAND8
        assign r1 = ~(k & clk & q);

        // SR- LATCH -------------------------------------
        
        // NAND6
        assign q1 = ~(s1 & q1bar);

        // NAND6
        assign q1bar = ~(r1 & q1);

    // JK FLIP FLOP 2 -----------------------------------

        // NAND3
        assign s2 = ~(q1 & clk2);

        // NAND4
        assign r2 = ~(q1bar & clk2);

        // SR- LATCH -------------------------------------
        
        // NAND1
        assign q = ~(s2 & qbar);

        // NAND2
        assign qbar = ~(r2 & q);

    // CLOCK -------------------------------------------

        assign clk2 = ~(clk);

endmodule
module jk_flip_flop_pulse_triggered_behavioral (
    input       clk,        // Clock
    input       j,          // Inputs
    input       k,          // 
    output reg  q,          // Output
    output      qbar);      //

    // INTERNAL WIRES
    assign qbar = ~q;

    always @(posedge clk) begin
        case({j,k})
            2'b0_0 : q <= q;
            2'b0_1 : q <= 1'b0;
            2'b1_0 : q <= 1'b1;
            2'b1_1 : q <= ~q;
        endcase
    end

endmodule
module sr_flip_flop_gate (
    input       clk,        // Clock
    input       s,          // Inputs
    input       r,          // 
    output      q,          // Output
    output      qbar);      //

    // INTERNAL WIRES
    wire        s1, r1;
  
    // NAND3
    nand (s1, s, clk);

    // NAND4
    nand (r1, r, clk);

    // SR- LATCH -------------------------------------
    
    // NAND1
    nand (q, s1, qbar);

    // NAND2
    nand (qbar, r1, q);

endmodule
module sr_flip_flop_dataflow (
    input       clk,        // Clock
    input       s,          // Inputs
    input       r,          // 
    output      q,          // Output
    output      qbar);      //

    // INTERNAL WIRES
    wire        s1, r1;
  
    // NAND3
    assign s1 = ~(s & clk);

    // NAND4
    assign r1 = ~(r & clk);

    // SR- LATCH -------------------------------------
    
    // NAND1
    assign q = ~(s1 & qbar);

    // NAND2
    assign qbar = ~(r1 & q);

endmodule
module sr_flip_flop_behavioral (
    input       clk,        // Clock
    input       s,          // Inputs
    input       r,          // 
    output reg  q,          // Output
    output      qbar);      //

    // INTERNAL WIRES
    assign qbar = ~q;

    always @(posedge clk) begin
        case({s,r})
            2'b0_0 : q <= q;
            2'b0_1 : q <= 1'b0;
            2'b1_0 : q <= 1'b1;
            2'b1_1 : q <= 1'bx;
        endcase
    end

endmodule
module d_flip_flop_gate (
    input       clk,        // Clock
    input       d,          // Inputs
    output      q,          // Output
    output      qbar);      //

    // INTERNAL WIRES
    wire        s, r;
    wire        s1, r1;
  
    assign s = d;
  
    // NOT1
    not (r, s);

    // SR FLIP-FLOP ---------------------------------

    // NAND3
    nand (s1, s, clk);

    // NAND4
    nand (r1, r, clk);

    // SR-LATCH -------------------------------------
    
    // NAND1
    nand (q, s1, qbar);

    // NAND2
    nand (qbar, r1, q);

endmodule
module d_flip_flop_dataflow (
    input       clk,        // Clock
    input       d,          // Inputs
    output      q,          // Output
    output      qbar);      //

    assign s = d;
    assign r = ~d;

    // SR FLIP-FLOP ---------------------------------

    // INTERNAL WIRES
    wire        s1, r1;
  
    // NAND3
    assign s1 = ~(s & clk);

    // NAND4
    assign r1 = ~(r & clk);

    // SR- LATCH -------------------------------------
    
    // NAND1
    assign q = ~(s1 & qbar);

    // NAND2
    assign qbar = ~(r1 & q);

endmodule
module d_flip_flop_behavioral (
    input       clk,        // Clock
    input       d,          // Inputs
    output reg  q,          // Output
    output      qbar);      //

    parameter    DATA0 = 1'b0,
                 DATA1 = 1'b1;

    // INTERNAL WIRES
    assign qbar = ~q;

    always @(posedge clk) begin
        case({d})
            DATA0 : q <= 1'b0;
            DATA1 : q <= 1'b1;
        endcase
    end

endmodule
module t_flip_flop_gate (
    input       clk,        // Clock
    input       t,          // Inputs
    output      q,          // Output
    output      qbar);      //

    // INTERNAL WIRES
    wire        j, k;
    wire        s, r;

    assign j = t;
    assign k = t;

    // JK FLIP-FLOP -----------------------------------

    // NAND3
    nand (s, j, clk, qbar);

    // NAND4
    nand (r, k, clk, q);

    // SR- LATCH -------------------------------------
    
    // NAND1
    nand (q, s, qbar);

    // NAND2
    nand (qbar, r, q);

endmodule
module t_flip_flop_dataflow (
    input       clk,        // Clock
    input       t,          // Inputs
    output      q,          // Output
    output      qbar);      //

    // INTERNAL WIRES
    wire        s, r;

    // JK FLIP-FLOP -----------------------------------
  
    // NAND3
    assign s = ~(t & clk & qbar);

    // NAND4
    assign r = ~(t & clk & q);

    // SR- LATCH -------------------------------------
    
    // NAND1
    assign q = ~(s & qbar);

    // NAND2
    assign qbar = ~(r & q);

endmodule
module t_flip_flop_behavioral (
    input       clk,        // Clock
    input       t,          // Inputs
    output reg  q,          // Output
    output      qbar);      //

    parameter   HOLD   = 1'b0,
                TOGGLE = 1'b1;

    // INTERNAL WIRES
    assign qbar = ~q;

    always @(posedge clk) begin
        case({t})
            HOLD :    q <= q;
            TOGGLE :  q <= ~q;
        endcase
    end

endmodule
module d_flip_flop_pulse_triggered_gate (
    input       clk,        // Clock
    input       d,          // Inputs
    output      q,          // Output
    output      qbar);      //

    // INTERNAL WIRES
    wire        clk1;

    //NOT 3  
    not (clk1, clk);

    // D-FLIP FLOP (BOSS)

        // INTERNAL WIRES
        wire        s1, r1;
        wire        s2, r2;
      
        assign s1 = d;
      
        // NOT2
        not (r1, s1);

        // SR FLIP-FLOP ---------------------------------

        // NAND7
        nand (s2, s1, clk1);

        // NAND8
        nand (r2, r1, clk1);

        // SR-LATCH -------------------------------------
        
        // NAND5
        nand (q1, s2, q1bar);

        // NAND6
        nand (q1bar, r2, q1);

    // D-FLIP FLOP (WORKER)

        // INTERNAL WIRES
        wire        s3, r3;
        wire        s4, r4;
      
        assign s3 = q1;
      
        // NOT1
        not (r3, s3);

        // SR FLIP-FLOP ---------------------------------

        // NAND3
        nand (s4, s3, clk1);

        // NAND4
        nand (r4, r3, clk1);

        // SR-LATCH -------------------------------------
        
        // NAND1
        nand (q, s4, qbar);

        // NAND2
        nand (qbar, r4, q);

endmodule
module d_flip_flop_pulse_triggered_dataflow (
    input       clk,        // Clock
    input       d,          // Inputs
    output      q,          // Output
    output      qbar);      //

    // INTERNAL WIRES
    wire        clk1;

    // NOT3  
    assign clk1 = ~clk;

    // D-FLIP FLOP (BOSS)

        // INTERNAL WIRES
        wire        s1, r1;
        wire        s2, r2;
      
        assign s1 = d;
      
        // NOT2
        assign r1 = ~s1;

        // SR FLIP-FLOP ---------------------------------

        // NAND7
        assign s2 = ~(s1 & clk1);

        // NAND8
        assign r2 = ~(r1 & clk1);

        // SR-LATCH -------------------------------------
        
        // NAND5
        assign q1 = ~( s2 & q1bar);

        // NAND6
        assign q1bar = ~(r2 & q1);

    // D-FLIP FLOP (WORKER)

        // INTERNAL WIRES
        wire        s3, r3;
        wire        s4, r4;
      
        assign s3 = q1;
      
        // NOT1
        assign r3 = ~s3;

        // SR FLIP-FLOP ---------------------------------

        // NAND3
        assign s4 = ~(s3 & clk1);

        // NAND4
        assign r4 = ~(r3 & clk1);

        // SR-LATCH -------------------------------------
        
        // NAND1
        assign q = ~(s4 & qbar);

        // NAND2
        assign qbar = ~(r4 & q);

endmodule
module d_flip_flop_pulse_triggered_behavioral (
    input       clk,        // Clock
    input       d,          // Inputs
    output reg  q,          // Output
    output      qbar);      //

    parameter    DATA0 = 1'b0,
                 DATA1 = 1'b1;

    // INTERNAL WIRES
    assign qbar = ~q;

    always @(posedge clk) begin
        case({d})
            DATA0 : q <= 1'b0;
            DATA1 : q <= 1'b1;
        endcase
    end

endmodule
module jeff_74x151_behavioral(
    input                d0,                  // DATA IN
    input                d1,                  // 
    input                d2,                  // 
    input                d3,                  // 
    input                d4,                  // 
    input                d5,                  // 
    input                d6,                  // 
    input                d7,                  // 
    input                a,                   // SELECT
    input                b,                   // 
    input                c,                   // 
    input                en,                  // ENABLE
    output reg           y,                   // DATA OUT
    output               w                    // INVERTED OUTPUT
);

    assign w = ~y;

    // ALWAYS BLOCK with NON-BLOCKING PROCEDURAL ASSIGNMENT STATEMENT
    always @ ( * ) begin
        if (en) begin
            case({c,b,a})
                3'b000 : y <= d0;
                3'b001 : y <= d1;
                3'b010 : y <= d2;
                3'b011 : y <= d3;
                3'b100 : y <= d4;
                3'b101 : y <= d5;
                3'b110 : y <= d6;
                3'b111 : y <= d7;
            endcase
        end else begin
            y <= 1'b1;
        end
    end

endmodule
module JEFF_74x151_TB;

    // DATA TYPES - DECLARE REGISTERS AND WIRES (PROBES)
    reg  [7:0]      D;
    reg  [2:0]      SEL;
    reg             EN;
    wire            Y;
    wire            W;

    // FOR TESTING  
    reg             TICK;
    reg [31:0]      VECTORCOUNT, ERRORS;
    reg             YEXPECTED;
    integer         FD, COUNT;
    reg [8*32-1:0]  COMMENT;

    // UNIT UNDER TEST (behavioral)
    jeff_74x151_behavioral UUT_jeff_74x151_behavioral(
        .d0(D[0]), .d1(D[1]), .d2(D[2]), .d3(D[3]), .d4(D[4]), .d5(D[5]), .d6(D[6]), .d7(D[7]),
        .a(SEL[0]), .b(SEL[1]), .c(SEL[2]),
        .en(EN),
        .y(Y), .w(W)
    );

    // SAVE EVERYTHING FROM TOP TB MODULE IN A DUMP FILE
    initial begin
        $dumpfile("jeff_74x151_tb.vcd");
        $dumpvars(0, JEFF_74x151_TB);
    end

    // TICK PERIOD
    localparam TICKPERIOD = 20;

    // TICK
    always begin
        #(TICKPERIOD/2) TICK = ~TICK;
    end

    // INITIALIZE TESTBENCH
    initial begin

        // OPEN VECTOR FILE - THROW AWAY FIRST LINE
        FD=$fopen("jeff_74x151_tb.tv","r");
        COUNT = $fscanf(FD, "%s", COMMENT);
        // $display ("FIRST LINE IS: %s", COMMENT);

        // INIT TESTBENCH
        COUNT = $fscanf(FD, "%s %b %b %b %b", COMMENT, EN, SEL, D, YEXPECTED);
        TICK = 0;
        VECTORCOUNT = 1;
        ERRORS = 0;

        // DISPAY OUTPUT AND MONITOR
        $display();
        $display("TEST START --------------------------------");
        $display();
        $display("                 | TIME(ns) | EN | SEL | D        | Y |");
        $display("                 --------------------------------------");
        // $monitor("%4d  %10s | %8d | %1b  | %1b | %1b | %1b |", VECTORCOUNT, COMMENT, $time, EN, SEL, D, Y);

    end

    // APPLY TEST VECTORS ON NEG EDGE TICK (ADD DELAY)
    always @(negedge TICK) begin

        // WAIT A BIT (AFTER CHECK)
        #5;

        // GET VECTORS FROM TB FILE
        COUNT = $fscanf(FD, "%s %b %b %b %b", COMMENT, EN, SEL, D, YEXPECTED);

        // CHECK IF EOF - PRINT SUMMARY, CLOSE VECTOR FILE AND FINISH TB
        if (COUNT == -1) begin
            $fclose(FD);
            $display();
            $display(" VECTORS: %4d", VECTORCOUNT);
            $display("  ERRORS: %4d", ERRORS);
            $display();
            $display("TEST END ----------------------------------");
            $display();
            $finish;
        end

        // GET ANOTHER VECTOR
        VECTORCOUNT = VECTORCOUNT + 1;

    end

    // CHECK TEST VECTORS ON POS EGDE TICK
    always @(posedge TICK) begin

        // WAIT A BIT
        #5;

        // DISPLAY OUTPUT ON POS EDGE TICK
        $display("%4d  %10s | %8d | %1b  | %1b | %1b | %1b |", VECTORCOUNT, COMMENT, $time, EN, SEL, D, Y);

        // CHECK EACH VECTOR RESULT
        if (Y !== YEXPECTED) begin
            $display("***ERROR (behavioral) - Expected Y = %b", YEXPECTED);
            ERRORS = ERRORS + 1;
        end

    end   

endmodule
module DEMUX_4x1_TB;

    // DATA TYPES - DECLARE REGISTERS AND WIRES (PROBES)
    reg             Y;
    reg [1:0]       SEL;
    wire            A, B, C, D;

    // FOR TESTING  
    reg             TICK;
    reg [31:0]      VECTORCOUNT, ERRORS;
    reg             AEXP, BEXP, CEXP, DEXP;
    integer         FD, COUNT;
    reg [8*32-1:0]  COMMENT;

    // UNIT UNDER TEST (behavioral)
    demux_1x4_behavioral UUT_demux_1x4_behavioral(
        .y(Y),
        .sel(SEL),
        .a(A), .b(B), .c(C), .d(D)
    );

    // SAVE EVERYTHING FROM TOP TB MODULE IN A DUMP FILE
    initial begin
        $dumpfile("demux_1x4_tb.vcd");
        $dumpvars(0, DEMUX_4x1_TB);
    end

    // TICK PERIOD
    localparam TICKPERIOD = 20;

    // TICK
    always begin
        #(TICKPERIOD/2) TICK = ~TICK;
    end

    // INITIALIZE TESTBENCH
    initial begin

        // OPEN VECTOR FILE - THROW AWAY FIRST LINE
        FD=$fopen("demux_1x4_tb.tv","r");
        COUNT = $fscanf(FD, "%s", COMMENT);
        // $display ("FIRST LINE IS: %s", COMMENT);

        // INIT TESTBENCH
        COUNT = $fscanf(FD, "%s %b %b %b %b %b %b", COMMENT, SEL, Y, AEXP, BEXP, CEXP, DEXP);
        TICK = 0;
        VECTORCOUNT = 1;
        ERRORS = 0;

        // DISPAY OUTPUT AND MONITOR
        $display();
        $display("TEST START --------------------------------");
        $display();
        $display("                 | TIME(ns) | SEL | Y | A | B | C | D |");
        $display("                 --------------------------------------");
        // $monitor("%4d  %10s | %8d | %1b  | %1b | %1b | %1b | %1b | %1b |", VECTORCOUNT, COMMENT, $time, SEL, Y, A, B, C, D);

    end

    // APPLY TEST VECTORS ON NEG EDGE TICK (ADD DELAY)
    always @(negedge TICK) begin

        // WAIT A BIT (AFTER CHECK)
        #5;

        // GET VECTORS FROM TB FILE
        COUNT = $fscanf(FD, "%s %b %b %b %b %b %b", COMMENT, SEL, Y, AEXP, BEXP, CEXP, DEXP);

        // CHECK IF EOF - PRINT SUMMARY, CLOSE VECTOR FILE AND FINISH TB
        if (COUNT == -1) begin
            $fclose(FD);
            $display();
            $display(" VECTORS: %4d", VECTORCOUNT);
            $display("  ERRORS: %4d", ERRORS);
            $display();
            $display("TEST END ----------------------------------");
            $display();
            $finish;
        end

        // GET ANOTHER VECTOR
        VECTORCOUNT = VECTORCOUNT + 1;

    end

    // CHECK TEST VECTORS ON POS EGDE TICK
    always @(posedge TICK) begin

        // WAIT A BIT
        #5;

        // DISPLAY OUTPUT ON POS EDGE TICK
        $display("%4d  %10s | %8d | %1b  | %1b | %1b | %1b | %1b | %1b |", VECTORCOUNT, COMMENT, $time, SEL, Y, A, B, C, D);

        // CHECK EACH VECTOR RESULT
        if ((A !== AEXP) | (B !== BEXP) | (C !== CEXP) | (D !== DEXP)) begin
            $display("***ERROR (behavioral) - Expected A=%b, B=%b, C=%b, D=%b", AEXP, BEXP, CEXP, DEXP);
            ERRORS = ERRORS + 1;
        end

    end   

endmodule
module demux_1x4_behavioral(
    input       y,               // 1 Input
    input       [1:0] sel,       // Select
    output reg  a, b, c, d);     // 4 Outputs

    // ALWAYS BLOCK with NON-BLOCKING PROCEDURAL ASSIGNMENT STATEMENT
    always @ ( * ) begin
        case(sel)
            2'b00 : begin
                a <= y; b <= 0; c <= 0; d <= 0;
            end
            2'b01 : begin
                a <= 0; b <= y; c <= 0; d <= 0;
            end
            2'b10 : begin
                a <= 0; b <= 0; c <= y; d <= 0;
            end
            2'b11 : begin
                a <= 0; b <= 0; c <= 0; d <= y;
            end
        endcase
    end

endmodule
module JEFF_74x157_TB;

    // DATA TYPES - DECLARE REGISTERS AND WIRES (PROBES)
    reg  [3:0]      A, B;
    reg             S;
    reg             EN;
    wire [3:0]      Y;

    // FOR TESTING  
    reg             TICK;
    reg  [31:0]     VECTORCOUNT, ERRORS;
    reg  [3:0]      YEXPECTED;
    integer         FD, COUNT;
    reg [8*32-1:0]  COMMENT;

    // UNIT UNDER TEST (behavioral)
    jeff_74x157_behavioral UUT_jeff_74x157_behavioral(
        .a(A), .b(B),
        .s(S),
        .en(EN),
        .y(Y)
    );

    // SAVE EVERYTHING FROM TOP TB MODULE IN A DUMP FILE
    initial begin
        $dumpfile("jeff_74x157_tb.vcd");
        $dumpvars(0, JEFF_74x157_TB);
    end

    // TICK PERIOD
    localparam TICKPERIOD = 20;

    // TICK
    always begin
        #(TICKPERIOD/2) TICK = ~TICK;
    end

    // INITIALIZE TESTBENCH
    initial begin

        // OPEN VECTOR FILE - THROW AWAY FIRST LINE
        FD=$fopen("jeff_74x157_tb.tv","r");
        COUNT = $fscanf(FD, "%s", COMMENT);
        // $display ("FIRST LINE IS: %s", COMMENT);

        // INIT TESTBENCH
        COUNT = $fscanf(FD, "%s %b %b %b %b %b", COMMENT, EN, S, A, B, YEXPECTED);
        TICK = 0;
        VECTORCOUNT = 1;
        ERRORS = 0;

        // DISPAY OUTPUT AND MONITOR
        $display();
        $display("TEST START --------------------------------");
        $display();
        $display("                 | TIME(ns) | EN | S |  A   |  B   |  Y   |");
        $display("                 ------------------------------------------");
        // $monitor("%4d  %10s | %8d | %1b  | %1b | %1b | %1b | %1b |", VECTORCOUNT, COMMENT, $time, EN, S, A, B, Y);

    end

    // APPLY TEST VECTORS ON NEG EDGE TICK (ADD DELAY)
    always @(negedge TICK) begin

        // WAIT A BIT (AFTER CHECK)
        #5;

        // GET VECTORS FROM TB FILE
        COUNT = $fscanf(FD, "%s %b %b %b %b %b", COMMENT, EN, S, A, B, YEXPECTED);

        // CHECK IF EOF - PRINT SUMMARY, CLOSE VECTOR FILE AND FINISH TB
        if (COUNT == -1) begin
            $fclose(FD);
            $display();
            $display(" VECTORS: %4d", VECTORCOUNT);
            $display("  ERRORS: %4d", ERRORS);
            $display();
            $display("TEST END ----------------------------------");
            $display();
            $finish;
        end

        // GET ANOTHER VECTOR
        VECTORCOUNT = VECTORCOUNT + 1;

    end

    // CHECK TEST VECTORS ON POS EGDE TICK
    always @(posedge TICK) begin

        // WAIT A BIT
        #5;

        // DISPLAY OUTPUT ON POS EDGE TICK
        $display("%4d  %10s | %8d | %1b  | %1b | %1b | %1b | %1b |", VECTORCOUNT, COMMENT, $time, EN, S, A, B, Y);

        // CHECK EACH VECTOR RESULT
        if (Y !== YEXPECTED) begin
            $display("***ERROR (behavioral) - Expected Y = %b", YEXPECTED);
            ERRORS = ERRORS + 1;
        end

    end   

endmodule
module jeff_74x157_behavioral(
    input       [3:0] a,            // INPUT DATA A
    input       [3:0] b,            // INPUT DATA B
    input             s,            // SELECT
    input             en,           // ENABLE
    output reg  [3:0] y             // OUTPUT DATA
);

    // ALWAYS BLOCK with NON-BLOCKING PROCEDURAL ASSIGNMENT STATEMENT
    always @ ( * ) begin
        if (~en) begin
            y <= 4'h0;
        end else begin
            case(s)
                1'b0 : y <= a;
                1'b1 : y <= b;
            endcase
        end
    end

endmodule
module mux_to_demux_structural(
    input           a1, b1, c1, d1,      // 4 Inputs
    input           [1:0] sel1,          // Select
    input           [1:0] sel2,          // Select
    output          a2, b2, c2, d2);     // 4 Outputs

    wire  y;

    // 4x1 MULTIPLEXER
    mux_4x1_behavioral MUX_4X1 (
        .a(a1), .b(b1), .c(c1), .d(d1),
        .sel(sel1),
        .y(y)
    );

    // 1x4 DEMULTIPLEXER
    demux_1x4_behavioral DEMUX_1X4 (
        .y(y),
        .sel(sel2),
        .a(a2), .b(b2), .c(c2), .d(d2)
    );

endmodule
module mux_4x1_behavioral(
    input       a, b, c, d,      // 4 Inputs
    input       [1:0] sel,       // Select
    output reg  y);              // 1 Output

    // ALWAYS BLOCK with NON-BLOCKING PROCEDURAL ASSIGNMENT STATEMENT
    always @ ( * ) begin
        case(sel)
            2'b00 : y <= a;
            2'b01 : y <= b;
            2'b10 : y <= c;
            2'b11 : y <= d;
        endcase
    end

endmodule
module MUX_4x1_TB;

    // DATA TYPES - DECLARE REGISTERS AND WIRES (PROBES)
    reg             A, B, C, D;
    reg [1:0]       SEL;
    wire            Y;

    // FOR TESTING  
    reg             TICK;
    reg [31:0]      VECTORCOUNT, ERRORS;
    reg             YEXPECTED;
    integer         FD, COUNT;
    reg [8*32-1:0]  COMMENT;

    // UNIT UNDER TEST (behavioral)
    mux_4x1_behavioral UUT_mux_4x1_behavioral(
        .a(A), .b(B), .c(C), .d(D),
        .sel(SEL),
        .y(Y)
    );

    // SAVE EVERYTHING FROM TOP TB MODULE IN A DUMP FILE
    initial begin
        $dumpfile("mux_4x1_tb.vcd");
        $dumpvars(0, MUX_4x1_TB);
    end

    // TICK PERIOD
    localparam TICKPERIOD = 20;

    // TICK
    always begin
        #(TICKPERIOD/2) TICK = ~TICK;
    end

    // INITIALIZE TESTBENCH
    initial begin

        // OPEN VECTOR FILE - THROW AWAY FIRST LINE
        FD=$fopen("mux_4x1_tb.tv","r");
        COUNT = $fscanf(FD, "%s", COMMENT);
        // $display ("FIRST LINE IS: %s", COMMENT);

        // INIT TESTBENCH
        COUNT = $fscanf(FD, "%s %b %b %b %b %b %b", COMMENT, SEL, A, B, C, D, YEXPECTED);
        TICK = 0;
        VECTORCOUNT = 1;
        ERRORS = 0;

        // DISPAY OUTPUT AND MONITOR
        $display();
        $display("TEST START --------------------------------");
        $display();
        $display("                 | TIME(ns) | SEL | A | B | C | D | Y |");
        $display("                 --------------------------------------");
        // $monitor("%4d  %10s | %8d | %1b  | %1b | %1b | %1b | %1b | %1b |", VECTORCOUNT, COMMENT, $time, SEL, A, B, C, D, Y);

    end

    // APPLY TEST VECTORS ON NEG EDGE TICK (ADD DELAY)
    always @(negedge TICK) begin

        // WAIT A BIT (AFTER CHECK)
        #5;

        // GET VECTORS FROM TB FILE
        COUNT = $fscanf(FD, "%s %b %b %b %b %b %b", COMMENT, SEL, A, B, C, D, YEXPECTED);

        // CHECK IF EOF - PRINT SUMMARY, CLOSE VECTOR FILE AND FINISH TB
        if (COUNT == -1) begin
            $fclose(FD);
            $display();
            $display(" VECTORS: %4d", VECTORCOUNT);
            $display("  ERRORS: %4d", ERRORS);
            $display();
            $display("TEST END ----------------------------------");
            $display();
            $finish;
        end

        // GET ANOTHER VECTOR
        VECTORCOUNT = VECTORCOUNT + 1;

    end

    // CHECK TEST VECTORS ON POS EGDE TICK
    always @(posedge TICK) begin

        // WAIT A BIT
        #5;

        // DISPLAY OUTPUT ON POS EDGE TICK
        $display("%4d  %10s | %8d | %1b  | %1b | %1b | %1b | %1b | %1b |", VECTORCOUNT, COMMENT, $time, SEL, A, B, C, D, Y);

        // CHECK EACH VECTOR RESULT
        if (Y !== YEXPECTED) begin
            $display("***ERROR (behavioral) - Expected Y = %b", YEXPECTED);
            ERRORS = ERRORS + 1;
        end

    end   

endmodule
module JEFF_74x181_TB;

    // DATA TYPES - DECLARE REGISTERS AND WIRES (PROBES)
    reg  [3:0]  A, B, S;
    reg         M, CI_BAR;
    wire [3:0]  F;
    wire        CO_BAR, AEQB, X, Y;

    // FOR TESTING  
    reg             TICK;
    reg [31:0]      VECTORCOUNT, ERRORS;
    reg [3:0]       FEXPECTED;
    integer         FD, COUNT;
    reg [8*32-1:0]  COMMENT;

    // UNIT UNDER TEST (dataflow)
    jeff_74x181 UUT_jeff_74x181(
        .a3(A[3]), .a2(A[2]), .a1(A[1]), .a0(A[0]),
        .b3(B[3]), .b2(B[2]), .b1(B[1]), .b0(B[0]),
        .s3(S[3]), .s2(S[2]), .s1(S[1]), .s0(S[0]),
        .m(M), .ci_bar(CI_BAR),
        .f3(F[3]), .f2(F[2]), .f1(F[1]), .f0(F[0]),
        .co_bar(CO_BAR), .aeqb(AEQB), .x(X), .y(Y)
    );

    // SAVE EVERYTHING FROM TOP TB MODULE IN A DUMP FILE
    initial begin
        $dumpfile("jeff_74x181_tb.vcd");
        $dumpvars(0, JEFF_74x181_TB);
    end

    // TICK PERIOD
    localparam TICKPERIOD = 20;

    // TICK
    always begin
        #(TICKPERIOD/2) TICK = ~TICK;
    end

    // INITIALIZE TESTBENCH
    initial begin

        // OPEN VECTOR FILE - THROW AWAY FIRST LINE
        FD=$fopen("jeff_74x181_tb.tv","r");
        COUNT = $fscanf(FD, "%s", COMMENT);
        // $display ("FIRST LINE IS: %s", COMMENT);

        // INIT TESTBENCH
        COUNT = $fscanf(FD, "%s %b %b %4b %4b %4b %4b", COMMENT, M, CI_BAR, S, A, B, FEXPECTED);
        TICK = 0;
        VECTORCOUNT = 1;
        ERRORS = 0;

        // DISPAY OUTPUT AND MONITOR
        $display();
        $display("TEST START --------------------------------");
        $display();
        $display("                       | TIME(ns) | M | CI_BAR |  S   |  A   |  B   |  F   |");
        $display("                       -----------------------------------------------------");
        // $monitor("%4d  %16s | %8d | %1b |   %1b    | %4b | %4b | %4b | %4b |", VECTORCOUNT, COMMENT, $time, M, CI_BAR, S, A, B, F);

    end

    // APPLY TEST VECTORS ON NEG EDGE TICK (ADD DELAY)
    always @(negedge TICK) begin

        // WAIT A BIT (AFTER CHECK)
        #5;

        // GET VECTORS FROM TB FILE
        COUNT = $fscanf(FD, "%s %b %b %4b %4b %4b %4b", COMMENT, M, CI_BAR, S, A, B, FEXPECTED);

        // CHECK IF EOF - PRINT SUMMARY, CLOSE VECTOR FILE AND FINISH TB
        if (COUNT == -1) begin
            $fclose(FD);
            $display();
            $display(" VECTORS: %4d", VECTORCOUNT);
            $display("  ERRORS: %4d", ERRORS);
            $display();
            $display("TEST END ----------------------------------");
            $display();
            $finish;
        end

        // GET ANOTHER VECTOR
        VECTORCOUNT = VECTORCOUNT + 1;

    end

    // CHECK TEST VECTORS ON POS EGDE TICK
    always @(posedge TICK) begin

        // WAIT A BIT
        #5;

        // DISPLAY OUTPUT ON POS EDGE TICK
        $display("%4d  %16s | %8d | %1b |   %1b    | %4b | %4b | %4b | %4b |", VECTORCOUNT, COMMENT, $time, M, CI_BAR, S, A, B, F);

        // CHECK EACH VECTOR RESULT
        if (F !== FEXPECTED) begin
            $display("***ERROR (gate) - Expected F = %b", FEXPECTED);
            ERRORS = ERRORS + 1;
        end

    end   

endmodule
module out_section_f2 (
    input   m_bar,
    input   ci_bar,
    input   input2_out1,
    input   input2_out2,
    input   input1_out1,
    input   input1_out2,
    input   input0_out1,
    input   input0_out2,
    output  f2);

assign f2 = ((input2_out1 ^ input2_out2) ^ ~((ci_bar & input0_out1 & input1_out1 & m_bar) | (input1_out1 & input0_out2 & m_bar) | (input1_out2 & m_bar)));

endmodule
module aeqb (   
    input   f3,
    input   f2,
    input   f1,
    input   f0,
    output  aeqb);

assign aeqb = (f3 & f2 & f1 & f0);

endmodule
module input_section (
    input   a,
    input   b,
    input   s3,
    input   s2,
    input   s1,
    input   s0,
    output  out1,
    output  out2);

assign out1 = ~((b & s3 & a) | (a & s2 & ~b));
assign out2 = ~((~b & s1) | (s0 & b) | (a));

endmodule
module invert_m (   
    input   a,
    output  y);

assign y = ~a;

endmodule
module out_section_f1 (
    input   m_bar,
    input   ci_bar,
    input   input1_out1,
    input   input1_out2,
    input   input0_out1,
    input   input0_out2,
    output  f1);

assign f1 = ((input1_out1 ^ input1_out2) ^ ~((ci_bar & input0_out1 & m_bar) | (input0_out2 & m_bar)));

endmodule
module out_section_f3 (
    input   m_bar,
    input   ci_bar,
    input   input3_out1,
    input   input3_out2,
    input   input2_out1,
    input   input2_out2,
    input   input1_out1,
    input   input1_out2,
    input   input0_out1,
    input   input0_out2,
    output  f3);

assign f3 = ((input3_out1 ^ input3_out2) ^ ~((ci_bar & input0_out1 & input1_out1 & input2_out1 & m_bar) | (input1_out1 & input2_out1 & input0_out2 & m_bar) | (input2_out1 & input1_out2 & m_bar) | (input2_out2 & m_bar)));

endmodule
module g_p_carry_section (
    input   input3_out1,
    input   input3_out2,
    input   input2_out1,
    input   input2_out2,
    input   input1_out1,
    input   input1_out2,
    input   input0_out1,
    input   input0_out2,
    input   ci_bar,
    output  co_bar,
    output  x,
    output  y);

assign y = ~((input3_out2) | (input3_out1 & input2_out2) | (input3_out1 & input2_out1 & input1_out2) | (input3_out1 & input2_out1 & input1_out1 & input0_out2));

assign co_bar = (~y | (input3_out1 & input2_out1 & input1_out1 & input0_out1 & ci_bar));

assign x = ~(input3_out1 & input2_out1 & input1_out1 & input0_out1);

endmodule
module out_section_f0 (
    input   m_bar,
    input   ci_bar,
    input   input0_out1,
    input   input0_out2,
    output  f0);

assign f0 = ((input0_out1 ^ input0_out2) ^ ~(ci_bar & m_bar));

endmodule
module encoder_8_3_behavioral(
    input      [7:0] in,    // 8 Inputs
    output reg [2:0] out);  // 3 Outputs

    // ALWAYS BLOCK with NON-BLOCKING PROCEDURAL ASSIGNMENT STATEMENT
    always @ ( * ) begin
        case(in)
            8'b00000001 : out <= 3'b000;
            8'b00000010 : out <= 3'b001;
            8'b00000100 : out <= 3'b010;
            8'b00001000 : out <= 3'b011;
            8'b00010000 : out <= 3'b100;
            8'b00100000 : out <= 3'b101;
            8'b01000000 : out <= 3'b110;
            8'b10000000 : out <= 3'b111;
            default     : out <= 3'b000;
        endcase
    end

endmodule
module ENCODER_8_3_TB;

    // DATA TYPES - DECLARE REGISTERS AND WIRES (PROBES)
    reg  [7:0]      IN;
    wire [2:0]      OUT;

    // FOR TESTING  
    reg             TICK;
    reg [31:0]      VECTORCOUNT, ERRORS;
    reg [2:0]       OUTEXPECTED;
    integer         FD, COUNT;
    reg [8*32-1:0]  COMMENT;

    // UNIT UNDER TEST (behavioral)
    encoder_8_3_behavioral UUT_encoder_8_3_behavioral(
        .in(IN),
        .out(OUT)
    );

    // SAVE EVERYTHING FROM TOP TB MODULE IN A DUMP FILE
    initial begin
        $dumpfile("encoder_8_3_tb.vcd");
        $dumpvars(0, ENCODER_8_3_TB);
    end

    // TICK PERIOD
    localparam TICKPERIOD = 20;

    // TICK
    always begin
        #(TICKPERIOD/2) TICK = ~TICK;
    end

    // INITIALIZE TESTBENCH
    initial begin

        // OPEN VECTOR FILE - THROW AWAY FIRST LINE
        FD=$fopen("encoder_8_3_tb.tv","r");
        COUNT = $fscanf(FD, "%s", COMMENT);
        // $display ("FIRST LINE IS: %s", COMMENT);

        // INIT TESTBENCH
        COUNT = $fscanf(FD, "%s %b %b", COMMENT, IN, OUTEXPECTED);
        TICK = 0;
        VECTORCOUNT = 1;
        ERRORS = 0;

        // DISPAY OUTPUT AND MONITOR
        $display();
        $display("TEST START --------------------------------");
        $display();
        $display("                 | TIME(ns) | IN  |   OUT    |");
        $display("                 -----------------------------");
        // $monitor("%4d  %10s | %8d | %1b | %1b |", VECTORCOUNT, COMMENT, $time, IN, OUT);

    end

    // APPLY TEST VECTORS ON NEG EDGE TICK (ADD DELAY)
    always @(negedge TICK) begin

        // WAIT A BIT (AFTER CHECK)
        #5;

        // GET VECTORS FROM TB FILE
        COUNT = $fscanf(FD, "%s %b %b %b", COMMENT, IN, OUTEXPECTED);

        // CHECK IF EOF - PRINT SUMMARY, CLOSE VECTOR FILE AND FINISH TB
        if (COUNT == -1) begin
            $fclose(FD);
            $display();
            $display(" VECTORS: %4d", VECTORCOUNT);
            $display("  ERRORS: %4d", ERRORS);
            $display();
            $display("TEST END ----------------------------------");
            $display();
            $finish;
        end

        // GET ANOTHER VECTOR
        VECTORCOUNT = VECTORCOUNT + 1;

    end

    // CHECK TEST VECTORS ON POS EGDE TICK
    always @(posedge TICK) begin

        // WAIT A BIT
        #5;

        // DISPLAY OUTPUT ON POS EDGE TICK
        $display("%4d  %10s | %8d | %1b | %1b |", VECTORCOUNT, COMMENT, $time, IN, OUT);

        // CHECK EACH VECTOR RESULT
        if (OUT !== OUTEXPECTED) begin
            $display("***ERROR (behavioral) - Expected OUT = %b", OUTEXPECTED);
            ERRORS = ERRORS + 1;
        end

    end   

endmodule
module decoder_3_8_behavioral(
    input       [2:0] in,       // 3 Input
    output  reg [7:0] out);     // 8 Outputs

    // ALWAYS BLOCK with NON-BLOCKING PROCEDURAL ASSIGNMENT STATEMENT
    always @ ( * ) begin
        case (in)
            3'b000 : out <= 8'b00000001;
            3'b001 : out <= 8'b00000010;
            3'b010 : out <= 8'b00000100;
            3'b011 : out <= 8'b00001000;
            3'b100 : out <= 8'b00010000;
            3'b101 : out <= 8'b00100000;
            3'b110 : out <= 8'b01000000;
            3'b111 : out <= 8'b10000000;
        endcase
    end

endmodule
module DECODER_3_8_TB;

    // DATA TYPES - DECLARE REGISTERS AND WIRES (PROBES)
    reg  [2:0]      IN;
    wire [7:0]      OUT;

    // FOR TESTING  
    reg             TICK;
    reg [31:0]      VECTORCOUNT, ERRORS;
    reg [7:0]       OUTEXPECTED;
    integer         FD, COUNT;
    reg [8*32-1:0]  COMMENT;

    // UNIT UNDER TEST (behavioral)
    decoder_3_8_behavioral UUT_decoder_3_8_behavioral(
        .in(IN),
        .out(OUT)
    );

    // SAVE EVERYTHING FROM TOP TB MODULE IN A DUMP FILE
    initial begin
        $dumpfile("decoder_3_8_tb.vcd");
        $dumpvars(0, DECODER_3_8_TB);
    end

    // TICK PERIOD
    localparam TICKPERIOD = 20;

    // TICK
    always begin
        #(TICKPERIOD/2) TICK = ~TICK;
    end

    // INITIALIZE TESTBENCH
    initial begin

        // OPEN VECTOR FILE - THROW AWAY FIRST LINE
        FD=$fopen("decoder_3_8_tb.tv","r");
        COUNT = $fscanf(FD, "%s", COMMENT);
        // $display ("FIRST LINE IS: %s", COMMENT);

        // INIT TESTBENCH
        COUNT = $fscanf(FD, "%s %b %b", COMMENT, IN, OUTEXPECTED);
        TICK = 0;
        VECTORCOUNT = 1;
        ERRORS = 0;

        // DISPAY OUTPUT AND MONITOR
        $display();
        $display("TEST START --------------------------------");
        $display();
        $display("                 | TIME(ns) | IN  |   OUT    |");
        $display("                 -----------------------------");
        // $monitor("%4d  %10s | %8d | %1b | %1b |", VECTORCOUNT, COMMENT, $time, IN, OUT);

    end

    // APPLY TEST VECTORS ON NEG EDGE TICK (ADD DELAY)
    always @(negedge TICK) begin

        // WAIT A BIT (AFTER CHECK)
        #5;

        // GET VECTORS FROM TB FILE
        COUNT = $fscanf(FD, "%s %b %b %b", COMMENT, IN, OUTEXPECTED);

        // CHECK IF EOF - PRINT SUMMARY, CLOSE VECTOR FILE AND FINISH TB
        if (COUNT == -1) begin
            $fclose(FD);
            $display();
            $display(" VECTORS: %4d", VECTORCOUNT);
            $display("  ERRORS: %4d", ERRORS);
            $display();
            $display("TEST END ----------------------------------");
            $display();
            $finish;
        end

        // GET ANOTHER VECTOR
        VECTORCOUNT = VECTORCOUNT + 1;

    end

    // CHECK TEST VECTORS ON POS EGDE TICK
    always @(posedge TICK) begin

        // WAIT A BIT
        #5;

        // DISPLAY OUTPUT ON POS EDGE TICK
        $display("%4d  %10s | %8d | %1b | %1b |", VECTORCOUNT, COMMENT, $time, IN, OUT);

        // CHECK EACH VECTOR RESULT
        if (OUT !== OUTEXPECTED) begin
            $display("***ERROR (behavioral) - Expected OUT = %b", OUTEXPECTED);
            ERRORS = ERRORS + 1;
        end

    end   

endmodule
module encoder_to_decoder_structural(
    input     [7:0] in,      // 8 Inputs
    output    [7:0] out      // 8 Outputs
);

    wire [7:0] connect;

    // ENCODER
    encoder_8_3_behavioral encoder_8_3 (
        .in(in),
        .out(connect)
    );

    // DECODER
    decoder_3_8_behavioral decoder_3_8 (
        .in(connect),
        .out(out)
    );

endmodule
module ENCODER_TO_DECODER_TB;

    // DATA TYPES - DECLARE REGISTERS AND WIRES (PROBES)
    reg  [7:0]      IN;
    wire [7:0]      OUT;

    // FOR TESTING  
    reg             TICK;
    reg [31:0]      VECTORCOUNT, ERRORS;
    reg [7:0]       OUTEXPECTED;
    integer         FD, COUNT;
    reg [8*32-1:0]  COMMENT;

    // UNIT UNDER TEST
    encoder_to_decoder_structural UUT_encoder_to_decoder_structural(
        .in(IN),
        .out(OUT)
    );

    // SAVE EVERYTHING FROM TOP TB MODULE IN A DUMP FILE
    initial begin
        $dumpfile("encoder_to_decoder_tb.vcd");
        $dumpvars(0, ENCODER_TO_DECODER_TB);
    end

    // TICK PERIOD
    localparam TICKPERIOD = 20;

    // TICK
    always begin
        #(TICKPERIOD/2) TICK = ~TICK;
    end

    // INITIALIZE TESTBENCH
    initial begin

        // OPEN VECTOR FILE - THROW AWAY FIRST LINE
        FD=$fopen("encoder_to_decoder_tb.tv","r");
        COUNT = $fscanf(FD, "%s", COMMENT);
        // $display ("FIRST LINE IS: %s", COMMENT);

        // INIT TESTBENCH
        COUNT = $fscanf(FD, "%s %b %b", COMMENT, IN, OUTEXPECTED);
        TICK = 0;
        VECTORCOUNT = 1;
        ERRORS = 0;

        // DISPAY OUTPUT AND MONITOR
        $display();
        $display("TEST START --------------------------------");
        $display();
        $display("                 | TIME(ns) |    IN    |    OUT   |");
        $display("                 ----------------------------------");
        // $monitor("%4d  %10s | %8d | %1b | %1b |", VECTORCOUNT, COMMENT, $time, IN, OUT);

    end

    // APPLY TEST VECTORS ON NEG EDGE TICK (ADD DELAY)
    always @(negedge TICK) begin

        // WAIT A BIT (AFTER CHECK)
        #5;

        // GET VECTORS FROM TB FILE
        COUNT = $fscanf(FD, "%s %b %b", COMMENT, IN, OUTEXPECTED);

        // CHECK IF EOF - PRINT SUMMARY, CLOSE VECTOR FILE AND FINISH TB
        if (COUNT == -1) begin
            $fclose(FD);
            $display();
            $display(" VECTORS: %4d", VECTORCOUNT);
            $display("  ERRORS: %4d", ERRORS);
            $display();
            $display("TEST END ----------------------------------");
            $display();
            $finish;
        end

        // GET ANOTHER VECTOR
        VECTORCOUNT = VECTORCOUNT + 1;

    end

    // CHECK TEST VECTORS ON POS EGDE TICK
    always @(posedge TICK) begin

        // WAIT A BIT
        #5;

        // DISPLAY OUTPUT ON POS EDGE TICK
        $display("%4d  %10s | %8d | %1b | %1b |", VECTORCOUNT, COMMENT, $time, IN, OUT);

        // CHECK EACH VECTOR RESULT
        if (OUT !== OUTEXPECTED) begin
            $display("***ERROR (behavioral) - Expected OUT = %b", OUTEXPECTED);
            ERRORS = ERRORS + 1;
        end

    end   

endmodule
module full_adder_gate(
    input       a,           // Data
    input       b,           // Data
    input       cin,         // Carry in
    output      sum,         // Sum of a + b
    output      cout);       // Carry out

    wire        w1, w2, w3;

    // GATE PRIMITIVE
    xor         xor1(w1, a, b);
    xor         xor2(sum, w1, cin);
    and         and1(w2, w1, cin);
    and         and2(w3, a, b);
    or          or1(cout, w2, w3);

endmodule
module full_adder_dataflow(
    input       a,           // Data
    input       b,           // Data
    input       cin,         // Carry in
    output      sum,         // Sum of a + b
    output      cout);       // Carry out

    // CONTINUOUS ASSIGNMENT STATEMENT
    assign sum  = a ^ b ^ cin;
    assign cout = (a & b) | (cin & (a ^ b));

endmodule
module full_adder_behavioral(
    input       a,           // Data
    input       b,           // Data
    input       cin,         // Carry in
    output reg  sum,         // Sum of a + b
    output reg  cout);       // Carry out

    // ALWAYS BLOCK with NON-BLOCKING PROCEDURAL ASSIGNMENT STATEMENT
    always @ ( a or b or cin) begin
        {cout, sum} <= a + b + cin;
    end

endmodule
module half_adder_gate(
    input       a,           // Data
    input       b,           // Data
    output      sum,         // Sum of a + b
    output      cout);       // Carry out


    // GATE PRIMITIVE
    xor         xor1(sum, a, b);
    and         and1(cout, a, b);

endmodule
module half_adder_dataflow(
    input       a,           // Data
    input       b,           // Data
    output      sum,         // Sum of a + b
    output      cout);       // Carry out

    // CONTINUOUS ASSIGNMENT STATEMENT
    assign sum  = a ^ b;
    assign cout = a & b;

endmodule
module half_adder_behavioral(
    input       a,           // Data
    input       b,           // Data
    output reg  sum,         // Sum of a + b
    output reg  cout);       // Carry out

    // ALWAYS BLOCK with NON-BLOCKING PROCEDURAL ASSIGNMENT STATEMENT
    always @ ( a or b) begin
        {cout, sum} <= a + b;
    end

endmodule
module MOORE_STATE_MACHINE_TB;

    // DATA TYPES - DECLARE REGISTERS AND WIRES (PROBES)
    reg        RST;
    reg        CLK;
    reg        IN;
    wire       FOUND;

    // FOR TESTING  
    reg [31:0]      VECTORCOUNT, ERRORS;
    reg             FOUNDEXP;
    integer         FD, COUNT;
    reg [8*32-1:0]  COMMENT;

    // UNIT UNDER TEST
    moore_state_machine_behavioral UUT_moore_state_machine_behavioral(
        .rst(RST),
        .clk(CLK),
        .in(IN),
        .found(FOUND)
    );

    // SAVE EVERYTHING FROM TOP TB MODULE IN A DUMP FILE
    initial begin
        $dumpfile("moore_state_machine_tb.vcd");
        $dumpvars(0, MOORE_STATE_MACHINE_TB);
    end

    // CLK PERIOD
    localparam CLKPERIOD = 20;

    // CLK
    always begin
        #(CLKPERIOD/2) CLK = ~CLK;
    end

    // INITIALIZE TESTBENCH
    initial begin

        // OPEN VECTOR FILE - THROW AWAY FIRST LINE
        FD=$fopen("moore_state_machine_tb.tv","r");
        COUNT = $fscanf(FD, "%s", COMMENT);
        // $display ("FIRST LINE IS: %s", COMMENT);

        // INIT TESTBENCH
        COUNT = $fscanf(FD, "%s %b %b %b", COMMENT, RST, IN, FOUNDEXP);
        CLK = 0;
        VECTORCOUNT = 1;
        ERRORS = 0;

        // DISPAY OUTPUT AND MONITOR
        $display();
        $display("TEST START --------------------------------");
        $display();
        $display("                 | TIME(ns) | RST | IN | FOUND |");
        $display("                 -------------------------------");
        // $monitor("%4d  %10s | %8d |  %1d  | %1d  |   %1d   |", VECTORCOUNT, COMMENT, $time, RST, IN, FOUND);

    end

    // APPLY TEST VECTORS ON NEG EDGE CLK (ADD DELAY)
    always @(negedge CLK) begin

        // WAIT A BIT (AFTER CHECK)
        #5;

        // GET VECTORS FROM TB FILE
        COUNT = $fscanf(FD, "%s %b %b %b", COMMENT, RST, IN, FOUNDEXP);

        // CHECK IF EOF - PRINT SUMMARY, CLOSE VECTOR FILE AND FINISH TB
        if (COUNT == -1) begin
            $fclose(FD);
            $display();
            $display(" VECTORS: %4d", VECTORCOUNT);
            $display("  ERRORS: %4d", ERRORS);
            $display();
            $display("TEST END ----------------------------------");
            $display();
            $finish;
        end

        // GET ANOTHER VECTOR
        VECTORCOUNT = VECTORCOUNT + 1;

    end

    // CHECK TEST VECTORS ON POS EGDE CLK
    always @(posedge CLK) begin

        // WAIT A BIT
        #5;

        // DISPLAY OUTPUT ON POS EDGE CLK
        $display("%4d  %10s | %8d |  %1d  | %1d  |   %1d   |", VECTORCOUNT, COMMENT, $time, RST, IN, FOUND);

        // CHECK EACH VECTOR RESULT
        if (FOUNDEXP !== FOUND) begin
            $display("***ERROR (behavioral) - Expected FOUND=%b", FOUNDEXP);
            ERRORS = ERRORS + 1;
        end

    end   

endmodule