OpenCores
URL https://opencores.org/ocsvn/t6507lp/t6507lp/trunk

Subversion Repositories t6507lp

[/] [t6507lp/] [trunk/] [rtl/] [verilog/] [t6507lp_fsm.v] - Diff between revs 242 and 243

Go to most recent revision | Only display areas with differences | Details | Blame | View Log

Rev 242 Rev 243
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////                                                                    ////
////                                                                    ////
//// T6507LP IP Core                                                    ////
//// T6507LP IP Core                                                    ////
////                                                                    ////
////                                                                    ////
//// This file is part of the T6507LP project                           ////
//// This file is part of the T6507LP project                           ////
//// http://www.opencores.org/cores/t6507lp/                            ////
//// http://www.opencores.org/cores/t6507lp/                            ////
////                                                                    ////
////                                                                    ////
//// Description                                                        ////
//// Description                                                        ////
//// 6507 FSM                                                           ////
//// 6507 FSM                                                           ////
////                                                                    ////
////                                                                    ////
//// TODO:                                                              ////
//// TODO:                                                              ////
//// - Fix relative mode, bit 7 means negative                          ////
//// - Fix relative mode, bit 7 means negative                          ////
//// - Check reset behavior                                             ////
//// - Check reset behavior                                             ////
//// - Comment the code                                                 ////
//// - Comment the code                                                 ////
////                                                                    ////
////                                                                    ////
//// Author(s):                                                         ////
//// Author(s):                                                         ////
//// - Gabriel Oshiro Zardo, gabrieloshiro@gmail.com                    ////
//// - Gabriel Oshiro Zardo, gabrieloshiro@gmail.com                    ////
//// - Samuel Nascimento Pagliarini (creep), snpagliarini@gmail.com     ////
//// - Samuel Nascimento Pagliarini (creep), snpagliarini@gmail.com     ////
////                                                                    ////
////                                                                    ////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////                                                                    ////
////                                                                    ////
//// Copyright (C) 2001 Authors and OPENCORES.ORG                       ////
//// Copyright (C) 2001 Authors and OPENCORES.ORG                       ////
////                                                                    ////
////                                                                    ////
//// This source file may be used and distributed without               ////
//// This source file may be used and distributed without               ////
//// restriction provided that this copyright statement is not          ////
//// restriction provided that this copyright statement is not          ////
//// removed from the file and that any derivative work contains        ////
//// removed from the file and that any derivative work contains        ////
//// the original copyright notice and the associated disclaimer.       ////
//// the original copyright notice and the associated disclaimer.       ////
////                                                                    ////
////                                                                    ////
//// This source file is free software; you can redistribute it         ////
//// This source file is free software; you can redistribute it         ////
//// and/or modify it under the terms of the GNU Lesser General         ////
//// and/or modify it under the terms of the GNU Lesser General         ////
//// Public License as published by the Free Software Foundation;       ////
//// Public License as published by the Free Software Foundation;       ////
//// either version 2.1 of the License, or (at your option) any         ////
//// either version 2.1 of the License, or (at your option) any         ////
//// later version.                                                     ////
//// later version.                                                     ////
////                                                                    ////
////                                                                    ////
//// This source is distributed in the hope that it will be             ////
//// This source is distributed in the hope that it will be             ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied         ////
//// useful, but WITHOUT ANY WARRANTY; without even the implied         ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR            ////
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR            ////
//// PURPOSE. See the GNU Lesser General Public License for more        ////
//// PURPOSE. See the GNU Lesser General Public License for more        ////
//// details.                                                           ////
//// details.                                                           ////
////                                                                    ////
////                                                                    ////
//// You should have received a copy of the GNU Lesser General          ////
//// You should have received a copy of the GNU Lesser General          ////
//// Public License along with this source; if not, download it         ////
//// Public License along with this source; if not, download it         ////
//// from http://www.opencores.org/lgpl.shtml                           ////
//// from http://www.opencores.org/lgpl.shtml                           ////
////                                                                    ////
////                                                                    ////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
 
 
`include "timescale.v"
`include "timescale.v"
 
 
module t6507lp_fsm(clk, reset_n, alu_result, alu_status, data_in, alu_x, alu_y, address, mem_rw, data_out, alu_opcode, alu_a, alu_enable);
module t6507lp_fsm(clk, reset_n, alu_result, alu_status, data_in, alu_x, alu_y, address, mem_rw, data_out, alu_opcode, alu_a, alu_enable);
        parameter [3:0] DATA_SIZE = 4'd8;
        parameter [3:0] DATA_SIZE = 4'd8;
        parameter [3:0] ADDR_SIZE = 4'd13;
        parameter [3:0] ADDR_SIZE = 4'd13;
 
 
        localparam [3:0] DATA_SIZE_ = DATA_SIZE - 4'b0001;
        localparam [3:0] DATA_SIZE_ = DATA_SIZE - 4'b0001;
        localparam [3:0] ADDR_SIZE_ = ADDR_SIZE - 4'b0001;
        localparam [3:0] ADDR_SIZE_ = ADDR_SIZE - 4'b0001;
 
 
        input clk;                              // master clock
        input clk;                              // master clock
        input reset_n;                          // active low reset
        input reset_n;                          // active low reset
        input [DATA_SIZE_:0] alu_result; // result from alu operation
        input [DATA_SIZE_:0] alu_result; // result from alu operation
        input [DATA_SIZE_:0] alu_status; // alu status register
        input [DATA_SIZE_:0] alu_status; // alu status register
        input [DATA_SIZE_:0] data_in;            // data that comes from the bus controller
        input [DATA_SIZE_:0] data_in;            // data that comes from the bus controller
        input [DATA_SIZE_:0] alu_x;              // alu x index register
        input [DATA_SIZE_:0] alu_x;              // alu x index register
        input [DATA_SIZE_:0] alu_y;              // alu y index register
        input [DATA_SIZE_:0] alu_y;              // alu y index register
        output reg [ADDR_SIZE_:0] address;       // system bus address
        output reg [ADDR_SIZE_:0] address;       // system bus address
        output reg mem_rw;                      // read = 0, write = 1
        output reg mem_rw;                      // read = 0, write = 1
        output reg [DATA_SIZE_:0] data_out;      // data that will be written somewhere else
        output reg [DATA_SIZE_:0] data_out;      // data that will be written somewhere else
        output reg [DATA_SIZE_:0] alu_opcode;    // current opcode
        output reg [DATA_SIZE_:0] alu_opcode;    // current opcode
        output reg [DATA_SIZE_:0] alu_a; // extra operand sent to the alu
        output reg [DATA_SIZE_:0] alu_a; // extra operand sent to the alu
        output reg alu_enable;                  // a flag that when high tells the alu when to perform the operations
        output reg alu_enable;                  // a flag that when high tells the alu when to perform the operations
 
 
 
 
        // FSM states. If aiming for less power consumption try gray coding.
        // FSM states. If aiming for less power consumption try gray coding.
        //localparam FETCH_OP_CALC = 5'b00001; this was never used
        //localparam FETCH_OP_CALC = 5'b00001; this was never used
        localparam FETCH_OP = 5'b00000;
        localparam FETCH_OP = 5'b00000;
        localparam FETCH_LOW = 5'b00010;
        localparam FETCH_LOW = 5'b00010;
        localparam FETCH_HIGH = 5'b00011;
        localparam FETCH_HIGH = 5'b00011;
        localparam READ_MEM = 5'b00100;
        localparam READ_MEM = 5'b00100;
        localparam DUMMY_WRT_CALC = 5'b00101;
        localparam DUMMY_WRT_CALC = 5'b00101;
        localparam WRITE_MEM = 5'b00110;
        localparam WRITE_MEM = 5'b00110;
        localparam FETCH_OP_CALC_PARAM = 5'b00111;
        localparam FETCH_OP_CALC_PARAM = 5'b00111;
        localparam READ_MEM_CALC_INDEX = 5'b01000;
        localparam READ_MEM_CALC_INDEX = 5'b01000;
        localparam FETCH_HIGH_CALC_INDEX = 5'b01001;
        localparam FETCH_HIGH_CALC_INDEX = 5'b01001;
        localparam READ_MEM_FIX_ADDR = 5'b01010;
        localparam READ_MEM_FIX_ADDR = 5'b01010;
        localparam FETCH_OP_EVAL_BRANCH = 5'b01011;
        localparam FETCH_OP_EVAL_BRANCH = 5'b01011;
        localparam FETCH_OP_FIX_PC = 5'b01100;
        localparam FETCH_OP_FIX_PC = 5'b01100;
        localparam READ_FROM_POINTER = 5'b01101;
        localparam READ_FROM_POINTER = 5'b01101;
        localparam READ_FROM_POINTER_X = 5'b01110;
        localparam READ_FROM_POINTER_X = 5'b01110;
        localparam READ_FROM_POINTER_X1 = 5'b01111;
        localparam READ_FROM_POINTER_X1 = 5'b01111;
        localparam PUSH_PCH = 5'b10000;
        localparam PUSH_PCH = 5'b10000;
        localparam PUSH_PCL = 5'b10001;
        localparam PUSH_PCL = 5'b10001;
        localparam PUSH_STATUS = 5'b10010;
        localparam PUSH_STATUS = 5'b10010;
        localparam FETCH_PCL = 5'b10011;
        localparam FETCH_PCL = 5'b10011;
        localparam FETCH_PCH = 5'b10100;
        localparam FETCH_PCH = 5'b10100;
        localparam INCREMENT_SP = 5'b10101;
        localparam INCREMENT_SP = 5'b10101;
        localparam PULL_STATUS = 5'b10110;
        localparam PULL_STATUS = 5'b10110;
        localparam PULL_PCL = 5'b10111;
        localparam PULL_PCL = 5'b10111;
        localparam PULL_PCH = 5'b11000;
        localparam PULL_PCH = 5'b11000;
        localparam INCREMENT_PC = 5'b11001;
        localparam INCREMENT_PC = 5'b11001;
        localparam PUSH_REGISTER = 5'b11010;
        localparam PUSH_REGISTER = 5'b11010;
        localparam PULL_REGISTER = 5'b11011;
        localparam PULL_REGISTER = 5'b11011;
        localparam DUMMY = 5'b11100;
        localparam DUMMY = 5'b11100;
        localparam RESET = 5'b11111;
        localparam RESET = 5'b11111;
 
 
        // OPCODES TODO: verify how this get synthesised
        // OPCODES TODO: verify how this get synthesised
        `include "t6507lp_package.v"
        `include "t6507lp_package.v"
 
 
        // mem_rw signals
        // mem_rw signals
        localparam MEM_READ = 1'b0;
        localparam MEM_READ = 1'b0;
        localparam MEM_WRITE = 1'b1;
        localparam MEM_WRITE = 1'b1;
 
 
        reg [ADDR_SIZE_:0] pc;           // program counter
        reg [ADDR_SIZE_:0] pc;           // program counter
        reg [DATA_SIZE:0] sp;            // stack pointer. 9 bits wide.
        reg [DATA_SIZE:0] sp;            // stack pointer. 9 bits wide.
        reg [DATA_SIZE_:0] ir;           // instruction register
        reg [DATA_SIZE_:0] ir;           // instruction register
        reg [ADDR_SIZE_:0] temp_addr;    // temporary address
        reg [ADDR_SIZE_:0] temp_addr;    // temporary address
        reg [DATA_SIZE_:0] temp_data;    // temporary data
        reg [DATA_SIZE_:0] temp_data;    // temporary data
 
 
        reg [4:0] state, next_state; // current and next state registers
        reg [4:0] state, next_state; // current and next state registers
 
 
        // wiring that simplifies the FSM logic by simplifying the addressing modes
        // wiring that simplifies the FSM logic by simplifying the addressing modes
        reg absolute;
        reg absolute;
        reg absolute_indexed;
        reg absolute_indexed;
        reg accumulator;
        reg accumulator;
        reg immediate;
        reg immediate;
        reg implied;
        reg implied;
        reg indirectx;
        reg indirectx;
        reg indirecty;
        reg indirecty;
        reg relative;
        reg relative;
        reg zero_page;
        reg zero_page;
        reg zero_page_indexed;
        reg zero_page_indexed;
        reg [DATA_SIZE_:0] index; // will be assigned with either X or Y
        reg [DATA_SIZE_:0] index; // will be assigned with either X or Y
 
 
        // regs that store the type of operation. again, this simplifies the FSM a lot.
        // regs that store the type of operation. again, this simplifies the FSM a lot.
        reg read;
        reg read;
        reg read_modify_write;
        reg read_modify_write;
        reg write;
        reg write;
        reg jump;
        reg jump;
        reg jump_indirect;
        reg jump_indirect;
        reg index_is_x;
        reg index_is_x;
        reg index_is_branch;
        reg index_is_branch;
 
 
        // regs for the special instructions
        // regs for the special instructions
        reg brk;
        reg brk;
        reg rti;
        reg rti;
        reg rts;
        reg rts;
        reg pha;
        reg pha;
        reg php;
        reg php;
        reg pla;
        reg pla;
        reg plp;
        reg plp;
        reg jsr;
        reg jsr;
        reg tsx;
        reg tsx;
        reg txs;
        reg txs;
        reg nop;
        reg nop;
 
 
        wire [ADDR_SIZE_:0] next_pc;      // a simple logic to add one to the PC
        wire [ADDR_SIZE_:0] next_pc;      // a simple logic to add one to the PC
        assign next_pc = pc + 13'b0000000000001;
        assign next_pc = pc + 13'b0000000000001;
 
 
        wire [DATA_SIZE:0] sp_plus_one;          // simple adder and subtracter for the stack pointer
        wire [DATA_SIZE:0] sp_plus_one;          // simple adder and subtracter for the stack pointer
        assign sp_plus_one = {1'b1, sp[7:0] + 8'b000000001};
        assign sp_plus_one = {1'b1, sp[7:0] + 8'b000000001};
 
 
        wire [DATA_SIZE:0] sp_minus_one;
        wire [DATA_SIZE:0] sp_minus_one;
        assign sp_minus_one = {1'b1, sp[7:0] - 8'b000000001};
        assign sp_minus_one = {1'b1, sp[7:0] - 8'b000000001};
 
 
        reg [ADDR_SIZE_:0] address_plus_index;   // this two registers are used when the instruction uses indexing.
        reg [ADDR_SIZE_:0] address_plus_index;   // this two registers are used when the instruction uses indexing.
        reg page_crossed;                       // address_plus_index always adds index to address and page_crossed asserts when the sum creates a carry.
        reg page_crossed;                       // address_plus_index always adds index to address and page_crossed asserts when the sum creates a carry.
 
 
        reg branch;     // a simple reg that is asserted everytime a branch will be executed.                   
        reg branch;     // a simple reg that is asserted everytime a branch will be executed.                   
 
 
        // this is the combinational logic related to indexed instructions
        // this is the combinational logic related to indexed instructions
        always @(*) begin
        always @(*) begin
                address_plus_index = 13'h000;
                address_plus_index = 13'h000;
                page_crossed = 1'b0;
                page_crossed = 1'b0;
 
 
                case (state)
                case (state)
                        READ_MEM_FIX_ADDR, FETCH_HIGH_CALC_INDEX: begin
                        READ_MEM_FIX_ADDR, FETCH_HIGH_CALC_INDEX: begin
                                {page_crossed, address_plus_index[7:0]} = temp_addr[7:0] + index;
                                {page_crossed, address_plus_index[7:0]} = temp_addr[7:0] + index;
                                address_plus_index[12:8] = temp_addr[12:8] + page_crossed;
                                address_plus_index[12:8] = temp_addr[12:8] + page_crossed;
                        end
                        end
                        READ_FROM_POINTER_X1: begin
                        READ_FROM_POINTER_X1: begin
                                {page_crossed, address_plus_index[7:0]} = temp_addr[7:0] + index;
                                {page_crossed, address_plus_index[7:0]} = temp_addr[7:0] + index;
                                address_plus_index[12:8] = temp_addr[12:8];
                                address_plus_index[12:8] = data_in[4:0];
                        end
                        end
                        FETCH_OP_FIX_PC, FETCH_OP_EVAL_BRANCH: begin
                        FETCH_OP_FIX_PC, FETCH_OP_EVAL_BRANCH: begin
                                if (branch) begin
                                if (branch) begin
                                        {page_crossed, address_plus_index[7:0]} = pc[7:0] + index;
                                        {page_crossed, address_plus_index[7:0]} = pc[7:0] + index;
                                        address_plus_index[12:8] = pc[12:8] + page_crossed;
                                        address_plus_index[12:8] = pc[12:8] + page_crossed;
                                        // warning: pc might feed these lines twice and cause branch failure
                                        // warning: pc might feed these lines twice and cause branch failure
                                end     // solution: add a temp reg i guess
                                end     // solution: add a temp reg i guess
                        end
                        end
 
 
                        READ_FROM_POINTER: begin
                        READ_FROM_POINTER: begin
                                if (indirectx) begin
                                if (indirectx) begin
                                        {page_crossed, address_plus_index[7:0]} = temp_data + index;
                                        {page_crossed, address_plus_index[7:0]} = temp_data + index;
                                        //address_plus_index[12:8] = 5'b00000; // already assigned earlier at this block
                                        //address_plus_index[12:8] = 5'b00000; // already assigned earlier at this block
                                end
                                end
                                else if (jump_indirect) begin
                                else if (jump_indirect) begin
                                        address_plus_index[7:0] = temp_addr[7:0] + 8'h01;
                                        address_plus_index[7:0] = temp_addr[7:0] + 8'h01;
                                        //address_plus_index[12:8] = 5'b00000;
                                        //address_plus_index[12:8] = 5'b00000;
                                end
                                end
                                else begin // indirecty falls here
                                else begin // indirecty falls here
                                        address_plus_index[7:0] = temp_data + 8'h01;
                                        address_plus_index[7:0] = temp_data + 8'h01;
                                        //address_plus_index[12:8] = 5'b00000;
                                        //address_plus_index[12:8] = 5'b00000;
                                end
                                end
                        end
                        end
 
 
                        READ_FROM_POINTER_X: begin
                        READ_FROM_POINTER_X: begin
                                {page_crossed, address_plus_index[7:0]} = temp_data + index + 8'h01;
                                {page_crossed, address_plus_index[7:0]} = temp_data + index + 8'h01;
                                //address_plus_index[12:8] = 5'b00000;
                                //address_plus_index[12:8] = 5'b00000;
                        end
                        end
 
 
                        READ_MEM_CALC_INDEX: begin
                        READ_MEM_CALC_INDEX: begin
                                {page_crossed, address_plus_index[7:0]} = temp_addr[7:0] + index;
                                {page_crossed, address_plus_index[7:0]} = temp_addr[7:0] + index;
                                //address_plus_index[12:8] = 5'b00000;
                                //address_plus_index[12:8] = 5'b00000;
                        end
                        end
                endcase
                endcase
        end
        end
 
 
        reg [2:0] rst_counter; // a counter to preserve the cpu idle for six cycles
        reg [2:0] rst_counter; // a counter to preserve the cpu idle for six cycles
 
 
        always @ (posedge clk or negedge reset_n) begin // sequencial always block
        always @ (posedge clk or negedge reset_n) begin // sequencial always block
                if (reset_n == 1'b0) begin
                if (reset_n == 1'b0) begin
                        // all registers must assume default values
                        // all registers must assume default values
                        pc <= 13'h0; // TODO: this is written somewhere. something about a reset vector. must be checked.
                        pc <= 13'h0; // TODO: this is written somewhere. something about a reset vector. must be checked.
                        sp <= 9'b111111111; // the default is 'h1FF 
                        sp <= 9'b111111111; // the default is 'h1FF 
                        ir <= 8'h00;
                        ir <= 8'h00;
                        temp_addr <= 13'h0000;
                        temp_addr <= 13'h0000;
                        temp_data <= 8'h00;
                        temp_data <= 8'h00;
                        state <= RESET;
                        state <= RESET;
                        // registered outputs also receive default values
                        // registered outputs also receive default values
                        address <= 13'h0000;
                        address <= 13'h0000;
                        mem_rw <= MEM_READ;
                        mem_rw <= MEM_READ;
                        data_out <= 8'h00;
                        data_out <= 8'h00;
                        rst_counter <= 3'h0;
                        rst_counter <= 3'h0;
                        index <= 8'h00;
                        index <= 8'h00;
                end
                end
                else begin
                else begin
                        state <= next_state;
                        state <= next_state;
 
 
                        case (state)
                        case (state)
                                RESET: begin    // The processor was reset
                                RESET: begin    // The processor was reset
                                        rst_counter <= rst_counter + 3'b001;
                                        rst_counter <= rst_counter + 3'b001;
                                        //sp <= 9'b111111111; // this prevents flipflops with different drivers
                                        //sp <= 9'b111111111; // this prevents flipflops with different drivers
                                        //$write("under reset"); 
                                        //$write("under reset"); 
                                end
                                end
                                /*
                                /*
                                FETCH_OP: executed when the processor was reset or the last instruction could not fetch.
                                FETCH_OP: executed when the processor was reset or the last instruction could not fetch.
                                FETCH_OP_CALC_PARAM: enables the alu with an argument (alu_a) and fetchs the next instruction opcode. (pipelining)
                                FETCH_OP_CALC_PARAM: enables the alu with an argument (alu_a) and fetchs the next instruction opcode. (pipelining)
                                */
                                */
                                FETCH_OP, FETCH_OP_CALC_PARAM: begin // this is the pipeline happening!
                                FETCH_OP, FETCH_OP_CALC_PARAM: begin // this is the pipeline happening!
                                        pc <= next_pc;
                                        pc <= next_pc;
                                        address <= next_pc;
                                        address <= next_pc;
                                        mem_rw <= MEM_READ;
                                        mem_rw <= MEM_READ;
                                        ir <= data_in;
                                        ir <= data_in;
                                end
                                end
                                /*
                                /*
                                in this state the opcode is already known so truly execution begins.
                                in this state the opcode is already known so truly execution begins.
                                all instructions execute this cycle.
                                all instructions execute this cycle.
                                */
                                */
                                FETCH_LOW: begin
                                FETCH_LOW: begin
                                        //$display("index_is_x = %b",index_is_x);
                                        //$display("index_is_x = %b",index_is_x);
                                        if (index_is_x == 1'b1) begin
                                        if (index_is_x == 1'b1) begin
                                                index <= alu_x;
                                                index <= alu_x;
                                                //$display("alu_x = %d",alu_x);
                                                //$display("alu_x = %d",alu_x);
                                        end
                                        end
                                        else begin
                                        else begin
                                                index <= alu_y;
                                                index <= alu_y;
                                                //$display("alu_y = %d",alu_y);
                                                //$display("alu_y = %d",alu_y);
                                        end
                                        end
                                        if (index_is_branch) begin
                                        if (index_is_branch) begin
                                                index <= temp_data;
                                                index <= temp_data;
                                        end
                                        end
                                        if (accumulator || implied || txs || tsx) begin
                                        if (accumulator || implied || txs || tsx) begin
                                                pc <= pc; // is this better?
                                                pc <= pc; // is this better?
                                                address <= pc;
                                                address <= pc;
                                                mem_rw <= MEM_READ;
                                                mem_rw <= MEM_READ;
 
 
                                                if (txs) begin
                                                if (txs) begin
                                                        sp[7:0] <= alu_x;
                                                        sp[7:0] <= alu_x;
                                                end
                                                end
                                                //alu_a
                                                //alu_a
                                        end
                                        end
                                        else if (immediate || relative) begin
                                        else if (immediate || relative) begin
                                                pc <= next_pc;
                                                pc <= next_pc;
                                                address <= next_pc;
                                                address <= next_pc;
                                                mem_rw <= MEM_READ;
                                                mem_rw <= MEM_READ;
                                                temp_data <= data_in; // the follow-up byte is saved in temp_data 
                                                temp_data <= data_in; // the follow-up byte is saved in temp_data 
                                        end
                                        end
                                        else if (absolute || absolute_indexed || jump_indirect) begin
                                        else if (absolute || absolute_indexed || jump_indirect) begin
                                                pc <= next_pc;
                                                pc <= next_pc;
                                                address <= next_pc;
                                                address <= next_pc;
                                                mem_rw <= MEM_READ;
                                                mem_rw <= MEM_READ;
                                                temp_addr <= {{5{1'b0}},data_in};
                                                temp_addr <= {{5{1'b0}},data_in};
                                                temp_data <= 8'h00;
                                                temp_data <= 8'h00;
                                        end
                                        end
                                        else if (zero_page) begin
                                        else if (zero_page) begin
                                                pc <= next_pc;
                                                pc <= next_pc;
                                                address <= {{5{1'b0}},data_in};
                                                address <= {{5{1'b0}},data_in};
                                                temp_addr <= {{5{1'b0}},data_in};
                                                temp_addr <= {{5{1'b0}},data_in};
 
 
                                                if (write) begin
                                                if (write) begin
                                                        mem_rw <= MEM_WRITE;
                                                        mem_rw <= MEM_WRITE;
                                                        data_out <= alu_result;
                                                        data_out <= alu_result;
                                                end
                                                end
                                                else begin
                                                else begin
                                                        mem_rw <= MEM_READ;
                                                        mem_rw <= MEM_READ;
                                                        data_out <= 8'h00;
                                                        data_out <= 8'h00;
                                                end
                                                end
                                        end
                                        end
                                        else if (zero_page_indexed) begin
                                        else if (zero_page_indexed) begin
                                                pc <= next_pc;
                                                pc <= next_pc;
                                                address <= {{5{1'b0}}, data_in};
                                                address <= {{5{1'b0}}, data_in};
                                                temp_addr <= {{5{1'b0}}, data_in};
                                                temp_addr <= {{5{1'b0}}, data_in};
                                                mem_rw <= MEM_READ;
                                                mem_rw <= MEM_READ;
                                        end
                                        end
                                        else if (indirectx || indirecty) begin
                                        else if (indirectx || indirecty) begin
                                                pc <= next_pc;
                                                pc <= next_pc;
                                                address <= data_in;
                                                address <= data_in;
                                                temp_data <= data_in;
                                                temp_data <= data_in;
                                                mem_rw <= MEM_READ;
                                                mem_rw <= MEM_READ;
                                        end
                                        end
                                        else begin // the special instructions will fall here: BRK, RTI, RTS...
                                        else begin // the special instructions will fall here: BRK, RTI, RTS...
                                                if (brk) begin
                                                if (brk) begin
                                                        pc <= next_pc;
                                                        pc <= next_pc;
                                                        address <= sp;
                                                        address <= sp;
                                                        data_out <= {{3{1'b0}}, pc[12:8]};
                                                        data_out <= {{3{1'b0}}, pc[12:8]};
                                                        mem_rw <= MEM_WRITE;
                                                        mem_rw <= MEM_WRITE;
                                                end
                                                end
                                                else if (rti || rts) begin
                                                else if (rti || rts) begin
                                                        address <= sp;
                                                        address <= sp;
                                                        mem_rw <= MEM_READ;
                                                        mem_rw <= MEM_READ;
                                                end
                                                end
                                                else if (pha || php) begin
                                                else if (pha || php) begin
                                                        pc <= pc;
                                                        pc <= pc;
                                                        address <= sp;
                                                        address <= sp;
                                                        data_out <= (pha) ? alu_result : alu_status;
                                                        data_out <= (pha) ? alu_result : alu_status;
                                                        mem_rw <= MEM_WRITE;
                                                        mem_rw <= MEM_WRITE;
                                                end
                                                end
                                                else if (pla || plp) begin
                                                else if (pla || plp) begin
                                                        pc <= pc;
                                                        pc <= pc;
                                                        address <= sp;
                                                        address <= sp;
                                                        mem_rw <= MEM_READ;
                                                        mem_rw <= MEM_READ;
                                                end
                                                end
                                                else begin // jsr
                                                else begin // jsr
                                                        address <= sp;
                                                        address <= sp;
                                                        mem_rw <= MEM_READ;
                                                        mem_rw <= MEM_READ;
                                                        temp_addr <= {{5{1'b0}}, data_in};
                                                        temp_addr <= {{5{1'b0}}, data_in};
                                                        pc <= next_pc;
                                                        pc <= next_pc;
                                                end
                                                end
                                        end
                                        end
                                end
                                end
                                FETCH_HIGH_CALC_INDEX: begin
                                FETCH_HIGH_CALC_INDEX: begin
                                        pc <= next_pc;
                                        pc <= next_pc;
                                        temp_addr[12:8] <= data_in[4:0];
                                        temp_addr[12:8] <= data_in[4:0];
                                        address <= {data_in[4:0], address_plus_index[7:0]};
                                        address <= {data_in[4:0], address_plus_index[7:0]};
                                        mem_rw <= MEM_READ;
                                        mem_rw <= MEM_READ;
                                        data_out <= 8'h00;
                                        data_out <= 8'h00;
                                end
                                end
                                // this cycle fetchs the next operand while still evaluating if a branch occurred.
                                // this cycle fetchs the next operand while still evaluating if a branch occurred.
                                FETCH_OP_EVAL_BRANCH: begin
                                FETCH_OP_EVAL_BRANCH: begin
                                        if (branch) begin
                                        if (branch) begin
                                                pc <= {{5{1'b0}}, address_plus_index[7:0]};
                                                pc <= {{5{1'b0}}, address_plus_index[7:0]};
                                                address <= {{5{1'b0}}, address_plus_index[7:0]};
                                                address <= {{5{1'b0}}, address_plus_index[7:0]};
                                                mem_rw <= MEM_READ;
                                                mem_rw <= MEM_READ;
                                                data_out <= 8'h00;
                                                data_out <= 8'h00;
                                        end
                                        end
                                        else begin
                                        else begin
                                                pc <= next_pc;
                                                pc <= next_pc;
                                                address <= next_pc;
                                                address <= next_pc;
                                                mem_rw <= MEM_READ;
                                                mem_rw <= MEM_READ;
                                                data_out <= 8'h00;
                                                data_out <= 8'h00;
                                                ir <= data_in;
                                                ir <= data_in;
                                        end
                                        end
                                end
                                end
                                // sometimes when reading memory page crosses may occur. the pc register must be fixed, i.e., add 16'h0100
                                // sometimes when reading memory page crosses may occur. the pc register must be fixed, i.e., add 16'h0100
                                FETCH_OP_FIX_PC: begin
                                FETCH_OP_FIX_PC: begin
                                        if (page_crossed) begin
                                        if (page_crossed) begin
                                                pc[12:8] <= address_plus_index[12:8];
                                                pc[12:8] <= address_plus_index[12:8];
                                                address[12:8] <= address_plus_index[12:8];
                                                address[12:8] <= address_plus_index[12:8];
                                        end
                                        end
                                        else begin
                                        else begin
                                                pc <= next_pc;
                                                pc <= next_pc;
                                                address <= next_pc;
                                                address <= next_pc;
                                                mem_rw <= MEM_READ;
                                                mem_rw <= MEM_READ;
                                                ir <= data_in;
                                                ir <= data_in;
                                        end
                                        end
                                end
                                end
                                // several instructions ocupy 3 bytes in memory. this cycle reads the third byte.
                                // several instructions ocupy 3 bytes in memory. this cycle reads the third byte.
                                FETCH_HIGH: begin
                                FETCH_HIGH: begin
                                        if (jump) begin
                                        if (jump) begin
                                                pc <= {data_in[4:0], temp_addr[7:0]}; // PCL <= first byte, PCH <= second byte
                                                pc <= {data_in[4:0], temp_addr[7:0]}; // PCL <= first byte, PCH <= second byte
                                                address <= {data_in[4:0], temp_addr[7:0]};
                                                address <= {data_in[4:0], temp_addr[7:0]};
                                                mem_rw <= MEM_READ;
                                                mem_rw <= MEM_READ;
                                                data_out <= 8'h00;
                                                data_out <= 8'h00;
                                        end
                                        end
                                        else begin
                                        else begin
                                                if (write) begin
                                                if (write) begin
                                                        pc <= next_pc;
                                                        pc <= next_pc;
                                                        temp_addr[12:8] <= data_in[4:0];
                                                        temp_addr[12:8] <= data_in[4:0];
                                                        address <= {data_in[4:0],temp_addr[7:0]};
                                                        address <= {data_in[4:0],temp_addr[7:0]};
                                                        mem_rw <= MEM_WRITE;
                                                        mem_rw <= MEM_WRITE;
                                                        data_out <= alu_result;
                                                        data_out <= alu_result;
                                                end
                                                end
                                                else begin // read_modify_write or just read
                                                else begin // read_modify_write or just read
                                                        pc <= next_pc;
                                                        pc <= next_pc;
                                                        temp_addr[12:8] <= data_in[4:0];
                                                        temp_addr[12:8] <= data_in[4:0];
                                                        address <= {data_in[4:0],temp_addr[7:0]};
                                                        address <= {data_in[4:0],temp_addr[7:0]};
                                                        mem_rw <= MEM_READ;
                                                        mem_rw <= MEM_READ;
                                                        data_out <= 8'h00;
                                                        data_out <= 8'h00;
                                                end
                                                end
                                        end
                                        end
                                end
                                end
                                // read memory at address
                                // read memory at address
                                READ_MEM: begin
                                READ_MEM: begin
                                        if (read_modify_write) begin
                                        if (read_modify_write) begin
                                                pc <= pc;
                                                pc <= pc;
                                                address <= temp_addr;
                                                address <= temp_addr;
                                                mem_rw <= MEM_WRITE;
                                                mem_rw <= MEM_WRITE;
                                                temp_data <= data_in;
                                                temp_data <= data_in;
                                                data_out <= data_in; // writeback the same value
                                                data_out <= data_in; // writeback the same value
                                        end
                                        end
                                        else begin
                                        else begin
                                                pc <= pc;
                                                pc <= pc;
                                                address <= pc;
                                                address <= pc;
                                                temp_data <= data_in;
                                                temp_data <= data_in;
                                                mem_rw <= MEM_READ;
                                                mem_rw <= MEM_READ;
                                                data_out <= 8'h00;
                                                data_out <= 8'h00;
                                        end
                                        end
                                end
                                end
                                READ_MEM_CALC_INDEX: begin
                                READ_MEM_CALC_INDEX: begin
                                                address <= address_plus_index;
                                                address <= address_plus_index;
                                                temp_addr <= address_plus_index;
                                                temp_addr <= address_plus_index;
 
 
                                                if (write) begin
                                                if (write) begin
                                                        mem_rw <= MEM_WRITE;
                                                        mem_rw <= MEM_WRITE;
                                                        data_out <= alu_result;
                                                        data_out <= alu_result;
                                                end
                                                end
                                                else begin
                                                else begin
                                                        mem_rw <= MEM_READ;
                                                        mem_rw <= MEM_READ;
                                                        data_out <= 8'h00;
                                                        data_out <= 8'h00;
                                                end
                                                end
 
 
                                end
                                end
                                READ_MEM_FIX_ADDR: begin
                                READ_MEM_FIX_ADDR: begin
                                        if (read) begin
                                        if (read) begin
                                                mem_rw <= MEM_READ;
                                                mem_rw <= MEM_READ;
                                                data_out <= 8'h00;
                                                data_out <= 8'h00;
 
 
                                                if (page_crossed) begin // fix address 
                                                if (page_crossed) begin // fix address 
                                                        address <= address_plus_index;
                                                        address <= address_plus_index;
                                                        temp_addr <= address_plus_index;
                                                        temp_addr <= address_plus_index;
                                                end
                                                end
                                                else begin
                                                else begin
                                                        address <= pc;
                                                        address <= pc;
                                                        temp_data <= data_in;
                                                        temp_data <= data_in;
                                                end
                                                end
                                        end
                                        end
                                        else if (write) begin
                                        else if (write) begin
                                                mem_rw <= MEM_WRITE;
                                                mem_rw <= MEM_WRITE;
                                                data_out <= alu_result;
                                                data_out <= alu_result;
                                                address <= address_plus_index;
                                                address <= address_plus_index;
                                                temp_addr <= address_plus_index;
                                                temp_addr <= address_plus_index;
 
 
                                        end
                                        end
                                        else begin // read modify write
                                        else begin // read modify write
                                                mem_rw <= MEM_READ;
                                                mem_rw <= MEM_READ;
                                                data_out <= 8'h00;
                                                data_out <= 8'h00;
                                                address <= address_plus_index;
                                                address <= address_plus_index;
                                                temp_addr <= address_plus_index;
                                                temp_addr <= address_plus_index;
                                        end
                                        end
                                end
                                end
                                // some instructions have a dummy write cycle. this is it.
                                // some instructions have a dummy write cycle. this is it.
                                DUMMY_WRT_CALC: begin
                                DUMMY_WRT_CALC: begin
                                        pc <= pc;
                                        pc <= pc;
                                        address <= temp_addr;
                                        address <= temp_addr;
                                        mem_rw <= MEM_WRITE;
                                        mem_rw <= MEM_WRITE;
                                        data_out <= alu_result;
                                        data_out <= alu_result;
                                end
                                end
                                WRITE_MEM: begin
                                WRITE_MEM: begin
                                        pc <= pc;
                                        pc <= pc;
                                        address <= pc;
                                        address <= pc;
                                        mem_rw <= MEM_READ;
                                        mem_rw <= MEM_READ;
                                        data_out <= 8'h00;
                                        data_out <= 8'h00;
                                end
                                end
                                READ_FROM_POINTER: begin
                                READ_FROM_POINTER: begin
                                        if (jump_indirect) begin
                                        if (jump_indirect) begin
                                                pc[7:0] <= data_in;
                                                pc[7:0] <= data_in;
                                                mem_rw <= MEM_READ;
                                                mem_rw <= MEM_READ;
                                                address <= address_plus_index;
                                                address <= address_plus_index;
                                        end
                                        end
                                        else begin
                                        else begin
                                                pc <= pc;
                                                pc <= pc;
                                                mem_rw <= MEM_READ;
                                                mem_rw <= MEM_READ;
 
 
                                                if (indirectx) begin
                                                if (indirectx) begin
                                                        address <= address_plus_index;
                                                        address <= address_plus_index;
                                                end
                                                end
                                                else begin // indirecty falls here
                                                else begin // indirecty falls here
                                                        address <= address_plus_index;
                                                        address <= address_plus_index;
                                                        temp_addr <= {{5{1'b0}}, data_in};
                                                        temp_addr <= {{5{1'b0}}, data_in};
                                                end
                                                end
                                        end
                                        end
                                end
                                end
                                READ_FROM_POINTER_X: begin
                                READ_FROM_POINTER_X: begin
                                        pc <= pc;
                                        pc <= pc;
                                        address <= address_plus_index;
                                        address <= address_plus_index;
                                        temp_addr[7:0] <= data_in;
                                        temp_addr[7:0] <= data_in;
                                        mem_rw <= MEM_READ;
                                        mem_rw <= MEM_READ;
                                end
                                end
                                READ_FROM_POINTER_X1: begin
                                READ_FROM_POINTER_X1: begin
                                        if (jump_indirect) begin
                                        if (jump_indirect) begin
                                                pc[12:8] <= data_in[4:0];
                                                pc[12:8] <= data_in[4:0];
                                                mem_rw <= MEM_READ;
                                                mem_rw <= MEM_READ;
                                                address <= {data_in[4:0], pc[7:0]};
                                                address <= {data_in[4:0], pc[7:0]};
                                        end
                                        end
                                        else if (indirectx) begin
                                        else if (indirectx) begin
                                                address <= {data_in[4:0], temp_addr[7:0]};
                                                address <= {data_in[4:0], temp_addr[7:0]};
                                                if (write) begin
                                                if (write) begin
                                                        mem_rw <= MEM_WRITE;
                                                        mem_rw <= MEM_WRITE;
                                                        data_out <= alu_result;
                                                        data_out <= alu_result;
                                                end
                                                end
                                                else begin
                                                else begin
                                                        mem_rw <= MEM_READ;
                                                        mem_rw <= MEM_READ;
                                                end
                                                end
                                        end
                                        end
                                        else begin // indirecty falls here
                                        else begin // indirecty falls here
                                                address <= address_plus_index;
                                                address <= address_plus_index;
                                                temp_addr[12:8] <= data_in;
                                                temp_addr[12:8] <= data_in;
                                                mem_rw <= MEM_READ;
                                                mem_rw <= MEM_READ;
                                        end
                                        end
                                end
                                end
                                PUSH_PCH: begin
                                PUSH_PCH: begin
                                        pc <= pc;
                                        pc <= pc;
                                        address <= sp_minus_one;
                                        address <= sp_minus_one;
                                        data_out <= pc[7:0];
                                        data_out <= pc[7:0];
                                        mem_rw <= MEM_WRITE;
                                        mem_rw <= MEM_WRITE;
                                        sp <= sp_minus_one;
                                        sp <= sp_minus_one;
                                end
                                end
                                PUSH_PCL: begin
                                PUSH_PCL: begin
                                        if (jsr) begin
                                        if (jsr) begin
                                                pc <= pc;
                                                pc <= pc;
                                                address <= pc;
                                                address <= pc;
                                                mem_rw <= MEM_READ;
                                                mem_rw <= MEM_READ;
                                                sp <= sp_minus_one;
                                                sp <= sp_minus_one;
                                        end
                                        end
                                        else begin
                                        else begin
                                                pc <= pc;
                                                pc <= pc;
                                                address <= sp_minus_one;
                                                address <= sp_minus_one;
                                                data_out <= alu_status;
                                                data_out <= alu_status;
                                                mem_rw <= MEM_WRITE;
                                                mem_rw <= MEM_WRITE;
                                                sp <= sp_minus_one;
                                                sp <= sp_minus_one;
                                        end
                                        end
                                end
                                end
                                PUSH_STATUS: begin
                                PUSH_STATUS: begin
                                        address <= 13'h1FFE;
                                        address <= 13'h1FFE;
                                        mem_rw <= MEM_READ;
                                        mem_rw <= MEM_READ;
                                        sp <= sp_minus_one;
                                        sp <= sp_minus_one;
                                end
                                end
                                FETCH_PCL: begin
                                FETCH_PCL: begin
                                        pc[7:0] <= data_in;
                                        pc[7:0] <= data_in;
                                        address <= 13'h1FFF;
                                        address <= 13'h1FFF;
                                        mem_rw <= MEM_READ;
                                        mem_rw <= MEM_READ;
                                end
                                end
                                FETCH_PCH: begin
                                FETCH_PCH: begin
                                        pc[12:8] <= data_in[4:0];
                                        pc[12:8] <= data_in[4:0];
                                        address <= {data_in[4:0], pc[7:0]};
                                        address <= {data_in[4:0], pc[7:0]};
                                        mem_rw <= MEM_READ;
                                        mem_rw <= MEM_READ;
                                end
                                end
                                INCREMENT_SP: begin
                                INCREMENT_SP: begin
                                        sp <= sp_plus_one;
                                        sp <= sp_plus_one;
                                        address <= sp_plus_one;
                                        address <= sp_plus_one;
                                end
                                end
                                PULL_STATUS: begin
                                PULL_STATUS: begin
                                        sp <= sp_plus_one;
                                        sp <= sp_plus_one;
                                        address <= sp_plus_one;
                                        address <= sp_plus_one;
                                        temp_data <= data_in;
                                        temp_data <= data_in;
                                end
                                end
                                PULL_PCL: begin
                                PULL_PCL: begin
                                        sp <= sp_plus_one;
                                        sp <= sp_plus_one;
                                        address <= sp_plus_one;
                                        address <= sp_plus_one;
                                        pc[7:0] <= data_in;
                                        pc[7:0] <= data_in;
                                end
                                end
                                PULL_PCH: begin
                                PULL_PCH: begin
                                        pc[12:8] <= data_in[4:0];
                                        pc[12:8] <= data_in[4:0];
                                        address <= {data_in[4:0], pc[7:0]};
                                        address <= {data_in[4:0], pc[7:0]};
                                end
                                end
                                INCREMENT_PC: begin
                                INCREMENT_PC: begin
                                        pc <= next_pc;
                                        pc <= next_pc;
                                        address <= next_pc;
                                        address <= next_pc;
                                end
                                end
                                PUSH_REGISTER: begin
                                PUSH_REGISTER: begin
                                        pc <= pc;
                                        pc <= pc;
                                        address <= pc;
                                        address <= pc;
                                        sp <= sp_minus_one;
                                        sp <= sp_minus_one;
                                        mem_rw <= MEM_READ;
                                        mem_rw <= MEM_READ;
                                        temp_data <= data_in;
                                        temp_data <= data_in;
                                end
                                end
                                PULL_REGISTER: begin
                                PULL_REGISTER: begin
                                        pc <= pc;
                                        pc <= pc;
                                        address <= pc;
                                        address <= pc;
                                        temp_data <= data_in;
                                        temp_data <= data_in;
                                end
                                end
                                DUMMY: begin
                                DUMMY: begin
                                        address <= sp;
                                        address <= sp;
                                        mem_rw <= MEM_WRITE;
                                        mem_rw <= MEM_WRITE;
                                end
                                end
                                default: begin
                                default: begin
                                        //$write("unknown state"); // TODO: check if synth really ignores this 2 lines. Otherwise wrap it with a `ifdef 
                                        //$write("unknown state"); // TODO: check if synth really ignores this 2 lines. Otherwise wrap it with a `ifdef 
                                        //$finish(0); 
                                        //$finish(0); 
                                end
                                end
 
 
                        endcase
                        endcase
                end
                end
        end
        end
 
 
        always @ (*) begin // this is the next_state logic and the combinational output logic always block
        always @ (*) begin // this is the next_state logic and the combinational output logic always block
                alu_opcode = 8'h00;
                alu_opcode = 8'h00;
                alu_a = 8'h00;
                alu_a = 8'h00;
                alu_enable = 1'b0;
                alu_enable = 1'b0;
                next_state = RESET; // these lines prevents latches
                next_state = RESET; // these lines prevents latches
 
 
                case (state)
                case (state)
                        RESET: begin
                        RESET: begin
                                if (rst_counter == 3'd6) begin
                                if (rst_counter == 3'd6) begin
                                        next_state = FETCH_OP;
                                        next_state = FETCH_OP;
                                end
                                end
                        end
                        end
                        FETCH_OP: begin
                        FETCH_OP: begin
                                next_state = FETCH_LOW;
                                next_state = FETCH_LOW;
                        end
                        end
                        FETCH_OP_CALC_PARAM: begin
                        FETCH_OP_CALC_PARAM: begin
                                next_state = FETCH_LOW;
                                next_state = FETCH_LOW;
                                alu_opcode = ir;
                                alu_opcode = ir;
                                alu_enable = 1'b1;
                                alu_enable = 1'b1;
                                alu_a = temp_data;
                                alu_a = temp_data;
                        end
                        end
                        FETCH_LOW: begin
                        FETCH_LOW: begin
                                if (accumulator  || implied || txs) begin
                                if (accumulator  || implied || txs) begin
                                        if (!nop) begin
                                        if (!nop) begin
                                                alu_opcode = ir;
                                                alu_opcode = ir;
                                                alu_enable = 1'b1;
                                                alu_enable = 1'b1;
                                        end
                                        end
                                        next_state = FETCH_OP;
                                        next_state = FETCH_OP;
                                end
                                end
                                else if (tsx) begin
                                else if (tsx) begin
                                        alu_opcode = ir;
                                        alu_opcode = ir;
                                        alu_enable = 1'b1;
                                        alu_enable = 1'b1;
                                        next_state = FETCH_OP;
                                        next_state = FETCH_OP;
                                        alu_a = sp[7:0];
                                        alu_a = sp[7:0];
                                end
                                end
                                else if (immediate) begin
                                else if (immediate) begin
                                        next_state = FETCH_OP_CALC_PARAM;
                                        next_state = FETCH_OP_CALC_PARAM;
                                end
                                end
                                else if (zero_page) begin
                                else if (zero_page) begin
                                        if (read || read_modify_write) begin
                                        if (read || read_modify_write) begin
                                                next_state = READ_MEM;
                                                next_state = READ_MEM;
                                        end
                                        end
                                        else if (write) begin
                                        else if (write) begin
                                                next_state = WRITE_MEM;
                                                next_state = WRITE_MEM;
                                                alu_opcode = ir;
                                                alu_opcode = ir;
                                                alu_enable = 1'b1;
                                                alu_enable = 1'b1;
                                                alu_a = 8'h00;
                                                alu_a = 8'h00;
                                        end
                                        end
                                        else begin
                                        else begin
                                                //$write("unknown behavior"); 
                                                //$write("unknown behavior"); 
                                                //$finish(0);
                                                //$finish(0);
                                        end
                                        end
                                end
                                end
                                else if (zero_page_indexed) begin
                                else if (zero_page_indexed) begin
                                        next_state = READ_MEM_CALC_INDEX;
                                        next_state = READ_MEM_CALC_INDEX;
                                end
                                end
                                else if (absolute || jump_indirect) begin
                                else if (absolute || jump_indirect) begin
                                        next_state = FETCH_HIGH;
                                        next_state = FETCH_HIGH;
                                        if (write) begin // this is being done one cycle early but i have checked and the ALU will still work properly
                                        if (write) begin // this is being done one cycle early but i have checked and the ALU will still work properly
                                                alu_opcode = ir;
                                                alu_opcode = ir;
                                                alu_enable = 1'b1;
                                                alu_enable = 1'b1;
                                                alu_a = 8'h00;
                                                alu_a = 8'h00;
                                        end
                                        end
                                end
                                end
                                else if (absolute_indexed) begin
                                else if (absolute_indexed) begin
                                        next_state = FETCH_HIGH_CALC_INDEX;
                                        next_state = FETCH_HIGH_CALC_INDEX;
                                end
                                end
                                else if (relative) begin
                                else if (relative) begin
                                        next_state = FETCH_OP_EVAL_BRANCH;
                                        next_state = FETCH_OP_EVAL_BRANCH;
                                end
                                end
                                else if (indirectx || indirecty) begin
                                else if (indirectx || indirecty) begin
                                        next_state = READ_FROM_POINTER;
                                        next_state = READ_FROM_POINTER;
                                end
                                end
                                else begin // all the special instructions will fall here
                                else begin // all the special instructions will fall here
                                        if (brk) begin
                                        if (brk) begin
                                                next_state = PUSH_PCH;
                                                next_state = PUSH_PCH;
                                        end
                                        end
                                        else if (rti || rts) begin
                                        else if (rti || rts) begin
                                                next_state = INCREMENT_SP;
                                                next_state = INCREMENT_SP;
                                        end
                                        end
                                        else if (pha) begin
                                        else if (pha) begin
                                                alu_opcode = ir;
                                                alu_opcode = ir;
                                                alu_enable = 1'b1;
                                                alu_enable = 1'b1;
                                                //alu_a = 8'h00;
                                                //alu_a = 8'h00;
                                                next_state = PUSH_REGISTER;
                                                next_state = PUSH_REGISTER;
                                        end
                                        end
                                        else if (php) begin
                                        else if (php) begin
                                                next_state = PUSH_REGISTER;
                                                next_state = PUSH_REGISTER;
                                        end
                                        end
                                        else if (pla || plp) begin
                                        else if (pla || plp) begin
                                                next_state = INCREMENT_SP;
                                                next_state = INCREMENT_SP;
                                        end
                                        end
                                        else begin // jsr
                                        else begin // jsr
                                                next_state = DUMMY;
                                                next_state = DUMMY;
                                        end
                                        end
                                end
                                end
                        end
                        end
                        READ_FROM_POINTER: begin
                        READ_FROM_POINTER: begin
                                if (indirectx) begin
                                if (indirectx) begin
                                        next_state = READ_FROM_POINTER_X;
                                        next_state = READ_FROM_POINTER_X;
                                end
                                end
                                else begin // indirecty and jump indirect falls here
                                else begin // indirecty and jump indirect falls here
                                        next_state = READ_FROM_POINTER_X1;
                                        next_state = READ_FROM_POINTER_X1;
                                end
                                end
                        end
                        end
                        READ_FROM_POINTER_X: begin
                        READ_FROM_POINTER_X: begin
                                next_state = READ_FROM_POINTER_X1;
                                next_state = READ_FROM_POINTER_X1;
                        end
                        end
                        READ_FROM_POINTER_X1: begin
                        READ_FROM_POINTER_X1: begin
                                if (jump_indirect) begin
                                if (jump_indirect) begin
                                        next_state = FETCH_OP;
                                        next_state = FETCH_OP;
                                end
                                end
                                else if (indirecty) begin
                                else if (indirecty) begin
                                        next_state = READ_MEM_FIX_ADDR;
                                        next_state = READ_MEM_FIX_ADDR;
                                end
                                end
                                else begin
                                else begin
                                        if (read) begin // no instruction using pointers is from type read_modify_write
                                        if (read) begin // no instruction using pointers is from type read_modify_write
                                                next_state = READ_MEM;
                                                next_state = READ_MEM;
                                        end
                                        end
                                        else if (write) begin
                                        else if (write) begin
                                                alu_opcode = ir;
                                                alu_opcode = ir;
                                                alu_enable = 1'b1;
                                                alu_enable = 1'b1;
                                                next_state = WRITE_MEM;
                                                next_state = WRITE_MEM;
                                        end
                                        end
                                end
                                end
                        end
                        end
                        FETCH_OP_EVAL_BRANCH: begin
                        FETCH_OP_EVAL_BRANCH: begin
                                if (branch) begin
                                if (branch) begin
                                        next_state = FETCH_OP_FIX_PC;
                                        next_state = FETCH_OP_FIX_PC;
                                end
                                end
                                else begin
                                else begin
                                        next_state = FETCH_LOW;
                                        next_state = FETCH_LOW;
                                end
                                end
                        end
                        end
                        FETCH_OP_FIX_PC: begin
                        FETCH_OP_FIX_PC: begin
                                if (page_crossed) begin
                                if (page_crossed) begin
                                        next_state = FETCH_OP;
                                        next_state = FETCH_OP;
                                end
                                end
                                else begin
                                else begin
                                        next_state = FETCH_LOW;
                                        next_state = FETCH_LOW;
                                end
                                end
                        end
                        end
                        FETCH_HIGH_CALC_INDEX: begin
                        FETCH_HIGH_CALC_INDEX: begin
                                next_state = READ_MEM_FIX_ADDR;
                                next_state = READ_MEM_FIX_ADDR;
                        end
                        end
                        READ_MEM_FIX_ADDR: begin
                        READ_MEM_FIX_ADDR: begin
                                if (read) begin
                                if (read) begin
                                        if (page_crossed) begin
                                        if (page_crossed) begin
                                                next_state = READ_MEM;
                                                next_state = READ_MEM;
                                        end
                                        end
                                        else begin
                                        else begin
                                                next_state = FETCH_OP_CALC_PARAM;
                                                next_state = FETCH_OP_CALC_PARAM;
                                        end
                                        end
                                end
                                end
                                else if (read_modify_write) begin
                                else if (read_modify_write) begin
                                        next_state = READ_MEM;
                                        next_state = READ_MEM;
                                end
                                end
                                else if (write) begin
                                else if (write) begin
                                        next_state = WRITE_MEM;
                                        next_state = WRITE_MEM;
                                        alu_enable = 1'b1;
                                        alu_enable = 1'b1;
                                        alu_opcode = ir;
                                        alu_opcode = ir;
                                end
                                end
                                else begin
                                else begin
                                        //$write("unknown behavior"); 
                                        //$write("unknown behavior"); 
                                        //$finish(0);
                                        //$finish(0);
                                end
                                end
                        end
                        end
                        FETCH_HIGH: begin
                        FETCH_HIGH: begin
                                if (jump_indirect) begin
                                if (jump_indirect) begin
                                        next_state = READ_FROM_POINTER;
                                        next_state = READ_FROM_POINTER;
                                end
                                end
                                else if (jump) begin
                                else if (jump) begin
                                        next_state = FETCH_OP;
                                        next_state = FETCH_OP;
                                end
                                end
                                else if (read || read_modify_write) begin
                                else if (read || read_modify_write) begin
                                        next_state = READ_MEM;
                                        next_state = READ_MEM;
                                end
                                end
                                else if (write) begin
                                else if (write) begin
                                        next_state = WRITE_MEM;
                                        next_state = WRITE_MEM;
                                end
                                end
                                else begin
                                else begin
                                        //$write("unknown behavior"); 
                                        //$write("unknown behavior"); 
                                        //$finish(0);
                                        //$finish(0);
                                end
                                end
                        end
                        end
                        READ_MEM_CALC_INDEX: begin
                        READ_MEM_CALC_INDEX: begin
                                if (read || read_modify_write) begin
                                if (read || read_modify_write) begin
                                        next_state = READ_MEM;
                                        next_state = READ_MEM;
                                end
                                end
                                else if (write) begin
                                else if (write) begin
                                        alu_opcode = ir;
                                        alu_opcode = ir;
                                        alu_enable = 1'b1;
                                        alu_enable = 1'b1;
                                        next_state = WRITE_MEM;
                                        next_state = WRITE_MEM;
                                end
                                end
                                else begin
                                else begin
                                        //$write("unknown behavior"); 
                                        //$write("unknown behavior"); 
                                        //$finish(0);
                                        //$finish(0);
                                end
                                end
                        end
                        end
                        READ_MEM: begin
                        READ_MEM: begin
                                if (read) begin
                                if (read) begin
                                        next_state = FETCH_OP_CALC_PARAM;
                                        next_state = FETCH_OP_CALC_PARAM;
                                end
                                end
                                else if (read_modify_write) begin
                                else if (read_modify_write) begin
                                        next_state = DUMMY_WRT_CALC;
                                        next_state = DUMMY_WRT_CALC;
                                end
                                end
                        end
                        end
                        DUMMY_WRT_CALC: begin
                        DUMMY_WRT_CALC: begin
                                alu_opcode = ir;
                                alu_opcode = ir;
                                alu_enable = 1'b1;
                                alu_enable = 1'b1;
                                alu_a = data_in;
                                alu_a = data_in;
                                next_state = WRITE_MEM;
                                next_state = WRITE_MEM;
                        end
                        end
                        WRITE_MEM: begin
                        WRITE_MEM: begin
                                next_state = FETCH_OP;
                                next_state = FETCH_OP;
                        end
                        end
                        PUSH_PCH: begin
                        PUSH_PCH: begin
                                next_state = PUSH_PCL;
                                next_state = PUSH_PCL;
                        end
                        end
                        PUSH_PCL: begin
                        PUSH_PCL: begin
                                if (jsr) begin
                                if (jsr) begin
                                        next_state = FETCH_HIGH;
                                        next_state = FETCH_HIGH;
                                end
                                end
                                else begin
                                else begin
                                        next_state = PUSH_STATUS;
                                        next_state = PUSH_STATUS;
                                end
                                end
                        end
                        end
                        PUSH_STATUS: begin
                        PUSH_STATUS: begin
                                next_state = FETCH_PCL;
                                next_state = FETCH_PCL;
                        end
                        end
                        FETCH_PCL: begin
                        FETCH_PCL: begin
                                next_state = FETCH_PCH;
                                next_state = FETCH_PCH;
                        end
                        end
                        FETCH_PCH: begin
                        FETCH_PCH: begin
                                next_state = FETCH_OP;
                                next_state = FETCH_OP;
                        end
                        end
                        INCREMENT_SP: begin
                        INCREMENT_SP: begin
                                if (rti) begin
                                if (rti) begin
                                        next_state = PULL_STATUS;
                                        next_state = PULL_STATUS;
                                end
                                end
                                else if (pla || plp) begin
                                else if (pla || plp) begin
                                        next_state = PULL_REGISTER;
                                        next_state = PULL_REGISTER;
                                end
                                end
                                else begin // rts
                                else begin // rts
                                        next_state = PULL_PCL;
                                        next_state = PULL_PCL;
                                end
                                end
                        end
                        end
                        PULL_STATUS: begin
                        PULL_STATUS: begin
                                next_state = PULL_PCL;
                                next_state = PULL_PCL;
                        end
                        end
                        PULL_PCL: begin
                        PULL_PCL: begin
                                next_state = PULL_PCH;
                                next_state = PULL_PCH;
 
 
                                if (rti) begin
                                if (rti) begin
                                        alu_opcode = ir;
                                        alu_opcode = ir;
                                        alu_enable = 1'b1;
                                        alu_enable = 1'b1;
                                        alu_a = temp_data;
                                        alu_a = temp_data;
                                end
                                end
                        end
                        end
                        PULL_PCH: begin
                        PULL_PCH: begin
                                if (rti) begin
                                if (rti) begin
                                        next_state = FETCH_OP;
                                        next_state = FETCH_OP;
                                end
                                end
                                else begin // rts
                                else begin // rts
                                        next_state = INCREMENT_PC;
                                        next_state = INCREMENT_PC;
                                end
                                end
                        end
                        end
                        INCREMENT_PC: begin
                        INCREMENT_PC: begin
                                next_state = FETCH_OP;
                                next_state = FETCH_OP;
                        end
                        end
                        PUSH_REGISTER: begin
                        PUSH_REGISTER: begin
                                next_state = FETCH_OP;
                                next_state = FETCH_OP;
                        end
                        end
                        PULL_REGISTER: begin
                        PULL_REGISTER: begin
                                next_state = FETCH_OP_CALC_PARAM;
                                next_state = FETCH_OP_CALC_PARAM;
                        end
                        end
                        DUMMY: begin
                        DUMMY: begin
                                next_state = PUSH_PCH;
                                next_state = PUSH_PCH;
                        end
                        end
                        default: begin
                        default: begin
                                next_state = RESET;
                                next_state = RESET;
                        end
                        end
                endcase
                endcase
        end
        end
 
 
        // this always block is responsible for updating the address mode and the type of operation being done
        // this always block is responsible for updating the address mode and the type of operation being done
        always @ (*) begin // 
        always @ (*) begin // 
                absolute = 1'b0;
                absolute = 1'b0;
                absolute_indexed = 1'b0;
                absolute_indexed = 1'b0;
                accumulator = 1'b0;
                accumulator = 1'b0;
                immediate = 1'b0;
                immediate = 1'b0;
                implied = 1'b0;
                implied = 1'b0;
                indirectx = 1'b0;
                indirectx = 1'b0;
                indirecty = 1'b0;
                indirecty = 1'b0;
                relative = 1'b0;
                relative = 1'b0;
                zero_page = 1'b0;
                zero_page = 1'b0;
                zero_page_indexed = 1'b0;
                zero_page_indexed = 1'b0;
                //index_is_x = 1'b1;
                //index_is_x = 1'b1;
                index_is_branch = 1'b0;
                index_is_branch = 1'b0;
 
 
                //index = 8'h00;
                //index = 8'h00;
 
 
                read = 1'b0;
                read = 1'b0;
                read_modify_write = 1'b0;
                read_modify_write = 1'b0;
                write = 1'b0;
                write = 1'b0;
                jump = 1'b0;
                jump = 1'b0;
                jump_indirect = 1'b0;
                jump_indirect = 1'b0;
                branch = 1'b0;
                branch = 1'b0;
 
 
                brk = 1'b0;
                brk = 1'b0;
                rti = 1'b0;
                rti = 1'b0;
                rts = 1'b0;
                rts = 1'b0;
                pha = 1'b0;
                pha = 1'b0;
                php = 1'b0;
                php = 1'b0;
                pla = 1'b0;
                pla = 1'b0;
                plp = 1'b0;
                plp = 1'b0;
                jsr = 1'b0;
                jsr = 1'b0;
                tsx = 1'b0;
                tsx = 1'b0;
                txs = 1'b0;
                txs = 1'b0;
                nop = 1'b0;
                nop = 1'b0;
 
 
                case (ir)
                case (ir)
                        CLC_IMP, CLD_IMP, CLI_IMP, CLV_IMP, DEX_IMP, DEY_IMP, INX_IMP, INY_IMP, SEC_IMP, SED_IMP, SEI_IMP, TAX_IMP,
                        CLC_IMP, CLD_IMP, CLI_IMP, CLV_IMP, DEX_IMP, DEY_IMP, INX_IMP, INY_IMP, SEC_IMP, SED_IMP, SEI_IMP, TAX_IMP,
                        TAY_IMP, TXA_IMP, TYA_IMP: begin
                        TAY_IMP, TXA_IMP, TYA_IMP: begin
                                implied = 1'b1;
                                implied = 1'b1;
                        end
                        end
                        NOP_IMP: begin
                        NOP_IMP: begin
                                implied = 1'b1;
                                implied = 1'b1;
                                nop = 1'b1;
                                nop = 1'b1;
                        end
                        end
                        ASL_ACC, LSR_ACC, ROL_ACC, ROR_ACC: begin
                        ASL_ACC, LSR_ACC, ROL_ACC, ROR_ACC: begin
                                accumulator = 1'b1;
                                accumulator = 1'b1;
                        end
                        end
                        ADC_IMM, AND_IMM, CMP_IMM, CPX_IMM, CPY_IMM, EOR_IMM, LDA_IMM, LDX_IMM, LDY_IMM, ORA_IMM, SBC_IMM: begin
                        ADC_IMM, AND_IMM, CMP_IMM, CPX_IMM, CPY_IMM, EOR_IMM, LDA_IMM, LDX_IMM, LDY_IMM, ORA_IMM, SBC_IMM: begin
                                immediate = 1'b1;
                                immediate = 1'b1;
                        end
                        end
                        ADC_ZPG, AND_ZPG, ASL_ZPG, BIT_ZPG, CMP_ZPG, CPX_ZPG, CPY_ZPG, DEC_ZPG, EOR_ZPG, INC_ZPG, LDA_ZPG, LDX_ZPG, LDY_ZPG,
                        ADC_ZPG, AND_ZPG, ASL_ZPG, BIT_ZPG, CMP_ZPG, CPX_ZPG, CPY_ZPG, DEC_ZPG, EOR_ZPG, INC_ZPG, LDA_ZPG, LDX_ZPG, LDY_ZPG,
                        LSR_ZPG, ORA_ZPG, ROL_ZPG, ROR_ZPG, SBC_ZPG, STA_ZPG, STX_ZPG, STY_ZPG: begin
                        LSR_ZPG, ORA_ZPG, ROL_ZPG, ROR_ZPG, SBC_ZPG, STA_ZPG, STX_ZPG, STY_ZPG: begin
                                zero_page = 1'b1;
                                zero_page = 1'b1;
                        end
                        end
                        ADC_ZPX, AND_ZPX, ASL_ZPX, CMP_ZPX, DEC_ZPX, EOR_ZPX, INC_ZPX, LDA_ZPX, LDY_ZPX, LSR_ZPX, ORA_ZPX, ROL_ZPX, ROR_ZPX,
                        ADC_ZPX, AND_ZPX, ASL_ZPX, CMP_ZPX, DEC_ZPX, EOR_ZPX, INC_ZPX, LDA_ZPX, LDY_ZPX, LSR_ZPX, ORA_ZPX, ROL_ZPX, ROR_ZPX,
                        SBC_ZPX, STA_ZPX, STY_ZPX: begin
                        SBC_ZPX, STA_ZPX, STY_ZPX: begin
                                zero_page_indexed = 1'b1;
                                zero_page_indexed = 1'b1;
                                index_is_x = 1'b1;
                                index_is_x = 1'b1;
                                //index = alu_x;
                                //index = alu_x;
                        end
                        end
                        LDX_ZPY, STX_ZPY: begin
                        LDX_ZPY, STX_ZPY: begin
                                zero_page_indexed = 1'b1;
                                zero_page_indexed = 1'b1;
                                index_is_x = 1'b0;
                                index_is_x = 1'b0;
                                //index = alu_y;
                                //index = alu_y;
                        end
                        end
                        BCC_REL: begin
                        BCC_REL: begin
                                relative = 1'b1;
                                relative = 1'b1;
                                index_is_branch = 1'b1;
                                index_is_branch = 1'b1;
                                //index = temp_data;
                                //index = temp_data;
 
 
                                if (!alu_status[C]) begin
                                if (!alu_status[C]) begin
                                        branch = 1'b1;
                                        branch = 1'b1;
                                end
                                end
                                else begin
                                else begin
                                        branch = 1'b0;
                                        branch = 1'b0;
                                end
                                end
                        end
                        end
                        BCS_REL: begin
                        BCS_REL: begin
                                relative = 1'b1;
                                relative = 1'b1;
                                index_is_branch = 1'b1;
                                index_is_branch = 1'b1;
                                //index = temp_data;
                                //index = temp_data;
 
 
                                if (alu_status[C]) begin
                                if (alu_status[C]) begin
                                        branch = 1'b1;
                                        branch = 1'b1;
                                end
                                end
                                else begin
                                else begin
                                        branch = 1'b0;
                                        branch = 1'b0;
                                end
                                end
                        end
                        end
                        BEQ_REL: begin
                        BEQ_REL: begin
                                relative = 1'b1;
                                relative = 1'b1;
                                index_is_branch = 1'b1;
                                index_is_branch = 1'b1;
                                //index = temp_data;
                                //index = temp_data;
 
 
                                if (alu_status[Z]) begin
                                if (alu_status[Z]) begin
                                        branch = 1'b1;
                                        branch = 1'b1;
                                end
                                end
                                else begin
                                else begin
                                        branch = 1'b0;
                                        branch = 1'b0;
                                end
                                end
                        end
                        end
                        BNE_REL: begin
                        BNE_REL: begin
                                relative = 1'b1;
                                relative = 1'b1;
                                index_is_branch = 1'b1;
                                index_is_branch = 1'b1;
                                //index = temp_data;
                                //index = temp_data;
 
 
                                if (alu_status[Z] == 1'b0) begin
                                if (alu_status[Z] == 1'b0) begin
                                        branch = 1'b1;
                                        branch = 1'b1;
                                end
                                end
                                else begin
                                else begin
                                        branch = 1'b0;
                                        branch = 1'b0;
                                end
                                end
                        end
                        end
                        BPL_REL: begin
                        BPL_REL: begin
                                relative = 1'b1;
                                relative = 1'b1;
                                index_is_branch = 1'b1;
                                index_is_branch = 1'b1;
                                //index = temp_data;
                                //index = temp_data;
 
 
                                if (!alu_status[N]) begin
                                if (!alu_status[N]) begin
                                        branch = 1'b1;
                                        branch = 1'b1;
                                end
                                end
                                else begin
                                else begin
                                        branch = 1'b0;
                                        branch = 1'b0;
                                end
                                end
                        end
                        end
                        BMI_REL: begin
                        BMI_REL: begin
                                relative = 1'b1;
                                relative = 1'b1;
                                index_is_branch = 1'b1;
                                index_is_branch = 1'b1;
                                //index = temp_data;
                                //index = temp_data;
 
 
                                if (alu_status[N]) begin
                                if (alu_status[N]) begin
                                        branch = 1'b1;
                                        branch = 1'b1;
                                end
                                end
                                else begin
                                else begin
                                        branch = 1'b0;
                                        branch = 1'b0;
                                end
                                end
                        end
                        end
                        BVC_REL: begin
                        BVC_REL: begin
                                relative = 1'b1;
                                relative = 1'b1;
                                index_is_branch = 1'b1;
                                index_is_branch = 1'b1;
                                //index = temp_data;
                                //index = temp_data;
 
 
                                if (!alu_status[V]) begin
                                if (!alu_status[V]) begin
                                        branch = 1'b1;
                                        branch = 1'b1;
                                end
                                end
                                else begin
                                else begin
                                        branch = 1'b0;
                                        branch = 1'b0;
                                end
                                end
                        end
                        end
                        BVS_REL: begin
                        BVS_REL: begin
                                relative = 1'b1;
                                relative = 1'b1;
                                index_is_branch = 1'b1;
                                index_is_branch = 1'b1;
                                //index = temp_data;
                                //index = temp_data;
 
 
                                if (alu_status[V]) begin
                                if (alu_status[V]) begin
                                        branch = 1'b1;
                                        branch = 1'b1;
                                end
                                end
                                else begin
                                else begin
                                        branch = 1'b0;
                                        branch = 1'b0;
                                end
                                end
                        end
                        end
                        ADC_ABS, AND_ABS, ASL_ABS, BIT_ABS, CMP_ABS, CPX_ABS, CPY_ABS, DEC_ABS, EOR_ABS, INC_ABS, LDA_ABS,
                        ADC_ABS, AND_ABS, ASL_ABS, BIT_ABS, CMP_ABS, CPX_ABS, CPY_ABS, DEC_ABS, EOR_ABS, INC_ABS, LDA_ABS,
                        LDX_ABS, LDY_ABS, LSR_ABS, ORA_ABS, ROL_ABS, ROR_ABS, SBC_ABS, STA_ABS, STX_ABS, STY_ABS: begin
                        LDX_ABS, LDY_ABS, LSR_ABS, ORA_ABS, ROL_ABS, ROR_ABS, SBC_ABS, STA_ABS, STX_ABS, STY_ABS: begin
                                absolute = 1'b1;
                                absolute = 1'b1;
                        end
                        end
                        ADC_ABX, AND_ABX, ASL_ABX, CMP_ABX, DEC_ABX, EOR_ABX, INC_ABX, LDA_ABX, LDY_ABX, LSR_ABX, ORA_ABX, ROL_ABX, ROR_ABX,
                        ADC_ABX, AND_ABX, ASL_ABX, CMP_ABX, DEC_ABX, EOR_ABX, INC_ABX, LDA_ABX, LDY_ABX, LSR_ABX, ORA_ABX, ROL_ABX, ROR_ABX,
                        SBC_ABX, STA_ABX: begin
                        SBC_ABX, STA_ABX: begin
                                absolute_indexed = 1'b1;
                                absolute_indexed = 1'b1;
                                index_is_x = 1'b1;
                                index_is_x = 1'b1;
                                //index = alu_x;
                                //index = alu_x;
                        end
                        end
                        ADC_ABY, AND_ABY, CMP_ABY, EOR_ABY, LDA_ABY, LDX_ABY, ORA_ABY, SBC_ABY, STA_ABY: begin
                        ADC_ABY, AND_ABY, CMP_ABY, EOR_ABY, LDA_ABY, LDX_ABY, ORA_ABY, SBC_ABY, STA_ABY: begin
                                absolute_indexed = 1'b1;
                                absolute_indexed = 1'b1;
                                index_is_x = 1'b0;
                                index_is_x = 1'b0;
                                //index = alu_y;
                                //index = alu_y;
                        end
                        end
                        ADC_IDX, AND_IDX, CMP_IDX, EOR_IDX, LDA_IDX, ORA_IDX, SBC_IDX, STA_IDX: begin
                        ADC_IDX, AND_IDX, CMP_IDX, EOR_IDX, LDA_IDX, ORA_IDX, SBC_IDX, STA_IDX: begin
                                indirectx = 1'b1;
                                indirectx = 1'b1;
                                index_is_x = 1'b1;
                                index_is_x = 1'b1;
                                //index = alu_x;
                                //index = alu_x;
                        end
                        end
                        ADC_IDY, AND_IDY, CMP_IDY, EOR_IDY, LDA_IDY, ORA_IDY, SBC_IDY, STA_IDY: begin
                        ADC_IDY, AND_IDY, CMP_IDY, EOR_IDY, LDA_IDY, ORA_IDY, SBC_IDY, STA_IDY: begin
                                indirecty = 1'b1;
                                indirecty = 1'b1;
                                index_is_x = 1'b0;
                                index_is_x = 1'b0;
                                //index = alu_y;        
                                //index = alu_y;        
                        end
                        end
                        JMP_ABS: begin
                        JMP_ABS: begin
                                absolute = 1'b1;
                                absolute = 1'b1;
                                jump = 1'b1;
                                jump = 1'b1;
                        end
                        end
                        JMP_IND: begin
                        JMP_IND: begin
                                jump_indirect = 1'b1;
                                jump_indirect = 1'b1;
                        end
                        end
                        BRK_IMP: begin
                        BRK_IMP: begin
                                brk = 1'b1;
                                brk = 1'b1;
                        end
                        end
                        RTI_IMP: begin
                        RTI_IMP: begin
                                rti = 1'b1;
                                rti = 1'b1;
                        end
                        end
                        RTS_IMP: begin
                        RTS_IMP: begin
                                rts = 1'b1;
                                rts = 1'b1;
                        end
                        end
                        PHA_IMP: begin
                        PHA_IMP: begin
                                pha = 1'b1;
                                pha = 1'b1;
                        end
                        end
                        PHP_IMP: begin
                        PHP_IMP: begin
                                php = 1'b1;
                                php = 1'b1;
                        end
                        end
                        PLA_IMP: begin
                        PLA_IMP: begin
                                pla = 1'b1;
                                pla = 1'b1;
                        end
                        end
                        PLP_IMP: begin
                        PLP_IMP: begin
                                plp = 1'b1;
                                plp = 1'b1;
                        end
                        end
                        JSR_ABS: begin
                        JSR_ABS: begin
                                jsr = 1'b1;
                                jsr = 1'b1;
                        end
                        end
                        TSX_IMP: begin
                        TSX_IMP: begin
                                tsx = 1'b1;
                                tsx = 1'b1;
                        end
                        end
                        TXS_IMP: begin
                        TXS_IMP: begin
                                txs = 1'b1;
                                txs = 1'b1;
                        end
                        end
                        default: begin
                        default: begin
                                index_is_x = 1'b1;
                                index_is_x = 1'b1;
                                //$write("state : %b", state);
                                //$write("state : %b", state);
                                if (reset_n == 1'b1 && state != FETCH_OP_FIX_PC) begin // the processor is NOT being reset neither it is fixing the pc
                                if (reset_n == 1'b1 && state != FETCH_OP_FIX_PC) begin // the processor is NOT being reset neither it is fixing the pc
                                        //$write("\nunknown OPCODE!!!!! 0x%h\n", ir);
                                        //$write("\nunknown OPCODE!!!!! 0x%h\n", ir);
                                        //$finish();
                                        //$finish();
                                end
                                end
                        end
                        end
                endcase
                endcase
 
 
                case (ir)
                case (ir)
                        ASL_ACC, ASL_ZPG, ASL_ZPX, ASL_ABS, ASL_ABX, LSR_ACC, LSR_ZPG, LSR_ZPX, LSR_ABS, LSR_ABX, ROL_ACC, ROL_ZPG, ROL_ZPX, ROL_ABS,
                        ASL_ACC, ASL_ZPG, ASL_ZPX, ASL_ABS, ASL_ABX, LSR_ACC, LSR_ZPG, LSR_ZPX, LSR_ABS, LSR_ABX, ROL_ACC, ROL_ZPG, ROL_ZPX, ROL_ABS,
                        ROL_ABX, ROR_ACC, ROR_ZPG, ROR_ZPX, ROR_ABS, ROR_ABX, INC_ZPG, INC_ZPX, INC_ABS, INC_ABX, DEC_ZPG, DEC_ZPX, DEC_ABS,
                        ROL_ABX, ROR_ACC, ROR_ZPG, ROR_ZPX, ROR_ABS, ROR_ABX, INC_ZPG, INC_ZPX, INC_ABS, INC_ABX, DEC_ZPG, DEC_ZPX, DEC_ABS,
                        DEC_ABX: begin
                        DEC_ABX: begin
                                read_modify_write = 1'b1;
                                read_modify_write = 1'b1;
                        end
                        end
                        STA_ZPG, STA_ZPX, STA_ABS, STA_ABX, STA_ABY, STA_IDX, STA_IDY, STX_ZPG, STX_ZPY, STX_ABS, STY_ZPG, STY_ZPX, STY_ABS: begin
                        STA_ZPG, STA_ZPX, STA_ABS, STA_ABX, STA_ABY, STA_IDX, STA_IDY, STX_ZPG, STX_ZPY, STX_ABS, STY_ZPG, STY_ZPX, STY_ABS: begin
                                write = 1'b1;
                                write = 1'b1;
                        end
                        end
                        default: begin // this should work fine since the previous case statement will detect the unknown/undocumented/unsupported opcodes
                        default: begin // this should work fine since the previous case statement will detect the unknown/undocumented/unsupported opcodes
                                read = 1'b1;
                                read = 1'b1;
                        end
                        end
                endcase
                endcase
        end
        end
endmodule
endmodule
 
 
 
 
 
 
 
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.