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

Subversion Repositories t6507lp

[/] [t6507lp/] [trunk/] [rtl/] [verilog/] [t6507lp_fsm.v] - Diff between revs 103 and 104

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

Rev 103 Rev 104
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
////                                                                    ////
////                                                                    ////
//// 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                          ////
//// - Code the indirect indexed mode                                   ////
//// - Code the indirect indexed mode                                   ////
//// - Code the absolute indirect mode                                  ////
//// - Code the absolute indirect mode                                  ////
////                                                                    ////
////                                                                    ////
//// 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                           ////
////                                                                    ////
////                                                                    ////
////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////
 
 
`timescale 1ns / 1ps
`timescale 1ns / 1ps
 
 
module t6507lp_fsm(clk, reset_n, alu_result, alu_status, data_in, address, control, data_out, alu_opcode, alu_a, alu_enable, alu_x, alu_y);
module t6507lp_fsm(clk, reset_n, alu_result, alu_status, data_in, address, control, data_out, alu_opcode, alu_a, alu_enable, alu_x, alu_y);
        parameter DATA_SIZE = 8;
        parameter DATA_SIZE = 8;
        parameter ADDR_SIZE = 13;
        parameter ADDR_SIZE = 13;
 
 
        localparam DATA_SIZE_ = DATA_SIZE - 4'b0001;
        localparam DATA_SIZE_ = DATA_SIZE - 4'b0001;
        localparam ADDR_SIZE_ = ADDR_SIZE - 4'b0001;
        localparam ADDR_SIZE_ = ADDR_SIZE - 4'b0001;
 
 
        input clk;
        input clk;
        input reset_n;
        input reset_n;
        input [DATA_SIZE_:0] alu_result;
        input [DATA_SIZE_:0] alu_result;
        input [DATA_SIZE_:0] alu_status;
        input [DATA_SIZE_:0] alu_status;
        input [DATA_SIZE_:0] data_in;
        input [DATA_SIZE_:0] data_in;
        output reg [ADDR_SIZE_:0] address;
        output reg [ADDR_SIZE_:0] address;
        output reg control; // one bit is enough? read = 0, write = 1
        output reg control; // one bit is enough? read = 0, write = 1
        output reg [DATA_SIZE_:0] data_out;
        output reg [DATA_SIZE_:0] data_out;
        output reg [DATA_SIZE_:0] alu_opcode;
        output reg [DATA_SIZE_:0] alu_opcode;
        output reg [DATA_SIZE_:0] alu_a;
        output reg [DATA_SIZE_:0] alu_a;
        output reg alu_enable;
        output reg alu_enable;
 
 
        input [DATA_SIZE_:0] alu_x;
        input [DATA_SIZE_:0] alu_x;
        input [DATA_SIZE_:0] alu_y;
        input [DATA_SIZE_:0] alu_y;
 
 
        // FSM states
        // FSM states
        localparam FETCH_OP = 5'b00000;
        localparam FETCH_OP = 5'b00000;
        localparam FETCH_OP_CALC = 5'b00001;
        localparam FETCH_OP_CALC = 5'b00001;
        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_PCL = 5'b10001;
 
        localparam PUSH_STATUS = 5'b10010;
 
        localparam FETCH_PCL = 5'b10011;
 
        localparam FETCH_PCH = 5'b10100;
 
 
        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"
 
 
        // control signals
        // control 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 [ADDR_SIZE_:0] sp;           // stack pointer
        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
        // TODO: not sure if this will be 4 bits wide. as of march 9th this was 4bit wide.
        // TODO: not sure if this will be 5 bits wide. as of march 24th this was 5bit wide.
 
 
        // wiring that simplifies the FSM logic
        // 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;
 
 
 
        // regs for the special instructions
 
        reg break;
 
 
        wire [ADDR_SIZE_:0] next_pc;
        wire [ADDR_SIZE_:0] next_pc;
        assign next_pc = pc + 13'b0000000000001;
        assign next_pc = pc + 13'b0000000000001;
 
 
        reg [ADDR_SIZE_:0] address_plus_index; // this would update more times than actually needed, consuming power.
        reg [ADDR_SIZE_:0] address_plus_index; // this would update more times than actually needed, consuming power.
        reg page_crossed;                       // so the simple assign was changed into a combinational always block
        reg page_crossed;                       // so the simple assign was changed into a combinational always block
 
 
        reg branch;
        reg branch;
 
 
        always @(*) begin
        always @(*) begin
                address_plus_index = 0;
                address_plus_index = 0;
                page_crossed = 0;
                page_crossed = 0;
 
 
                if (state == READ_MEM_CALC_INDEX || state == READ_MEM_FIX_ADDR || state == FETCH_HIGH_CALC_INDEX) begin
                if (state == READ_MEM_CALC_INDEX || state == READ_MEM_FIX_ADDR || state == 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
                else if (branch) begin
                else if (branch) begin
                        if (state == FETCH_OP_FIX_PC || state == FETCH_OP_EVAL_BRANCH) begin
                        if (state == FETCH_OP_FIX_PC || state == FETCH_OP_EVAL_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;// warning: pc might feed these lines twice and cause branch failure
                                address_plus_index[12:8] = pc[12:8] + page_crossed;// 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
                else if (state == READ_FROM_POINTER) begin
                else if (state == 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;
                                address_plus_index[12:8] = 5'b00000;
                        end
                        end
                        else if (jump_indirect) begin
                        else if (jump_indirect) begin
                                address_plus_index[7:0] = temp_addr + 8'h01;
                                address_plus_index[7:0] = temp_addr + 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
                else if (state == READ_FROM_POINTER_X) begin
                else if (state == 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
                else if (state == READ_FROM_POINTER_X1) begin
                else if (state == 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] + page_crossed;
                        address_plus_index[12:8] = temp_addr[12:8] + page_crossed;
                end
                end
        end
        end
 
 
        wire [8:0] sp_plus_one;
        wire [8:0] sp_plus_one;
        assign sp_plus_one = sp + 9'b000000001;
        assign sp_plus_one = sp + 9'b000000001;
 
 
        wire [8:0] sp_minus_one;
        wire [8:0] sp_minus_one;
        assign sp_minus_one = sp - 9'b000000001;
        assign sp_minus_one = sp - 9'b000000001;
 
 
        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 <= 0; // TODO: this is written somewhere. something about a reset vector. must be checked.
                        pc <= 0; // TODO: this is written somewhere. something about a reset vector. must be checked.
                        sp <= 9'b100000000; // the default is 'h100 
                        sp <= 9'b100000000; // the default is 'h100 
                        ir <= 8'h00;
                        ir <= 8'h00;
                        temp_addr <= 13'h00;
                        temp_addr <= 13'h00;
                        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 <= 0;
                        address <= 0;
                        control <= MEM_READ;
                        control <= MEM_READ;
                        data_out <= 8'h00;
                        data_out <= 8'h00;
                end
                end
                else begin
                else begin
                        state <= next_state;
                        state <= next_state;
 
 
                        case (state)
                        case (state)
                                RESET: begin
                                RESET: begin    // The processor was reset
                                        // The processor was reset
 
                                        $write("under reset");
                                        $write("under reset");
                                end
                                end
                                FETCH_OP: begin // this state is the simplest one. it is a simple fetch that must be done when the cpu was reset or
                                /*
                                                // the last cycle was a memory write.
                                FETCH_OP: executed when the processor was reset or the last instruction could not fetch.
 
                                FETCH_OP_CALC: enables the alu 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, FETCH_OP_CALC_PARAM: begin // this is the pipeline happening!
                                        pc <= next_pc;
                                        pc <= next_pc;
                                        address <= next_pc;
                                        address <= next_pc;
                                        control <= MEM_READ;
                                        control <= MEM_READ;
                                        ir <= data_in;
                                        ir <= data_in;
                                end
                                end
                                FETCH_OP_CALC, FETCH_OP_CALC_PARAM: begin // this is the pipeline happening!
                                /*
                                        pc <= next_pc;
                                in this state the opcode is already known so truly execution begins.
                                        address <= next_pc;
                                all instruction execute this cycle.
                                        control <= MEM_READ;
                                */
                                        ir <= data_in;
                                FETCH_LOW: begin
                                end
 
                                FETCH_LOW: begin // in this state the opcode is already known so truly execution begins
 
                                        if (accumulator || implied) begin
                                        if (accumulator || implied) begin
                                                pc <= pc; // is this better?
                                                pc <= pc; // is this better?
                                                address <= pc;
                                                address <= pc;
                                                control <= MEM_READ;
                                                control <= MEM_READ;
                                        end
                                        end
                                        else if (immediate || relative) begin
                                        else if (immediate || relative) begin
                                                pc <= next_pc;
                                                pc <= next_pc;
                                                address <= next_pc;
                                                address <= next_pc;
                                                control <= MEM_READ;
                                                control <= 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;
                                                control <= MEM_READ;
                                                control <= 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
                                                        control <= MEM_WRITE;
                                                        control <= MEM_WRITE;
                                                        data_out <= alu_result;
                                                        data_out <= alu_result;
                                                end
                                                end
                                                else begin
                                                else begin
                                                        control <= MEM_READ;
                                                        control <= 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};
                                                control <= MEM_READ;
                                                control <= 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;
                                                control <= MEM_READ;
                                                control <= 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 (break) begin
 
                                                        pc <= next_pc;
 
                                                        address <= sp;
 
                                                        data_out <= {{3{1'b0}}, pc[12:8]};
 
                                                        control <= MEM_WRITE;
 
                                                        sp <= sp_minus_one;
 
                                                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]};
                                        control <= MEM_READ;
                                        control <= 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.
                                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]};
                                                control <= MEM_READ;
                                                control <= 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;
                                                control <= MEM_READ;
                                                control <= 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
                                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;
                                                control <= MEM_READ;
                                                control <= 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.
                                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]};
                                                control <= MEM_READ;
                                                control <= 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]};
                                                        control <= MEM_WRITE;
                                                        control <= 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]};
                                                        control <= MEM_READ;
                                                        control <= MEM_READ;
                                                        data_out <= 8'h00;
                                                        data_out <= 8'h00;
                                                end
                                                end
                                        end
                                        end
                                        //else begin
                                        //else begin
                                        //      $write("FETCHHIGH PROBLEM"); 
                                        //      $write("FETCHHIGH PROBLEM"); 
                                        //      $finish(0); 
                                        //      $finish(0); 
                                        //end
                                        //end
                                end
                                end
                                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;
                                                control <= MEM_WRITE;
                                                control <= 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;
                                                control <= MEM_READ;
                                                control <= MEM_READ;
                                                data_out <= 8'h00;
                                                data_out <= 8'h00;
                                        end
                                        end
                                end
                                end
                                READ_MEM_CALC_INDEX: begin
                                READ_MEM_CALC_INDEX: begin
                                                //pc <= next_pc; // pc was  already updated in the previous cycle
                                                //pc <= next_pc; // pc was  already updated in the previous cycle
                                                address <= address_plus_index;
                                                address <= address_plus_index;
                                                temp_addr <= address_plus_index;
                                                temp_addr <= address_plus_index;
 
 
                                                if (write) begin
                                                if (write) begin
                                                        control <= MEM_WRITE;
                                                        control <= MEM_WRITE;
                                                        data_out <= alu_result;
                                                        data_out <= alu_result;
                                                end
                                                end
                                                else begin
                                                else begin
                                                        control <= MEM_READ;
                                                        control <= 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
                                                control <= MEM_READ;
                                                control <= MEM_READ;
                                                data_out <= 8'h00;
                                                data_out <= 8'h00;
 
 
                                                if (page_crossed) begin
                                                if (page_crossed) begin
                                                        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
                                                control <= MEM_WRITE;
                                                control <= 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
                                                control <= MEM_READ;
                                                control <= 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
                                DUMMY_WRT_CALC: begin
                                DUMMY_WRT_CALC: begin
                                        pc <= pc;
                                        pc <= pc;
                                        address <= temp_addr;
                                        address <= temp_addr;
                                        control <= MEM_WRITE;
                                        control <= 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;
                                        control <= MEM_READ;
                                        control <= 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;
                                                control <= MEM_READ;
                                                control <= MEM_READ;
                                                address <= address_plus_index;
                                                address <= address_plus_index;
                                        end
                                        end
                                        else begin
                                        else begin
                                                pc <= pc;
                                                pc <= pc;
                                                control <= MEM_READ;
                                                control <= 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;
                                        control <= MEM_READ;
                                        control <= 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];
                                                control <= MEM_READ;
                                                control <= 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
                                                        control <= MEM_WRITE;
                                                        control <= MEM_WRITE;
                                                        data_out <= alu_result;
                                                        data_out <= alu_result;
                                                end
                                                end
                                                else begin
                                                else begin
                                                        control <= MEM_READ;
                                                        control <= 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;
                                                control <= MEM_READ;
                                                control <= MEM_READ;
                                        end
                                        end
                                end
                                end
 
                                PUSH_PCH: begin
 
                                        pc <= pc;
 
                                        address <= sp;
 
                                        data_out <= pc[7:0];
 
                                        control <= MEM_WRITE;
 
                                        sp <= sp_minus_one;
 
                                end
 
                                PUSH_PCL: begin
 
                                        pc <= pc;
 
                                        address <= sp;
 
                                        data_out <= alu_status;
 
                                        control <= MEM_WRITE;
 
                                        sp <= sp_minus_one;
 
                                end
 
                                PUSH_STATUS: begin
 
                                        address <= 13'hFFFE;
 
                                        control <= MEM_READ;
 
                                end
 
                                FETCH_PCL: begin
 
                                        pc[7:0] <= data_in;
 
                                        address <= 13'hFFFF;
 
                                        control <= MEM_READ;
 
                                end
 
                                FETCH_PCH: begin
 
                                        pc[12:8] <= data_in[4:0];
 
                                        address <= {data_in[4:0], pc[7:0]};
 
                                        control <= MEM_READ;
 
                                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 output logic always block
        always @ (*) begin // this is the next_state logic and the 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; // this prevents the latch
                next_state = RESET; // this prevents the latch
 
 
                case (state)
                case (state)
                        RESET: begin
                        RESET: begin
                                next_state = FETCH_OP;
                                next_state = FETCH_OP;
                        end
                        end
                        FETCH_OP: begin
                        FETCH_OP: begin
                                next_state = FETCH_LOW;
                                next_state = FETCH_LOW;
                        end
                        end
                        //FETCH_OP_CALC: begin // so far no addressing mode required the use of this state
                        //FETCH_OP_CALC: begin // so far no addressing mode required the use of this state
                        //      next_state = FETCH_LOW;
                        //      next_state = FETCH_LOW;
                        //      alu_opcode = ir;
                        //      alu_opcode = ir;
                        //      alu_enable = 1'b1;
                        //      alu_enable = 1'b1;
                        //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) begin
                                if (accumulator  || implied) begin
                                        alu_opcode = ir;
                                        alu_opcode = ir;
                                        alu_enable = 1'b1;
                                        alu_enable = 1'b1;
                                        next_state = FETCH_OP;
                                        next_state = FETCH_OP;
                                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 // at least the absolute address mode falls here
                                else if (absolute || jump_indirect) begin // at least the absolute address mode falls here
                                        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
                                        next_state = RESET;
                                        if (break) begin
 
                                                next_state = PUSH_PCH;
 
                                        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 // read_modify_write was showing up here for no reason. no instruction using pointers is from that type.
                                        if (read) begin // read_modify_write was showing up here for no reason. no instruction using pointers is from that type.
                                                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
 
                                next_state = PUSH_PCL;
 
                        end
 
                        PUSH_PCL: begin
 
                                next_state = PUSH_STATUS;
 
                        end
 
                        PUSH_STATUS: begin
 
                                next_state = FETCH_PCL;
 
                        end
 
                        FETCH_PCL: begin
 
                                next_state = FETCH_PCH;
 
                        end
 
                        FETCH_PCH: begin
 
                                next_state = FETCH_OP;
 
                        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 = 1'b0;
                index = 1'b0;
 
 
                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;
 
 
 
                break = 1'b0;
 
 
                case (ir)
                case (ir)
                        CLC_IMP, CLD_IMP, CLI_IMP, CLV_IMP, DEX_IMP, DEY_IMP, INX_IMP, INY_IMP, NOP_IMP, PHA_IMP, PHP_IMP, PLA_IMP,
                        CLC_IMP, CLD_IMP, CLI_IMP, CLV_IMP, DEX_IMP, DEY_IMP, INX_IMP, INY_IMP, NOP_IMP, PHA_IMP, PHP_IMP, PLA_IMP,
                        PLP_IMP, RTI_IMP, RTS_IMP, SEC_IMP, SED_IMP, SEI_IMP, TAX_IMP, TAY_IMP, TSX_IMP, TXA_IMP, TXS_IMP, TYA_IMP: begin
                        PLP_IMP, RTI_IMP, RTS_IMP, SEC_IMP, SED_IMP, SEI_IMP, TAX_IMP, TAY_IMP, TSX_IMP, TXA_IMP, TXS_IMP, TYA_IMP: begin
                                implied = 1'b1;
                                implied = 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 = 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 = alu_y;
                                index = alu_y;
                        end
                        end
                        BCC_REL: begin
                        BCC_REL: begin
                                relative = 1'b1;
                                relative = 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 = 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 = 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 = 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 = 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 = 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 = 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 = 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, JSR_ABS, LDA_ABS,
                        ADC_ABS, AND_ABS, ASL_ABS, BIT_ABS, CMP_ABS, CPX_ABS, CPY_ABS, DEC_ABS, EOR_ABS, INC_ABS, JSR_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 = 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 = 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 = 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 = 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
                                // something goes in here
                                break = 1'b1;
                        end
                        end
                        default: begin
                        default: begin
                                $write("state : %b", state);
                                $write("state : %b", state);
                                if (reset_n == 1 && state != FETCH_OP_FIX_PC) begin // the processor is NOT being reset neither it is fixing the pc
                                if (reset_n == 1 && 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.