dakies/OSS_Verilog huggingface dataset:
module moore_state_machine_behavioral (
    input        clk,           // clk
    input        rst,           // Reset
    input        in,            // Serial in
    output reg   found);        // Found pattern

    // DATA TYPES
    reg [2:0] state;

    // STATES - BINARY ENCODED STYLE - USE ANY STYLE YOU WANT
    parameter [2:0] START     = 3'b000;
    parameter [2:0] ZERO      = 3'b001;
    parameter [2:0] WAIT      = 3'b010;
    parameter [2:0] S1        = 3'b011;
    parameter [2:0] S2        = 3'b100;
    parameter [2:0] S3        = 3'b101;
    parameter [2:0] FOUND     = 3'b110;

    // MOORE STATE MACHINE
    // ALWAYS BLOCK with NON-BLOCKING PROCEDURAL ASSIGNMENT STATEMENT
    always @ (posedge clk) begin
        if (rst) begin
            state <= START;
            found <= 1'b0;
        end else begin
            case (state)
                START: begin
                    found <= 1'b0;
                    if (in==0)  begin state <= ZERO;   end
                    else        begin state <= START;  end
                end
                ZERO: begin
                    found <= 1'b0;
                    if (in==0)  begin state <= WAIT;   end
                    else        begin state <= START;  end
                end
                WAIT: begin
                    found <= 1'b0;
                    if (in==1)  begin state <= S1;     end
                    else        begin state <= WAIT;   end
                end
                S1: begin
                    found <= 1'b0;
                    if (in==1)  begin state <= S2;     end
                    else        begin state <= ZERO;   end
                end
                S2:begin
                    found <= 1'b0;
                    if (in==0)  begin state <= S3;     end
                    else        begin state <= START;  end
                end
                S3:begin
                    found <= 1'b0;
                    if (in==1)  begin state <= FOUND;  end // Found pattern
                    else        begin state <= WAIT;   end
                end
                FOUND:begin
                    found <= 1'b1;
                    if (in==1)  begin state <= START;  end
                    else        begin state <= ZERO;   end
                end
            endcase
        end
    end

endmodule
module mealy_state_machine_behavioral (
    input        clk,           // clk
    input        rst,           // Reset
    input        in,            // Serial in
    output reg   found);        // Found pattern

    // DATA TYPES
    reg [2:0] state;

    // STATES - BINARY ENCODED STYLE - USE ANY STYLE YOU WANT
    parameter [2:0] START     = 3'b000;
    parameter [2:0] ZERO      = 3'b001;
    parameter [2:0] WAIT      = 3'b010;
    parameter [2:0] S1        = 3'b011;
    parameter [2:0] S2        = 3'b100;
    parameter [2:0] S3        = 3'b101;

    // MEALY STATE MACHINE
    // ALWAYS BLOCK with NON-BLOCKING PROCEDURAL ASSIGNMENT STATEMENT
    always @ (posedge clk) begin
        if (rst) begin
            state <= START;
            found <= 1'b0;
        end else begin
            case (state)
                START: begin
                    if (in==0)  begin state <= ZERO;  found <= 1'b0; end
                    else        begin state <= START; found <= 1'b0; end
                end
                ZERO: begin
                    if (in==0)  begin state <= WAIT;  found <= 1'b0; end
                    else        begin state <= START; found <= 1'b0; end
                end
                WAIT: begin
                    if (in==1)  begin state <= S1;    found <= 1'b0; end
                    else        begin state <= WAIT;  found <= 1'b0; end
                end
                S1: begin
                    if (in==1)  begin state <= S2;    found <= 1'b0; end
                    else        begin state <= ZERO;  found <= 1'b0; end
                end
                S2:begin
                    if (in==0)  begin state <= S3;    found <= 1'b0; end
                    else        begin state <= START; found <= 1'b0; end
                end
                S3:begin
                    if (in==1)  begin state <= START; found <= 1'b1; end // Found pattern
                    else        begin state <= WAIT;  found <= 1'b0; end
                end
            endcase
        end
    end

endmodule
module MEALY_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
    mealy_state_machine_behavioral UUT_mealy_state_machine_behavioral(
        .rst(RST),
        .clk(CLK),
        .in(IN),
        .found(FOUND)
    );

    // SAVE EVERYTHING FROM TOP TB MODULE IN A DUMP FILE
    initial begin
        $dumpfile("mealy_state_machine_tb.vcd");
        $dumpvars(0, MEALY_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("mealy_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
module priority_arbiter_behavioral(
    input       clk,          // Clock  
    input       rst,          // Reset
    input       req_0,        // Request 0
    input       req_1,        // Request 1
    input       req_2,        // Request 2
    output reg  gnt_0,        // Grant 0
    output reg  gnt_1,        // Grant 1
    output reg  gnt_2         // Grant 2
);

    // ALWAYS BLOCK with NON-BLOCKING PROCEDURAL ASSIGNMENT STATEMENT
    always @ (posedge clk or posedge rst) begin
        if (rst) begin
            gnt_0 <= 0;
            gnt_1 <= 0;
            gnt_2 <= 0;
        end else if (req_0) begin
            gnt_0 <= 1;
            gnt_1 <= 0;
            gnt_2 <= 0;
        end else if (req_1) begin
            gnt_0 <= 0;
            gnt_1 <= 1;
            gnt_2 <= 0;
        end else if (req_2) begin
            gnt_0 <= 0;
            gnt_1 <= 0;
            gnt_2 <= 1;
        end else begin
            gnt_0 <= 0;
            gnt_1 <= 0;
            gnt_2 <= 0;
        end
    end

endmodule
module fifo_synchronous_structural(
    input  clk,             // Clock
    input  rst,             // Reset
    // PUSH
    input  [7:0] data_in,   // DATA In
    input  push,            // Push/Write enable
    output full,            // Full
    // POP
    output [7:0] data_out,  // DATA Out
    input  pop,             // Pop/Read enable
    output empty);          // Empty

    //FIFO
    // parameter DATA_WIDTH = 8;
    // parameter ADDR_WIDTH = 4;
    // parameter RAM_DEPTH = (1 << ADDR_WIDTH);

    // DATA TYPES
    wire [3:0] w_ptr;
    wire [3:0] r_ptr;
    wire       w_next;
    wire       r_next;
    parameter  zeros = 8'h00;
    parameter  zero =   1'b0;

    // 16x8 dual port RAM
    dual_port_ram_synchronous_behavioral dual_port_ram_synchronous(
        .clk(clk),           
        .we_A(push),
        .we_B(zero),
        .addr_A(w_ptr),
        .addr_B(r_ptr),
        .data_in_A(data_in),
        .data_in_B(zeros),
        .data_out_A(),
        .data_out_B(data_out)
    );

    write_logic write_logic(
        .we(push),
        .full(full),
        .w_next(w_next)
    );

    read_logic read_logic(
        .re(pop),
        .empty(empty),
        .r_next(r_next)
    );

    write_ptr write_ptr(
        .clk(clk),
        .rst(rst),
        .w_next(w_next),
        .w_ptr(w_ptr)
    );

    read_ptr read_ptr(
        .clk(clk),
        .rst(rst),
        .r_next(r_next),
        .r_ptr(r_ptr)
    );

    compare_and_status_logic compare_and_status_logic(
        .w_ptr(w_ptr),
        .full(full),
        .r_ptr(r_ptr),
        .empty(empty)
    );

endmodule
module single_port_ram_synchronous_behavioral(
    input  clk,                                         // Clock
    input  we,                                          // Write enable
    input  [ADDR_WIDTH-1:0] addr,                       // Address
    input  [DATA_WIDTH-1:0] data_in,                    // Data to write
    output reg [DATA_WIDTH-1:0] data_out);              // Data to read

    // PARAMETERS
    parameter DATA_WIDTH = 8;
    parameter ADDR_WIDTH = 4;
    parameter MEM_DEPTH = 16;

    // DATA TYPES
    reg [DATA_WIDTH-1:0] mem [0:MEM_DEPTH-1];           // RAM (16x8)

    // ALWAYS BLOCK with NON-BLOCKING PROCEDURAL ASSIGNMENT STATEMENT
    always @(posedge clk) begin
        // WRITE (DATA PASS)
        if (we) begin
            mem[addr] <= data_in;
            data_out <= data_in;
        // READ
        end else begin
            data_out <= mem[addr];
        end
    end

endmodule
module SINGLE_PORT_RAM_SYNCHRONOUS_TB;

    // DATA TYPES - DECLARE REGISTERS AND WIRES (PROBES)
    reg             CLK;
    reg             WE;
    reg  [3:0]      ADDR;
    reg  [7:0]      DATA_IN;
    wire [7:0]      DATA_OUT;
  
    // FOR TESTING  
    reg [31:0]      VECTORCOUNT, ERRORS;
    reg [7:0]       DATA_OUTEXP;
    integer         FD, COUNT;
    reg [8*32-1:0]  COMMENT;

    // UNIT UNDER TEST
    single_port_ram_synchronous_behavioral UUT_single_port_ram_synchronous_behavioral(
        .clk (CLK),
        .we (WE),
        .addr (ADDR),
        .data_in (DATA_IN),
        .data_out (DATA_OUT)
    );

    // SAVE EVERYTHING FROM TOP TB MODULE IN A DUMP FILE
    initial begin
        $dumpfile("single_port_ram_synchronous_tb.vcd");
        $dumpvars(0, SINGLE_PORT_RAM_SYNCHRONOUS_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("single_port_ram_synchronous_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, WE, ADDR, DATA_IN, DATA_OUTEXP);
        CLK = 0;
        VECTORCOUNT = 1;
        ERRORS = 0;

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

    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 %b", COMMENT, WE, ADDR, DATA_IN, DATA_OUTEXP);

        // 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 | %1b | %1b  | %1b | %1b |", VECTORCOUNT, COMMENT, $time, WE, ADDR, DATA_IN, DATA_OUT);

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

    end   

endmodule
module dual_port_ram_asynchronous_behavioral(
    input  clk_A,                                       // Clock A
    input  clk_B,                                       // Clock B
    // PORT A
    input  we_A,                                        // Write enable
    input  [ADDR_WIDTH-1:0] addr_A,                     // Address
    input  [DATA_WIDTH-1:0] data_in_A,                  // Data to write
    output reg [DATA_WIDTH-1:0] data_out_A,             // Data to read
    // PORT B
    input  we_B,                                        // Write enable
    input  [ADDR_WIDTH-1:0] addr_B,                     // Address
    input  [DATA_WIDTH-1:0] data_in_B,                  // Data to write
    output reg [DATA_WIDTH-1:0] data_out_B);            // Data to read

    // PARAMETERS
    parameter DATA_WIDTH = 8;
    parameter ADDR_WIDTH = 4;
    parameter MEM_DEPTH = 16;

    // DATA TYPES
    reg [DATA_WIDTH-1:0] mem [0:MEM_DEPTH-1];           // RAM (16x8)

    // PORT A
    // ALWAYS BLOCK with NON-BLOCKING PROCEDURAL ASSIGNMENT STATEMENT
    always @(posedge clk_A) begin
        // WRITE (DATA PASS)
        if (we_A) begin
            mem[addr_A] <= data_in_A;
            data_out_A <= data_in_A;
        // READ
        end else begin
            data_out_A <= mem[addr_A];
        end
    end

    // PORT B - HAS PRECEDENCE FOR WRITE
    // ALWAYS BLOCK with NON-BLOCKING PROCEDURAL ASSIGNMENT STATEMENT
    always @(posedge clk_B) begin
        //WRITE (DATA PASS)
        if (we_B) begin
            mem[addr_B] <= data_in_B;
            data_out_B <= data_in_B;
        //READ
        end else begin
            data_out_B <= mem[addr_B];
        end
    end

endmodule
module dual_port_ram_synchronous_behavioral(
    input  clk,                                         // Clock
    // PORT A
    input  we_A,                                        // Write enable
    input  [ADDR_WIDTH-1:0] addr_A,                     // Address
    input  [DATA_WIDTH-1:0] data_in_A,                  // Data to write
    output reg [DATA_WIDTH-1:0] data_out_A,             // Data to read
    // PORT B
    input  we_B,                                        // Write enable
    input  [ADDR_WIDTH-1:0] addr_B,                     // Address
    input  [DATA_WIDTH-1:0] data_in_B,                  // Data to write
    output reg [DATA_WIDTH-1:0] data_out_B);            // Data to read

    // PARAMETERS
    parameter DATA_WIDTH = 8;
    parameter ADDR_WIDTH = 4;
    parameter MEM_DEPTH = 16;

    // DATA TYPES
    reg [DATA_WIDTH-1:0] mem [0:MEM_DEPTH-1];           // RAM (16x8)

    // PORT A
    // ALWAYS BLOCK with NON-BLOCKING PROCEDURAL ASSIGNMENT STATEMENT
    always @(posedge clk) begin
        // WRITE (DATA PASS)
        if (we_A) begin
            mem[addr_A] <= data_in_A;
            data_out_A <= data_in_A;
        // READ    
        end else begin
            data_out_A <= mem[addr_A];
        end
    end

    // PORT B - HAS PRECEDENCE FOR WRITE
    // ALWAYS BLOCK with NON-BLOCKING PROCEDURAL ASSIGNMENT STATEMENT
    always @(posedge clk) begin
        //WRITE (DATA PASS)
        if (we_B) begin
            mem[addr_B] <= data_in_B;
            data_out_B <= data_in_B;
        //READ
        end else begin
            data_out_B <= mem[addr_B];
        end
    end

endmodule
module fifo_asynchronous_structural(
    // PUSH
    input  wclk,            // Write Clock
    input  wrst,            // Write Reset
    input  [7:0] data_in,   // DATA In
    input  push,            // Write enable
    output full,            // Full
    // POP
    input  rclk,            // Read Clock
    input  rrst,            // Read Reset
    output [7:0] data_out,  // DATA Out
    input  pop,             // Read enable
    output empty);          // Empty

    // DATA TYPES
    wire [3:0] w_ptr;
    wire [3:0] r_ptr;
    wire       w_next;
    wire       r_next;
    parameter  zeros = 8'h00;
    parameter  zero =   1'b0;

    // 16x8 dual port RAM
    dual_port_ram_asynchronous_behavioral dual_port_ram_asynchronous(
        .clk_A(wclk),
        .clk_B(rclk),           
        .we_A(push),
        .we_B(zero),
        .addr_A(w_ptr),
        .addr_B(r_ptr),
        .data_in_A(data_in),
        .data_in_B(zeros),
        .data_out_A(),
        .data_out_B(data_out)
    );

    write_logic write_logic(
        .we(push),
        .full(full),
        .w_next(w_next)
    );

    read_logic read_logic(
        .re(pop),
        .empty(empty),
        .r_next(r_next)
    );

    write_ptr write_ptr(
        .clk(wclk),
        .rst(wrst),
        .w_next(w_next),
        .w_ptr(w_ptr)
    );

    read_ptr read_ptr(
        .clk(rclk),
        .rst(rrst),
        .r_next(r_next),
        .r_ptr(r_ptr)
    );

    compare_and_status_logic compare_and_status_logic(
        .w_ptr(w_ptr),
        .full(full),
        .r_ptr(r_ptr),
        .empty(empty)
    );

endmodule
module lifo_synchronous_structural(
    input  clk,             // Clock
    input  rst,             // Reset
    input  [7:0] data_in,   // DATA In
    input  push,            // Write enable
    output full,            // Full
    output [7:0] data_out,  // DATA Out
    input  pop,             // Read enable
    output empty);          // Empty

    //FIFO
    // parameter DATA_WIDTH = 8;
    // parameter ADDR_WIDTH = 4;
    // parameter RAM_DEPTH = (1 << ADDR_WIDTH);

    // DATA TYPES
    wire [3:0] wrt_ptr, rd_ptr;
    wire       w_next;
    wire       r_next;
    parameter  zeros = 8'h00;
    parameter  zero =   1'b0;

    // 16x8 dual port RAM
    dual_port_ram_synchronous_behavioral dual_port_ram_synchronous(
        .clk(clk),           
        .we_A(push),
        .we_B(zero),
        .addr_A(wrt_ptr),
        .addr_B(rd_ptr),
        .data_in_A(data_in),
        .data_in_B(zeros),
        .data_out_A(),
        .data_out_B(data_out)
    );

    write_logic write_logic(
        .we(push),
        .full(full),
        .w_next(w_next)
    );

    read_logic read_logic(
        .re(pop),
        .empty(empty),
        .r_next(r_next)
    );

    stack_ptr_control stack_ptr_control(
        .clk(clk),
        .rst(rst),
        .w_next(w_next),
        .r_next(r_next),
        .wrt_ptr(wrt_ptr),
        .rd_ptr(rd_ptr)
    );

    compare_and_status_logic compare_and_status_logic(
        .wrt_ptr(wrt_ptr),
        .full(full),
        .empty(empty)
    );

endmodule
module write_logic (
    input       we,              // Write enable
    input       full,            // Full
    output reg  w_next);         // Write next

    //If FIFO full write counter should not increment
    always @(*) begin
        if (we && (!full))
            w_next=1;
        else
            w_next=0;
    end

endmodule
module read_ptr (
    input             clk,              // Clock
    input             rst,              // Reset
    input             r_next,           // Read next
    output reg [3:0]  r_ptr);           // Read pointer

    // ALWAYS BLOCK with NON-BLOCKING PROCEDURAL ASSIGNMENT STATEMENT
    always @ (posedge clk) begin
        if (rst) begin
            r_ptr <= 3'b000;
        end else if (r_next) begin
            r_ptr <= r_ptr + 1;
        end else begin
            r_ptr <= r_ptr;
        end
    end

endmodule
module read_logic (
    input       re,              // Read enable
    input       empty,           // Empty
    output reg  r_next);         // Read next

    //If FIFO empty read counter should not increment
    always @(*) begin
        if (re && (!empty))
            r_next=1;
        else
            r_next=0;
    end

endmodule
module compare_and_status_logic (
    input  [3:0] w_ptr,     // Write pointer
    output reg   full,      // Full
    input  [3:0] r_ptr,     // Read pointer
    output reg   empty);    // Empty

    parameter depth = 4'b1111;  // Depth of the FIFO

    // DATA TYPES
    reg [3:0] ptr_diff;

    // FULL STATUS
    always @(*) begin
        if (ptr_diff == depth) begin
          full = 1'b1;
        end else begin
          full = 1'b0;
        end
    end

    // EMPTY STATUS
    always @(*) begin
        if (ptr_diff == 0) begin
          empty = 1'b1;
        end else begin
          empty = 1'b0;
        end
    end

    // HOW MUCH MEMORY USED
    // ALWAYS BLOCK with NON-BLOCKING PROCEDURAL ASSIGNMENT STATEMENT
    always @(*) begin
        if (w_ptr > r_ptr) begin
            ptr_diff <= w_ptr - r_ptr + 1;
        end else if (w_ptr < r_ptr) begin
            ptr_diff <= (depth - r_ptr) + w_ptr + 1;
        end else if (w_ptr == r_ptr) begin
            ptr_diff <= 0;
        end
    end

endmodule
module write_ptr (
    input             clk,              // Clock
    input             rst,              // Reset
    input             w_next,           // Write next
    output reg [3:0]  w_ptr);           // Write pointer

    // ALWAYS BLOCK with NON-BLOCKING PROCEDURAL ASSIGNMENT STATEMENT
    always @ (posedge clk) begin
        if (rst) begin
            w_ptr <= 3'b000;
        end else if (w_next) begin
            w_ptr <= w_ptr + 1;
        end else begin
            w_ptr <= w_ptr;
        end
    end

endmodule
module stack_ptr_control (
    input             clk,              // Clock
    input             rst,              // Reset
    input             w_next,           // Write next
    input             r_next,           // Read next
    output reg [3:0]  wrt_ptr,          // Write pointer
    output reg [3:0]  rd_ptr);          // Read pointer

    // ALWAYS BLOCK with NON-BLOCKING PROCEDURAL ASSIGNMENT STATEMENT
    always @ (posedge clk) begin
        //RESET
        if (rst) begin
            wrt_ptr <= 4'b0000;
            rd_ptr <= 4'b0000;
        // BOTTOM - PUSH
        end else if ((wrt_ptr == 4'b0000) & (w_next)) begin
            wrt_ptr <= wrt_ptr + 1;
        // BOTTOM - POP
        end else if ((rd_ptr == 4'b0000) & (r_next)) begin
            wrt_ptr <= 4'b0000;
        // PUSH
        end else if (w_next) begin
            wrt_ptr <= wrt_ptr + 1;
            rd_ptr <= rd_ptr + 1;
        // POP
        end else if (r_next) begin
            wrt_ptr <= wrt_ptr - 1;
            rd_ptr <= rd_ptr - 1;
        end
    end

endmodule
module compare_and_status_logic (
    input  [3:0] wrt_ptr,         // Stack pointer
    output reg   full,            // Full
    output reg   empty);          // Empty

    parameter depth = 4'b1111;    // Depth of the FIFO

    // HOW MUCH MEMORY USED
    // ALWAYS BLOCK with NON-BLOCKING PROCEDURAL ASSIGNMENT STATEMENT
    always @(*) begin
        if (wrt_ptr == 0) begin
            full <= 1'b0;
            empty <= 1'b1;
        end else if (wrt_ptr < depth) begin
            full <= 1'b0;
            empty <= 1'b0;
        end else if (wrt_ptr == depth) begin
            full <= 1'b1;
            empty <= 1'b0;
        end
    end

endmodule
module simple_8_bit_register_behavioral (
    input       [7:0]   data_in,    // Data to load
    input               clk,        // Clock
    input               ld_bar,     // Load
    input               clr_bar,    // Clear
    output  reg [7:0]   data_out    // Output Data
);

    // 8-BIT REGISTER
    // ALWAYS BLOCK with NON-BLOCKING PROCEDURAL ASSIGNMENT STATEMENT
    always @ (posedge clk) begin
        if (~clr_bar) begin
            data_out <= 0;
        end else if (~ld_bar) begin
            data_out <= data_in;
        end
    end

endmodule
module SIMPLE_8_BIT_REGISTER_TB;

    // DATA TYPES - DECLARE REGISTERS AND WIRES (PROBES)
    reg  [7:0]      DATA_IN;
    reg             CLK;
    reg             LD_BAR;
    reg             CLR_BAR;
    wire [7:0]      DATA_OUT;

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


    // UNIT UNDER TEST
    simple_8_bit_register_behavioral uut(
        .data_in (DATA_IN),
        .clk(CLK),
        .ld_bar(LD_BAR),
        .clr_bar(CLR_BAR),
        .data_out(DATA_OUT)
    );

    // SAVE EVERYTHING FROM TOP TB MODULE IN A DUMP FILE
    initial begin
        $dumpfile("simple_8_bit_register_tb.vcd");
        $dumpvars(0, SIMPLE_8_BIT_REGISTER_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("simple_8_bit_register_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, LD_BAR, CLR_BAR, DATA_IN, DATA_OUTEXP);
        CLK = 0;
        VECTORCOUNT = 1;
        ERRORS = 0;

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

    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 %b", COMMENT, LD_BAR, CLR_BAR, DATA_IN, DATA_OUTEXP);

        // 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 |   %1b    |    %1b    | %1b | %1b |", VECTORCOUNT, COMMENT, $time, LD_BAR, CLR_BAR, DATA_IN, DATA_OUT);

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

    end   

endmodule
module left_shift_register_behavioral (
    input            clk,           // clk
    input            rst,           // Reset
    input            d,             // d
    output reg [3:0] out);          // out

    // LEFT SHIFT REGISTER
    // ALWAYS BLOCK with NON-BLOCKING PROCEDURAL ASSIGNMENT STATEMENT
    always @ (posedge clk) begin
        if (rst) begin
            out <= 4'b0000;
        end else begin
            out <= {out[2:0], d};
        end
    end

endmodule
module LEFT_SHIFT_REGISTER_TB;

    // DATA TYPES - DECLARE REGISTERS AND WIRES (PROBES)
    reg             CLK;
    reg             RST;
    reg             D;
    wire [3:0]      OUT;

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

    // UNIT UNDER TEST (behavioral)
    left_shift_register_behavioral UUT_left_shift_register_behavioral(
        .clk(CLK),
        .rst(RST),
        .d(D),
        .out(OUT)
    );

    // SAVE EVERYTHING FROM TOP TB MODULE IN A DUMP FILE
    initial begin
        $dumpfile("left_shift_register_tb.vcd");
        $dumpvars(0, LEFT_SHIFT_REGISTER_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("left_shift_register_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, D, OUTEXP);
        CLK = 0;
        VECTORCOUNT = 1;
        ERRORS = 0;

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

    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, D, OUTEXP);

        // 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 | %b   | %1b | %1b |", VECTORCOUNT, COMMENT, $time, RST, D, OUT);

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

    end   

endmodule
module jeff_74x161(
    input           clr_bar,             // ASYNC CLEAR
    input           ld_bar,              // LOAD
    input           ent,                 // ENABLE T
    input           enp,                 // ENABLE P
    input           clk,                 // CLK
    input           a, b, c, d,          // DATA IN
    output          qa, qb, qc, qd,      // DATA OUT
    output          rco);                // RIPPLE CARRY OUTPUT

    wire ld;
    wire ent_and_enp;

    assign rco = ent & qd & qc & qb & qa;

    assign ld = ~ld_bar;
    assign ent_and_enp = ent & enp;

    assign feedback_qd = ent_and_enp & qc & qb & qa;

    output_section OUTPUT_QD (
        .clr_bar(clr_bar),
        .ld(ld),
        .feedback(feedback_qd),
        .clk(clk),
        .data(d),
        .q(qd)
    );

    assign feedback_qc =  ent_and_enp & qb & qa;

    output_section OUTPUT_QC (
        .clr_bar(clr_bar),
        .ld(ld),
        .feedback(feedback_qc),
        .clk(clk),
        .data(c),
        .q(qc)
    );

    assign feedback_qb = ent_and_enp & qa;

    output_section OUTPUT_QB (
        .clr_bar(clr_bar),
        .ld(ld),
        .feedback(feedback_qb),
        .clk(clk),
        .data(b),
        .q(qb)
    );

    assign feedback_qa = ent_and_enp;

    output_section OUTPUT_QA (
        .clr_bar(clr_bar),
        .ld(ld),
        .feedback(feedback_qa),
        .clk(clk),
        .data(a),
        .q(qa)
    );

endmodule
module output_section (
    input  clr_bar,
    input  ld,
    input  feedback,
    input  clk,
    input  data,
    output q);

wire NOTHING;

assign to_j_and_k = (feedback | ld);

assign to_j = ~(ld & to_k);
assign to_k = ~(data & ld);
 
assign j = (to_j & to_j_and_k);
assign k = (to_k & to_j_and_k);

jk_flip_flop_pos_edge_sync_clear_behavioral JK (
    .clk(clk),       
    .clrbar(clr_bar),
    .j(j),        
    .k(k),        
    .q(q),    
    .qbar(NOTHING)     
);

endmodule
module button1_sync_push_release_behavioral (
    input           clk,            // CLOCK
    input           pressed,        // BUTTON IN
    output reg      out);           // PULSE FOR 1 CLOCK CYCLE

    // ALWAYS BLOCK with NON-BLOCKING PROCEDURAL ASSIGNMENT STATEMENT
    always @(posedge clk) begin
            if (pressed) begin          // BUTTON PRESSED
                out <= 1'b1;
            end else begin              //  BUTTON NOT PRESSED
                out <= 1'b0;
            end
    end

endmodule
module button2_sync_clock_pulse_behavioral (
    input           clk,            // CLOCK
    input           pressed,        // BUTTON IN (YOU CAN HOLD AND RELEASE WHENEVER)
    output reg      out);           // PULSE FOR 1 CLOCK CYCLE

    reg lock = 0;

    // ALWAYS BLOCK with NON-BLOCKING PROCEDURAL ASSIGNMENT STATEMENT
    always @(posedge clk) begin
            if (pressed & ~lock) begin              // BUTTON PRESSED
                lock <= 1'b1;                       // - Lock
                out <= 1'b1;                        // - Pulse
            end else if (~pressed & lock) begin     // RELEASE LOCK
                lock <= 1'b0;
                out <= 1'b0;
            end else begin
                out <= 1'b0;
            end
    end

endmodule
module button3_sync_two_presses_behavioral (
    input           clk,            // CLOCK
    input           pressed,        // BUTTON IN (YOU CAN HOLD AND RELEASE WHENEVER)
    output          out);           // TWO PRESSES

    reg lock = 0;
    reg toggle = 0;

    assign out = toggle;

    // ALWAYS BLOCK with NON-BLOCKING PROCEDURAL ASSIGNMENT STATEMENT
    always @ (posedge clk) begin
        if (pressed & ~lock) begin              // BUTTON PRESSED
            lock <= 1'b1;                       // - Lock
            toggle <= ~toggle;                  // - Toggle
        end else if (~pressed & lock) begin     // WAIT TILL BUTTON RELEASED
            lock <= 1'b0;                       // - Release Lock
        end
    end

endmodule
module button4_async_clock_pulse_behavioral (
    input           clk,            // CLOCK
    input           pressed,        // BUTTON IN (YOU CAN HOLD AND RELEASE WHENEVER)
    output          out);           // PULSE FOR 1 CLOCK CYCLE

    reg was_pressed = 0;
    reg lock = 0;
    reg pre_out = 0;

    assign out = pre_out;

    // ALWAYS BLOCK with NON-BLOCKING PROCEDURAL ASSIGNMENT STATEMENT
    always @(posedge clk or posedge pressed) begin
        if (pressed & ~was_pressed & ~lock) begin       // BUTTON PRESSED - Then forget about it until later
            was_pressed <= 1'b1;
        end else if (was_pressed & ~lock) begin         // OUT HIGH
            lock <= 1;
            was_pressed <= 0;
            pre_out <= 1'b1;
        end else if (lock & out) begin                  // OUT LOW
            pre_out <= 1'b0;
        end else if (~pressed & lock) begin             // WAIT TILL BUTTON RELEASED
            lock <= 1'b0;
        end
    end

endmodule
module button5_async_two_presses_behavioral (
    input           clk,            // CLOCK
    input           pressed,        // BUTTON IN (YOU CAN HOLD AND RELEASE WHENEVER)
    output          out);           // PULSE FOR 1 CLOCK CYCLE

    reg was_pressed = 0;
    reg lock = 0;
    reg toggle = 0;

    assign out = toggle;

    // ALWAYS BLOCK with NON-BLOCKING PROCEDURAL ASSIGNMENT STATEMENT
    always @(posedge clk or posedge pressed) begin
        if (pressed & ~was_pressed & ~lock) begin       // BUTTON PRESSED - Then forget about it for now
            was_pressed <= 1'b1;
        end else if (was_pressed & ~lock) begin         // OUT HIGH
            toggle <= ~toggle;                          // - toggle
            was_pressed <= 1'b0;
            lock <= 1;
        end else if (~pressed & lock) begin             // WAIT TILL BUTTON RELEASED
            lock <= 1'b0;
        end
    end

endmodule
module simple_pipeline_behavioral (
    input                 clk,          // Clock
    input       [7:0]     a, b, c, d,   // Data
    output reg  [7:0]     f);           // Output Data

    reg [7:0] y1, y2, y3, d1, d2;

    // STAGE 1
    // ALWAYS BLOCK with NON-BLOCKING PROCEDURAL ASSIGNMENT STATEMENT
    always @ (posedge clk) begin
        y1 <= a + b;
        y2 <= c - d;
        d1 <= d;
    end

    // STAGE 2
    // ALWAYS BLOCK with NON-BLOCKING PROCEDURAL ASSIGNMENT STATEMENT
    always @ (posedge clk) begin
        y3 <= y1 + y2;
        d2 <=  d1;
    end

    // STAGE 3
    // ALWAYS BLOCK with NON-BLOCKING PROCEDURAL ASSIGNMENT STATEMENT
    always @ (posedge clk) begin
        f <= y3 * d2;
    end

endmodule
module SIMPLE_PIPELINE_TB;

    // DATA TYPES - DECLARE REGISTERS AND WIRES (PROBES)
    reg  [7:0]      A, B, C, D;
    reg             CLK;
    wire [7:0]      F;

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

    // UNIT UNDER TEST (behavioral)
    simple_pipeline_behavioral UUT_simple_pipeline_behavioral(
        .clk(CLK),
        .a (A),
        .b (B),
        .c (C),
        .d (D),
        .f (F)
    );

    // SAVE EVERYTHING FROM TOP TB MODULE IN A DUMP FILE
    initial begin
        $dumpfile("simple_pipeline_tb.vcd");
        $dumpvars(0, SIMPLE_PIPELINE_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("simple_pipeline_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, A, B, C, D, FEXP);
        CLK = 0;
        VECTORCOUNT = 1;
        ERRORS = 0;

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

    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 %b %b", COMMENT, A, B, C, D, FEXP);

        // 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 | %1b | %1b | %1b | %1b | %1b |", VECTORCOUNT, COMMENT, $time, A, B, C, D, F);

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

    end   

endmodule
module programable_8_bit_microprocessor (
    input  [3:0]    OPCODE,             //
    input  [7:0]    DATA_IN_A,          // 
    input  [7:0]    DATA_IN_B,          // 
    input           GO_BAR,             // 
    input           RESET,              // 
    input           JAM,                // 
    input           SYSTEM_CLK,         // 
    input  [23:0]   MW,                 //
    output [7:0]    MICROADDRESS,       // 
    output [7:0]    DATA_OUT            // 
);

    // WIRES
    wire [3:0]     STATUS_BITS; 
    wire [23:13]   CONTROL_BITS;
    wire           EIL_BAR;

    // CONTROL_SECTION
    control CONTROL_SECTION (
        .OPCODE(OPCODE),
        .GO_BAR(GO_BAR),
        .RESET(RESET),
        .JAM(JAM),
        .SYSTEM_CLK(SYSTEM_CLK),
        .STATUS_BITS(STATUS_BITS),
        .MW(MW),
        .MICROADDRESS(MICROADDRESS),
        .CONTROL_BITS(CONTROL_BITS),        // ORDER DIFFERENT FROM THESIS
        .EIL_BAR(EIL_BAR)
    );

    // PROCESSOR SECTION
    processor PROCESSOR_SECTION (
        .DATA_IN_A(DATA_IN_A),
        .DATA_IN_B(DATA_IN_B),
        .SYSTEM_CLK(SYSTEM_CLK),
        .EIL_BAR(EIL_BAR),
        .CONTROL_BITS(CONTROL_BITS),
        .STATUS_BITS(STATUS_BITS),
        .DATA_OUT(DATA_OUT)
    );

endmodule
module ta377_bar(
    input           EN_BAR,             //
    input           CLK,                //
    input  [7:0]    D,                  // 
    output [7:0]    Q                   // 
);

assign EN = ~EN_BAR;

// 8-bit register, clock enable
// Replaced ta377 in THESIS with jeff_74x377
jeff_74x377_structural U1 (
    .en_bar(EN_BAR),
    .clk(CLK),
    .d0(D[0]),
    .d1(D[1]),
    .d2(D[2]),
    .d3(D[3]),
    .d4(D[4]),
    .d5(D[5]),
    .d6(D[6]),
    .d7(D[7]),
    .q0(Q[0]),
    .q1(Q[1]),
    .q2(Q[2]),
    .q3(Q[3]),
    .q4(Q[4]),
    .q5(Q[5]),
    .q6(Q[6]),
    .q7(Q[7])
);

endmodule
module ta181_bar(
    input           A3_BAR, A2_BAR, A1_BAR, A0_BAR,     // WORD 1
    input           B3_BAR, B2_BAR, B1_BAR, B0_BAR,     // WORD 2
    input           S3, S2, S1, S0,                     // FUNCTION SELECT
    input           M,                                  // MODE: 0 is arithmetic, 1 is logic
    input           CI,                                 // CARRY IN
    output          F3_BAR, F2_BAR, F1_BAR, F0_BAR,     // OUTPUT
    output          CO,                                 // CARRY OUT
    output          AEQB,                               // WHEN A = B
    output          P_BAR,                              // PROPAGATE - I don't use this
    output          G_BAR                               // GENERATE - I don't use this
);

// WIRES REMOVED TO KEEP ALU POSITIVE
// wire A0_SIG, A1_SIG, A2_SIG, A3_SIG;
// wire B0_SIG, B1_SIG, B2_SIG, B3_SIG;
// wire F0_SIG, F1_SIG, F2_SIG, F3_SIG;

assign CO = ~CO_BAR; // NOT IN THESIS
assign CI_BAR = ~CI; // NOT IN THESIS

// 4-bit arithmetic logic unit and function generator
// Replaced ta181 in THESIS with jeff_74x181
jeff_74x181 U1 (
    .a3(A3_BAR),
    .a2(A2_BAR),
    .a1(A1_BAR),
    .a0(A0_BAR),
    .b3(B3_BAR),
    .b2(B2_BAR),
    .b1(B1_BAR),
    .b0(B0_BAR),
    .s3(S3),
    .s2(S2),
    .s1(S1),
    .s0(S0),
    .m(M),
    .ci_bar(CI_BAR),
    .f3(F3_BAR),
    .f2(F2_BAR),
    .f1(F1_BAR),
    .f0(F0_BAR),
    .co_bar(CO_BAR),
    .aeqb(AEQB),
    .x(P_BAR),
    .y(G_BAR)
);

//not1 INV1 (.a(A3_BAR), .y(A3_SIG)); // REMOVED THIS TO KEEP IT POSTITVE
//not1 INV2 (.a(A2_BAR), .y(A2_SIG));
//not1 INV3 (.a(A1_BAR), .y(A1_SIG));
//not1 INV4 (.a(A0_BAR), .y(A0_SIG));
//not1 INV5 (.a(B3_BAR), .y(B3_SIG));
//not1 INV6 (.a(B2_BAR), .y(B2_SIG));
//not1 INV7 (.a(B1_BAR), .y(B1_SIG));
//not1 INV8 (.a(B0_BAR), .y(B0_SIG));
//not1 INV9 (.a(F3_SIG), .y(F3_BAR));
//not1 INV10 (.a(F2_SIG), .y(F2_BAR));
//not1 INV11 (.a(F1_SIG), .y(F1_BAR));
//not1 INV12 (.a(F0_SIG), .y(F0_BAR));

endmodule
module zp_bit (
    input  [7:0]    F8,                 // 
    output          ZP_BAR              // 
);

wire [3:0] W;

// Replaced nor2 in THESIS with Jeff's nor2
nor2_behavioral U1 (
    .a(F8[0]),
    .b(F8[1]),
    .y(W[0])
);

nor2_behavioral U2 (
    .a(F8[2]),
    .b(F8[3]),
    .y(W[1])
);

nor2_behavioral U3 (
    .a(F8[4]),
    .b(F8[5]),
    .y(W[2])
);

nor2_behavioral U4 (
    .a(F8[6]),
    .b(F8[7]),
    .y(W[3])
);

// Replaced nand4 in THESIS with Jeff's nand4
nand4_behavioral U5 (
    .a(W[0]),
    .b(W[1]),
    .c(W[2]),
    .d(W[3]),
    .y(ZP_BAR)
);

endmodule
module counter8(
    input  [3:0]    COUNTER_IN_LOW,     // 
    input  [7:4]    COUNTER_IN_HIGH,    // 
    input           MPC_LOAD_BAR,       //
    input           RESET,              //
    input           COUNT,              //
    input           SYSTEM_CLK,         // 
    output [7:0]    COUNTER_OUT         // 
);

// WIRES
wire            CARRY;
wire            NOTHING;

// ASSIGN VALUES
assign HIGH             = 1'b1;

// COUNTER1 - 4-bit synchronous counter
ta161_bar COUNTER1 (
    .CLR_BAR(RESET),
    .LD_BAR(MPC_LOAD_BAR),
    .ENT(HIGH),
    .ENP(COUNT),
    .CLK(SYSTEM_CLK),
    .A(COUNTER_IN_LOW[0]),
    .B(COUNTER_IN_LOW[1]),
    .C(COUNTER_IN_LOW[2]),
    .D(COUNTER_IN_LOW[3]),
    .QA(COUNTER_OUT[0]),
    .QB(COUNTER_OUT[1]),
    .QC(COUNTER_OUT[2]),
    .QD(COUNTER_OUT[3]),
    .RCO(CARRY)
);

// COUNTER2 - 4-bit synchronous counter
ta161_bar COUNTER2 (
    .CLR_BAR(RESET),
    .LD_BAR(MPC_LOAD_BAR),
    .ENT(CARRY),
    .ENP(COUNT),
    .CLK(SYSTEM_CLK),
    .A(COUNTER_IN_HIGH[4]),
    .B(COUNTER_IN_HIGH[5]),
    .C(COUNTER_IN_HIGH[6]),
    .D(COUNTER_IN_HIGH[7]),
    .QA(COUNTER_OUT[4]),
    .QB(COUNTER_OUT[5]),
    .QC(COUNTER_OUT[6]),
    .QD(COUNTER_OUT[7]),
    .RCO(NOTHING)
);

endmodule
module register_ab8(
    input [7:0]     DATA_IN,            // 
    input           SYSTEM_CLK,         // 
    input           ENABLE_CLK,         // 
    output [7:0]    DATA_OUT            // 
);

// WIRES
wire         W1;

// ASSIGN VALUES
assign LOW              = 1'b0;

// OR GATE
//   Replaced or2 in THESIS with jeff's or2
or2_behavioral OR1 (
    .a(SYSTEM_CLK),
    .b(ENABLE_CLK),
    .y(W1)
);

// 8-bit register, clock enable
ta377_bar DFFS (
    .EN_BAR(LOW),
    .CLK(W1),
    .D(DATA_IN),
    .Q(DATA_OUT)
);

endmodule
module ta157_4(
    input  [3:0]    A4,                 // 
    input  [3:0]    B4,                 // 
    input           S,                  //
    input           EN_BAR,             //
    output [3:0]    Y4                  // 
);

// Replaced ta157_bar and ta157 in THESIS with jeff_74x157
assign EN = ~EN_BAR;

// Quad 2x1 multiplexers
jeff_74x157_behavioral MUX0 (
    .a(A4),
    .b(B4),
    .s(S),
    .en(EN),
    .y(Y4)
);

endmodule
module ta151_bar(
    input           D0,                 // 
    input           D1,                 // 
    input           D2,                 // 
    input           D3,                 // 
    input           D4,                 // 
    input           D5,                 // 
    input           D6,                 // 
    input           D7,                 //
    input           A,                  // 
    input           B,                  // 
    input           C,                  // 
    input           EN_BAR,             // 
    output          Y,                  // 
    output          W                   // 
);

assign EN = ~EN_BAR;

// 8-line to 1-line data selector/multiplexer
// Replaced ta151 in THESIS with jeff_74x151
jeff_74x151_behavioral U1 (
    .d0(D0),
    .d1(D1),
    .d2(D2),
    .d3(D3),
    .d4(D4),
    .d5(D5),
    .d6(D6),
    .d7(D7),
    .a(A),
    .b(B),
    .c(C),
    .en(EN),
    .y(Y),
    .w(W)
);

endmodule