OpenCores
URL https://opencores.org/ocsvn/6809_6309_compatible_core/6809_6309_compatible_core/trunk

Subversion Repositories 6809_6309_compatible_core

[/] [6809_6309_compatible_core/] [trunk/] [rtl/] [verilog/] [MC6809_cpu.v] - Diff between revs 2 and 4

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 2 Rev 4
Line 31... Line 31...
reg [7:0] k_ofslo, k_ofshi, k_eahi, k_ealo;
reg [7:0] k_ofslo, k_ofshi, k_eahi, k_ealo;
reg [5:0] state, // state of the main state machine
reg [5:0] state, // state of the main state machine
          next_state, // next state to exit to from the read from [PC] state machine
          next_state, // next state to exit to from the read from [PC] state machine
                  next_mem_state, // next state to exit to from the read from memory state machine
                  next_mem_state, // next state to exit to from the read from memory state machine
                  next_push_state; // next state to exit to from push multiple state machine
                  next_push_state; // next state to exit to from push multiple state machine
reg k_cpu_oe, k_cpu_we, k_inc_pc, k_pull_reg_write;
reg k_cpu_oe, k_cpu_we, k_inc_pc;
reg [15:0] k_cpu_addr, k_new_pc;
reg [15:0] k_cpu_addr, k_new_pc;
reg k_write_pc, k_inc_su, k_dec_su, k_set_e, k_clear_e;
reg k_write_pc, k_inc_su, k_dec_su, k_set_e, k_clear_e;
reg [1:0] k_mem_dest;
reg [1:0] k_mem_dest;
 
reg k_write_dest; // set for 1 clock when a register has to be written, dec_o_dest_reg_addr has the register source
reg k_write_post_incdec; // asserted when in the last write cycle or in write back for loads
reg k_write_post_incdec; // asserted when in the last write cycle or in write back for loads
 
reg k_forced_mem_size; // used to force the size of a memory read to be 16 bits, used for vector fetch
/****
/****
 * Decoder outputs
 * Decoder outputs
 */
 */
wire [2:0] dec_o_p1_mode; // addressing mode
wire [2:0] dec_o_p1_mode; // addressing mode
wire [2:0] dec_o_p1_optype; // k_opcode type
wire [2:0] dec_o_p1_optype; // k_opcode type
Line 49... Line 51...
wire dec_o_ea_ofs8, dec_o_ea_ofs16, dec_o_ea_wpost, dec_o_ea_ofs0, dec_o_ea_indirect;
wire dec_o_ea_ofs8, dec_o_ea_ofs16, dec_o_ea_wpost, dec_o_ea_ofs0, dec_o_ea_indirect;
/* alu k_opcode decoder */
/* alu k_opcode decoder */
wire [4:0] dec_o_alu_opcode;
wire [4:0] dec_o_alu_opcode;
wire [1:0] dec_o_right_path_mod; /* Modifier for alu's right path input */
wire [1:0] dec_o_right_path_mod; /* Modifier for alu's right path input */
/* register decoder */
/* register decoder */
wire dec_o_wdest_8, dec_o_wdest_16, dec_o_write_flags;
wire dec_o_wdest, dec_o_source_size, dec_o_write_flags;
wire [3:0] dec_o_left_path_addr, dec_o_right_path_addr, dec_o_dest_reg_addr;
wire [3:0] dec_o_left_path_addr, dec_o_right_path_addr, dec_o_dest_reg_addr;
/* test condition */
/* test condition */
wire dec_o_cond_taken;
wire dec_o_cond_taken;
/* ALU outputs */
/* ALU outputs */
wire [15:0] alu_o_result;
wire [15:0] alu_o_result;
Line 67... Line 69...
reg [3:0] datamux_o_dest_reg_addr, datamux_o_alu_in_left_path_addr;
reg [3:0] datamux_o_dest_reg_addr, datamux_o_alu_in_left_path_addr;
reg [15:0] datamux_o_alu_in_left_path_data, datamux_o_alu_in_right_path_data, datamux_o_dest;
reg [15:0] datamux_o_alu_in_left_path_data, datamux_o_alu_in_right_path_data, datamux_o_dest;
 
 
reg k_p2_valid, k_p3_valid; /* 1 when k_postbyte0 has been loaded for page 2 or page 3 */
reg k_p2_valid, k_p3_valid; /* 1 when k_postbyte0 has been loaded for page 2 or page 3 */
 
 
/* Interrupt sync registers */
/*
 
 * Interrupt sync registers
 
 */
 
 
reg [2:0] k_reg_nmi, k_reg_irq, k_reg_firq;
reg [2:0] k_reg_nmi, k_reg_irq, k_reg_firq;
wire k_nmi_req, k_firq_req, k_irq_req;
wire k_nmi_req, k_firq_req, k_irq_req;
 
 
assign k_nmi_req = k_reg_nmi[2] & k_reg_nmi[1];
assign k_nmi_req = k_reg_nmi[2] & k_reg_nmi[1];
Line 94... Line 98...
        .path_left_addr(datamux_o_alu_in_left_path_addr),
        .path_left_addr(datamux_o_alu_in_left_path_addr),
        .path_right_addr(dec_o_right_path_addr),
        .path_right_addr(dec_o_right_path_addr),
        .write_reg_addr(datamux_o_dest_reg_addr),
        .write_reg_addr(datamux_o_dest_reg_addr),
        .eapostbyte( k_ind_ea ),
        .eapostbyte( k_ind_ea ),
        .offset16({ k_ofshi, k_ofslo }),
        .offset16({ k_ofshi, k_ofslo }),
        .write_reg_8(dec_o_wdest_8 & (state == `SEQ_GRAL_WBACK)),
        .write_reg(k_write_dest),
        .write_reg_16(dec_o_wdest_16 & (state == `SEQ_GRAL_WBACK)),
        //.write_reg_16(dec_o_wdest_16 & (state == `SEQ_GRAL_WBACK)),
        .write_pull_reg(k_pull_reg_write),
        //.write_pull_reg(k_pull_reg_write),
        .write_post(k_write_post_incdec),
        .write_post(k_write_post_incdec),
        .write_pc(k_write_pc),
        .write_pc(k_write_pc),
        .inc_pc(k_inc_pc),
        .inc_pc(k_inc_pc),
        .inc_su(k_inc_su),
        .inc_su(k_inc_su),
        .dec_su(k_dec_su),
        .dec_su(k_dec_su),
Line 126... Line 130...
        .page2_valid(k_p2_valid),
        .page2_valid(k_p2_valid),
        .page3_valid(k_p3_valid),
        .page3_valid(k_p3_valid),
        .path_left_addr(dec_o_left_path_addr),
        .path_left_addr(dec_o_left_path_addr),
        .path_right_addr(dec_o_right_path_addr),
        .path_right_addr(dec_o_right_path_addr),
        .dest_reg(dec_o_dest_reg_addr),
        .dest_reg(dec_o_dest_reg_addr),
        .write_dest_8(dec_o_wdest_8),
        .write_dest(dec_o_wdest),
        .write_dest_16(dec_o_wdest_16),
        .source_size(dec_o_source_size),
        .result_size(dec_o_alu_size)
        .result_size(dec_o_alu_size)
        );
        );
 
 
decode_op dec_op(
decode_op dec_op(
        .opcode(k_opcode),
        .opcode(k_opcode),
Line 226... Line 230...
                datamux_o_dest = alu_o_result;
                datamux_o_dest = alu_o_result;
                case (dec_o_p1_optype)
                case (dec_o_p1_optype)
                        `OP_PULL, `OP_RTS: // destination register
                        `OP_PULL, `OP_RTS: // destination register
                                datamux_o_dest = { k_memhi, k_memlo };
                                datamux_o_dest = { k_memhi, k_memlo };
                        `OP_LEA:
                        `OP_LEA:
                                if (dec_o_ea_indirect & dec_o_alu_size)
                                if (dec_o_ea_indirect)// & dec_o_alu_size)
                                        datamux_o_dest = { k_memhi, k_memlo };
                                        datamux_o_dest = { k_memhi, k_memlo };
                                else
                                else
                                        datamux_o_dest = regs_o_eamem_addr;
                                        datamux_o_dest = regs_o_eamem_addr;
                endcase
                endcase
        end
        end
Line 240... Line 244...
always @(*)
always @(*)
        begin
        begin
                if (dec_o_left_path_addr == `RN_MEM8)
                if (dec_o_left_path_addr == `RN_MEM8)
                        datamux_o_alu_in_left_path_data = { k_memhi, k_memlo };
                        datamux_o_alu_in_left_path_data = { k_memhi, k_memlo };
                else
                else
                        begin
                case (dec_o_p1_optype)
 
                        `OP_LEA:
 
                                if (dec_o_ea_indirect)// & dec_o_alu_size)
 
                                        datamux_o_alu_in_left_path_data = { k_memhi, k_memlo };
 
                                else
 
                                        datamux_o_alu_in_left_path_data = regs_o_eamem_addr;
 
                        default:
                                datamux_o_alu_in_left_path_data = regs_o_left_path_data;
                                datamux_o_alu_in_left_path_data = regs_o_left_path_data;
 
                endcase
                        end
                        end
        end
/* PC as destination from jmp/bsr mux */
 
always @(*)
 
        begin
 
                k_new_pc = { k_memhi,k_memlo }; // used to fetch reset vector
 
                case (dec_o_p1_mode)
 
                        `REL16: k_new_pc = regs_o_pc + { k_memhi,k_memlo };
 
                        `REL8: k_new_pc = regs_o_pc + { {8{k_memlo[7]}}, k_memlo };
 
                        `EXTENDED: k_new_pc = { k_eahi,k_ealo };
 
                        `DIRECT: k_new_pc = { regs_o_dp, k_ealo };
 
                        `INDEXED:
 
                                if (dec_o_ea_indirect)
 
                                        k_new_pc = { k_memhi,k_memlo };
 
                                else
 
                                        k_new_pc = regs_o_eamem_addr;
 
 
 
                endcase
 
        end
/* ALU right input mux */
/* ALU right input mux */
always @(*)
always @(*)
        begin
        begin
                case (dec_o_right_path_addr)
                case (dec_o_right_path_addr)
                        `RN_MEM8:
                        `RN_MEM8:
Line 300... Line 326...
                                        k_write_post_incdec <= 0;
                                        k_write_post_incdec <= 0;
                                if (k_dec_su)
                                if (k_dec_su)
                                        k_dec_su <= 0;
                                        k_dec_su <= 0;
                                if (k_inc_su)
                                if (k_inc_su)
                                        k_inc_su <= 0;
                                        k_inc_su <= 0;
                                if (k_pull_reg_write)
                                //if (k_pull_reg_write)
                                        k_pull_reg_write <= 0;
                                //      k_pull_reg_write <= 0;
                                if (k_set_e)
                                if (k_set_e)
                                        k_set_e <= 0;
                                        k_set_e <= 0;
                                if (k_clear_e)
                                if (k_clear_e)
                                        k_clear_e <= 0;
                                        k_clear_e <= 0;
 
                                if (k_write_dest)
 
                                        k_write_dest <= 0;
                        case (state)
                        case (state)
                                `SEQ_COLDRESET:
                                `SEQ_COLDRESET:
                                        begin
                                        begin
 
                                                k_forced_mem_size <= 1;
                                                state <= `SEQ_MEM_READ_H;
                                                state <= `SEQ_MEM_READ_H;
                                                k_eahi <= 8'hff;
                                                k_eahi <= 8'hff;
                                                k_ealo <= 8'hfe;
                                                k_ealo <= 8'hfe;
                                                next_mem_state <= `SEQ_LOADPC;
                                                next_mem_state <= `SEQ_LOADPC;
                                        end
                                        end
                                `SEQ_NMI:
                                `SEQ_NMI:
                                        begin
                                        begin
 
                                                k_forced_mem_size <= 1;
                                                k_reg_nmi <= 2'h0;
                                                k_reg_nmi <= 2'h0;
                                                { k_eahi, k_ealo } <= 16'hfffc;
                                                { k_eahi, k_ealo } <= 16'hfffc;
                                                k_pp_regs <= 8'hff;
                                                k_pp_regs <= 8'hff;
                                                k_set_e <= 1;
                                                k_set_e <= 1;
                                                state <= `SEQ_PREPUSH; // first stack the registers
                                                state <= `SEQ_PREPUSH; // first stack the registers
                                                next_push_state <= `SEQ_MEM_READ_H; // than load new PC
                                                next_push_state <= `SEQ_MEM_READ_H; // than load new PC
                                                next_mem_state <= `SEQ_FETCH; // than continue fetching instructions
                                                next_mem_state <= `SEQ_FETCH; // than continue fetching instructions
                                        end
                                        end
                                `SEQ_SWI:
                                `SEQ_SWI:
                                        begin
                                        begin
 
                                                k_forced_mem_size <= 1;
                                                state <= `SEQ_MEM_READ_H;
                                                state <= `SEQ_MEM_READ_H;
                                                { k_eahi, k_ealo } <= 16'hfffa;
                                                { k_eahi, k_ealo } <= 16'hfffa;
                                                k_pp_regs <= 8'hff;
                                                k_pp_regs <= 8'hff;
                                                state <= `SEQ_PREPUSH; // first stack the registers
                                                state <= `SEQ_PREPUSH; // first stack the registers
                                                next_push_state <= `SEQ_MEM_READ_H; // than load new PC
                                                next_push_state <= `SEQ_MEM_READ_H; // than load new PC
                                                next_mem_state <= `SEQ_FETCH; // than continue fetching instructions
                                                next_mem_state <= `SEQ_FETCH; // than continue fetching instructions
                                                k_set_e <= 1;
                                                k_set_e <= 1;
                                        end
                                        end
                                `SEQ_IRQ:
                                `SEQ_IRQ:
                                        begin
                                        begin
 
                                                k_forced_mem_size <= 1;
                                                k_reg_irq <= 2'h0;
                                                k_reg_irq <= 2'h0;
                                                state <= `SEQ_MEM_READ_H;
                                                state <= `SEQ_MEM_READ_H;
                                                { k_eahi, k_ealo } <= 16'hfff8;
                                                { k_eahi, k_ealo } <= 16'hfff8;
                                                k_pp_regs <= 8'hff;
                                                k_pp_regs <= 8'hff;
                                                next_mem_state <= `SEQ_PREPUSH;
                                                next_mem_state <= `SEQ_PREPUSH;
Line 348... Line 380...
                                                next_push_state <= `SEQ_MEM_READ_H; // than load new PC
                                                next_push_state <= `SEQ_MEM_READ_H; // than load new PC
                                                next_mem_state <= `SEQ_FETCH; // than continue fetching instructions
                                                next_mem_state <= `SEQ_FETCH; // than continue fetching instructions
                                        end
                                        end
                                `SEQ_FIRQ:
                                `SEQ_FIRQ:
                                        begin
                                        begin
 
                                                k_forced_mem_size <= 1;
                                                k_reg_firq <= 2'h0;
                                                k_reg_firq <= 2'h0;
                                                { k_eahi, k_ealo } <= 16'hfff6;
                                                { k_eahi, k_ealo } <= 16'hfff6;
                                                k_pp_regs <= 8'h81; // PC & CC
                                                k_pp_regs <= 8'h81; // PC & CC
                                                k_clear_e <= 1;
                                                k_clear_e <= 1;
                                                state <= `SEQ_PREPUSH; // first stack the registers
                                                state <= `SEQ_PREPUSH; // first stack the registers
                                                next_push_state <= `SEQ_MEM_READ_H; // than load new PC
                                                next_push_state <= `SEQ_MEM_READ_H; // than load new PC
                                                next_mem_state <= `SEQ_FETCH; // than continue fetching instructions
                                                next_mem_state <= `SEQ_FETCH; // than continue fetching instructions
                                        end
                                        end
                                `SEQ_SWI2:
                                `SEQ_SWI2:
                                        begin
                                        begin
 
                                                k_forced_mem_size <= 1;
                                                { k_eahi, k_ealo } <= 16'hfff4;
                                                { k_eahi, k_ealo } <= 16'hfff4;
                                                k_pp_regs <= 8'hff;
                                                k_pp_regs <= 8'hff;
                                                k_set_e <= 1;
                                                k_set_e <= 1;
                                                state <= `SEQ_PREPUSH; // first stack the registers
                                                state <= `SEQ_PREPUSH; // first stack the registers
                                                next_push_state <= `SEQ_MEM_READ_H; // than load new PC
                                                next_push_state <= `SEQ_MEM_READ_H; // than load new PC
                                                next_mem_state <= `SEQ_FETCH; // than continue fetching instructions
                                                next_mem_state <= `SEQ_FETCH; // than continue fetching instructions
                                        end
                                        end
                                `SEQ_SWI3:
                                `SEQ_SWI3:
                                        begin
                                        begin
 
                                                k_forced_mem_size <= 1;
                                                { k_eahi, k_ealo } <= 16'hfff2;
                                                { k_eahi, k_ealo } <= 16'hfff2;
                                                k_pp_regs <= 8'hff;
                                                k_pp_regs <= 8'hff;
                                                k_set_e <= 1;
                                                k_set_e <= 1;
                                                state <= `SEQ_PREPUSH; // first stack the registers
                                                state <= `SEQ_PREPUSH; // first stack the registers
                                                next_push_state <= `SEQ_MEM_READ_H; // than load new PC
                                                next_push_state <= `SEQ_MEM_READ_H; // than load new PC
                                                next_mem_state <= `SEQ_FETCH; // than continue fetching instructions
                                                next_mem_state <= `SEQ_FETCH; // than continue fetching instructions
                                        end
                                        end
                                `SEQ_UNDEF:
                                `SEQ_UNDEF:
                                        begin
                                        begin
 
                                                k_forced_mem_size <= 1;
                                                { k_eahi, k_ealo } <= 16'hfff0;
                                                { k_eahi, k_ealo } <= 16'hfff0;
                                                k_pp_regs <= 8'hff;
                                                k_pp_regs <= 8'hff;
                                                k_set_e <= 1;
                                                k_set_e <= 1;
                                                state <= `SEQ_PREPUSH; // first stack the registers
                                                state <= `SEQ_PREPUSH; // first stack the registers
                                                next_push_state <= `SEQ_MEM_READ_H; // than load new PC
                                                next_push_state <= `SEQ_MEM_READ_H; // than load new PC
Line 408... Line 444...
                                        end
                                        end
                                `SEQ_FETCH_1:
                                `SEQ_FETCH_1:
                                        begin
                                        begin
                                                k_cpu_oe <= 1;
                                                k_cpu_oe <= 1;
                                                state <= `SEQ_FETCH_2;
                                                state <= `SEQ_FETCH_2;
 
                                                k_inc_pc <= 1;
                                        end
                                        end
                                `SEQ_FETCH_2:
                                `SEQ_FETCH_2:
                                        begin
                                        begin
                                                k_opcode <= cpu_data_i;
                                                k_opcode <= cpu_data_i;
                                                case (cpu_data_i[7:0]) /* page 2 & 3 opcodes are recognized here */
                                                case (cpu_data_i[7:0]) /* page 2 & 3 opcodes are recognized here */
Line 433... Line 470...
                                                                k_p2_valid <= 0; // set when an k_opcode is page 2
                                                                k_p2_valid <= 0; // set when an k_opcode is page 2
                                                                k_p3_valid <= 0; // set when an k_opcode is page 3
                                                                k_p3_valid <= 0; // set when an k_opcode is page 3
                                                        end
                                                        end
                                                endcase
                                                endcase
                                                k_pp_active_reg <= 8'h00; // prevents wrong register in left/dest data muxes
                                                k_pp_active_reg <= 8'h00; // prevents wrong register in left/dest data muxes
                                                k_inc_pc <= 1;
 
                                        end
                                        end
                                `SEQ_FETCH_3:
                                `SEQ_FETCH_3:
                                        begin
                                        begin
                                                state <= `SEQ_FETCH_4;
                                                state <= `SEQ_FETCH_4;
                                                k_cpu_addr <= regs_o_pc;
                                                k_cpu_addr <= regs_o_pc;
Line 458... Line 494...
                                                /* here we have the first byte of the k_opcode and should be decided to which state we jump
                                                /* here we have the first byte of the k_opcode and should be decided to which state we jump
                                                 * inherent means that no extra info is needed
                                                 * inherent means that no extra info is needed
                                                 * ALU opcodes need routing of registers to/from the ALU to the registers
                                                 * ALU opcodes need routing of registers to/from the ALU to the registers
                                                 */
                                                 */
                                                case (dec_o_p1_mode)
                                                case (dec_o_p1_mode)
                                                        `NONE: // unknown k_opcode and push/pull... refetch ?
                                                        `NONE: // unknown k_opcode or push/pull... refetch ?
                                                                begin
                                                                begin
                                                                        casex (k_opcode)
                                                                        casex (k_opcode)
                                                                                8'h39: // RTS
                                                                                8'h39: // RTS
                                                                                        begin
                                                                                        begin
                                                                                                state <= `SEQ_PREPULL;
                                                                                                state <= `SEQ_PREPULL;
Line 508... Line 544...
                                                                        state <= `SEQ_PC_READ_L;
                                                                        state <= `SEQ_PC_READ_L;
                                                                        k_mem_dest <= `MEMDEST_MH; // operand to memlo/memhi
                                                                        k_mem_dest <= `MEMDEST_MH; // operand to memlo/memhi
                                                                        if ((dec_o_right_path_addr == `RN_MEM8) || (dec_o_right_path_addr == `RN_MEM16) ||
                                                                        if ((dec_o_right_path_addr == `RN_MEM8) || (dec_o_right_path_addr == `RN_MEM16) ||
                                                                                (dec_o_left_path_addr == `RN_MEM8))
                                                                                (dec_o_left_path_addr == `RN_MEM8))
                                                                                begin
                                                                                begin
                                                                                        if (dec_o_alu_size)
 
                                                                                                next_state <= `SEQ_MEM_READ_H;
                                                                                                next_state <= `SEQ_MEM_READ_H;
                                                                                        else
 
                                                                                                next_state <= `SEQ_MEM_READ_L;
 
                                                                                        next_mem_state <= `SEQ_GRAL_ALU; // read then alu
                                                                                        next_mem_state <= `SEQ_GRAL_ALU; // read then alu
                                                                                end
                                                                                end
                                                                        else
                                                                        else
                                                                                next_state <= `SEQ_GRAL_ALU; // no read
                                                                                next_state <= `SEQ_GRAL_ALU; // no read
                                                                        k_eahi <= regs_o_dp;
                                                                        k_eahi <= regs_o_dp;
Line 527... Line 560...
                                                                        state <= `SEQ_PC_READ_H; // loads address
                                                                        state <= `SEQ_PC_READ_H; // loads address
                                                                        k_mem_dest <= `MEMDEST_MH; // operand to memlo/memhi
                                                                        k_mem_dest <= `MEMDEST_MH; // operand to memlo/memhi
                                                                        if ((dec_o_right_path_addr == `RN_MEM8) || (dec_o_right_path_addr == `RN_MEM16) ||
                                                                        if ((dec_o_right_path_addr == `RN_MEM8) || (dec_o_right_path_addr == `RN_MEM16) ||
                                                                                (dec_o_left_path_addr == `RN_MEM8))
                                                                                (dec_o_left_path_addr == `RN_MEM8))
                                                                                begin
                                                                                begin
                                                                                        if (dec_o_alu_size)
 
                                                                                                next_state <= `SEQ_MEM_READ_H;
                                                                                                next_state <= `SEQ_MEM_READ_H;
                                                                                        else
 
                                                                                                next_state <= `SEQ_MEM_READ_L;
 
                                                                                        next_mem_state <= `SEQ_GRAL_ALU; // read then alu
                                                                                        next_mem_state <= `SEQ_GRAL_ALU; // read then alu
                                                                                end
                                                                                end
                                                                        else
                                                                        else
                                                                                next_state <= `SEQ_GRAL_ALU; // no read
                                                                                next_state <= `SEQ_GRAL_ALU; // no read
                                                                end
                                                                end
Line 581... Line 611...
                                                                        state <= `SEQ_PC_READ_L;
                                                                        state <= `SEQ_PC_READ_L;
                                                                        k_mem_dest <= `MEMDEST_MH; // operand to memlo/memhi
                                                                        k_mem_dest <= `MEMDEST_MH; // operand to memlo/memhi
                                                                        if ((dec_o_right_path_addr == `RN_MEM8) || (dec_o_right_path_addr == `RN_MEM16) ||
                                                                        if ((dec_o_right_path_addr == `RN_MEM8) || (dec_o_right_path_addr == `RN_MEM16) ||
                                                                                (dec_o_left_path_addr == `RN_MEM8))
                                                                                (dec_o_left_path_addr == `RN_MEM8))
                                                                                begin
                                                                                begin
                                                                                        if (dec_o_alu_size)
 
                                                                                                next_state <= `SEQ_MEM_READ_H;
                                                                                                next_state <= `SEQ_MEM_READ_H;
                                                                                        else
 
                                                                                                next_state <= `SEQ_MEM_READ_L;
 
                                                                                        next_mem_state <= `SEQ_GRAL_ALU; // read then alu
                                                                                        next_mem_state <= `SEQ_GRAL_ALU; // read then alu
                                                                                end
                                                                                end
                                                                        else
                                                                        else
                                                                                next_state <= `SEQ_GRAL_ALU; // no read
                                                                                next_state <= `SEQ_GRAL_ALU; // no read
                                                                        k_eahi <= regs_o_dp;
                                                                        k_eahi <= regs_o_dp;
Line 600... Line 627...
                                                                        state <= `SEQ_PC_READ_H; // loads address
                                                                        state <= `SEQ_PC_READ_H; // loads address
                                                                        k_mem_dest <= `MEMDEST_MH; // operand to memlo/memhi
                                                                        k_mem_dest <= `MEMDEST_MH; // operand to memlo/memhi
                                                                        if ((dec_o_right_path_addr == `RN_MEM8) || (dec_o_right_path_addr == `RN_MEM16) ||
                                                                        if ((dec_o_right_path_addr == `RN_MEM8) || (dec_o_right_path_addr == `RN_MEM16) ||
                                                                                (dec_o_left_path_addr == `RN_MEM8))
                                                                                (dec_o_left_path_addr == `RN_MEM8))
                                                                                begin
                                                                                begin
                                                                                        if (dec_o_alu_size)
 
                                                                                                next_state <= `SEQ_MEM_READ_H;
                                                                                                next_state <= `SEQ_MEM_READ_H;
                                                                                        else
 
                                                                                                next_state <= `SEQ_MEM_READ_L;
 
                                                                                        next_mem_state <= `SEQ_GRAL_ALU; // read then alu
                                                                                        next_mem_state <= `SEQ_GRAL_ALU; // read then alu
                                                                                end
                                                                                end
                                                                        else
                                                                        else
                                                                                next_state <= `SEQ_GRAL_ALU; // no read
                                                                                next_state <= `SEQ_GRAL_ALU; // no read
                                                                end
                                                                end
Line 617... Line 641...
                                                                        next_state <= `SEQ_JMP_LOAD_PC;
                                                                        next_state <= `SEQ_JMP_LOAD_PC;
                                                                end
                                                                end
                                                endcase
                                                endcase
                                        end
                                        end
                                `SEQ_GRAL_ALU:
                                `SEQ_GRAL_ALU:
 
                                        begin
                                        state <= `SEQ_GRAL_WBACK;
                                        state <= `SEQ_GRAL_WBACK;
 
                                                k_write_dest <= 1; /* write destination on wback */
 
                                        end
                                `SEQ_GRAL_WBACK:
                                `SEQ_GRAL_WBACK:
                                        begin
                                        begin
                                                next_mem_state <= `SEQ_FETCH;
                                                next_mem_state <= `SEQ_FETCH;
                                                case (dec_o_dest_reg_addr)
                                                case (dec_o_dest_reg_addr)
                                                        `RN_MEM8: state <= `SEQ_MEM_WRITE_L;
                                                        `RN_MEM8: state <= `SEQ_MEM_WRITE_L;
Line 670... Line 697...
                                                                                if ((dec_o_right_path_addr == `RN_MEM8) || (dec_o_right_path_addr == `RN_MEM16) ||
                                                                                if ((dec_o_right_path_addr == `RN_MEM8) || (dec_o_right_path_addr == `RN_MEM16) ||
                                                                                        (dec_o_left_path_addr == `RN_MEM8))
                                                                                        (dec_o_left_path_addr == `RN_MEM8))
                                                                                        begin
                                                                                        begin
                                                                                                k_mem_dest <= `MEMDEST_MH; // operand land in k_memhi/lo
                                                                                                k_mem_dest <= `MEMDEST_MH; // operand land in k_memhi/lo
                                                                                                next_mem_state <= `SEQ_GRAL_ALU;
                                                                                                next_mem_state <= `SEQ_GRAL_ALU;
                                                                                                if (dec_o_alu_size)
 
                                                                                                        state <= `SEQ_MEM_READ_H;
                                                                                                        state <= `SEQ_MEM_READ_H;
                                                                                                else
 
                                                                                                        state <= `SEQ_MEM_READ_L;
 
                                                                                        end
                                                                                        end
                                                                                else
                                                                                else
                                                                                        state <= `SEQ_GRAL_ALU; // no load, then store
                                                                                        state <= `SEQ_GRAL_ALU; // no load, then store
                                                                        end
                                                                        end
                                        end
                                        end
Line 686... Line 710...
                                                if ((dec_o_right_path_addr == `RN_MEM8) || (dec_o_right_path_addr == `RN_MEM16) ||
                                                if ((dec_o_right_path_addr == `RN_MEM8) || (dec_o_right_path_addr == `RN_MEM16) ||
                                                        (dec_o_left_path_addr == `RN_MEM8))
                                                        (dec_o_left_path_addr == `RN_MEM8))
                                                        begin
                                                        begin
                                                                k_mem_dest <= `MEMDEST_MH; // operand land in k_memhi/lo
                                                                k_mem_dest <= `MEMDEST_MH; // operand land in k_memhi/lo
                                                                next_mem_state <= `SEQ_GRAL_ALU;
                                                                next_mem_state <= `SEQ_GRAL_ALU;
                                                                if (dec_o_alu_size)
 
                                                                        state <= `SEQ_MEM_READ_H;
                                                                        state <= `SEQ_MEM_READ_H;
                                                                else
 
                                                                        state <= `SEQ_MEM_READ_L;
 
                                                        end
                                                        end
                                                else
                                                else
                                                        state <= `SEQ_GRAL_ALU; // no load, then store
                                                        state <= `SEQ_GRAL_ALU; // no load, then store
                                        end
                                        end
                                `SEQ_JMP_LOAD_PC:
                                `SEQ_JMP_LOAD_PC:
                                        begin
                                        begin
                                                case (dec_o_p1_mode)
 
                                                        `REL16:
 
                                                                begin
 
                                                                        k_new_pc <= regs_o_pc + { k_memhi,k_memlo };
 
                                                                        if (dec_o_cond_taken)
 
                                                                                k_write_pc <= 1;
 
                                                                end
 
                                                        `REL8:
 
                                                                begin
 
                                                                        k_new_pc <= regs_o_pc + { {8{k_memlo[7]}}, k_memlo };
 
                                                                        if (dec_o_cond_taken)
 
                                                                                k_write_pc <= 1;
 
                                                                end
 
                                                        `EXTENDED:
 
                                                                begin
 
                                                                        k_new_pc <= { k_eahi,k_ealo };
 
                                                                        k_write_pc <= 1;
 
                                                                end
 
                                                        `DIRECT:
 
                                                                begin
 
                                                                        k_new_pc <= { regs_o_dp, k_ealo };
 
                                                                        k_write_pc <= 1;
 
                                                                end
 
                                                        `INDEXED:
 
                                                                begin
 
                                                                        if (dec_o_ea_indirect)
 
                                                                                k_new_pc <= { k_memhi,k_memlo };
 
                                                                        else
 
                                                                                k_new_pc <= regs_o_eamem_addr;
 
                                                                        k_write_pc <= 1;
 
                                                                end
 
                                                endcase
 
                                                state <= `SEQ_FETCH;
                                                state <= `SEQ_FETCH;
 
 
                                        end
                                        end
                                `SEQ_JSR_PUSH:
                                `SEQ_JSR_PUSH:
                                        begin
                                        begin
                                                k_pp_active_reg <= 8'h80; // push PC
                                                k_pp_active_reg <= 8'h80; // push PC
                                                state <= `SEQ_PUSH_WRITE_L;
                                                state <= `SEQ_PUSH_WRITE_L;
Line 741... Line 729...
                                        end
                                        end
                                `SEQ_PREPUSH:
                                `SEQ_PREPUSH:
                                        begin
                                        begin
                                                next_state <= `SEQ_PREPUSH;
                                                next_state <= `SEQ_PREPUSH;
                                                if (k_pp_regs > 0)
                                                if (k_pp_regs > 0)
 
                                                        begin
                                                        state <= `SEQ_PUSH_WRITE_L;
                                                        state <= `SEQ_PUSH_WRITE_L;
 
                                                                //k_dec_su <= 1;
 
                                                        end
                                                else
                                                else
                                                        state <= next_push_state;
                                                        state <= next_push_state;
                                                if (k_pp_regs[7]) begin k_pp_regs[7] <= 0; k_pp_active_reg <= 8'h80; end
                                                if (k_pp_regs[7]) begin k_pp_regs[7] <= 0; k_pp_active_reg <= 8'h80; end
                                                else
                                                else
                                                if (k_pp_regs[6]) begin k_pp_regs[6] <= 0; k_pp_active_reg <= 8'h40; end
                                                if (k_pp_regs[6]) begin k_pp_regs[6] <= 0; k_pp_active_reg <= 8'h40; end
Line 762... Line 753...
                                                else
                                                else
                                                if (k_pp_regs[0]) begin k_pp_regs[0] <= 0; k_pp_active_reg <= 8'h01; end
                                                if (k_pp_regs[0]) begin k_pp_regs[0] <= 0; k_pp_active_reg <= 8'h01; end
                                        end
                                        end
                                `SEQ_PREPULL:
                                `SEQ_PREPULL:
                                        begin
                                        begin
                                                k_inc_su <= 1;
                                                if (k_pp_regs != 8'h0)
 
                                                        begin
                                                k_mem_dest <= `MEMDEST_MH;
                                                k_mem_dest <= `MEMDEST_MH;
                                                next_mem_state <= `SEQ_PREPULL;
                                                next_mem_state <= `SEQ_PREPULL;
 
                                                        end
 
                                                else
 
                                                        state <= `SEQ_FETCH; // end of sequence
                                                if (k_pp_regs[0]) begin k_pp_active_reg <= 8'h01; k_pp_regs[0] <= 0; state <= `SEQ_MEM_READ_L; end
                                                if (k_pp_regs[0]) begin k_pp_active_reg <= 8'h01; k_pp_regs[0] <= 0; state <= `SEQ_MEM_READ_L; end
                                                else
                                                else
                                                if (k_pp_regs[1]) begin k_pp_active_reg <= 8'h02; k_pp_regs[1] <= 0; state <= `SEQ_MEM_READ_L; end
                                                if (k_pp_regs[1]) begin k_pp_active_reg <= 8'h02; k_pp_regs[1] <= 0; state <= `SEQ_MEM_READ_L; end
                                                else
                                                else
                                                if (k_pp_regs[2]) begin k_pp_active_reg <= 8'h04; k_pp_regs[2] <= 0; state <= `SEQ_MEM_READ_L; end
                                                if (k_pp_regs[2]) begin k_pp_active_reg <= 8'h04; k_pp_regs[2] <= 0; state <= `SEQ_MEM_READ_L; end
Line 779... Line 774...
                                                else
                                                else
                                                if (k_pp_regs[5]) begin k_pp_active_reg <= 8'h20; k_pp_regs[5] <= 0; state <= `SEQ_MEM_READ_H;end
                                                if (k_pp_regs[5]) begin k_pp_active_reg <= 8'h20; k_pp_regs[5] <= 0; state <= `SEQ_MEM_READ_H;end
                                                else
                                                else
                                                if (k_pp_regs[6]) begin k_pp_active_reg <= 8'h40; k_pp_regs[6] <= 0; state <= `SEQ_MEM_READ_H; end
                                                if (k_pp_regs[6]) begin k_pp_active_reg <= 8'h40; k_pp_regs[6] <= 0; state <= `SEQ_MEM_READ_H; end
                                                else
                                                else
                                                        begin
 
                                                                next_mem_state <= `SEQ_FETCH; // end of sequence
 
                                                                if (k_pp_regs[7]) begin k_pp_active_reg <= 8'h80;  k_pp_regs[7] <= 0; state <= `SEQ_MEM_READ_H; end
                                                                if (k_pp_regs[7]) begin k_pp_active_reg <= 8'h80;  k_pp_regs[7] <= 0; state <= `SEQ_MEM_READ_H; end
                                                        end
                                                        end
                                        end
 
                                `SEQ_PUSH_WRITE_L: // first low byte push 
                                `SEQ_PUSH_WRITE_L: // first low byte push 
                                        begin
                                        begin
                                                k_cpu_data_o <= regs_o_left_path_data[7:0];
                                                k_cpu_data_o <= regs_o_left_path_data[7:0];
                                                state <= `SEQ_PUSH_WRITE_L_1;
                                                state <= `SEQ_PUSH_WRITE_L_1;
                                                k_cpu_we <= 1; // write
                                                k_cpu_we <= 1; // write
                                                k_cpu_addr <= regs_o_su;
                                                k_cpu_addr <= regs_o_su - 16'h1;
                                                k_dec_su <= 1; // decrement stack pointer
                                                k_dec_su <= 1;
                                        end
                                        end
                                `SEQ_PUSH_WRITE_L_1:
                                `SEQ_PUSH_WRITE_L_1:
                                        begin
                                        begin
                                                if (k_pp_active_reg[7:4] > 0)
                                                if (k_pp_active_reg[7:4] > 0)
                                                        state <= `SEQ_PUSH_WRITE_H;
                                                        state <= `SEQ_PUSH_WRITE_H;
                                                else
                                                else
                                                        if (k_pp_regs[3:0] > 0)
                                                        if (k_pp_regs[3:0] > 0)
                                                                state <= `SEQ_PREPUSH;
                                                                state <= `SEQ_PREPUSH;
                                                        else
                                                        else
                                                                state <= next_push_state;
                                                                state <= next_push_state;
 
                                                k_cpu_addr <= k_cpu_addr - 16'h1; // when pushing 16 bits the second decrement comes too late 
                                        end
                                        end
                                `SEQ_PUSH_WRITE_H: // reads high byte
                                `SEQ_PUSH_WRITE_H: // reads high byte
                                        begin
                                        begin
                                                k_cpu_data_o <= regs_o_left_path_data[15:8];
                                                k_cpu_data_o <= regs_o_left_path_data[15:8];
                                                state <= `SEQ_PUSH_WRITE_H_1;
                                                state <= `SEQ_PUSH_WRITE_H_1;
                                                k_cpu_we <= 1; // write
                                                k_cpu_we <= 1; // write
 
                                                if (k_pp_active_reg[3:0] > 0)
                                                k_cpu_addr <= regs_o_su;
                                                k_cpu_addr <= regs_o_su;
                                                k_dec_su <= 1; // decrement stack pointer
                                                k_dec_su <= 1; // decrement stack pointer
                                        end
                                        end
                                `SEQ_PUSH_WRITE_H_1:
                                `SEQ_PUSH_WRITE_H_1:
                                        begin
                                        begin
 
                                                if (next_state == `SEQ_JMP_LOAD_PC)
 
                                                        k_write_pc <= 1; // load PC in the next cycle, the mux output will have the right source
                                                state <= next_state;
                                                state <= next_state;
                                        end
                                        end
                                `SEQ_PC_READ_H: // reads high byte for [PC], used by IMM, DIR, EXT
                                `SEQ_PC_READ_H: // reads high byte for [PC], used by IMM, DIR, EXT
                                        begin
                                        begin
                                                k_cpu_addr <= regs_o_pc;
                                                k_cpu_addr <= regs_o_pc;
Line 853... Line 849...
                                                        `NONE: k_pp_regs <= cpu_data_i; // push & pull
                                                        `NONE: k_pp_regs <= cpu_data_i; // push & pull
                                                        `REL8, `REL16, `IMMEDIATE: k_memlo <= cpu_data_i;
                                                        `REL8, `REL16, `IMMEDIATE: k_memlo <= cpu_data_i;
                                                        `DIRECT, `EXTENDED: k_ealo <= cpu_data_i;
                                                        `DIRECT, `EXTENDED: k_ealo <= cpu_data_i;
                                                        `INDEXED: k_ofslo <= cpu_data_i;
                                                        `INDEXED: k_ofslo <= cpu_data_i;
                                                endcase
                                                endcase
 
                                                if ((next_state == `SEQ_JMP_LOAD_PC) & (dec_o_cond_taken))
 
                                                        k_write_pc <= 1; // load PC in the next cycle, the mux output will have the right source
                                                state <= next_state;
                                                state <= next_state;
                                        end
                                        end
                                `SEQ_MEM_READ_H: // reads high byte
                                `SEQ_MEM_READ_H: // reads high byte
                                        begin
                                        begin
                                                case (dec_o_p1_mode)
                                                case (dec_o_p1_mode)
                                                        `NONE: begin k_cpu_addr <= regs_o_su; k_inc_su <= 1; end // pull, rts, rti
                                                        `NONE: begin k_cpu_addr <= regs_o_su; k_inc_su <= 1; end // pull, rts, rti
                                                        `INDEXED: k_cpu_addr <= regs_o_eamem_addr;
                                                        `INDEXED: k_cpu_addr <= regs_o_eamem_addr;
                                                        default: k_cpu_addr <= { k_eahi, k_ealo };
                                                        default: k_cpu_addr <= { k_eahi, k_ealo };
                                                endcase
                                                endcase
 
                                                if (k_forced_mem_size | dec_o_source_size | (k_pp_active_reg[7:4] != 0))
                                                state <= `SEQ_MEM_READ_H_1;
                                                state <= `SEQ_MEM_READ_H_1;
 
                                                else
 
                                                        state <= `SEQ_MEM_READ_L_1;
 
                                                k_forced_mem_size <= 0; // used for vector fetch
                                        end
                                        end
                                `SEQ_MEM_READ_H_1:
                                `SEQ_MEM_READ_H_1:
                                        begin
                                        begin
                                                k_cpu_oe <= 1; // read
                                                k_cpu_oe <= 1; // read
                                                state <= `SEQ_MEM_READ_H_2;
                                                state <= `SEQ_MEM_READ_H_2;
                                        end
                                        end
                                `SEQ_MEM_READ_H_2:
                                `SEQ_MEM_READ_H_2:
                                        begin
                                        begin
                                                case (k_mem_dest)
                                                case (k_mem_dest)
                                                        `MEMDEST_PC: k_new_pc[15:8] <= cpu_data_i;
                                                        `MEMDEST_PC,//: k_new_pc[15:8] <= cpu_data_i;
                                                        `MEMDEST_MH: k_memhi <= cpu_data_i;
                                                        `MEMDEST_MH: k_memhi <= cpu_data_i;
                                                        `MEMDEST_AH: k_eahi <= cpu_data_i;
                                                        `MEMDEST_AH: k_eahi <= cpu_data_i;
                                                endcase
                                                endcase
                                                state <= `SEQ_MEM_READ_L_1;
                                                state <= `SEQ_MEM_READ_L_1;
                                                k_cpu_addr  <= k_cpu_addr + 16'h1;
                                                k_cpu_addr  <= k_cpu_addr + 16'h1;
 
                                                case (dec_o_p1_mode)
 
                                                        `NONE: begin k_inc_su <= 1; end // pull, rts, rti
 
                                                endcase
                                        end
                                        end
                                `SEQ_MEM_READ_L: // reads high byte
                                `SEQ_MEM_READ_L: // reads low byte
                                        begin
                                        begin
 
                                                // falls through from READ_MEM_H with the right address
                                                case (dec_o_p1_mode)
                                                case (dec_o_p1_mode)
                                                        `NONE: k_cpu_addr <= regs_o_su; // pull, rts, rti
                                                        `NONE: begin k_cpu_addr <= regs_o_su; k_inc_su <= 1; end // pull, rts, rti
                                                        `INDEXED: k_cpu_addr <= regs_o_eamem_addr;
 
                                                        default: k_cpu_addr <= { k_eahi, k_ealo };
 
                                                endcase
                                                endcase
                                                state <= `SEQ_MEM_READ_L_1;
                                                state <= `SEQ_MEM_READ_L_1;
                                        end
                                        end
                                `SEQ_MEM_READ_L_1:
                                `SEQ_MEM_READ_L_1:
                                        begin
                                        begin
Line 896... Line 900...
                                                state <= `SEQ_MEM_READ_L_2;
                                                state <= `SEQ_MEM_READ_L_2;
                                        end
                                        end
                                `SEQ_MEM_READ_L_2:
                                `SEQ_MEM_READ_L_2:
                                        begin
                                        begin
                                                case (k_mem_dest)
                                                case (k_mem_dest)
                                                        `MEMDEST_PC: begin k_new_pc[7:0] <= cpu_data_i; k_write_pc <= 1; end
                                                        `MEMDEST_PC: begin k_memlo <= cpu_data_i; k_write_pc <= 1; end
                                                        `MEMDEST_MH: k_memlo <= cpu_data_i;
                                                        `MEMDEST_MH: k_memlo <= cpu_data_i;
                                                        `MEMDEST_AH: k_ealo <= cpu_data_i;
                                                        `MEMDEST_AH: k_ealo <= cpu_data_i;
                                                endcase
                                                endcase
                                                case (dec_o_p1_mode)
                                                case (dec_o_p1_mode)
                                                        `NONE, `INHERENT: k_pull_reg_write <= 1; // pull, rts, rti
                                                        `NONE, `INHERENT: k_write_dest <= 1; // pull, rts, rti
                                                endcase
                                                endcase
                                                state <= next_mem_state;
                                                state <= next_mem_state;
                                        end
                                        end
                                `SEQ_MEM_WRITE_H: // writes high byte
                                `SEQ_MEM_WRITE_H: // writes high byte
                                        begin
                                        begin
                                                case (dec_o_p1_mode)
                                                case (dec_o_p1_mode)
                                                        `INDEXED: k_cpu_addr <= regs_o_eamem_addr;
                                                        `INDEXED: k_cpu_addr <= regs_o_eamem_addr;
                                                        default: k_cpu_addr <= { k_eahi, k_ealo };
                                                        default: k_cpu_addr <= { k_eahi, k_ealo };
                                                endcase
                                                endcase
                                                k_cpu_data_o <= datamux_o_dest[7:0];
                                                k_cpu_data_o <= datamux_o_dest[15:8];
                                                state <= `SEQ_MEM_WRITE_H_1;
                                                state <= `SEQ_MEM_WRITE_H_1;
                                                k_cpu_we <= 1; // read
                                                k_cpu_we <= 1; // read
                                        end
                                        end
                                `SEQ_MEM_WRITE_H_1:
                                `SEQ_MEM_WRITE_H_1:
                                        begin
                                        begin
                                                state <= `SEQ_MEM_WRITE_L;
                                                state <= `SEQ_MEM_WRITE_L;
                                                k_cpu_addr <= k_cpu_addr + 16'h1;
                                                k_cpu_addr <= k_cpu_addr + 16'h1;
                                        end
                                        end
                                `SEQ_MEM_WRITE_L: // reads high byte
                                `SEQ_MEM_WRITE_L: // reads high byte
                                        begin
                                        begin
                                                if (!dec_o_alu_size)
                                                if (!dec_o_alu_size) // only if it is a n 8 bit write
                                                        case (dec_o_p1_mode)
                                                        case (dec_o_p1_mode)
                                                                `INDEXED: k_cpu_addr <= regs_o_eamem_addr;
                                                                `INDEXED: k_cpu_addr <= regs_o_eamem_addr;
                                                                default: k_cpu_addr <= { k_eahi, k_ealo };
                                                                default: k_cpu_addr <= { k_eahi, k_ealo };
                                                        endcase
                                                        endcase
                                                k_cpu_data_o <= datamux_o_dest[7:0];
                                                k_cpu_data_o <= datamux_o_dest[7:0];

powered by: WebSVN 2.1.0

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