data/full_repos/permissive/144902498/source/rtl/fsm.v
None: at end of input
1: b'%Error: data/full_repos/permissive/144902498/source/rtl/fsm.v:3: Cannot find include file: buswidth.vh\n`include "buswidth.vh" \n         ^~~~~~~~~~~~~\n        ... Looked in:\n             data/full_repos/permissive/144902498/source/rtl,data/full_repos/permissive/144902498/buswidth.vh\n             data/full_repos/permissive/144902498/source/rtl,data/full_repos/permissive/144902498/buswidth.vh.v\n             data/full_repos/permissive/144902498/source/rtl,data/full_repos/permissive/144902498/buswidth.vh.sv\n             buswidth.vh\n             buswidth.vh.v\n             buswidth.vh.sv\n             obj_dir/buswidth.vh\n             obj_dir/buswidth.vh.v\n             obj_dir/buswidth.vh.sv\n%Error: data/full_repos/permissive/144902498/source/rtl/fsm.v:33: Cannot find include file: fsm.vh\n`include "fsm.vh" \n         ^~~~~~~~\n%Error: data/full_repos/permissive/144902498/source/rtl/fsm.v:34: Cannot find include file: interrupt.vh\n`include "interrupt.vh" \n         ^~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/144902498/source/rtl/fsm.v:35: Cannot find include file: opcode.vh\n`include "opcode.vh" \n         ^~~~~~~~~~~\n%Error: data/full_repos/permissive/144902498/source/rtl/fsm.v:12: Define or directive not defined: \'`INT_MODE_WIDTH\'\n    input [`INT_MODE_WIDTH-1:0] int_mode_next,\n           ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/144902498/source/rtl/fsm.v:17: Define or directive not defined: \'`OP_PREFIX_WIDTH\'\n    input [`OP_PREFIX_WIDTH-1:0] reg_op_prefix,\n           ^~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/144902498/source/rtl/fsm.v:29: Define or directive not defined: \'`INT_MODE_WIDTH\'\n    output reg [`INT_MODE_WIDTH-1:0] int_mode,\n                ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/144902498/source/rtl/fsm.v:30: Define or directive not defined: \'`FSM_STATE_WIDTH\'\n    output reg [`FSM_STATE_WIDTH-1:0] state\n                ^~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/144902498/source/rtl/fsm.v:44: Define or directive not defined: \'`FSM_STATE_WIDTH\'\nreg [`FSM_STATE_WIDTH-1:0] state_next;\n     ^~~~~~~~~~~~~~~~\n%Error: Exiting due to 9 error(s)\n'
module fsm (
    input clk,
    input n_reset,
    input ipram_loaded,
    input int_disable,
    input int_enable,
    input int_mode_change,
    input [`INT_MODE_WIDTH-1:0] int_mode_next,
    input int_request_int,
    input int_request_nmi,
    input int_restore,
    input [7:0] reg_instr,
    input [`OP_PREFIX_WIDTH-1:0] reg_op_prefix,
    input regfile_flag_s,
    input regfile_flag_z,
    input regfile_flag_pv,
    input regfile_flag_c,
    output reg halt_n_halt,
    output reg halt_n_halt_we,
    output reg int_active_int,
    output reg int_active_nmi,
    output reg int_iff2,
    output reg int_sampled_int,
    output reg int_sampled_nmi,
    output reg [`INT_MODE_WIDTH-1:0] int_mode,
    output reg [`FSM_STATE_WIDTH-1:0] state
);

`include "fsm.vh"
`include "interrupt.vh"
`include "opcode.vh"

reg int_done;
reg int_enable_buf;
reg int_iff1;
reg int_sample;
reg int_suppress;

reg cond;
reg [`FSM_STATE_WIDTH-1:0] state_next;



always @(posedge clk or negedge n_reset) begin
    if (n_reset == 1'b0) begin
        state <= FSM_STATE_IDLE;

        int_active_int  <= 1'b0;
        int_active_nmi  <= 1'b0;
        int_enable_buf  <= 1'b0;
        int_iff1        <= 1'b0;
        int_iff2        <= 1'b0;
        int_mode        <= INT_MODE_0;
        int_sampled_int <= 1'b0;
        int_sampled_nmi <= 1'b0;
    end
    else begin
        if (int_sample) begin
            state <= state_next;


            if (int_request_nmi) begin
                int_sampled_nmi <= 1'b1;
            end
            else if (int_iff1 && !int_enable_buf && int_request_int) begin
                int_sampled_int <= 1'b1;
            end


            if (int_enable_buf)
                int_enable_buf <= 1'b0;
        end
        else begin

            if (!int_suppress && int_sampled_nmi) begin
                state <= FSM_STATE_ACK_NMI_1;

                int_active_nmi <= 1'b1;
            end
            else if (!int_suppress && !int_disable && !int_enable &&
                     int_sampled_int) begin

                state <= FSM_STATE_ACK_INT_1;

                int_active_int <= 1'b1;
            end
            else begin
                state <= state_next;

                if (int_done) begin
                    int_active_int <= 1'b0;
                    int_active_nmi <= 1'b0;
                end
            end


            if (int_disable) begin
                int_iff1 <= 1'b0;
                int_iff2 <= 1'b0;
            end
            else if (int_enable) begin
                int_iff1 <= 1'b1;
                int_iff2 <= 1'b1;
            end
            else if (int_restore) begin
                if (!int_suppress && int_sampled_nmi)
                    int_iff1 <= 1'b0;
                else
                    int_iff1 <= int_iff2;
            end
            else if (!int_suppress && int_sampled_nmi) begin
                int_iff2 <= int_iff1;
                int_iff1 <= 1'b0;
            end


            if (int_enable)
                int_enable_buf <= 1'b1;


            if (int_mode_change) begin
                int_mode <= int_mode_next;
            end


            int_sampled_int <= 1'b0;
            int_sampled_nmi <= 1'b0;
        end
    end
end



always @* begin
    case (reg_instr[5:3])
        3'b000: cond = !regfile_flag_z;
        3'b001: cond =  regfile_flag_z;
        3'b010: cond = !regfile_flag_c;
        3'b011: cond =  regfile_flag_c;
        3'b100: cond = !regfile_flag_pv;
        3'b101: cond =  regfile_flag_pv;
        3'b110: cond = !regfile_flag_s;
        3'b111: cond =  regfile_flag_s;
    endcase
end

always @* begin
    halt_n_halt    = 1'b1;
    halt_n_halt_we = 1'b0;
    int_done       = 1'b0;
    int_sample     = 1'b0;
    int_suppress   = 1'b0;
    state_next     = FSM_STATE_IDLE;

    case (state)
        FSM_STATE_IDLE: begin
            if (ipram_loaded == 1'b1) begin
                state_next = FSM_STATE_INSTR_FETCH1_1;
            end else begin
                state_next = FSM_STATE_IDLE;
            end
        end
        FSM_STATE_INSTR_FETCH1_1: begin
            state_next = FSM_STATE_INSTR_FETCH1_2;
        end
        FSM_STATE_INSTR_FETCH1_2: begin
            state_next = FSM_STATE_INSTR_FETCH1_3;
            int_sample = 1'b1;
        end
        FSM_STATE_INSTR_FETCH1_3: begin
            casez (reg_instr)
                8'hDD, 8'hFD, 8'hED, 8'hCB:
                begin
                    state_next   = FSM_STATE_INSTR_FETCH2_1;
                    int_suppress = 1'b1;
                end
                8'b01110110:
                begin
                    state_next     = FSM_STATE_INSTR_FETCH1_1;
                    halt_n_halt    = int_sampled_int;
                    halt_n_halt_we = 1'b1;
                end
                8'b00101010,
                8'b00100010,
                8'b00110010,
                8'b00110110,
                8'b00111010,
                8'b00???110,
                8'b00??0001,
                8'b11???110,
                8'b11000011,
                8'b11???010,
                8'b00011000,
                8'b00111000,
                8'b00110000,
                8'b00101000,
                8'b00100000,
                8'b00010000,
                8'b11001101,
                8'b11011011,
                8'b11010011:
                begin
                    state_next   = FSM_STATE_OP_FETCH1_1;
                    int_suppress = 1'b1;
                end
                8'b11??0001,
                8'b000?1010,
                8'b11100011,
                8'b0011010?,
                8'b01???110,
                8'b10???110,
                8'b11001001:
                begin
                    state_next   = FSM_STATE_MEM_READ1_1;
                    int_suppress = 1'b1;
                end
                8'b11??0101,
                8'b11???111:
                begin
                    state_next   = FSM_STATE_PRE_MEM_WRITE_1;
                    int_suppress = 1'b1;
                end
                8'b000?0010,
                8'b01110???:
                begin
                    state_next   = FSM_STATE_MEM_WRITE1_1;
                    int_suppress = 1'b1;
                end
                8'b11???100:
                begin
                    if (cond) begin
                        state_next   = FSM_STATE_OP_FETCH1_1;
                        int_suppress = 1'b1;
                    end
                    else begin
                        state_next = FSM_STATE_PRE_INSTR_FETCH_1;
                    end
                end
                8'b11???000:
                begin
                    if (cond) begin
                        state_next   = FSM_STATE_MEM_READ1_1;
                        int_suppress = 1'b1;
                    end
                    else begin
                        state_next = FSM_STATE_INSTR_FETCH1_1;
                    end
                end
                default: begin
                    state_next = FSM_STATE_INSTR_FETCH1_1;
                end
            endcase
        end
        FSM_STATE_INSTR_FETCH2_1: begin
            state_next = FSM_STATE_INSTR_FETCH2_2;
        end
        FSM_STATE_INSTR_FETCH2_2: begin
            state_next = FSM_STATE_INSTR_FETCH2_3;
            int_sample = 1'b1;
        end
        FSM_STATE_INSTR_FETCH2_3: begin
            casez ({ reg_op_prefix, reg_instr })
                { OP_PREFIX_DD, 8'b00100001 },
                { OP_PREFIX_DD, 8'b00100010 },
                { OP_PREFIX_DD, 8'b00101010 },
                { OP_PREFIX_DD, 8'b0011010? },
                { OP_PREFIX_DD, 8'b00110110 },
                { OP_PREFIX_DD, 8'b01110??? },
                { OP_PREFIX_DD, 8'b01???110 },
                { OP_PREFIX_DD, 8'b10???110 },
                { OP_PREFIX_DD, 8'b11001011 },
                { OP_PREFIX_ED, 8'b01??0011 },
                { OP_PREFIX_ED, 8'b01??1011 },
                { OP_PREFIX_FD, 8'b00100001 },
                { OP_PREFIX_FD, 8'b00100010 },
                { OP_PREFIX_FD, 8'b00101010 },
                { OP_PREFIX_FD, 8'b0011010? },
                { OP_PREFIX_FD, 8'b00110110 },
                { OP_PREFIX_FD, 8'b01110??? },
                { OP_PREFIX_FD, 8'b01???110 },
                { OP_PREFIX_FD, 8'b10???110 },
                { OP_PREFIX_FD, 8'b11001011 }:
                begin
                    state_next   = FSM_STATE_OP_FETCH1_1;
                    int_suppress = 1'b1;
                end
                { OP_PREFIX_CB,   8'b?????110 },
                { OP_PREFIX_DD,   8'b11100011 },
                { OP_PREFIX_DD,   8'b11100001 },
                { OP_PREFIX_ED,   8'b101??000 },
                { OP_PREFIX_ED,   8'b101??001 },
                { OP_PREFIX_ED,   8'b0110?111 },
                { OP_PREFIX_ED,   8'b0100?101 },
                { OP_PREFIX_FD,   8'b11100011 },
                { OP_PREFIX_ED,   8'b101??011 },
                { OP_PREFIX_FD,   8'b11100001 }:
                begin
                    state_next   = FSM_STATE_MEM_READ1_1;
                    int_suppress = 1'b1;
                end
                { OP_PREFIX_DD, 8'b11100101 },
                { OP_PREFIX_FD, 8'b11100101 }:
                begin
                    state_next   = FSM_STATE_PRE_MEM_WRITE_1;
                    int_suppress = 1'b1;
                end
                { OP_PREFIX_ED, 8'b01???000 },
                { OP_PREFIX_ED, 8'b101??010 }:
                begin
                    state_next   = FSM_STATE_IO_READ_1;
                    int_suppress = 1'b1;
                end
                { OP_PREFIX_ED, 8'b01???001 }:
                begin
                    state_next   = FSM_STATE_IO_WRITE_1;
                    int_suppress = 1'b1;
                end
                default: begin
                    state_next = FSM_STATE_INSTR_FETCH1_1;
                end
            endcase
        end
        FSM_STATE_INSTR_FETCH3_1: begin
            state_next = FSM_STATE_INSTR_FETCH3_2;
        end
        FSM_STATE_INSTR_FETCH3_2: begin
            state_next = FSM_STATE_INSTR_FETCH3_3;
            int_sample = 1'b1;
        end
        FSM_STATE_INSTR_FETCH3_3: begin
            state_next   = FSM_STATE_PRE_MEM_READ_1;
            int_suppress = 1'b1;
        end
        FSM_STATE_OP_FETCH1_1: begin
            state_next = FSM_STATE_OP_FETCH1_2;
        end
        FSM_STATE_OP_FETCH1_2: begin
            state_next = FSM_STATE_OP_FETCH1_3;

            casez ({ reg_op_prefix, reg_instr })
                { OP_PREFIX_NONE,  8'b00100010 },
                { OP_PREFIX_NONE,  8'b00101010 },
                { OP_PREFIX_NONE,  8'b00110010 },
                { OP_PREFIX_NONE,  8'b00110110 },
                { OP_PREFIX_NONE,  8'b00111010 },
                { OP_PREFIX_NONE,  8'b11000011 },
                { OP_PREFIX_NONE,  8'b11001101 },
                { OP_PREFIX_NONE,  8'b11010011 },
                { OP_PREFIX_NONE,  8'b11011011 },
                { OP_PREFIX_NONE,  8'b11???010 },
                { OP_PREFIX_NONE,  8'b11???100 },
                { OP_PREFIX_CB,    8'b00???110 },
                { OP_PREFIX_DD,    8'b00100010 },
                { OP_PREFIX_DD,    8'b00100001 },
                { OP_PREFIX_DD,    8'b00101010 },
                { OP_PREFIX_DD,    8'b0011010? },
                { OP_PREFIX_DD,    8'b00110110 },
                { OP_PREFIX_DD,    8'b01110??? },
                { OP_PREFIX_DD,    8'b01???110 },
                { OP_PREFIX_DD,    8'b10???110 },
                { OP_PREFIX_ED,    8'b01??0011 },
                { OP_PREFIX_ED,    8'b01??1011 },
                { OP_PREFIX_FD,    8'b00100001 },
                { OP_PREFIX_FD,    8'b00100010 },
                { OP_PREFIX_FD,    8'b00101010 },
                { OP_PREFIX_FD,    8'b0011010? },
                { OP_PREFIX_FD,    8'b00110110 },
                { OP_PREFIX_FD,    8'b01110??? },
                { OP_PREFIX_FD,    8'b01???110 },
                { OP_PREFIX_FD,    8'b10???110 },
                { OP_PREFIX_DD_CB, 8'b?????110 },
                { OP_PREFIX_FD_CB, 8'b?????110 }:
                begin
                    int_sample = 1'b0;
                end
                default: begin
                    int_sample = 1'b1;
                end
            endcase
        end
        FSM_STATE_OP_FETCH1_3: begin
            casez ({ reg_op_prefix, reg_instr })
                { OP_PREFIX_DD_CB, 8'b???????? },
                { OP_PREFIX_FD_CB, 8'b???????? }:
                begin
                    state_next = FSM_STATE_INSTR_FETCH3_1;
                end
                { OP_PREFIX_NONE, 8'b00100010 },
                { OP_PREFIX_NONE, 8'b00101010 },
                { OP_PREFIX_NONE, 8'b00110010 },
                { OP_PREFIX_NONE, 8'b00111010 },
                { OP_PREFIX_NONE, 8'b00??0001 },
                { OP_PREFIX_NONE, 8'b11000011 },
                { OP_PREFIX_NONE, 8'b11001101 },
                { OP_PREFIX_NONE, 8'b11???010 },
                { OP_PREFIX_NONE, 8'b11???100 },
                { OP_PREFIX_DD,   8'b00100001 },
                { OP_PREFIX_DD,   8'b00100010 },
                { OP_PREFIX_DD,   8'b00101010 },
                { OP_PREFIX_DD,   8'b00110110 },
                { OP_PREFIX_ED,   8'b01??0011 },
                { OP_PREFIX_ED,   8'b01??1011 },
                { OP_PREFIX_FD,   8'b00100001 },
                { OP_PREFIX_FD,   8'b00100010 },
                { OP_PREFIX_FD,   8'b00101010 },
                { OP_PREFIX_FD,   8'b00110110 }:
                begin
                    state_next = FSM_STATE_OP_FETCH2_1;
                end
                { OP_PREFIX_DD, 8'b01???110 },
                { OP_PREFIX_DD, 8'b10???110 },
                { OP_PREFIX_DD, 8'b0011010? },
                { OP_PREFIX_FD, 8'b01???110 },
                { OP_PREFIX_FD, 8'b10???110 },
                { OP_PREFIX_FD, 8'b0011010? }:
                begin
                    state_next = FSM_STATE_PRE_MEM_READ_1;
                end
                { OP_PREFIX_DD, 8'b01110??? },
                { OP_PREFIX_FD, 8'b01110??? }:
                begin
                    state_next = FSM_STATE_PRE_MEM_WRITE_1;
                end
                { OP_PREFIX_NONE, 8'b00110110 }:
                begin
                    state_next = FSM_STATE_MEM_WRITE1_1;
                end
                { OP_PREFIX_NONE, 8'b11011011 }:
                begin
                    state_next = FSM_STATE_IO_READ_1;
                end
                { OP_PREFIX_NONE, 8'b11010011 }:
                begin
                    state_next = FSM_STATE_IO_WRITE_1;
                end
                default: begin
                    state_next = FSM_STATE_INSTR_FETCH1_1;
                end
            endcase
        end
        FSM_STATE_OP_FETCH2_1: begin
            state_next = FSM_STATE_OP_FETCH2_2;
        end
        FSM_STATE_OP_FETCH2_2: begin
            state_next = FSM_STATE_OP_FETCH2_3;

            casez ({ reg_op_prefix, reg_instr })
                { OP_PREFIX_NONE, 8'b00100010 },
                { OP_PREFIX_NONE, 8'b00101010 },
                { OP_PREFIX_NONE, 8'b00110010 },
                { OP_PREFIX_NONE, 8'b00111010 },
                { OP_PREFIX_NONE, 8'b11001101 },
                { OP_PREFIX_NONE, 8'b11???100 },
                { OP_PREFIX_DD,   8'b00100010 },
                { OP_PREFIX_DD,   8'b00101010 },
                { OP_PREFIX_DD,   8'b00110110 },
                { OP_PREFIX_ED,   8'b01??0011 },
                { OP_PREFIX_ED,   8'b01??1011 },
                { OP_PREFIX_FD,   8'b00100010 },
                { OP_PREFIX_FD,   8'b00101010 },
                { OP_PREFIX_FD,   8'b00110110 }:
                begin
                    int_sample = 1'b0;
                end
                default: begin
                    int_sample = 1'b1;
                end
            endcase
        end
        FSM_STATE_OP_FETCH2_3: begin
            casez ({ reg_op_prefix, reg_instr })
                { OP_PREFIX_NONE, 8'b00101010 },
                { OP_PREFIX_NONE, 8'b00111010 },
                { OP_PREFIX_DD,   8'b00101010 },
                { OP_PREFIX_ED,   8'b01??1011 },
                { OP_PREFIX_FD,   8'b00101010 }:
                begin
                    state_next = FSM_STATE_MEM_READ1_1;
                end
                { OP_PREFIX_DD, 8'b00110110 },
                { OP_PREFIX_FD, 8'b00110110 }:
                begin
                    state_next = FSM_STATE_PRE_MEM_WRITE_1;
                end
                { OP_PREFIX_NONE, 8'b00100010 },
                { OP_PREFIX_NONE, 8'b00110010 },
                { OP_PREFIX_NONE, 8'b11001101 },
                { OP_PREFIX_NONE, 8'b11???100 },
                { OP_PREFIX_DD,   8'b00100010 },
                { OP_PREFIX_ED,   8'b01??0011 },
                { OP_PREFIX_FD,   8'b00100010 }:
                begin
                    state_next = FSM_STATE_MEM_WRITE1_1;
                end
                default: begin
                    state_next = FSM_STATE_INSTR_FETCH1_1;
                end
            endcase
        end
        FSM_STATE_MEM_READ1_1: begin
            state_next = FSM_STATE_MEM_READ1_2;
        end
        FSM_STATE_MEM_READ1_2: begin
            state_next = FSM_STATE_MEM_READ1_3;

            if (int_active_int && int_mode == INT_MODE_2) begin
                int_sample = 1'b0;
            end
            else begin
                casez ({ reg_op_prefix, reg_instr })
                    { OP_PREFIX_NONE,  8'b11??0001 },
                    { OP_PREFIX_NONE,  8'b00101010 },
                    { OP_PREFIX_NONE,  8'b0011010? },
                    { OP_PREFIX_NONE,  8'b11001001 },
                    { OP_PREFIX_NONE,  8'b11100011 },
                    { OP_PREFIX_NONE,  8'b11???000 },
                    { OP_PREFIX_CB,    8'b00???110 },
                    { OP_PREFIX_CB,    8'b1????110 },
                    { OP_PREFIX_DD,    8'b00101010 },
                    { OP_PREFIX_DD,    8'b11100001 },
                    { OP_PREFIX_DD,    8'b0011010? },
                    { OP_PREFIX_DD,    8'b11100011 },
                    { OP_PREFIX_ED,    8'b0100?101 },
                    { OP_PREFIX_ED,    8'b0110?111 },
                    { OP_PREFIX_ED,    8'b01??1011 },
                    { OP_PREFIX_ED,    8'b101??000 },
                    { OP_PREFIX_ED,    8'b1011?001 },
                    { OP_PREFIX_FD,    8'b00101010 },
                    { OP_PREFIX_FD,    8'b11100001 },
                    { OP_PREFIX_FD,    8'b0011010? },
                    { OP_PREFIX_FD,    8'b11100011 },
                    { OP_PREFIX_DD_CB, 8'b00???110 },
                    { OP_PREFIX_DD_CB, 8'b1????110 },
                    { OP_PREFIX_FD_CB, 8'b00???110 },
                    { OP_PREFIX_FD_CB, 8'b1????110 }:
                    begin
                        int_sample = 1'b0;
                    end
                    default: begin
                        int_sample = 1'b1;
                    end
                endcase
            end
        end
        FSM_STATE_MEM_READ1_3: begin
            if (int_active_int && int_mode == INT_MODE_2) begin
                state_next = FSM_STATE_PRE_MEM_READ_2;
            end
            else begin
                casez ({ reg_op_prefix, reg_instr })
                    { OP_PREFIX_NONE, 8'b00101010 },
                    { OP_PREFIX_NONE, 8'b11??0001 },
                    { OP_PREFIX_DD,   8'b00101010 },
                    { OP_PREFIX_DD,   8'b11100001 },
                    { OP_PREFIX_ED,   8'b01??1011 },
                    { OP_PREFIX_FD,   8'b00101010 },
                    { OP_PREFIX_FD,   8'b11100001 }:
                    begin
                        state_next = FSM_STATE_PRE_MEM_READ_2;
                    end
                    { OP_PREFIX_NONE, 8'b11001001 },
                    { OP_PREFIX_NONE, 8'b11???000 },
                    { OP_PREFIX_ED,   8'b0100?101 }:
                    begin
                        state_next = FSM_STATE_MEM_READ2_1;
                    end
                    { OP_PREFIX_NONE,  8'b0011010? },
                    { OP_PREFIX_CB,    8'b00???110 },
                    { OP_PREFIX_CB,    8'b1????110 },
                    { OP_PREFIX_DD,    8'b0011010? },
                    { OP_PREFIX_ED,    8'b0110?111 },
                    { OP_PREFIX_FD,    8'b0011010? },
                    { OP_PREFIX_DD_CB, 8'b00???110 },
                    { OP_PREFIX_DD_CB, 8'b1????110 },
                    { OP_PREFIX_FD_CB, 8'b00???110 },
                    { OP_PREFIX_FD_CB, 8'b1????110 }:
                    begin
                        state_next = FSM_STATE_PRE_MEM_WRITE_1;
                    end
                    { OP_PREFIX_NONE, 8'b11100011 },
                    { OP_PREFIX_DD,   8'b11100011 },
                    { OP_PREFIX_ED,   8'b101??000 },
                    { OP_PREFIX_FD,   8'b11100011 }:
                    begin
                        state_next = FSM_STATE_MEM_WRITE1_1;
                    end
                    { OP_PREFIX_ED, 8'b101??011 }:
                    begin
                        state_next = FSM_STATE_IO_WRITE_1;
                    end
                    { OP_PREFIX_ED, 8'b1011?001 }:
                    begin
                        state_next = FSM_STATE_BLOCK_TRANSFER;

                        int_sample = 1'b1;
                    end
                    default: begin
                        state_next = FSM_STATE_INSTR_FETCH1_1;
                    end
                endcase
            end
        end
        FSM_STATE_MEM_READ2_1: begin
            state_next = FSM_STATE_MEM_READ2_2;
        end
        FSM_STATE_MEM_READ2_2: begin
            state_next = FSM_STATE_MEM_READ2_3;

            if (int_active_int && int_mode == INT_MODE_2) begin
                int_sample = 1'b1;
            end
            else begin
                case ({ reg_op_prefix, reg_instr })
                    { OP_PREFIX_NONE, 8'b11100011 },
                    { OP_PREFIX_DD,   8'b11100011 },
                    { OP_PREFIX_FD,   8'b11100011 }:
                    begin
                        int_sample = 1'b0;
                    end
                    default: begin
                        int_sample = 1'b1;
                    end
                endcase
            end
        end
        FSM_STATE_MEM_READ2_3: begin
            if (int_active_int && int_mode == INT_MODE_2) begin
                state_next = FSM_STATE_INSTR_FETCH1_1;

                int_done = 1'b1;
            end
            else begin
                case ({ reg_op_prefix, reg_instr })
                    { OP_PREFIX_NONE, 8'b11100011 },
                    { OP_PREFIX_DD,   8'b11100011 },
                    { OP_PREFIX_FD,   8'b11100011 }:
                    begin
                        state_next = FSM_STATE_MEM_WRITE2_1;
                    end
                    default: begin
                        state_next = FSM_STATE_INSTR_FETCH1_1;
                    end
                endcase
            end

            if (int_active_int && int_mode == INT_MODE_2)
                int_done = 1'b1;
        end
        FSM_STATE_MEM_WRITE1_1: begin
            state_next = FSM_STATE_MEM_WRITE1_2;
        end
        FSM_STATE_MEM_WRITE1_2: begin
            state_next = FSM_STATE_MEM_WRITE1_3;

            if (int_active_int || int_active_nmi) begin
                int_sample = 1'b0;
            end
            else begin
                casez ({ reg_op_prefix, reg_instr })
                    { OP_PREFIX_NONE, 8'b00100010 },
                    { OP_PREFIX_NONE, 8'b11??0101 },
                    { OP_PREFIX_NONE, 8'b11100011 },
                    { OP_PREFIX_NONE, 8'b11???100 },
                    { OP_PREFIX_NONE, 8'b11???111 },
                    { OP_PREFIX_DD,   8'b00100010 },
                    { OP_PREFIX_DD,   8'b11100101 },
                    { OP_PREFIX_DD,   8'b11100011 },
                    { OP_PREFIX_ED,   8'b01??0011 },
                    { OP_PREFIX_FD,   8'b00100010 },
                    { OP_PREFIX_FD,   8'b11100101 },
                    { OP_PREFIX_FD,   8'b11100011 }:
                    begin
                        int_sample = 1'b0;
                    end
                    default: begin
                        int_sample = 1'b1;
                    end
                endcase
            end
        end
        FSM_STATE_MEM_WRITE1_3: begin
            if (int_active_nmi || (int_active_int && int_mode != INT_MODE_0)) begin
                state_next = FSM_STATE_PRE_MEM_WRITE_2;
            end
            else begin
                casez ({ reg_op_prefix, reg_instr })
                    { OP_PREFIX_NONE, 8'b11100011 },
                    { OP_PREFIX_DD,   8'b11100011 },
                    { OP_PREFIX_FD,   8'b11100011 }:
                    begin
                        state_next = FSM_STATE_PRE_MEM_READ_2;
                    end
                    { OP_PREFIX_ED, 8'b1011?010 }:
                    begin
                        if (!regfile_flag_z)
                            state_next = FSM_STATE_PRE_MEM_READ_1;
                    end
                    { OP_PREFIX_NONE, 8'b00100010 },
                    { OP_PREFIX_NONE, 8'b11??0101 },
                    { OP_PREFIX_NONE, 8'b11???100 },
                    { OP_PREFIX_NONE, 8'b11001101 },
                    { OP_PREFIX_NONE, 8'b11???111 },
                    { OP_PREFIX_DD,   8'b00100010 },
                    { OP_PREFIX_DD,   8'b11100101 },
                    { OP_PREFIX_ED,   8'b01??0011 },
                    { OP_PREFIX_FD,   8'b00100010 },
                    { OP_PREFIX_FD,   8'b11100101 }:
                    begin
                        state_next = FSM_STATE_PRE_MEM_WRITE_2;
                    end
                    default: begin
                        int_sample = 1'b1;
                        state_next = FSM_STATE_INSTR_FETCH1_1;
                    end
                endcase
            end
        end
        FSM_STATE_MEM_WRITE2_1: begin
            state_next = FSM_STATE_MEM_WRITE2_2;
        end
        FSM_STATE_MEM_WRITE2_2: begin
            state_next = FSM_STATE_MEM_WRITE2_3;

            if ((int_active_int && (int_mode != INT_MODE_2)) || int_active_nmi)
                int_sample = 1'b0;
            else
                int_sample = 1'b1;
        end
        FSM_STATE_MEM_WRITE2_3: begin
            if (int_active_int && int_mode == INT_MODE_2)
                state_next = FSM_STATE_MEM_READ1_1;
            else
                state_next = FSM_STATE_INSTR_FETCH1_1;

            if ((int_active_int && int_mode != INT_MODE_2) || int_active_nmi)
                int_done = 1'b1;
        end
        FSM_STATE_IO_READ_1: begin
            state_next = FSM_STATE_IO_READ_2;
        end
        FSM_STATE_IO_READ_2: begin
            state_next = FSM_STATE_IO_READ_3;

            casez ({ reg_op_prefix, reg_instr })
                { OP_PREFIX_ED, 8'b101??010 }:
                begin
                    int_sample = 1'b0;
                end
                default: begin
                    int_sample = 1'b1;
                end
            endcase
        end
        FSM_STATE_IO_READ_3: begin
            casez ({ reg_op_prefix, reg_instr })
                { OP_PREFIX_ED, 8'b101??010 }:
                begin
                    state_next = FSM_STATE_MEM_WRITE1_1;
                end
                default: begin
                    state_next = FSM_STATE_INSTR_FETCH1_1;
                end
            endcase
        end
        FSM_STATE_IO_WRITE_1: begin
            state_next = FSM_STATE_IO_WRITE_2;
        end
        FSM_STATE_IO_WRITE_2: begin
            state_next = FSM_STATE_IO_WRITE_3;
            int_sample = 1'b1;
        end
        FSM_STATE_IO_WRITE_3: begin
            casez ({ reg_op_prefix, reg_instr })
                { OP_PREFIX_ED, 8'b1010?011 }:
                begin
                    state_next = FSM_STATE_INSTR_FETCH1_1;
                end
                { OP_PREFIX_ED, 8'b1011?011 }:
                begin
                    if (!regfile_flag_z)
                        state_next = FSM_STATE_PRE_INSTR_FETCH_1;
                    else
                        state_next = FSM_STATE_INSTR_FETCH1_1;
                end
            endcase
        end
        FSM_STATE_ACK_INT_1: begin
            state_next = FSM_STATE_ACK_INT_2;
        end
        FSM_STATE_ACK_INT_2: begin
            state_next = FSM_STATE_ACK_INT_3;
        end
        FSM_STATE_ACK_INT_3: begin
            state_next = FSM_STATE_ACK_INT_4;
        end
        FSM_STATE_ACK_INT_4: begin
            case (int_mode)
                INT_MODE_0: begin
                    state_next = FSM_STATE_INSTR_FETCH1_3;
                    int_done = 1'b1;
                end
                INT_MODE_1,
                INT_MODE_2: begin
                    state_next = FSM_STATE_PRE_MEM_WRITE_1;
                end
            endcase
        end
        FSM_STATE_ACK_NMI_1: begin
            state_next = FSM_STATE_ACK_NMI_2;
        end
        FSM_STATE_ACK_NMI_2: begin
            state_next = FSM_STATE_PRE_MEM_WRITE_1;
        end
        FSM_STATE_PRE_INSTR_FETCH_1: begin
            state_next = FSM_STATE_INSTR_FETCH1_1;
        end
        FSM_STATE_PRE_MEM_READ_1: begin
            state_next = FSM_STATE_MEM_READ1_1;
        end
        FSM_STATE_PRE_MEM_READ_2: begin
            state_next = FSM_STATE_MEM_READ2_1;
        end
        FSM_STATE_PRE_MEM_WRITE_1: begin
            state_next = FSM_STATE_MEM_WRITE1_1;
        end
        FSM_STATE_PRE_MEM_WRITE_2: begin
            state_next = FSM_STATE_MEM_WRITE2_1;
        end
        FSM_STATE_BLOCK_TRANSFER: begin
            state_next = FSM_STATE_INSTR_FETCH1_1;
        end
    endcase
end

endmodule
module fsm (
    input clk,
    input n_reset,
    input ipram_loaded,
    input int_disable,
    input int_enable,
    input int_mode_change,
    input [`INT_MODE_WIDTH-1:0] int_mode_next,
    input int_request_int,
    input int_request_nmi,
    input int_restore,
    input [7:0] reg_instr,
    input [`OP_PREFIX_WIDTH-1:0] reg_op_prefix,
    input regfile_flag_s,
    input regfile_flag_z,
    input regfile_flag_pv,
    input regfile_flag_c,
    output reg halt_n_halt,
    output reg halt_n_halt_we,
    output reg int_active_int,
    output reg int_active_nmi,
    output reg int_iff2,
    output reg int_sampled_int,
    output reg int_sampled_nmi,
    output reg [`INT_MODE_WIDTH-1:0] int_mode,
    output reg [`FSM_STATE_WIDTH-1:0] state
);


`include "fsm.vh"
`include "interrupt.vh"
`include "opcode.vh"

reg int_done;
reg int_enable_buf;
reg int_iff1;
reg int_sample;
reg int_suppress;

reg cond;
reg [`FSM_STATE_WIDTH-1:0] state_next;



always @(posedge clk or negedge n_reset) begin
    if (n_reset == 1'b0) begin
        state <= FSM_STATE_IDLE;

        int_active_int  <= 1'b0;
        int_active_nmi  <= 1'b0;
        int_enable_buf  <= 1'b0;
        int_iff1        <= 1'b0;
        int_iff2        <= 1'b0;
        int_mode        <= INT_MODE_0;
        int_sampled_int <= 1'b0;
        int_sampled_nmi <= 1'b0;
    end
    else begin
        if (int_sample) begin
            state <= state_next;


            if (int_request_nmi) begin
                int_sampled_nmi <= 1'b1;
            end
            else if (int_iff1 && !int_enable_buf && int_request_int) begin
                int_sampled_int <= 1'b1;
            end


            if (int_enable_buf)
                int_enable_buf <= 1'b0;
        end
        else begin

            if (!int_suppress && int_sampled_nmi) begin
                state <= FSM_STATE_ACK_NMI_1;

                int_active_nmi <= 1'b1;
            end
            else if (!int_suppress && !int_disable && !int_enable &&
                     int_sampled_int) begin

                state <= FSM_STATE_ACK_INT_1;

                int_active_int <= 1'b1;
            end
            else begin
                state <= state_next;

                if (int_done) begin
                    int_active_int <= 1'b0;
                    int_active_nmi <= 1'b0;
                end
            end


            if (int_disable) begin
                int_iff1 <= 1'b0;
                int_iff2 <= 1'b0;
            end
            else if (int_enable) begin
                int_iff1 <= 1'b1;
                int_iff2 <= 1'b1;
            end
            else if (int_restore) begin
                if (!int_suppress && int_sampled_nmi)
                    int_iff1 <= 1'b0;
                else
                    int_iff1 <= int_iff2;
            end
            else if (!int_suppress && int_sampled_nmi) begin
                int_iff2 <= int_iff1;
                int_iff1 <= 1'b0;
            end


            if (int_enable)
                int_enable_buf <= 1'b1;


            if (int_mode_change) begin
                int_mode <= int_mode_next;
            end


            int_sampled_int <= 1'b0;
            int_sampled_nmi <= 1'b0;
        end
    end
end



always @* begin
    case (reg_instr[5:3])
        3'b000: cond = !regfile_flag_z;
        3'b001: cond =  regfile_flag_z;
        3'b010: cond = !regfile_flag_c;
        3'b011: cond =  regfile_flag_c;
        3'b100: cond = !regfile_flag_pv;
        3'b101: cond =  regfile_flag_pv;
        3'b110: cond = !regfile_flag_s;
        3'b111: cond =  regfile_flag_s;
    endcase
end

always @* begin
    halt_n_halt    = 1'b1;
    halt_n_halt_we = 1'b0;
    int_done       = 1'b0;
    int_sample     = 1'b0;
    int_suppress   = 1'b0;
    state_next     = FSM_STATE_IDLE;

    case (state)
        FSM_STATE_IDLE: begin
            if (ipram_loaded == 1'b1) begin
                state_next = FSM_STATE_INSTR_FETCH1_1;
            end else begin
                state_next = FSM_STATE_IDLE;
            end
        end
        FSM_STATE_INSTR_FETCH1_1: begin
            state_next = FSM_STATE_INSTR_FETCH1_2;
        end
        FSM_STATE_INSTR_FETCH1_2: begin
            state_next = FSM_STATE_INSTR_FETCH1_3;
            int_sample = 1'b1;
        end
        FSM_STATE_INSTR_FETCH1_3: begin
            casez (reg_instr)
                8'hDD, 8'hFD, 8'hED, 8'hCB:
                begin
                    state_next   = FSM_STATE_INSTR_FETCH2_1;
                    int_suppress = 1'b1;
                end
                8'b01110110:
                begin
                    state_next     = FSM_STATE_INSTR_FETCH1_1;
                    halt_n_halt    = int_sampled_int;
                    halt_n_halt_we = 1'b1;
                end
                8'b00101010,
                8'b00100010,
                8'b00110010,
                8'b00110110,
                8'b00111010,
                8'b00???110,
                8'b00??0001,
                8'b11???110,
                8'b11000011,
                8'b11???010,
                8'b00011000,
                8'b00111000,
                8'b00110000,
                8'b00101000,
                8'b00100000,
                8'b00010000,
                8'b11001101,
                8'b11011011,
                8'b11010011:
                begin
                    state_next   = FSM_STATE_OP_FETCH1_1;
                    int_suppress = 1'b1;
                end
                8'b11??0001,
                8'b000?1010,
                8'b11100011,
                8'b0011010?,
                8'b01???110,
                8'b10???110,
                8'b11001001:
                begin
                    state_next   = FSM_STATE_MEM_READ1_1;
                    int_suppress = 1'b1;
                end
                8'b11??0101,
                8'b11???111:
                begin
                    state_next   = FSM_STATE_PRE_MEM_WRITE_1;
                    int_suppress = 1'b1;
                end
                8'b000?0010,
                8'b01110???:
                begin
                    state_next   = FSM_STATE_MEM_WRITE1_1;
                    int_suppress = 1'b1;
                end
                8'b11???100:
                begin
                    if (cond) begin
                        state_next   = FSM_STATE_OP_FETCH1_1;
                        int_suppress = 1'b1;
                    end
                    else begin
                        state_next = FSM_STATE_PRE_INSTR_FETCH_1;
                    end
                end
                8'b11???000:
                begin
                    if (cond) begin
                        state_next   = FSM_STATE_MEM_READ1_1;
                        int_suppress = 1'b1;
                    end
                    else begin
                        state_next = FSM_STATE_INSTR_FETCH1_1;
                    end
                end
                default: begin
                    state_next = FSM_STATE_INSTR_FETCH1_1;
                end
            endcase
        end
        FSM_STATE_INSTR_FETCH2_1: begin
            state_next = FSM_STATE_INSTR_FETCH2_2;
        end
        FSM_STATE_INSTR_FETCH2_2: begin
            state_next = FSM_STATE_INSTR_FETCH2_3;
            int_sample = 1'b1;
        end
        FSM_STATE_INSTR_FETCH2_3: begin
            casez ({ reg_op_prefix, reg_instr })
                { OP_PREFIX_DD, 8'b00100001 },
                { OP_PREFIX_DD, 8'b00100010 },
                { OP_PREFIX_DD, 8'b00101010 },
                { OP_PREFIX_DD, 8'b0011010? },
                { OP_PREFIX_DD, 8'b00110110 },
                { OP_PREFIX_DD, 8'b01110??? },
                { OP_PREFIX_DD, 8'b01???110 },
                { OP_PREFIX_DD, 8'b10???110 },
                { OP_PREFIX_DD, 8'b11001011 },
                { OP_PREFIX_ED, 8'b01??0011 },
                { OP_PREFIX_ED, 8'b01??1011 },
                { OP_PREFIX_FD, 8'b00100001 },
                { OP_PREFIX_FD, 8'b00100010 },
                { OP_PREFIX_FD, 8'b00101010 },
                { OP_PREFIX_FD, 8'b0011010? },
                { OP_PREFIX_FD, 8'b00110110 },
                { OP_PREFIX_FD, 8'b01110??? },
                { OP_PREFIX_FD, 8'b01???110 },
                { OP_PREFIX_FD, 8'b10???110 },
                { OP_PREFIX_FD, 8'b11001011 }:
                begin
                    state_next   = FSM_STATE_OP_FETCH1_1;
                    int_suppress = 1'b1;
                end
                { OP_PREFIX_CB,   8'b?????110 },
                { OP_PREFIX_DD,   8'b11100011 },
                { OP_PREFIX_DD,   8'b11100001 },
                { OP_PREFIX_ED,   8'b101??000 },
                { OP_PREFIX_ED,   8'b101??001 },
                { OP_PREFIX_ED,   8'b0110?111 },
                { OP_PREFIX_ED,   8'b0100?101 },
                { OP_PREFIX_FD,   8'b11100011 },
                { OP_PREFIX_ED,   8'b101??011 },
                { OP_PREFIX_FD,   8'b11100001 }:
                begin
                    state_next   = FSM_STATE_MEM_READ1_1;
                    int_suppress = 1'b1;
                end
                { OP_PREFIX_DD, 8'b11100101 },
                { OP_PREFIX_FD, 8'b11100101 }:
                begin
                    state_next   = FSM_STATE_PRE_MEM_WRITE_1;
                    int_suppress = 1'b1;
                end
                { OP_PREFIX_ED, 8'b01???000 },
                { OP_PREFIX_ED, 8'b101??010 }:
                begin
                    state_next   = FSM_STATE_IO_READ_1;
                    int_suppress = 1'b1;
                end
                { OP_PREFIX_ED, 8'b01???001 }:
                begin
                    state_next   = FSM_STATE_IO_WRITE_1;
                    int_suppress = 1'b1;
                end
                default: begin
                    state_next = FSM_STATE_INSTR_FETCH1_1;
                end
            endcase
        end
        FSM_STATE_INSTR_FETCH3_1: begin
            state_next = FSM_STATE_INSTR_FETCH3_2;
        end
        FSM_STATE_INSTR_FETCH3_2: begin
            state_next = FSM_STATE_INSTR_FETCH3_3;
            int_sample = 1'b1;
        end
        FSM_STATE_INSTR_FETCH3_3: begin
            state_next   = FSM_STATE_PRE_MEM_READ_1;
            int_suppress = 1'b1;
        end
        FSM_STATE_OP_FETCH1_1: begin
            state_next = FSM_STATE_OP_FETCH1_2;
        end
        FSM_STATE_OP_FETCH1_2: begin
            state_next = FSM_STATE_OP_FETCH1_3;

            casez ({ reg_op_prefix, reg_instr })
                { OP_PREFIX_NONE,  8'b00100010 },
                { OP_PREFIX_NONE,  8'b00101010 },
                { OP_PREFIX_NONE,  8'b00110010 },
                { OP_PREFIX_NONE,  8'b00110110 },
                { OP_PREFIX_NONE,  8'b00111010 },
                { OP_PREFIX_NONE,  8'b11000011 },
                { OP_PREFIX_NONE,  8'b11001101 },
                { OP_PREFIX_NONE,  8'b11010011 },
                { OP_PREFIX_NONE,  8'b11011011 },
                { OP_PREFIX_NONE,  8'b11???010 },
                { OP_PREFIX_NONE,  8'b11???100 },
                { OP_PREFIX_CB,    8'b00???110 },
                { OP_PREFIX_DD,    8'b00100010 },
                { OP_PREFIX_DD,    8'b00100001 },
                { OP_PREFIX_DD,    8'b00101010 },
                { OP_PREFIX_DD,    8'b0011010? },
                { OP_PREFIX_DD,    8'b00110110 },
                { OP_PREFIX_DD,    8'b01110??? },
                { OP_PREFIX_DD,    8'b01???110 },
                { OP_PREFIX_DD,    8'b10???110 },
                { OP_PREFIX_ED,    8'b01??0011 },
                { OP_PREFIX_ED,    8'b01??1011 },
                { OP_PREFIX_FD,    8'b00100001 },
                { OP_PREFIX_FD,    8'b00100010 },
                { OP_PREFIX_FD,    8'b00101010 },
                { OP_PREFIX_FD,    8'b0011010? },
                { OP_PREFIX_FD,    8'b00110110 },
                { OP_PREFIX_FD,    8'b01110??? },
                { OP_PREFIX_FD,    8'b01???110 },
                { OP_PREFIX_FD,    8'b10???110 },
                { OP_PREFIX_DD_CB, 8'b?????110 },
                { OP_PREFIX_FD_CB, 8'b?????110 }:
                begin
                    int_sample = 1'b0;
                end
                default: begin
                    int_sample = 1'b1;
                end
            endcase
        end
        FSM_STATE_OP_FETCH1_3: begin
            casez ({ reg_op_prefix, reg_instr })
                { OP_PREFIX_DD_CB, 8'b???????? },
                { OP_PREFIX_FD_CB, 8'b???????? }:
                begin
                    state_next = FSM_STATE_INSTR_FETCH3_1;
                end
                { OP_PREFIX_NONE, 8'b00100010 },
                { OP_PREFIX_NONE, 8'b00101010 },
                { OP_PREFIX_NONE, 8'b00110010 },
                { OP_PREFIX_NONE, 8'b00111010 },
                { OP_PREFIX_NONE, 8'b00??0001 },
                { OP_PREFIX_NONE, 8'b11000011 },
                { OP_PREFIX_NONE, 8'b11001101 },
                { OP_PREFIX_NONE, 8'b11???010 },
                { OP_PREFIX_NONE, 8'b11???100 },
                { OP_PREFIX_DD,   8'b00100001 },
                { OP_PREFIX_DD,   8'b00100010 },
                { OP_PREFIX_DD,   8'b00101010 },
                { OP_PREFIX_DD,   8'b00110110 },
                { OP_PREFIX_ED,   8'b01??0011 },
                { OP_PREFIX_ED,   8'b01??1011 },
                { OP_PREFIX_FD,   8'b00100001 },
                { OP_PREFIX_FD,   8'b00100010 },
                { OP_PREFIX_FD,   8'b00101010 },
                { OP_PREFIX_FD,   8'b00110110 }:
                begin
                    state_next = FSM_STATE_OP_FETCH2_1;
                end
                { OP_PREFIX_DD, 8'b01???110 },
                { OP_PREFIX_DD, 8'b10???110 },
                { OP_PREFIX_DD, 8'b0011010? },
                { OP_PREFIX_FD, 8'b01???110 },
                { OP_PREFIX_FD, 8'b10???110 },
                { OP_PREFIX_FD, 8'b0011010? }:
                begin
                    state_next = FSM_STATE_PRE_MEM_READ_1;
                end
                { OP_PREFIX_DD, 8'b01110??? },
                { OP_PREFIX_FD, 8'b01110??? }:
                begin
                    state_next = FSM_STATE_PRE_MEM_WRITE_1;
                end
                { OP_PREFIX_NONE, 8'b00110110 }:
                begin
                    state_next = FSM_STATE_MEM_WRITE1_1;
                end
                { OP_PREFIX_NONE, 8'b11011011 }:
                begin
                    state_next = FSM_STATE_IO_READ_1;
                end
                { OP_PREFIX_NONE, 8'b11010011 }:
                begin
                    state_next = FSM_STATE_IO_WRITE_1;
                end
                default: begin
                    state_next = FSM_STATE_INSTR_FETCH1_1;
                end
            endcase
        end
        FSM_STATE_OP_FETCH2_1: begin
            state_next = FSM_STATE_OP_FETCH2_2;
        end
        FSM_STATE_OP_FETCH2_2: begin
            state_next = FSM_STATE_OP_FETCH2_3;

            casez ({ reg_op_prefix, reg_instr })
                { OP_PREFIX_NONE, 8'b00100010 },
                { OP_PREFIX_NONE, 8'b00101010 },
                { OP_PREFIX_NONE, 8'b00110010 },
                { OP_PREFIX_NONE, 8'b00111010 },
                { OP_PREFIX_NONE, 8'b11001101 },
                { OP_PREFIX_NONE, 8'b11???100 },
                { OP_PREFIX_DD,   8'b00100010 },
                { OP_PREFIX_DD,   8'b00101010 },
                { OP_PREFIX_DD,   8'b00110110 },
                { OP_PREFIX_ED,   8'b01??0011 },
                { OP_PREFIX_ED,   8'b01??1011 },
                { OP_PREFIX_FD,   8'b00100010 },
                { OP_PREFIX_FD,   8'b00101010 },
                { OP_PREFIX_FD,   8'b00110110 }:
                begin
                    int_sample = 1'b0;
                end
                default: begin
                    int_sample = 1'b1;
                end
            endcase
        end
        FSM_STATE_OP_FETCH2_3: begin
            casez ({ reg_op_prefix, reg_instr })
                { OP_PREFIX_NONE, 8'b00101010 },
                { OP_PREFIX_NONE, 8'b00111010 },
                { OP_PREFIX_DD,   8'b00101010 },
                { OP_PREFIX_ED,   8'b01??1011 },
                { OP_PREFIX_FD,   8'b00101010 }:
                begin
                    state_next = FSM_STATE_MEM_READ1_1;
                end
                { OP_PREFIX_DD, 8'b00110110 },
                { OP_PREFIX_FD, 8'b00110110 }:
                begin
                    state_next = FSM_STATE_PRE_MEM_WRITE_1;
                end
                { OP_PREFIX_NONE, 8'b00100010 },
                { OP_PREFIX_NONE, 8'b00110010 },
                { OP_PREFIX_NONE, 8'b11001101 },
                { OP_PREFIX_NONE, 8'b11???100 },
                { OP_PREFIX_DD,   8'b00100010 },
                { OP_PREFIX_ED,   8'b01??0011 },
                { OP_PREFIX_FD,   8'b00100010 }:
                begin
                    state_next = FSM_STATE_MEM_WRITE1_1;
                end
                default: begin
                    state_next = FSM_STATE_INSTR_FETCH1_1;
                end
            endcase
        end
        FSM_STATE_MEM_READ1_1: begin
            state_next = FSM_STATE_MEM_READ1_2;
        end
        FSM_STATE_MEM_READ1_2: begin
            state_next = FSM_STATE_MEM_READ1_3;

            if (int_active_int && int_mode == INT_MODE_2) begin
                int_sample = 1'b0;
            end
            else begin
                casez ({ reg_op_prefix, reg_instr })
                    { OP_PREFIX_NONE,  8'b11??0001 },
                    { OP_PREFIX_NONE,  8'b00101010 },
                    { OP_PREFIX_NONE,  8'b0011010? },
                    { OP_PREFIX_NONE,  8'b11001001 },
                    { OP_PREFIX_NONE,  8'b11100011 },
                    { OP_PREFIX_NONE,  8'b11???000 },
                    { OP_PREFIX_CB,    8'b00???110 },
                    { OP_PREFIX_CB,    8'b1????110 },
                    { OP_PREFIX_DD,    8'b00101010 },
                    { OP_PREFIX_DD,    8'b11100001 },
                    { OP_PREFIX_DD,    8'b0011010? },
                    { OP_PREFIX_DD,    8'b11100011 },
                    { OP_PREFIX_ED,    8'b0100?101 },
                    { OP_PREFIX_ED,    8'b0110?111 },
                    { OP_PREFIX_ED,    8'b01??1011 },
                    { OP_PREFIX_ED,    8'b101??000 },
                    { OP_PREFIX_ED,    8'b1011?001 },
                    { OP_PREFIX_FD,    8'b00101010 },
                    { OP_PREFIX_FD,    8'b11100001 },
                    { OP_PREFIX_FD,    8'b0011010? },
                    { OP_PREFIX_FD,    8'b11100011 },
                    { OP_PREFIX_DD_CB, 8'b00???110 },
                    { OP_PREFIX_DD_CB, 8'b1????110 },
                    { OP_PREFIX_FD_CB, 8'b00???110 },
                    { OP_PREFIX_FD_CB, 8'b1????110 }:
                    begin
                        int_sample = 1'b0;
                    end
                    default: begin
                        int_sample = 1'b1;
                    end
                endcase
            end
        end
        FSM_STATE_MEM_READ1_3: begin
            if (int_active_int && int_mode == INT_MODE_2) begin
                state_next = FSM_STATE_PRE_MEM_READ_2;
            end
            else begin
                casez ({ reg_op_prefix, reg_instr })
                    { OP_PREFIX_NONE, 8'b00101010 },
                    { OP_PREFIX_NONE, 8'b11??0001 },
                    { OP_PREFIX_DD,   8'b00101010 },
                    { OP_PREFIX_DD,   8'b11100001 },
                    { OP_PREFIX_ED,   8'b01??1011 },
                    { OP_PREFIX_FD,   8'b00101010 },
                    { OP_PREFIX_FD,   8'b11100001 }:
                    begin
                        state_next = FSM_STATE_PRE_MEM_READ_2;
                    end
                    { OP_PREFIX_NONE, 8'b11001001 },
                    { OP_PREFIX_NONE, 8'b11???000 },
                    { OP_PREFIX_ED,   8'b0100?101 }:
                    begin
                        state_next = FSM_STATE_MEM_READ2_1;
                    end
                    { OP_PREFIX_NONE,  8'b0011010? },
                    { OP_PREFIX_CB,    8'b00???110 },
                    { OP_PREFIX_CB,    8'b1????110 },
                    { OP_PREFIX_DD,    8'b0011010? },
                    { OP_PREFIX_ED,    8'b0110?111 },
                    { OP_PREFIX_FD,    8'b0011010? },
                    { OP_PREFIX_DD_CB, 8'b00???110 },
                    { OP_PREFIX_DD_CB, 8'b1????110 },
                    { OP_PREFIX_FD_CB, 8'b00???110 },
                    { OP_PREFIX_FD_CB, 8'b1????110 }:
                    begin
                        state_next = FSM_STATE_PRE_MEM_WRITE_1;
                    end
                    { OP_PREFIX_NONE, 8'b11100011 },
                    { OP_PREFIX_DD,   8'b11100011 },
                    { OP_PREFIX_ED,   8'b101??000 },
                    { OP_PREFIX_FD,   8'b11100011 }:
                    begin
                        state_next = FSM_STATE_MEM_WRITE1_1;
                    end
                    { OP_PREFIX_ED, 8'b101??011 }:
                    begin
                        state_next = FSM_STATE_IO_WRITE_1;
                    end
                    { OP_PREFIX_ED, 8'b1011?001 }:
                    begin
                        state_next = FSM_STATE_BLOCK_TRANSFER;

                        int_sample = 1'b1;
                    end
                    default: begin
                        state_next = FSM_STATE_INSTR_FETCH1_1;
                    end
                endcase
            end
        end
        FSM_STATE_MEM_READ2_1: begin
            state_next = FSM_STATE_MEM_READ2_2;
        end
        FSM_STATE_MEM_READ2_2: begin
            state_next = FSM_STATE_MEM_READ2_3;

            if (int_active_int && int_mode == INT_MODE_2) begin
                int_sample = 1'b1;
            end
            else begin
                case ({ reg_op_prefix, reg_instr })
                    { OP_PREFIX_NONE, 8'b11100011 },
                    { OP_PREFIX_DD,   8'b11100011 },
                    { OP_PREFIX_FD,   8'b11100011 }:
                    begin
                        int_sample = 1'b0;
                    end
                    default: begin
                        int_sample = 1'b1;
                    end
                endcase
            end
        end
        FSM_STATE_MEM_READ2_3: begin
            if (int_active_int && int_mode == INT_MODE_2) begin
                state_next = FSM_STATE_INSTR_FETCH1_1;

                int_done = 1'b1;
            end
            else begin
                case ({ reg_op_prefix, reg_instr })
                    { OP_PREFIX_NONE, 8'b11100011 },
                    { OP_PREFIX_DD,   8'b11100011 },
                    { OP_PREFIX_FD,   8'b11100011 }:
                    begin
                        state_next = FSM_STATE_MEM_WRITE2_1;
                    end
                    default: begin
                        state_next = FSM_STATE_INSTR_FETCH1_1;
                    end
                endcase
            end

            if (int_active_int && int_mode == INT_MODE_2)
                int_done = 1'b1;
        end
        FSM_STATE_MEM_WRITE1_1: begin
            state_next = FSM_STATE_MEM_WRITE1_2;
        end
        FSM_STATE_MEM_WRITE1_2: begin
            state_next = FSM_STATE_MEM_WRITE1_3;

            if (int_active_int || int_active_nmi) begin
                int_sample = 1'b0;
            end
            else begin
                casez ({ reg_op_prefix, reg_instr })
                    { OP_PREFIX_NONE, 8'b00100010 },
                    { OP_PREFIX_NONE, 8'b11??0101 },
                    { OP_PREFIX_NONE, 8'b11100011 },
                    { OP_PREFIX_NONE, 8'b11???100 },
                    { OP_PREFIX_NONE, 8'b11???111 },
                    { OP_PREFIX_DD,   8'b00100010 },
                    { OP_PREFIX_DD,   8'b11100101 },
                    { OP_PREFIX_DD,   8'b11100011 },
                    { OP_PREFIX_ED,   8'b01??0011 },
                    { OP_PREFIX_FD,   8'b00100010 },
                    { OP_PREFIX_FD,   8'b11100101 },
                    { OP_PREFIX_FD,   8'b11100011 }:
                    begin
                        int_sample = 1'b0;
                    end
                    default: begin
                        int_sample = 1'b1;
                    end
                endcase
            end
        end
        FSM_STATE_MEM_WRITE1_3: begin
            if (int_active_nmi || (int_active_int && int_mode != INT_MODE_0)) begin
                state_next = FSM_STATE_PRE_MEM_WRITE_2;
            end
            else begin
                casez ({ reg_op_prefix, reg_instr })
                    { OP_PREFIX_NONE, 8'b11100011 },
                    { OP_PREFIX_DD,   8'b11100011 },
                    { OP_PREFIX_FD,   8'b11100011 }:
                    begin
                        state_next = FSM_STATE_PRE_MEM_READ_2;
                    end
                    { OP_PREFIX_ED, 8'b1011?010 }:
                    begin
                        if (!regfile_flag_z)
                            state_next = FSM_STATE_PRE_MEM_READ_1;
                    end
                    { OP_PREFIX_NONE, 8'b00100010 },
                    { OP_PREFIX_NONE, 8'b11??0101 },
                    { OP_PREFIX_NONE, 8'b11???100 },
                    { OP_PREFIX_NONE, 8'b11001101 },
                    { OP_PREFIX_NONE, 8'b11???111 },
                    { OP_PREFIX_DD,   8'b00100010 },
                    { OP_PREFIX_DD,   8'b11100101 },
                    { OP_PREFIX_ED,   8'b01??0011 },
                    { OP_PREFIX_FD,   8'b00100010 },
                    { OP_PREFIX_FD,   8'b11100101 }:
                    begin
                        state_next = FSM_STATE_PRE_MEM_WRITE_2;
                    end
                    default: begin
                        int_sample = 1'b1;
                        state_next = FSM_STATE_INSTR_FETCH1_1;
                    end
                endcase
            end
        end
        FSM_STATE_MEM_WRITE2_1: begin
            state_next = FSM_STATE_MEM_WRITE2_2;
        end
        FSM_STATE_MEM_WRITE2_2: begin
            state_next = FSM_STATE_MEM_WRITE2_3;

            if ((int_active_int && (int_mode != INT_MODE_2)) || int_active_nmi)
                int_sample = 1'b0;
            else
                int_sample = 1'b1;
        end
        FSM_STATE_MEM_WRITE2_3: begin
            if (int_active_int && int_mode == INT_MODE_2)
                state_next = FSM_STATE_MEM_READ1_1;
            else
                state_next = FSM_STATE_INSTR_FETCH1_1;

            if ((int_active_int && int_mode != INT_MODE_2) || int_active_nmi)
                int_done = 1'b1;
        end
        FSM_STATE_IO_READ_1: begin
            state_next = FSM_STATE_IO_READ_2;
        end
        FSM_STATE_IO_READ_2: begin
            state_next = FSM_STATE_IO_READ_3;

            casez ({ reg_op_prefix, reg_instr })
                { OP_PREFIX_ED, 8'b101??010 }:
                begin
                    int_sample = 1'b0;
                end
                default: begin
                    int_sample = 1'b1;
                end
            endcase
        end
        FSM_STATE_IO_READ_3: begin
            casez ({ reg_op_prefix, reg_instr })
                { OP_PREFIX_ED, 8'b101??010 }:
                begin
                    state_next = FSM_STATE_MEM_WRITE1_1;
                end
                default: begin
                    state_next = FSM_STATE_INSTR_FETCH1_1;
                end
            endcase
        end
        FSM_STATE_IO_WRITE_1: begin
            state_next = FSM_STATE_IO_WRITE_2;
        end
        FSM_STATE_IO_WRITE_2: begin
            state_next = FSM_STATE_IO_WRITE_3;
            int_sample = 1'b1;
        end
        FSM_STATE_IO_WRITE_3: begin
            casez ({ reg_op_prefix, reg_instr })
                { OP_PREFIX_ED, 8'b1010?011 }:
                begin
                    state_next = FSM_STATE_INSTR_FETCH1_1;
                end
                { OP_PREFIX_ED, 8'b1011?011 }:
                begin
                    if (!regfile_flag_z)
                        state_next = FSM_STATE_PRE_INSTR_FETCH_1;
                    else
                        state_next = FSM_STATE_INSTR_FETCH1_1;
                end
            endcase
        end
        FSM_STATE_ACK_INT_1: begin
            state_next = FSM_STATE_ACK_INT_2;
        end
        FSM_STATE_ACK_INT_2: begin
            state_next = FSM_STATE_ACK_INT_3;
        end
        FSM_STATE_ACK_INT_3: begin
            state_next = FSM_STATE_ACK_INT_4;
        end
        FSM_STATE_ACK_INT_4: begin
            case (int_mode)
                INT_MODE_0: begin
                    state_next = FSM_STATE_INSTR_FETCH1_3;
                    int_done = 1'b1;
                end
                INT_MODE_1,
                INT_MODE_2: begin
                    state_next = FSM_STATE_PRE_MEM_WRITE_1;
                end
            endcase
        end
        FSM_STATE_ACK_NMI_1: begin
            state_next = FSM_STATE_ACK_NMI_2;
        end
        FSM_STATE_ACK_NMI_2: begin
            state_next = FSM_STATE_PRE_MEM_WRITE_1;
        end
        FSM_STATE_PRE_INSTR_FETCH_1: begin
            state_next = FSM_STATE_INSTR_FETCH1_1;
        end
        FSM_STATE_PRE_MEM_READ_1: begin
            state_next = FSM_STATE_MEM_READ1_1;
        end
        FSM_STATE_PRE_MEM_READ_2: begin
            state_next = FSM_STATE_MEM_READ2_1;
        end
        FSM_STATE_PRE_MEM_WRITE_1: begin
            state_next = FSM_STATE_MEM_WRITE1_1;
        end
        FSM_STATE_PRE_MEM_WRITE_2: begin
            state_next = FSM_STATE_MEM_WRITE2_1;
        end
        FSM_STATE_BLOCK_TRANSFER: begin
            state_next = FSM_STATE_INSTR_FETCH1_1;
        end
    endcase
end

endmodule