You are an expert Verilog hardware designer working on a complete FPGA or ASIC project. You are given the full source code of a Verilog project. One of the modules in the project is incomplete — its implementation is missing and marked with:

// >>> Module Implementation Begin

// <<< Module Implementation End

Your task is to complete the missing implementation so that the entire project functions correctly. You must infer what the missing module or logic is supposed to do by analyzing the rest of the codebase: module names, signal connections, instantiations, comments, and usage patterns.

Follow these rules:

1. Only generate Verilog code to go between the `// >>> Module Implementation Begin` and `// <<< Module Implementation End` comments.
2. Use Verilog-2001 syntax. Ensure the code is synthesizable.
3. Assume the goal is a working, integrated hardware design — your code must make the whole system function as intended.
4. Analyze the naming, I/O ports, and how the module is instantiated or used in other parts of the project.
5. Implement correct behavior based on design context. Do not guess randomly — reason it out.
6. Avoid vendor-specific features unless explicitly required.
7. Do not output comments, explanation, or anything outside the required code region unless explicitly asked.

Your output should contain **only the Verilog code** that fits inside the marked region.

/*
 * Copyright (c) 2024 Zachary Frazee
 * SPDX-License-Identifier: Apache-2.0
 */

`define default_netname none

//---------------------------------
//Top Level Project Module
//---------------------------------
module tt_um_minibyte (
    input  wire [7:0] ui_in,    // Dedicated inputs
    output wire [7:0] uo_out,   // Dedicated outputs
    input  wire [7:0] uio_in,   // IOs: Input path
    output wire [7:0] uio_out,  // IOs: Output path
    output wire [7:0] uio_oe,   // IOs: Enable path (active high: 0=input, 1=output)
    input  wire       ena,      // will go high when the design is enabled
    input  wire       clk,      // clock
    input  wire       rst_n     // reset_n - low to reset
);
    //---------------------------------
    //Top Level Singal Notes
    //---------------------------------
    //ui_in          => Test and Configuration bits
    //uo_out         => WE and 7-bit Address Buss
    //uio_in/uio_out => 8-bit Bidirectional Data Buss
    //uio_oe         => Output Enable for Data Buss
    //---------------------------------
    //ui_in (Test)
    //      bit[7]   => ENABLE ONBOARD REG RAM
    //      bit[6:5] => UNUSED
    //      bit[4]   => ENABLE DEMO ROM
    //      bit[3]   => HALT CONTROL UNIT
    //      bit[2:0] => DEBUG OUTPUT SIGNAL CONTROL
    //                  0 -> Normal        output
    //                  1 -> A             output
    //                  2 -> A (UPPER BIT) output
    //                  3 -> M             output
    //                  4 -> PC            output
    //                  5 -> IR            output
    //                  6 -> CCR           output
    //                  7 -> CU STATE      output
    //---------------------------------
    //uio_in/uio_out
    //      bit[7]   => WE (Write Enable)
    //      bit[6:0] => Address Buss
    //---------------------------------

    //---------------------------------
    //Wires
    //---------------------------------
    wire [6:0] address_buss;
    wire       we_signal;

    wire [7:0] tm_control_bits;

    wire [7:0] data_buss_in;
    wire [7:0] data_buss_out;
    wire [7:0] data_buss_oe;

    wire [7:0] data_buss_rom;
    wire [7:0] data_buss_ram;

    wire [7:0] data_buss_muxed_in;

    wire drive_enable_sig;
    wire nc_addr_buss_bit_7;

    //---------------------------------
    //Assignments
    //---------------------------------
    assign uo_out[6:0]     = address_buss;
    assign uo_out[7]       = we_signal;

    assign tm_control_bits = ui_in;

    assign data_buss_in    = uio_in;
    assign uio_out         = data_buss_out;
    assign uio_oe          = data_buss_oe;


    //---------------------------------
    //Minibyte CPU
    //---------------------------------
    minibyte_cpu cpu(
        //Basic Inputs
        .clk_in(clk), .ena_in(ena), .rst_in(rst_n),

        .halt_in(tm_control_bits[3]),

        //Memory and IO Inputs
        .data_in(data_buss_muxed_in),

        //DFT Inputs
        .tm_control({tm_control_bits[2:0]}),

        //Memory and IO Outputs
        .addr_out   ({nc_addr_buss_bit_7,address_buss}),  //Only 7 bits get connected as we need to save one output for WE below:(
        .data_out   (data_buss_out),
        .we_out     (we_signal),                          //Dedicated output bit 7 gets used for WE
        .drive_out  (drive_enable_sig)
    );

    //---------------------------------
    //Input Device MUX
    //---------------------------------
    reg [1:0] input_mux_control;

    always @ (tm_control_bits, reg_ram_active) begin
        //Enable Onboard RAM
        if(tm_control_bits[7] == 1 && reg_ram_active)
            input_mux_control = 2'b11;

        //Enable Demo ROM
        else if(tm_control_bits[4] == 1)
            input_mux_control = 2'b01;

        //Enable Normal Input
        else
            input_mux_control = 2'b00;
    end

    minibyte_genmux_4x input_mux(
        //Mux Inputs
        .a_in(data_buss_in),
        .b_in(data_buss_rom),
        .c_in(8'h00),
        .d_in(data_buss_ram),

        //Mux Select
        .sel_in(input_mux_control),

        //Mux Output
        .mux_out(data_buss_muxed_in)
    );

    //---------------------------------
    //Demo ROM
    //---------------------------------
    demo_rom_64B rom(
        //Input Addr and Enable
        .address(address_buss[5:0]), //Lower 6 addr buss bits

        //Output Data
        .data_out(data_buss_rom)
    );

    //---------------------------------
    //Onboard REG RAM
    //---------------------------------
    reg reg_ram_active;

    //Register ram is only active for addresses
    //0x78, 0x79, 0x7a, 0x7b, 0x7c, 0x7d, 0x7e, 0x7f
    always @ (address_buss) begin
        if(address_buss >= 7'h78)
            reg_ram_active = 1;
        else
            reg_ram_active = 0;
    end

    reg_ram_8B ram(
        //Input CLK and RST
        .clk_in(clk),
        .rst_in(rst_n),

        //Input Addr
        .address(address_buss[2:0]),

        //Input Data
        .data_in(data_buss_out),

        //Input WE
        .we_in(we_signal),
        .en_in(reg_ram_active),

        //Output Data
        .data_out(data_buss_ram)
    );

    //---------------------------------
    //Output enable control
    //---------------------------------
    drive_enable_fanout oe_driver(
        //Drive enable input signal
        .drive_en(drive_enable_sig),

        //Output drive signals
        .drive(data_buss_oe)
    );

endmodule


/*
 * Copyright (c) 2024 Zachary Frazee
 * SPDX-License-Identifier: Apache-2.0
 */

//---------------------------------
//Top Level CPU Module
//---------------------------------
module minibyte_cpu (
    //Basic Inputs
    input  wire       clk_in, ena_in, rst_in,
    input  wire       halt_in,

    //Memory and IO Inputs
    input  wire [7:0] data_in,

    //DFT Testmode Inputs
    input  wire [2:0] tm_control,

    //Memory and IO Outputs
    output wire [7:0] addr_out,
    output wire [7:0] data_out,
    output wire       we_out,
    output wire       drive_out
);

    //Main Data Buss
    //--------------------------------
    wire [7:0] main_buss;

    //Data out comes from the main buss
    assign data_out = main_buss;


    //ALU A-Side Input Data Buss
    //--------------------------------
    wire [7:0] alu_a_buss;


    //Address Busses
    //--------------------------------
    wire [7:0] m_addr_buss;
    wire [7:0] pc_addr_buss;
    wire [7:0] ir_op_buss;
    wire [7:0] normal_addr_out;

    //DFT Wires
    //--------------------------------
    wire [7:0] dft_cu_state;

    //Control Signals
    //--------------------------------

    //Set register signals
    wire ctrl_set_a;
    wire ctrl_set_m;
    wire ctrl_set_pc;
    wire ctrl_set_ir;
    wire ctrl_set_ccr;

    //Inc register signals
    wire ctrl_inc_pc;

    //Addr mux signals
    wire       ctrl_addr_mux;

    //Alu control signals
    wire [3:0] ctrl_alu_op;

    //Data direction control
    wire   ctrl_we_out;
    wire   ctrl_drive_out;
    assign we_out=ctrl_we_out;
    assign drive_out=ctrl_drive_out;


    //Branch Signals
    //--------------------------------
    wire [1:0] flags_zn_buss;
    wire [1:0] ccr_zn_buss;


    //A Register
    //--------------------------------
    minibyte_genreg reg_a(
        //Basic Inputs
        .clk_in(clk_in), .rst_in(rst_in),

        //Register Inputs
        .reg_in(main_buss),
        .set_in(ctrl_set_a),

        //Register Outputs
        .reg_out(alu_a_buss)
    );


    //M Register
    //--------------------------------
    minibyte_genreg reg_m(
        //Basic Inputs
        .clk_in(clk_in), .rst_in(rst_in),

        //Register Inputs
        .reg_in(main_buss),
        .set_in(ctrl_set_m),

        //Register Outputs
        .reg_out(m_addr_buss)
    );


    //PC Register
    //--------------------------------
    minibyte_pcreg reg_pc(
        //Basic Inputs
        .clk_in(clk_in), .rst_in(rst_in),

        //Register Inputs
        .reg_in(main_buss),
        .set_in(ctrl_set_pc),
        .inc_in(ctrl_inc_pc),

        //Register Outputs
        .reg_out(pc_addr_buss)
    );


    //IR Register
    //--------------------------------
    minibyte_genreg reg_ir(
        //Basic Inputs
        .clk_in(clk_in), .rst_in(rst_in),

        //Register Inputs
        .reg_in(main_buss),
        .set_in(ctrl_set_ir),

        //Register Outputs
        .reg_out(ir_op_buss)
    );


    //CCR Register
    //--------------------------------
    minibyte_ccrreg reg_ccr(
        //Basic Inputs
        .clk_in(clk_in), .rst_in(rst_in),

        //Register Inputs
        .reg_in(flags_zn_buss),
        .set_in(ctrl_set_ccr),

        //Register Outputs
        .reg_out(ccr_zn_buss)
    );


    //Addr Out Mux
    //--------------------------------
    minibyte_genmux_2x addr_mux(
        //Mux Inputs
        .a_in(pc_addr_buss),
        .b_in(m_addr_buss),

        //Mux Select
        .sel_in(ctrl_addr_mux),

        //Mux Output
        .mux_out(normal_addr_out)
    );


    //Debug Out Mux
    //--------------------------------
    minibyte_genmux_8x tm_debug_out_mux(
        //Mux Inputs
        .a_in(normal_addr_out),        //0 -> Normal        output
        .b_in(alu_a_buss),             //1 -> A             output
        .c_in({7'h0, alu_a_buss[7]}),  //2 -> A (UPPER BIT) output
        .d_in(m_addr_buss),            //3 -> M             output
        .e_in(pc_addr_buss),           //4 -> PC            output
        .f_in(ir_op_buss),             //5 -> IR            output
        .g_in({6'h0,ccr_zn_buss}),     //6 -> CCR           output
        .h_in(dft_cu_state),           //7 -> CU STATE      output

        //Mux Select
        .sel_in(tm_control[2:0]),

        //Mux Output
        .mux_out(addr_out)
    );


    //ALU
    //--------------------------------
    minibyte_alu alu(
        //ALU Inputs
        .a_in(alu_a_buss),
        .b_in(data_in),
        .alu_op_in(ctrl_alu_op),

        .res_out(main_buss),
        .flags_zn_out(flags_zn_buss)
    );


    //Control Unit
    //--------------------------------
    minibyte_cu cu(
        //Basic Inputs
        .clk_in(clk_in), .ena_in(ena_in), .rst_in(rst_in),
        .halt_in(halt_in),

        //IR Input
        .ir_op_buss_in(ir_op_buss),

        //ALU Flags Input
        .ccr_flag_zn_in(ccr_zn_buss),

        //Control signal outputs
        .set_a_out(ctrl_set_a),
        .set_m_out(ctrl_set_m),
        .set_pc_out(ctrl_set_pc),
        .set_ir_out(ctrl_set_ir),
        .set_ccr_out(ctrl_set_ccr),
        .inc_pc_out(ctrl_inc_pc),

        //Addr select signals
        .addr_mux_out(ctrl_addr_mux),

        //Alu control signals
        .alu_op_out(ctrl_alu_op),

        //Write to memory
        .we_out(ctrl_we_out),

        //Drive enable on data bus
        .drive_out(ctrl_drive_out),

        //DFT Output
        .dft_curr_state(dft_cu_state)
    );

endmodule


/*
 * Copyright (c) 2024 Zachary Frazee
 * SPDX-License-Identifier: Apache-2.0
 */

//---------------------------------
//Control Unit
//---------------------------------
module minibyte_cu(
    //Basic Inputs
    input  wire       clk_in, ena_in, rst_in,
    input  wire       halt_in,

    //IR Input
    input  wire [7:0] ir_op_buss_in,

    //ALU Flags Input
    input  wire [1:0] ccr_flag_zn_in,

    //Control signal outputs
    output reg        set_a_out,
    output reg        set_m_out,
    output reg        set_pc_out,
    output reg        set_ir_out,
    output reg        set_ccr_out,
    output reg        inc_pc_out,

    //Addr select signals
    output reg        addr_mux_out,

    //Alu control signals
    output reg [3:0]  alu_op_out,

    //Write to memory
    output reg        we_out,

    //Drive enable on data bus
    output reg        drive_out,

    //DFT Output
    output reg  [7:0] dft_curr_state
);

    //State machine memory
    //--------------------------
    reg [7:0] curr_state, next_state;

    //CPU IR opcodes
    //--------------------------
    parameter IR_NOP     = 8'h00;
    parameter IR_LDA_IMM = 8'h01;
    parameter IR_LDA_DIR = 8'h02;
    parameter IR_STA_DIR = 8'h03;
    parameter IR_STA_IND = 8'h04;
    parameter IR_ADD_IMM = 8'h05;
    parameter IR_ADD_DIR = 8'h06;
    parameter IR_SUB_IMM = 8'h07;
    parameter IR_SUB_DIR = 8'h08;
    parameter IR_AND_IMM = 8'h09;
    parameter IR_AND_DIR = 8'h0A;
    parameter IR_OR_IMM  = 8'h0B;
    parameter IR_OR_DIR  = 8'h0C;
    parameter IR_XOR_IMM = 8'h0D;
    parameter IR_XOR_DIR = 8'h0E;
    parameter IR_LSL_IMM = 8'h0F;
    parameter IR_LSL_DIR = 8'h10;
    parameter IR_LSR_IMM = 8'h11;
    parameter IR_LSR_DIR = 8'h12;
    parameter IR_ASL_IMM = 8'h13;
    parameter IR_ASL_DIR = 8'h14;
    parameter IR_ASR_IMM = 8'h15;
    parameter IR_ASR_DIR = 8'h16;
    parameter IR_RSL_IMM = 8'h17;
    parameter IR_RSL_DIR = 8'h18;
    parameter IR_RSR_IMM = 8'h19;
    parameter IR_RSR_DIR = 8'h1A;
    parameter IR_JMP_DIR = 8'h1B;
    parameter IR_JMP_IND = 8'h1C;
    parameter IR_BNE_DIR = 8'h1D;
    parameter IR_BNE_IND = 8'h1E;
    parameter IR_BEQ_DIR = 8'h1F;
    parameter IR_BEQ_IND = 8'h20;
    parameter IR_BPL_DIR = 8'h21;
    parameter IR_BPL_IND = 8'h22;
    parameter IR_BMI_DIR = 8'h23;
    parameter IR_BMI_IND = 8'h24;

    //State machine opcodes
    //--------------------------
    parameter S_RESET_0   = 8'h00;
    parameter S_PC_INC_0  = 8'h01;
    parameter S_FETCH_0   = 8'h02;
    parameter S_FETCH_1   = 8'h03;
    parameter S_FETCH_2   = 8'h04;
    parameter S_DECODE_0  = 8'h05;
    parameter S_LDA_IMM_0 = 8'h06;
    parameter S_LDA_IMM_1 = 8'h07;
    parameter S_LDA_DIR_0 = 8'h08;
    parameter S_LDA_DIR_1 = 8'h09;
    parameter S_LDA_DIR_2 = 8'h0A;
    parameter S_LDA_DIR_3 = 8'h0B;
    parameter S_STA_DIR_0 = 8'h0C;
    parameter S_STA_DIR_1 = 8'h0D;
    parameter S_STA_DIR_2 = 8'h0E;
    parameter S_STA_DIR_3 = 8'h0F;
    parameter S_STA_IND_0 = 8'h10;
    parameter S_STA_IND_1 = 8'h11;
    parameter S_STA_IND_2 = 8'h12;
    parameter S_STA_IND_3 = 8'h13;
    parameter S_STA_IND_4 = 8'h14;
    parameter S_STA_IND_5 = 8'h15;
    parameter S_ADD_IMM_0 = 8'h16;
    parameter S_ADD_IMM_1 = 8'h17;
    parameter S_ADD_DIR_0 = 8'h18;
    parameter S_ADD_DIR_1 = 8'h19;
    parameter S_ADD_DIR_2 = 8'h1A;
    parameter S_ADD_DIR_3 = 8'h1B;
    parameter S_SUB_IMM_0 = 8'h1C;
    parameter S_SUB_IMM_1 = 8'h1D;
    parameter S_SUB_DIR_0 = 8'h1E;
    parameter S_SUB_DIR_1 = 8'h1F;
    parameter S_SUB_DIR_2 = 8'h20;
    parameter S_SUB_DIR_3 = 8'h21;
    parameter S_AND_IMM_0 = 8'h22;
    parameter S_AND_IMM_1 = 8'h23;
    parameter S_AND_DIR_0 = 8'h24;
    parameter S_AND_DIR_1 = 8'h25;
    parameter S_AND_DIR_2 = 8'h26;
    parameter S_AND_DIR_3 = 8'h27;
    parameter S_OR_IMM_0  = 8'h28;
    parameter S_OR_IMM_1  = 8'h29;
    parameter S_OR_DIR_0  = 8'h2A;
    parameter S_OR_DIR_1  = 8'h2B;
    parameter S_OR_DIR_2  = 8'h2C;
    parameter S_OR_DIR_3  = 8'h2D;
    parameter S_XOR_IMM_0 = 8'h2E;
    parameter S_XOR_IMM_1 = 8'h2F;
    parameter S_XOR_DIR_0 = 8'h30;
    parameter S_XOR_DIR_1 = 8'h31;
    parameter S_XOR_DIR_2 = 8'h32;
    parameter S_XOR_DIR_3 = 8'h33;
    parameter S_LSL_IMM_0 = 8'h34;
    parameter S_LSL_IMM_1 = 8'h35;
    parameter S_LSL_DIR_0 = 8'h36;
    parameter S_LSL_DIR_1 = 8'h37;
    parameter S_LSL_DIR_2 = 8'h38;
    parameter S_LSL_DIR_3 = 8'h39;
    parameter S_LSR_IMM_0 = 8'h3A;
    parameter S_LSR_IMM_1 = 8'h3B;
    parameter S_LSR_DIR_0 = 8'h3C;
    parameter S_LSR_DIR_1 = 8'h3D;
    parameter S_LSR_DIR_2 = 8'h3E;
    parameter S_LSR_DIR_3 = 8'h3F;
    parameter S_ASL_IMM_0 = 8'h40;
    parameter S_ASL_IMM_1 = 8'h41;
    parameter S_ASL_DIR_0 = 8'h42;
    parameter S_ASL_DIR_1 = 8'h43;
    parameter S_ASL_DIR_2 = 8'h44;
    parameter S_ASL_DIR_3 = 8'h45;
    parameter S_ASR_IMM_0 = 8'h46;
    parameter S_ASR_IMM_1 = 8'h47;
    parameter S_ASR_DIR_0 = 8'h48;
    parameter S_ASR_DIR_1 = 8'h49;
    parameter S_ASR_DIR_2 = 8'h4A;
    parameter S_ASR_DIR_3 = 8'h4B;
    parameter S_RSL_IMM_0 = 8'h4C;
    parameter S_RSL_IMM_1 = 8'h4D;
    parameter S_RSL_DIR_0 = 8'h4E;
    parameter S_RSL_DIR_1 = 8'h4F;
    parameter S_RSL_DIR_2 = 8'h50;
    parameter S_RSL_DIR_3 = 8'h51;
    parameter S_RSR_IMM_0 = 8'h52;
    parameter S_RSR_IMM_1 = 8'h53;
    parameter S_RSR_DIR_0 = 8'h54;
    parameter S_RSR_DIR_1 = 8'h55;
    parameter S_RSR_DIR_2 = 8'h56;
    parameter S_RSR_DIR_3 = 8'h57;
    parameter S_JMP_DIR_0 = 8'h58;
    parameter S_JMP_DIR_1 = 8'h59;
    parameter S_JMP_IND_0 = 8'h5A;
    parameter S_JMP_IND_1 = 8'h5B;
    parameter S_JMP_IND_2 = 8'h5C;
    parameter S_JMP_IND_3 = 8'h5D;

    //--------------------------
    //ALU OPS
    //--------------------------
    parameter OP_ALU_PASSA = 4'b0000;
    parameter OP_ALU_PASSB = 4'b0001;
    parameter OP_ALU_ADD   = 4'b0010;
    parameter OP_ALU_SUB   = 4'b0011;
    parameter OP_ALU_AND   = 4'b0100;
    parameter OP_ALU_OR    = 4'b0101;
    parameter OP_ALU_XOR   = 4'b0110;
    parameter OP_ALU_LSL   = 4'b0111;
    parameter OP_ALU_LSR   = 4'b1000;
    parameter OP_ALU_ASL   = 4'b1001;
    parameter OP_ALU_ASR   = 4'b1010;
    parameter OP_ALU_RSL   = 4'b1011;
    parameter OP_ALU_RSR   = 4'b1100;

    //State memory block
    //--------------------------
    always @ (posedge clk_in or negedge rst_in) begin
        //Reset to S_RESET_0 on reset
        if(!rst_in)
            curr_state <= S_RESET_0;

        //Dont move states if enable is low
        else if(!ena_in)
            curr_state <= curr_state;

        //Otherwise go to next state on every clk
        else
            curr_state <= next_state;
    end


    //Output logic
    //--------------------------
    always @ (curr_state) begin
        case(curr_state)

            //Reset sequence
            //-----

            //Do nothing until the next state
            S_RESET_0: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //ALU dont care
                alu_op_out   = 0;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //PC Increment
            //-----

            //Increment PC
            S_PC_INC_0: begin
                //Increment program counter
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 1;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //ALU dont care
                alu_op_out   = 0;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Fetch sequence
            //-----

            //Send PC addr out
            S_FETCH_0: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //B (mem input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSB;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Load IR from memory
            S_FETCH_1: begin
                //Set IR Reg
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 1;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //B (mem input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSB;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Inc PC now that IR is loaded
            S_FETCH_2: begin
                //Inc PC
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 1;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //B (mem input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSB;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Decode sequence
            //-----

            //Do nothing until the next state
            S_DECODE_0: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //ALU dont care
                alu_op_out   = 0;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //LDA_IMM sequence
            //-----

            //Pass incoming data from memory to the main buss
            S_LDA_IMM_0: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //B (mem input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSB;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Latch data to A
            S_LDA_IMM_1: begin
                //Latch A
                set_a_out    = 1;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //B (mem input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSB;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //LDA_DIR sequence
            //-----

            //Pass incoming data from memory to the main buss
            S_LDA_DIR_0: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //B (mem input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSB;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Latch data to M
            S_LDA_DIR_1: begin
                //Latch M
                set_a_out    = 0;
                set_m_out    = 1;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //B (mem input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSB;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Set addr out to M
            S_LDA_DIR_2: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //M selected
                addr_mux_out = 1;

                //B (mem input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSB;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Latch data to A
            S_LDA_DIR_3: begin
                //Latch A
                set_a_out    = 1;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //M selected
                addr_mux_out = 1;

                //B (mem input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSB;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //STA_DIR sequence
            //-----

            //Pass incoming data from memory to the main buss
            S_STA_DIR_0: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //B (mem input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSB;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Latch data to M
            S_STA_DIR_1: begin
                //Latch M
                set_a_out    = 0;
                set_m_out    = 1;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //B (mem input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSB;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Set address and WE, also prepare A data on the main buss
            S_STA_DIR_2: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //M selected
                addr_mux_out = 1;

                //A (A input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSA;

                //Set WE so that the receiving device is ready for us to drive data
                we_out       = 1;
                drive_out    = 0;
            end

            //Drive the data out
            S_STA_DIR_3: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //M selected
                addr_mux_out = 1;

                //A (A input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSA;

                //Drive out A data
                we_out       = 1;
                drive_out    = 1;
            end

            //STA_IND sequence
            //-----

            //Pass incoming data from memory to the main buss
            S_STA_IND_0: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //B (mem input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSB;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Latch data to M
            S_STA_IND_1: begin
                //Latch M
                set_a_out    = 0;
                set_m_out    = 1;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //B (mem input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSB;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end


            //Fetch data located at this address
            S_STA_IND_2: begin
                //Latch M
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //M selected
                addr_mux_out = 1;

                //B (mem input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSB;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Latch data to M
            S_STA_IND_3: begin
                //Latch M
                set_a_out    = 0;
                set_m_out    = 1;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //M selected
                addr_mux_out = 1;

                //B (mem input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSB;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Set address and WE, also prepare A data on the main buss
            S_STA_IND_4: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //M selected
                addr_mux_out = 1;

                //A (A input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSA;

                //Set WE so that the receiving device is ready for us to drive data
                we_out       = 1;
                drive_out    = 0;
            end

            //Drive the data out
            S_STA_IND_5: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //M selected
                addr_mux_out = 1;

                //A (A input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSA;

                //Drive out A data
                we_out       = 1;
                drive_out    = 1;
            end

            //ADD_IMM sequence
            //-----

            //Add the incoming data from the operand that the PC is pointing to
            S_ADD_IMM_0: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //ALU->Addition
                alu_op_out   = OP_ALU_ADD;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Latch data to A/CCR
            S_ADD_IMM_1: begin
                //Latch A and CCR
                set_a_out    = 1;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 1;

                //PC selected
                addr_mux_out = 0;

                //ALU->Addition
                alu_op_out   = OP_ALU_ADD;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //ADD_DIR sequence
            //-----

            //Pass incoming data from memory to the main buss
            S_ADD_DIR_0: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //B (mem input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSB;

                //Dont write
                we_out       = 0;
                drive_out    = 0;
            end

            //Latch data to M
            S_ADD_DIR_1: begin
                //Latch M
                set_a_out    = 0;
                set_m_out    = 1;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //B (mem input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSB;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Set addr out to M and prep to add incoming data
            S_ADD_DIR_2: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //M selected
                addr_mux_out = 1;

                //ALU->Addition
                alu_op_out   = OP_ALU_ADD;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Latch data to A/CCR
            S_ADD_DIR_3: begin
                //Latch A and CCR
                set_a_out    = 1;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 1;

                //M selected
                addr_mux_out = 1;

                //ALU->Addition
                alu_op_out   = OP_ALU_ADD;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //SUB_IMM sequence
            //-----

            //Subtract the incoming data from the operand that the PC is pointing to
            S_SUB_IMM_0: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //ALU->Subtraction
                alu_op_out   = OP_ALU_SUB;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Latch data to A/CCR
            S_SUB_IMM_1: begin
                //Latch A and CCR
                set_a_out    = 1;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 1;

                //PC selected
                addr_mux_out = 0;

                //ALU->Subtraction
                alu_op_out   = OP_ALU_SUB;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //SUB_DIR sequence
            //-----

            //Pass incoming data from memory to the main buss
            S_SUB_DIR_0: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //B (mem input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSB;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Latch data to M
            S_SUB_DIR_1: begin
                //Latch M
                set_a_out    = 0;
                set_m_out    = 1;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //B (mem input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSB;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Set addr out to M and prep to subtract incoming data
            S_SUB_DIR_2: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //M selected
                addr_mux_out = 1;

                //ALU->Subtraction
                alu_op_out   = OP_ALU_SUB;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Latch data to A/CCR
            S_SUB_DIR_3: begin
                //Latch A and CCR
                set_a_out    = 1;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 1;

                //M selected
                addr_mux_out = 1;

                //ALU->Subtraction
                alu_op_out   = OP_ALU_SUB;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //AND_IMM sequence
            //-----

            //And the incoming data from the operand that the PC is pointing to
            S_AND_IMM_0: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //ALU->Logical AND
                alu_op_out   = OP_ALU_AND;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Latch data to A/CCR
            S_AND_IMM_1: begin
                //Latch A and CCR
                set_a_out    = 1;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 1;

                //PC selected
                addr_mux_out = 0;

                //ALU->Logical AND
                alu_op_out   = OP_ALU_AND;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //AND_DIR sequence
            //-----

            //Pass incoming data from memory to the main buss
            S_AND_DIR_0: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //B (mem input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSB;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Latch data to M
            S_AND_DIR_1: begin
                //Latch M
                set_a_out    = 0;
                set_m_out    = 1;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //B (mem input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSB;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Set addr out to M and prep to AND incoming data
            S_AND_DIR_2: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //M selected
                addr_mux_out = 1;

                //ALU->Logical AND
                alu_op_out   = OP_ALU_AND;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Latch data to A/CCR
            S_AND_DIR_3: begin
                //Latch A and CCR
                set_a_out    = 1;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 1;

                //M selected
                addr_mux_out = 1;

                //ALU->Logical AND
                alu_op_out   = OP_ALU_AND;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //OR_IMM sequence
            //-----

            //And the incoming data from the operand that the PC is pointing to
            S_OR_IMM_0: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //ALU->Logical OR
                alu_op_out   = OP_ALU_OR;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Latch data to A/CCR
            S_OR_IMM_1: begin
                //Latch A and CCR
                set_a_out    = 1;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 1;

                //PC selected
                addr_mux_out = 0;

                //ALU->Logical OR
                alu_op_out   = OP_ALU_OR;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //OR_DIR sequence
            //-----

            //Pass incoming data from memory to the main buss
            S_OR_DIR_0: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //B (mem input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSB;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Latch data to M
            S_OR_DIR_1: begin
                //Latch M
                set_a_out    = 0;
                set_m_out    = 1;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //B (mem input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSB;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Set addr out to M and prep to OR incoming data
            S_OR_DIR_2: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //M selected
                addr_mux_out = 1;

                //ALU->Logical OR
                alu_op_out   = OP_ALU_OR;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Latch data to A/CCR
            S_OR_DIR_3: begin
                //Latch A and CCR
                set_a_out    = 1;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 1;

                //M selected
                addr_mux_out = 1;

                //ALU->Logical OR
                alu_op_out   = OP_ALU_OR;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //XOR_IMM sequence
            //-----

            //And the incoming data from the operand that the PC is pointing to
            S_XOR_IMM_0: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //ALU->Logical XOR
                alu_op_out   = OP_ALU_XOR;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Latch data to A/CCR
            S_XOR_IMM_1: begin
                //Latch A and CCR
                set_a_out    = 1;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 1;

                //PC selected
                addr_mux_out = 0;

                //ALU->Logical XOR
                alu_op_out   = OP_ALU_XOR;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //XOR_DIR sequence
            //-----

            //Pass incoming data from memory to the main buss
            S_XOR_DIR_0: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //B (mem input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSB;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Latch data to M
            S_XOR_DIR_1: begin
                //Latch M
                set_a_out    = 0;
                set_m_out    = 1;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //B (mem input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSB;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Set addr out to M and prep to XOR incoming data
            S_XOR_DIR_2: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //M selected
                addr_mux_out = 1;

                //ALU->Logical XOR
                alu_op_out   = OP_ALU_XOR;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Latch data to A/CCR
            S_XOR_DIR_3: begin
                //Latch A and CCR
                set_a_out    = 1;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 1;

                //M selected
                addr_mux_out = 1;

                //ALU->Logical XOR
                alu_op_out   = OP_ALU_XOR;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //LSL_IMM sequence
            //-----

            //Add the incoming data from the operand that the PC is pointing to
            S_LSL_IMM_0: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //ALU->Logical Shift Left
                alu_op_out   = OP_ALU_LSL;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Latch data to A/CCR
            S_LSL_IMM_1: begin
                //Latch A and CCR
                set_a_out    = 1;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 1;

                //PC selected
                addr_mux_out = 0;

                //ALU->Logical Shift Left
                alu_op_out   = OP_ALU_LSL;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //LSL_DIR sequence
            //-----

            //Pass incoming data from memory to the main buss
            S_LSL_DIR_0: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //B (mem input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSB;

                //Dont write
                we_out       = 0;
                drive_out    = 0;
            end

            //Latch data to M
            S_LSL_DIR_1: begin
                //Latch M
                set_a_out    = 0;
                set_m_out    = 1;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //B (mem input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSB;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Set addr out to M and prep to add incoming data
            S_LSL_DIR_2: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //M selected
                addr_mux_out = 1;

                //ALU->Logical Shift Left
                alu_op_out   = OP_ALU_LSL;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Latch data to A/CCR
            S_LSL_DIR_3: begin
                //Latch A and CCR
                set_a_out    = 1;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 1;

                //M selected
                addr_mux_out = 1;

                //ALU->Logical Shift Left
                alu_op_out   = OP_ALU_LSL;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //LSR_IMM sequence
            //-----

            //Add the incoming data from the operand that the PC is pointing to
            S_LSR_IMM_0: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //ALU->Logical Shift Right
                alu_op_out   = OP_ALU_LSR;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Latch data to A/CCR
            S_LSR_IMM_1: begin
                //Latch A and CCR
                set_a_out    = 1;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 1;

                //PC selected
                addr_mux_out = 0;

                //ALU->Logical Shift Right
                alu_op_out   = OP_ALU_LSR;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //LSR_DIR sequence
            //-----

            //Pass incoming data from memory to the main buss
            S_LSR_DIR_0: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //B (mem input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSB;

                //Dont write
                we_out       = 0;
                drive_out    = 0;
            end

            //Latch data to M
            S_LSR_DIR_1: begin
                //Latch M
                set_a_out    = 0;
                set_m_out    = 1;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //B (mem input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSB;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Set addr out to M and prep to add incoming data
            S_LSR_DIR_2: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //M selected
                addr_mux_out = 1;

                //ALU->Logical Shift Right
                alu_op_out   = OP_ALU_LSR;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Latch data to A/CCR
            S_LSR_DIR_3: begin
                //Latch A and CCR
                set_a_out    = 1;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 1;

                //M selected
                addr_mux_out = 1;

                //ALU->Logical Shift Right
                alu_op_out   = OP_ALU_LSR;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //ASL_IMM sequence
            //-----

            //Add the incoming data from the operand that the PC is pointing to
            S_ASL_IMM_0: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //ALU->Arithmetic Shift Left
                alu_op_out   = OP_ALU_ASL;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Latch data to A/CCR
            S_ASL_IMM_1: begin
                //Latch A and CCR
                set_a_out    = 1;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 1;

                //PC selected
                addr_mux_out = 0;

                //ALU->Arithmetic Shift Left
                alu_op_out   = OP_ALU_ASL;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //ASL_DIR sequence
            //-----

            //Pass incoming data from memory to the main buss
            S_ASL_DIR_0: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //B (mem input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSB;

                //Dont write
                we_out       = 0;
                drive_out    = 0;
            end

            //Latch data to M
            S_ASL_DIR_1: begin
                //Latch M
                set_a_out    = 0;
                set_m_out    = 1;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //B (mem input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSB;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Set addr out to M and prep to add incoming data
            S_ASL_DIR_2: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //M selected
                addr_mux_out = 1;

                //ALU->Arithmetic Shift Left
                alu_op_out   = OP_ALU_ASL;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Latch data to A/CCR
            S_ASL_DIR_3: begin
                //Latch A and CCR
                set_a_out    = 1;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 1;

                //M selected
                addr_mux_out = 1;

                //ALU->Arithmetic Shift Left
                alu_op_out   = OP_ALU_ASL;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //ASR_IMM sequence
            //-----

            //Add the incoming data from the operand that the PC is pointing to
            S_ASR_IMM_0: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //ALU->Arithmetic Shift Right
                alu_op_out   = OP_ALU_ASR;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Latch data to A/CCR
            S_ASR_IMM_1: begin
                //Latch A and CCR
                set_a_out    = 1;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 1;

                //PC selected
                addr_mux_out = 0;

                //ALU->Arithmetic Shift Right
                alu_op_out   = OP_ALU_ASR;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //ASR_DIR sequence
            //-----

            //Pass incoming data from memory to the main buss
            S_ASR_DIR_0: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //B (mem input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSB;

                //Dont write
                we_out       = 0;
                drive_out    = 0;
            end

            //Latch data to M
            S_ASR_DIR_1: begin
                //Latch M
                set_a_out    = 0;
                set_m_out    = 1;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //B (mem input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSB;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Set addr out to M and prep to add incoming data
            S_ASR_DIR_2: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //M selected
                addr_mux_out = 1;

                //ALU->Arithmetic Shift Right
                alu_op_out   = OP_ALU_ASR;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Latch data to A/CCR
            S_ASR_DIR_3: begin
                //Latch A and CCR
                set_a_out    = 1;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 1;

                //M selected
                addr_mux_out = 1;

                //ALU->Arithmetic Shift Right
                alu_op_out   = OP_ALU_ASR;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //RSL_IMM sequence
            //-----

            //Add the incoming data from the operand that the PC is pointing to
            S_RSL_IMM_0: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //ALU->Rotary Shift Left
                alu_op_out   = OP_ALU_RSL;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Latch data to A/CCR
            S_RSL_IMM_1: begin
                //Latch A and CCR
                set_a_out    = 1;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 1;

                //PC selected
                addr_mux_out = 0;

                //ALU->Rotary Shift Left
                alu_op_out   = OP_ALU_RSL;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //RSL_DIR sequence
            //-----

            //Pass incoming data from memory to the main buss
            S_RSL_DIR_0: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //B (mem input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSB;

                //Dont write
                we_out       = 0;
                drive_out    = 0;
            end

            //Latch data to M
            S_RSL_DIR_1: begin
                //Latch M
                set_a_out    = 0;
                set_m_out    = 1;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //B (mem input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSB;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Set addr out to M and prep to add incoming data
            S_RSL_DIR_2: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //M selected
                addr_mux_out = 1;

                //ALU->Rotary Shift Left
                alu_op_out   = OP_ALU_RSL;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Latch data to A/CCR
            S_RSL_DIR_3: begin
                //Latch A and CCR
                set_a_out    = 1;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 1;

                //M selected
                addr_mux_out = 1;

                //ALU->Rotary Shift Left
                alu_op_out   = OP_ALU_RSL;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //RSR_IMM sequence
            //-----

            //Add the incoming data from the operand that the PC is pointing to
            S_RSR_IMM_0: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //ALU->Rotary Shift Right
                alu_op_out   = OP_ALU_RSR;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Latch data to A/CCR
            S_RSR_IMM_1: begin
                //Latch A and CCR
                set_a_out    = 1;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 1;

                //PC selected
                addr_mux_out = 0;

                //ALU->Rotary Shift Right
                alu_op_out   = OP_ALU_RSR;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //RSR_DIR sequence
            //-----

            //Pass incoming data from memory to the main buss
            S_RSR_DIR_0: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //B (mem input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSB;

                //Dont write
                we_out       = 0;
                drive_out    = 0;
            end

            //Latch data to M
            S_RSR_DIR_1: begin
                //Latch M
                set_a_out    = 0;
                set_m_out    = 1;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //B (mem input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSB;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Set addr out to M and prep to add incoming data
            S_RSR_DIR_2: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //M selected
                addr_mux_out = 1;

                //ALU->Rotary Shift Right
                alu_op_out   = OP_ALU_RSR;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Latch data to A/CCR
            S_RSR_DIR_3: begin
                //Latch A and CCR
                set_a_out    = 1;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 1;

                //M selected
                addr_mux_out = 1;

                //ALU->Rotary Shift Right
                alu_op_out   = OP_ALU_RSR;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //JMP_DIR sequence
            //-----

            //Pass incoming data from memory to the main buss
            S_JMP_DIR_0: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //B (mem input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSB;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Latch data to PC
            S_JMP_DIR_1: begin
                //Latch PC
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 1;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //B (mem input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSB;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //JMP_IND sequence
            //-----

            //Pass incoming data from memory to the main buss
            S_JMP_IND_0: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //B (mem input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSB;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Latch data to M
            S_JMP_IND_1: begin
                //Latch M
                set_a_out    = 0;
                set_m_out    = 1;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //B (mem input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSB;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Set addr out to M
            S_JMP_IND_2: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //M selected
                addr_mux_out = 1;

                //B (mem input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSB;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Latch data to PC
            S_JMP_IND_3: begin
                //Latch PC
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 1;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //M selected
                addr_mux_out = 1;

                //B (mem input) passthrough to main bus
                alu_op_out   = OP_ALU_PASSB;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

            //Default (INVALID) sequence
            //-----
            default: begin
                //Dont set or inc any registers
                set_a_out    = 0;
                set_m_out    = 0;
                set_pc_out   = 0;
                inc_pc_out   = 0;
                set_ir_out   = 0;
                set_ccr_out  = 0;

                //PC selected
                addr_mux_out = 0;

                //ALU dont care
                alu_op_out   = 0;

                //Dont write or drive
                we_out       = 0;
                drive_out    = 0;
            end

        endcase
    end


    //Next state logic
    //--------------------------
    always @ (curr_state, ir_op_buss_in, ccr_flag_zn_in, halt_in) begin
        //DFT Output
        dft_curr_state = curr_state;

        //Next state logic
        case(curr_state)
            //Reset sequence (skips PC increment on boot)
            S_RESET_0: next_state = S_FETCH_0;

            //PC Increment
            S_PC_INC_0: next_state = S_FETCH_0;

            //Fetch sequence
            S_FETCH_0: begin
                if(halt_in == 1)
                    next_state = S_FETCH_0; //Remain in S_FETCH_0 forever if halt is asserted
                else
                    next_state = S_FETCH_1; //Otherwise continue fetching this instruction
            end

            S_FETCH_1: next_state = S_FETCH_2;
            S_FETCH_2: next_state = S_DECODE_0;

            //Decode IR Opcode
            S_DECODE_0: begin
                case(ir_op_buss_in)
                    //IR_NOP (does nothing)
                    IR_NOP: next_state = S_FETCH_0;

                    //IR_LDA_IMM (load immediate value to A)
                    IR_LDA_IMM: next_state = S_LDA_IMM_0;

                    //IR_LDA_DIR (load direct value to A)
                    IR_LDA_DIR: next_state = S_LDA_DIR_0;

                    //IR_STA_DIR (store A at direct address)
                    IR_STA_DIR: next_state = S_STA_DIR_0;

                    //IR_STA_IND (store A at indirect address)
                    IR_STA_IND: next_state = S_STA_IND_0;

                    //IR_ADD_IMM (add immediate value to A)
                    IR_ADD_IMM: next_state = S_ADD_IMM_0;

                    //IR_ADD_DIR (add direct value to A)
                    IR_ADD_DIR: next_state = S_ADD_DIR_0;

                    //IR_SUB_IMM (subtract immediate value from A)
                    IR_SUB_IMM: next_state = S_SUB_IMM_0;

                    //IR_SUB_DIR (subtract direct value from A)
                    IR_SUB_DIR: next_state = S_SUB_DIR_0;

                    //IR_AND_IMM (logical AND immediate value with A)
                    IR_AND_IMM: next_state = S_AND_IMM_0;

                    //IR_AND_DIR (logical AND direct value with A)
                    IR_AND_DIR: next_state = S_AND_DIR_0;

                    //IR_OR_IMM (logical OR immediate value with A)
                    IR_OR_IMM: next_state = S_OR_IMM_0;

                    //IR_OR_DIR (logical OR direct value with A)
                    IR_OR_DIR: next_state = S_OR_DIR_0;

                    //IR_XOR_IMM (logical XOR immediate value with A)
                    IR_XOR_IMM: next_state = S_XOR_IMM_0;

                    //IR_XOR_DIR (logical XOR direct value with A)
                    IR_XOR_DIR: next_state = S_XOR_DIR_0;

                    //IR_LSL_IMM (logical left shift immediate value with A)
                    IR_LSL_IMM: next_state = S_LSL_IMM_0;

                    //IR_LSL_DIR (logical left shift direct value with A)
                    IR_LSL_DIR: next_state = S_LSL_DIR_0;

                    //IR_LSR_IMM (logical right shift immediate value with A)
                    IR_LSR_IMM: next_state = S_LSR_IMM_0;

                    //IR_LSR_DIR (logical right shift direct value with A)
                    IR_LSR_DIR: next_state = S_LSR_DIR_0;

                    //IR_ASL_IMM (arithmetic left shift immediate value with A)
                    IR_ASL_IMM: next_state = S_ASL_IMM_0;

                    //IR_ASL_DIR (arithmetic left shift direct value with A)
                    IR_ASL_DIR: next_state = S_ASL_DIR_0;

                    //IR_ASR_IMM (arithmetic right shift immediate value with A)
                    IR_ASR_IMM: next_state = S_ASR_IMM_0;

                    //IR_ASR_DIR (arithmetic right shift direct value with A)
                    IR_ASR_DIR: next_state = S_ASR_DIR_0;

                    //IR_RSL_IMM (rotary left shift immediate value with A)
                    IR_RSL_IMM: next_state = S_RSL_IMM_0;

                    //IR_RSL_DIR (rotary left shift direct value with A)
                    IR_RSL_DIR: next_state = S_RSL_DIR_0;

                    //IR_RSR_IMM (rotary right shift immediate value with A)
                    IR_RSR_IMM: next_state = S_RSR_IMM_0;

                    //IR_RSR_DIR (rotary right shift direct value with A)
                    IR_RSR_DIR: next_state = S_RSR_DIR_0;

                    //IR_JMP_DIR (load direct value to PC)
                    IR_JMP_DIR: next_state = S_JMP_DIR_0;

                    //IR_LDA_DIR (load indirect value to PC)
                    IR_JMP_IND: next_state = S_JMP_IND_0;

                    //IR_BNE_DIR (banch if z clear direct)
                    IR_BNE_DIR: begin
                        if(ccr_flag_zn_in[1] == 0)
                            next_state = S_JMP_DIR_0;
                        else
                            next_state = S_PC_INC_0;
                    end

                    //IR_BNE_IND (banch if z clear indirect)
                    IR_BNE_IND: begin
                        if(ccr_flag_zn_in[1] == 0)
                            next_state = S_JMP_IND_0;
                        else
                            next_state = S_PC_INC_0;
                    end

                    //IR_BEQ_DIR (banch if z set direct)
                    IR_BEQ_DIR: begin
                        if(ccr_flag_zn_in[1] == 1)
                            next_state = S_JMP_DIR_0;
                        else
                            next_state = S_PC_INC_0;
                    end

                    //IR_BEQ_IND (banch if z set indirect)
                    IR_BEQ_IND: begin
                        if(ccr_flag_zn_in[1] == 1)
                            next_state = S_JMP_IND_0;
                        else
                            next_state = S_PC_INC_0;
                    end

                    //IR_BPL_DIR (banch if n clear direct)
                    IR_BPL_DIR: begin
                        if(ccr_flag_zn_in[0] == 0)
                            next_state = S_JMP_DIR_0;
                        else
                            next_state = S_PC_INC_0;
                    end

                    //IR_BPL_IND (banch if n clear indirect)
                    IR_BPL_IND: begin
                        if(ccr_flag_zn_in[0] == 0)
                            next_state = S_JMP_IND_0;
                        else
                            next_state = S_PC_INC_0;
                    end

                    //IR_BMI_DIR (banch if n set direct)
                    IR_BMI_DIR: begin
                        if(ccr_flag_zn_in[0] == 1)
                            next_state = S_JMP_DIR_0;
                        else
                            next_state = S_PC_INC_0;
                    end

                    //IR_BMI_IND (banch if n set indirect)
                    IR_BMI_IND: begin
                        if(ccr_flag_zn_in[0] == 1)
                            next_state = S_JMP_IND_0;
                        else
                            next_state = S_PC_INC_0;
                    end

                    //Invalid IR, goto fetch_0
                    default: next_state = S_FETCH_0;

                endcase
            end

            //LDA_IMM sequence
            S_LDA_IMM_0: next_state = S_LDA_IMM_1;
            S_LDA_IMM_1: next_state = S_PC_INC_0;

            //LDA_DIR sequence
            S_LDA_DIR_0: next_state = S_LDA_DIR_1;
            S_LDA_DIR_1: next_state = S_LDA_DIR_2;
            S_LDA_DIR_2: next_state = S_LDA_DIR_3;
            S_LDA_DIR_3: next_state = S_PC_INC_0;

            //STA_DIR sequence
            S_STA_DIR_0: next_state = S_STA_DIR_1;
            S_STA_DIR_1: next_state = S_STA_DIR_2;
            S_STA_DIR_2: next_state = S_STA_DIR_3;
            S_STA_DIR_3: next_state = S_PC_INC_0;

            //STA_IND sequence
            S_STA_IND_0: next_state = S_STA_IND_1;
            S_STA_IND_1: next_state = S_STA_IND_2;
            S_STA_IND_2: next_state = S_STA_IND_3;
            S_STA_IND_3: next_state = S_STA_IND_4;
            S_STA_IND_4: next_state = S_STA_IND_5;
            S_STA_IND_5: next_state = S_PC_INC_0;

            //ADD_IMM sequence
            S_ADD_IMM_0: next_state = S_ADD_IMM_1;
            S_ADD_IMM_1: next_state = S_PC_INC_0;

            //ADD_DIR sequence
            S_ADD_DIR_0: next_state = S_ADD_DIR_1;
            S_ADD_DIR_1: next_state = S_ADD_DIR_2;
            S_ADD_DIR_2: next_state = S_ADD_DIR_3;
            S_ADD_DIR_3: next_state = S_PC_INC_0;

            //SUB_IMM sequence
            S_SUB_IMM_0: next_state = S_SUB_IMM_1;
            S_SUB_IMM_1: next_state = S_PC_INC_0;

            //SUB_DIR sequence
            S_SUB_DIR_0: next_state = S_SUB_DIR_1;
            S_SUB_DIR_1: next_state = S_SUB_DIR_2;
            S_SUB_DIR_2: next_state = S_SUB_DIR_3;
            S_SUB_DIR_3: next_state = S_PC_INC_0;

            //AND_IMM sequence
            S_AND_IMM_0: next_state = S_AND_IMM_1;
            S_AND_IMM_1: next_state = S_PC_INC_0;

            //AND_DIR sequence
            S_AND_DIR_0: next_state = S_AND_DIR_1;
            S_AND_DIR_1: next_state = S_AND_DIR_2;
            S_AND_DIR_2: next_state = S_AND_DIR_3;
            S_AND_DIR_3: next_state = S_PC_INC_0;

            //OR_IMM sequence
            S_OR_IMM_0: next_state = S_OR_IMM_1;
            S_OR_IMM_1: next_state = S_PC_INC_0;

            //OR_DIR sequence
            S_OR_DIR_0: next_state = S_OR_DIR_1;
            S_OR_DIR_1: next_state = S_OR_DIR_2;
            S_OR_DIR_2: next_state = S_OR_DIR_3;
            S_OR_DIR_3: next_state = S_PC_INC_0;

            //XOR_IMM sequence
            S_XOR_IMM_0: next_state = S_XOR_IMM_1;
            S_XOR_IMM_1: next_state = S_PC_INC_0;

            //XOR_DIR sequence
            S_XOR_DIR_0: next_state = S_XOR_DIR_1;
            S_XOR_DIR_1: next_state = S_XOR_DIR_2;
            S_XOR_DIR_2: next_state = S_XOR_DIR_3;
            S_XOR_DIR_3: next_state = S_PC_INC_0;

            //LSL_IMM sequence
            S_LSL_IMM_0: next_state = S_LSL_IMM_1;
            S_LSL_IMM_1: next_state = S_PC_INC_0;

            //LSL_DIR sequence
            S_LSL_DIR_0: next_state = S_LSL_DIR_1;
            S_LSL_DIR_1: next_state = S_LSL_DIR_2;
            S_LSL_DIR_2: next_state = S_LSL_DIR_3;
            S_LSL_DIR_3: next_state = S_PC_INC_0;

            //LSR_IMM sequence
            S_LSR_IMM_0: next_state = S_LSR_IMM_1;
            S_LSR_IMM_1: next_state = S_PC_INC_0;

            //LSR_DIR sequence
            S_LSR_DIR_0: next_state = S_LSR_DIR_1;
            S_LSR_DIR_1: next_state = S_LSR_DIR_2;
            S_LSR_DIR_2: next_state = S_LSR_DIR_3;
            S_LSR_DIR_3: next_state = S_PC_INC_0;

            //ASL_IMM sequence
            S_ASL_IMM_0: next_state = S_ASL_IMM_1;
            S_ASL_IMM_1: next_state = S_PC_INC_0;

            //ASL_DIR sequence
            S_ASL_DIR_0: next_state = S_ASL_DIR_1;
            S_ASL_DIR_1: next_state = S_ASL_DIR_2;
            S_ASL_DIR_2: next_state = S_ASL_DIR_3;
            S_ASL_DIR_3: next_state = S_PC_INC_0;

            //ASR_IMM sequence
            S_ASR_IMM_0: next_state = S_ASR_IMM_1;
            S_ASR_IMM_1: next_state = S_PC_INC_0;

            //ASR_DIR sequence
            S_ASR_DIR_0: next_state = S_ASR_DIR_1;
            S_ASR_DIR_1: next_state = S_ASR_DIR_2;
            S_ASR_DIR_2: next_state = S_ASR_DIR_3;
            S_ASR_DIR_3: next_state = S_PC_INC_0;

            //RSL_IMM sequence
            S_RSL_IMM_0: next_state = S_RSL_IMM_1;
            S_RSL_IMM_1: next_state = S_PC_INC_0;

            //RSL_DIR sequence
            S_RSL_DIR_0: next_state = S_RSL_DIR_1;
            S_RSL_DIR_1: next_state = S_RSL_DIR_2;
            S_RSL_DIR_2: next_state = S_RSL_DIR_3;
            S_RSL_DIR_3: next_state = S_PC_INC_0;

            //RSR_IMM sequence
            S_RSR_IMM_0: next_state = S_RSR_IMM_1;
            S_RSR_IMM_1: next_state = S_PC_INC_0;

            //RSR_DIR sequence
            S_RSR_DIR_0: next_state = S_RSR_DIR_1;
            S_RSR_DIR_1: next_state = S_RSR_DIR_2;
            S_RSR_DIR_2: next_state = S_RSR_DIR_3;
            S_RSR_DIR_3: next_state = S_PC_INC_0;

            //JMP_DIR sequence
            S_JMP_DIR_0: next_state = S_JMP_DIR_1;
            S_JMP_DIR_1: next_state = S_FETCH_0;

            //JMP_IND sequence
            S_JMP_IND_0: next_state = S_JMP_IND_1;
            S_JMP_IND_1: next_state = S_JMP_IND_2;
            S_JMP_IND_2: next_state = S_JMP_IND_3;
            S_JMP_IND_3: next_state = S_FETCH_0;

            //Should never get here
            default:
                next_state = S_PC_INC_0;
        endcase
    end
endmodule


/*
 * Copyright (c) 2024 Zachary Frazee
 * SPDX-License-Identifier: Apache-2.0
 */

//---------------------------------------------------------------------------------------------------------
// MINIBYTE ALU
//---------------------------------------------------------------------------------------------------------
// OPERATION | ALU_OP | MEANING
//---------------------------------------------------------------------------------------------------------
// PASSA     | 0b0000  | Passthrough input A
// PASSB     | 0b0001  | Passthrough input B
// ADD       | 0b0010  | Add A and B
// SUB       | 0b0011  | Subtract B from A
// AND       | 0b0100  | Logical and of A, B
// OR        | 0b0101  | Logical or of A, B
// XOR       | 0b0110  | Logical xor of A, B
// LSL       | 0b0111  | Logical shift A left by B
// LSR       | 0b1000  | Logical shift A right by B
// ASL       | 0b1001  | Arithmetic shift A left by B
// ASR       | 0b1010  | Arithmetic shift A right by B
// RSL       | 0b1011  | Rotary shift A left by B
// RSR       | 0b1100  | Rotary shift A right by B
//---------------------------------------------------------------------------------------------------------

//--------------------------
//Params
//--------------------------
parameter ALU_PASSA  = 4'b0000;
parameter ALU_PASSB  = 4'b0001;
parameter ALU_ADD    = 4'b0010;
parameter ALU_SUB    = 4'b0011;
parameter ALU_AND    = 4'b0100;
parameter ALU_OR     = 4'b0101;
parameter ALU_XOR    = 4'b0110;
parameter ALU_LSL    = 4'b0111;
parameter ALU_LSR    = 4'b1000;
parameter ALU_ASL    = 4'b1001;
parameter ALU_ASR    = 4'b1010;
parameter ALU_RSL    = 4'b1011;
parameter ALU_RSR    = 4'b1100;

//--------------------------
//ALU Module
//--------------------------
module minibyte_alu (
    //ALU Inputs
    input wire signed [7:0] a_in,
    input wire signed [7:0] b_in,
    input wire        [3:0] alu_op_in,

    //ALU Outputs
    output reg signed [7:0] res_out,
    output reg        [1:0] flags_zn_out
);

    //Main Procedural Block
    //--------------------------
    always @(*) begin

        //Assign ALU result
        //---------------------
        case(alu_op_in)

            //A Passthrough
            //--------------
            ALU_PASSA:
                res_out = a_in;

            //B Passthrough
            //--------------
            ALU_PASSB:
                res_out = b_in;

            //Addition
            //--------------
            ALU_ADD:
                res_out = a_in + b_in;

            //Subtraction
            //--------------
            ALU_SUB:
                res_out = a_in - b_in;

            //Logical AND
            //--------------
            ALU_AND:
                res_out = a_in & b_in;

            //Logical OR
            //--------------
            ALU_OR:
                res_out = a_in | b_in;

            //Logical XOR
            //--------------
            ALU_XOR:
                res_out = a_in ^ b_in;

            //Logical Shift Left
            //--------------
            ALU_LSL:
                res_out = a_in << b_in;

            //Logical Shift Right
            //--------------
            ALU_LSR:
                res_out = a_in >> b_in;

            //Arithmetic Shift Left
            //--------------
            ALU_ASL:
                res_out = a_in <<< b_in;

            //Arithmetic Shift Right
            //--------------
            ALU_ASR:
                res_out = a_in >>> b_in;

            //Rotary Shift Left
            //--------------
            ALU_RSL:
                case(b_in[2:0])
                    //Hardcoded concatenations of all possible inputs
                    3'b000:
                        res_out = a_in;
                    3'b001:
                        res_out = {a_in[6:0], a_in[7]};
                    3'b010:
                        res_out = {a_in[5:0], a_in[7:6]};
                    3'b011:
                        res_out = {a_in[4:0], a_in[7:5]};
                    3'b100:
                        res_out = {a_in[3:0], a_in[7:4]};
                    3'b101:
                        res_out = {a_in[2:0], a_in[7:3]};
                    3'b110:
                        res_out = {a_in[1:0], a_in[7:2]};
                    3'b111:
                        res_out = {a_in[0], a_in[7:1]};
                endcase

            //Rotary Shift Right
            //--------------
            ALU_RSR:
                case(b_in[2:0])
                    //Hardcoded concatenations of all possible inputs
                    3'b000:
                        res_out = a_in;
                    3'b001:
                        res_out = {a_in[0], a_in[7:1]};
                    3'b010:
                        res_out = {a_in[1:0], a_in[7:2]};
                    3'b011:
                        res_out = {a_in[2:0], a_in[7:3]};
                    3'b100:
                        res_out = {a_in[3:0], a_in[7:4]};
                    3'b101:
                        res_out = {a_in[4:0], a_in[7:5]};
                    3'b110:
                        res_out = {a_in[5:0], a_in[7:6]};
                    3'b111:
                        res_out = {a_in[6:0], a_in[7]};
                endcase

            //Default (SHOULD NEVER GET HERE)
            //--------------
            default:
                res_out = 0;

        endcase

        //Assign Zero flag
        //---------------------
        if(res_out == 0)
            flags_zn_out[1] = 1;
        else
            flags_zn_out[1] = 0;

        //Assign Negative flag
        //---------------------
        flags_zn_out[0] = res_out[7];

    end

endmodule


/*
 * Copyright (c) 2024 Zachary Frazee
 * SPDX-License-Identifier: Apache-2.0
 */

//--------------------------
//General Register Module
//--------------------------
module minibyte_genreg (
    //Basic Inputs
    input  wire       clk_in, rst_in,

    //Register Inputs
    input  wire [7:0] reg_in,
    input  wire       set_in,

    //Register Outputs
    output reg  [7:0] reg_out
);

    //Main Procedural Block
    //--------------------------
    always @(posedge clk_in or negedge rst_in) begin
        //Reset if rst goes low
        if(!rst_in)
            reg_out <= 0;
        else
            //Set register to input if set signal goes high on a clk
            if(set_in)
                reg_out <= reg_in;
    end
endmodule

//--------------------------
//CCR Register Module
//--------------------------
module minibyte_ccrreg (
    //Basic Inputs
    input  wire       clk_in, rst_in,

    //Register Inputs
    input  wire [1:0] reg_in,
    input  wire       set_in,

    //Register Outputs
    output reg  [1:0] reg_out
);

    //Main Procedural Block
    //--------------------------
    always @(posedge clk_in or negedge rst_in) begin
        //Reset if rst goes low
        if(!rst_in)
            reg_out <= 0;
        else
            //Set register to input if set signal goes high on a clk
            if(set_in)
                reg_out <= reg_in;
    end
endmodule

//---------------------------------
//Program Counter Register Module
//---------------------------------
module minibyte_pcreg (
    //Basic Inputs
    input  wire       clk_in, rst_in,

    //Register Inputs
    input  wire [7:0] reg_in,
    input  wire       set_in,
    input  wire       inc_in,

    //Register Outputs
    output reg  [7:0] reg_out
);

    //Main Procedural Block
    //--------------------------
    always @(posedge clk_in or negedge rst_in) begin
        //Reset if rst goes low
        if(!rst_in)
            reg_out <= 0;
        else
            //Set register to input if set signal goes high
            if(set_in)
                reg_out <= reg_in;

            //Increment register if inc signal goes high on a clk
            else if(inc_in)
                reg_out <= reg_out + 1;
    end
endmodule


/*
 * Copyright (c) 2024 Zachary Frazee
 * SPDX-License-Identifier: Apache-2.0
 */

//---------------------------------
//Generic 2->1 Mux Module
//---------------------------------
module minibyte_genmux_2x(
    //Mux Inputs
    input  wire [7:0] a_in,
    input  wire [7:0] b_in,

    //Mux Select
    input  wire       sel_in,

    //Mux Output
    output reg  [7:0] mux_out
);

    //Main Procedural Block
    //--------------------------
    always @(*) begin
        //A out if sel is 0
        if(sel_in == 0)
            mux_out = a_in;
        //B out if sel is 1
        else
            mux_out = b_in;
    end

endmodule

//---------------------------------
//Generic 4->1 Mux Module
//---------------------------------
module minibyte_genmux_4x(
    //Mux Inputs
    input  wire [7:0] a_in,
    input  wire [7:0] b_in,
    input  wire [7:0] c_in,
    input  wire [7:0] d_in,

    //Mux Select
    input  wire [1:0] sel_in,

    //Mux Output
    output reg  [7:0] mux_out
);

    //Main Procedural Block
    //--------------------------
    always @(*) begin
        //A out if sel is 00
        if(sel_in == 2'b00)
            mux_out = a_in;

        //B out if sel is 01
        else if(sel_in == 2'b01)
            mux_out = b_in;

        //C out if sel is 10
        else if(sel_in == 2'b10)
            mux_out = c_in;

        //D out if sel is 11
        else
            mux_out = d_in;
    end

endmodule


//---------------------------------
//Generic 8->1 Mux Module
//---------------------------------
module minibyte_genmux_8x(
    //Mux Inputs
    input  wire [7:0] a_in,
    input  wire [7:0] b_in,
    input  wire [7:0] c_in,
    input  wire [7:0] d_in,
    input  wire [7:0] e_in,
    input  wire [7:0] f_in,
    input  wire [7:0] g_in,
    input  wire [7:0] h_in,

    //Mux Select
    input  wire [2:0] sel_in,

    //Mux Output
    output reg  [7:0] mux_out
);
// >>> Module Implementation Begin

// <<< Module Implementation End
endmodule





/*
 * Copyright (c) 2024 Zachary Frazee
 * SPDX-License-Identifier: Apache-2.0
 */

//---------------------------------
//Drive enable device
//---------------------------------
module drive_enable_fanout(
    //Drive enable input signal
    input  wire      drive_en,

    //Output drive signals
    output reg [7:0] drive
);

    //Main Procedural Block
    //--------------------------
    always @(*) begin
        if(drive_en == 0)
            drive = 0;
        else
            drive = 8'hff;
    end

endmodule


/*
 * Copyright (c) 2024 Zachary Frazee
 * SPDX-License-Identifier: Apache-2.0
 */


//CPU IR opcodes
//--------------------------
parameter _NOP     = 8'h00;
parameter _LDA_IMM = 8'h01;
parameter _LDA_DIR = 8'h02;
parameter _STA_DIR = 8'h03;
//parameter _STA_IND = 8'h04;
parameter _ADD_IMM = 8'h05;
//parameter _ADD_DIR = 8'h06;
//parameter _SUB_IMM = 8'h07;
//parameter _SUB_DIR = 8'h08;
//parameter _AND_IMM = 8'h09;
//parameter _AND_DIR = 8'h0A;
//parameter _OR_IMM  = 8'h0B;
//parameter _OR_DIR  = 8'h0C;
//parameter _XOR_IMM = 8'h0D;
//parameter _XOR_DIR = 8'h0E;
parameter _LSL_IMM = 8'h0F;
//parameter _LSL_DIR = 8'h10;
//parameter _LSR_IMM = 8'h11;
//parameter _LSR_DIR = 8'h12;
//parameter _ASL_IMM = 8'h13;
//parameter _ASL_DIR = 8'h14;
//parameter _ASR_IMM = 8'h15;
//parameter _ASR_DIR = 8'h16;
//parameter _RSL_IMM = 8'h17;
//parameter _RSL_DIR = 8'h18;
//parameter _RSR_IMM = 8'h19;
//parameter _RSR_DIR = 8'h1A;
parameter _JMP_DIR = 8'h1B;
//parameter _JMP_IND = 8'h1C;
parameter _BNE_DIR = 8'h1D;
//parameter _BNE_IND = 8'h1E;
//parameter _BEQ_DIR = 8'h1F;
//parameter _BEQ_IND = 8'h20;
parameter _BPL_DIR = 8'h21;
//parameter _BPL_IND = 8'h22;
//parameter _BMI_DIR = 8'h23;
//parameter _BMI_IND = 8'h24;

//--------------------------
//Demo ROM Program
//--------------------------
module demo_rom_64B(
    //Input Addr
    input wire [5:0] address,

    //Output Data
    output reg [7:0] data_out
);
    always @(address)
        case(address)
            6'h00:   data_out = _NOP;        //First istr is a NOP
            6'h01:   data_out = _LDA_IMM;    //Make sure A is zero
            6'h02:   data_out = 0;
            6'h03:   data_out = _NOP;        //NOP is the START of the LOOP0
            6'h04:   data_out = _ADD_IMM;    //ADD 1 to A
            6'h05:   data_out = 1;
            6'h06:   data_out = _STA_DIR;    //Write this value to 0x40
            6'h07:   data_out = 8'h40;
            6'h08:   data_out = _BNE_DIR;    //Keep branching to LOOP0 until we roll over to 0
            6'h09:   data_out = 8'h03;

            6'h0A:   data_out = _LDA_IMM;    //Load a 1 into A
            6'h0B:   data_out = 1;
            6'h0C:   data_out = _STA_DIR;    //Write this value to 0x40
            6'h0D:   data_out = 8'h40;
            6'h0E:   data_out = _NOP;        //NOP is the START of the LOOP1
            6'h0F:   data_out = _LSL_IMM;    //Shift A left by 1
            6'h10:   data_out = 1;
            6'h11:   data_out = _STA_DIR;    //Write this value to 0x40
            6'h12:   data_out = 8'h40;
            6'h13:   data_out = _BPL_DIR;    //Keep branching to LOOP1 until we hit 0b10000000
            6'h14:   data_out = 8'h0E;

            6'h15:   data_out = _LDA_IMM;    //Load DEADBEEF into RAM
            6'h16:   data_out = 8'hDE;
            6'h17:   data_out = _STA_DIR;
            6'h18:   data_out = 8'h78;
            6'h19:   data_out = _LDA_IMM;
            6'h1A:   data_out = 8'hAD;
            6'h1B:   data_out = _STA_DIR;
            6'h1C:   data_out = 8'h79;
            6'h1D:   data_out = _LDA_IMM;
            6'h1E:   data_out = 8'hBE;
            6'h1F:   data_out = _STA_DIR;
            6'h20:   data_out = 8'h7A;
            6'h21:   data_out = _LDA_IMM;
            6'h22:   data_out = 8'hEF;
            6'h23:   data_out = _STA_DIR;
            6'h24:   data_out = 8'h7B;

            6'h25:   data_out = _LDA_DIR;    //READ out the contents of RAM
            6'h26:   data_out = 8'h78;
            6'h27:   data_out = _STA_DIR;    //Write this value to 0x40
            6'h28:   data_out = 8'h40;
            6'h29:   data_out = _LDA_DIR;    //READ out the contents of RAM
            6'h2A:   data_out = 8'h79;
            6'h2B:   data_out = _STA_DIR;    //Write this value to 0x40
            6'h2C:   data_out = 8'h40;
            6'h2D:   data_out = _LDA_DIR;    //READ out the contents of RAM
            6'h2E:   data_out = 8'h7A;
            6'h2F:   data_out = _STA_DIR;    //Write this value to 0x40
            6'h30:   data_out = 8'h40;
            6'h31:   data_out = _LDA_DIR;    //READ out the contents of RAM
            6'h32:   data_out = 8'h7B;
            6'h33:   data_out = _STA_DIR;    //Write this value to 0x40
            6'h34:   data_out = 8'h40;

            6'h35:   data_out = _JMP_DIR;    //Start the whole thing over!
            6'h36:   data_out = 8'h00;

            default: data_out = 0;           //Unused space
        endcase
endmodule


/*
 * Copyright (c) 2024 Zachary Frazee
 * SPDX-License-Identifier: Apache-2.0
 */

//--------------------------
//REGISTER RAM
//--------------------------
module reg_ram_8B(
    //Input CLK and RST
    input wire clk_in,
    input wire rst_in,

    //Input Addr
    input wire [2:0] address,

    //Input Data
    input wire [7:0] data_in,

    //Input WE and EN
    input wire we_in,
    input wire en_in,

    //Output Data
    output reg [7:0] data_out
);
    //Data busses
    //------------------------------------
    reg  [7:0] r_we;

    reg  [7:0] r0_out_data;
    reg  [7:0] r1_out_data;
    reg  [7:0] r2_out_data;
    reg  [7:0] r3_out_data;
    reg  [7:0] r4_out_data;
    reg  [7:0] r5_out_data;
    reg  [7:0] r6_out_data;
    reg  [7:0] r7_out_data;

    //Data registers
    //------------------------------------
    minibyte_genreg r0(
        //Basic Inputs
        .clk_in(clk_in), .rst_in(rst_in),

        //Register Inputs
        .reg_in(data_in),
        .set_in(r_we[0]),

        //Register Outputs
        .reg_out(r0_out_data)
    );

    minibyte_genreg r1(
        //Basic Inputs
        .clk_in(clk_in), .rst_in(rst_in),

        //Register Inputs
        .reg_in(data_in),
        .set_in(r_we[1]),

        //Register Outputs
        .reg_out(r1_out_data)
    );

    minibyte_genreg r2(
        //Basic Inputs
        .clk_in(clk_in), .rst_in(rst_in),

        //Register Inputs
        .reg_in(data_in),
        .set_in(r_we[2]),

        //Register Outputs
        .reg_out(r2_out_data)
    );

    minibyte_genreg r3(
        //Basic Inputs
        .clk_in(clk_in), .rst_in(rst_in),

        //Register Inputs
        .reg_in(data_in),
        .set_in(r_we[3]),

        //Register Outputs
        .reg_out(r3_out_data)
    );

    minibyte_genreg r4(
        //Basic Inputs
        .clk_in(clk_in), .rst_in(rst_in),

        //Register Inputs
        .reg_in(data_in),
        .set_in(r_we[4]),

        //Register Outputs
        .reg_out(r4_out_data)
    );

    minibyte_genreg r5(
        //Basic Inputs
        .clk_in(clk_in), .rst_in(rst_in),

        //Register Inputs
        .reg_in(data_in),
        .set_in(r_we[5]),

        //Register Outputs
        .reg_out(r5_out_data)
    );

    minibyte_genreg r6(
        //Basic Inputs
        .clk_in(clk_in), .rst_in(rst_in),

        //Register Inputs
        .reg_in(data_in),
        .set_in(r_we[6]),

        //Register Outputs
        .reg_out(r6_out_data)
    );

    minibyte_genreg r7(
        //Basic Inputs
        .clk_in(clk_in), .rst_in(rst_in),

        //Register Inputs
        .reg_in(data_in),
        .set_in(r_we[7]),

        //Register Outputs
        .reg_out(r7_out_data)
    );

    //Register control logic
    //------------------------------------
    always @ (*) begin
        if (!en_in) begin
            data_out = 8'h00;
            r_we     = 8'h00;
        end

        else if (we_in) begin
            case(address)
                3'b000:
                    r_we = 8'b00000001;
                3'b001:
                    r_we = 8'b00000010;
                3'b010:
                    r_we = 8'b00000100;
                3'b011:
                    r_we = 8'b00001000;
                3'b100:
                    r_we = 8'b00010000;
                3'b101:
                    r_we = 8'b00100000;
                3'b110:
                    r_we = 8'b01000000;
                3'b111:
                    r_we = 8'b10000000;
                default:
                    r_we = 8'b00000000;
            endcase

            data_out = 8'h00;
        end

        else begin
            case(address)
                3'b000:
                    data_out = r0_out_data;
                3'b001:
                    data_out = r1_out_data;
                3'b010:
                    data_out = r2_out_data;
                3'b011:
                    data_out = r3_out_data;
                3'b100:
                    data_out = r4_out_data;
                3'b101:
                    data_out = r5_out_data;
                3'b110:
                    data_out = r6_out_data;
                3'b111:
                    data_out = r7_out_data;
            endcase

            r_we = 8'h00;
        end
    end

endmodule


Reference solution:
rtl/generated.v: 
    //Main Procedural Block
    //--------------------------
    always @(*) begin
        //A out if sel is 000
        if(sel_in == 3'b000)
            mux_out = a_in;

        //B out if sel is 001
        else if(sel_in == 3'b001)
            mux_out = b_in;

        //C out if sel is 010
        else if(sel_in == 3'b010)
            mux_out = c_in;

        //D out if sel is 011
        else if(sel_in == 3'b011)
            mux_out = d_in;

        //E out if sel is 100
        else if(sel_in == 3'b100)
            mux_out = e_in;

        //F out if sel is 101
        else if(sel_in == 3'b101)
            mux_out = f_in;

        //G out if sel is 110
        else if(sel_in == 3'b110)
            mux_out = g_in;

        //H out if sel is 111
        else
            mux_out = h_in;
    end