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

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [debugger/] [src/] [cpu_sysc_plugin/] [riverlib/] [core/] [execute.cpp] - Diff between revs 3 and 4

Show entire file | Details | Blame | View Log

Rev 3 Rev 4
Line 1... Line 1...
/**
/*
 * @file
 *  Copyright 2018 Sergey Khabarov, sergeykhbr@gmail.com
 * @copyright  Copyright 2016 GNSS Sensor Ltd. All right reserved.
 *
 * @author     Sergey Khabarov - sergeykhbr@gmail.com
 *  Licensed under the Apache License, Version 2.0 (the "License");
 * @brief      CPU Instruction Execution stage.
 *  you may not use this file except in compliance with the License.
 
 *  You may obtain a copy of the License at
 
 *
 
 *      http://www.apache.org/licenses/LICENSE-2.0
 
 *
 
 *  Unless required by applicable law or agreed to in writing, software
 
 *  distributed under the License is distributed on an "AS IS" BASIS,
 
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
 *  See the License for the specific language governing permissions and
 
 *  limitations under the License.
 */
 */
 
 
#include "execute.h"
#include "execute.h"
#include "riscv-isa.h"
#include "riscv-isa.h"
 
 
Line 16... Line 25...
    sensitive << i_pipeline_hold;
    sensitive << i_pipeline_hold;
    sensitive << i_d_valid;
    sensitive << i_d_valid;
    sensitive << i_d_pc;
    sensitive << i_d_pc;
    sensitive << i_d_instr;
    sensitive << i_d_instr;
    sensitive << i_wb_done;
    sensitive << i_wb_done;
    sensitive << i_memop_load;
 
    sensitive << i_memop_store;
    sensitive << i_memop_store;
 
    sensitive << i_memop_load;
    sensitive << i_memop_sign_ext;
    sensitive << i_memop_sign_ext;
    sensitive << i_memop_size;
    sensitive << i_memop_size;
    sensitive << i_unsigned_op;
    sensitive << i_unsigned_op;
    sensitive << i_rv32;;
    sensitive << i_rv32;
 
    sensitive << i_compressed;
    sensitive << i_isa_type;
    sensitive << i_isa_type;
    sensitive << i_ivec;
    sensitive << i_ivec;
    sensitive << i_rdata1;
 
    sensitive << i_rdata2;
 
    sensitive << i_csr_rdata;
 
    sensitive << i_ext_irq;
 
    sensitive << i_ie;
    sensitive << i_ie;
    sensitive << i_mtvec;
    sensitive << i_mtvec;
    sensitive << i_mode;
    sensitive << i_mode;
    sensitive << i_break_mode;
    sensitive << i_break_mode;
    sensitive << i_unsup_exception;
    sensitive << i_unsup_exception;
 
    sensitive << i_ext_irq;
    sensitive << i_dport_npc_write;
    sensitive << i_dport_npc_write;
    sensitive << i_dport_npc;
    sensitive << i_dport_npc;
 
    sensitive << i_rdata1;
 
    sensitive << i_rdata2;
 
    sensitive << i_csr_rdata;
    sensitive << r.d_valid;
    sensitive << r.d_valid;
 
    sensitive << r.pc;
    sensitive << r.npc;
    sensitive << r.npc;
    sensitive << r.hazard_depth;
    sensitive << r.instr;
    sensitive << r.hazard_addr0;
 
    sensitive << r.hazard_addr1;
 
    sensitive << r.res_val;
    sensitive << r.res_val;
    sensitive << r.memop_load;
    sensitive << r.memop_load;
    sensitive << r.memop_store;
    sensitive << r.memop_store;
    sensitive << w_hazard_detected;
    sensitive << r.memop_addr;
 
    sensitive << r.multi_res_addr;
 
    sensitive << r.multi_pc;
 
    sensitive << r.multi_npc;
 
    sensitive << r.multi_instr;
    sensitive << r.multi_ena[Multi_MUL];
    sensitive << r.multi_ena[Multi_MUL];
    sensitive << r.multi_ena[Multi_DIV];
    sensitive << r.multi_ena[Multi_DIV];
    sensitive << r.multi_res_addr;
    sensitive << r.multi_rv32;
 
    sensitive << r.multi_unsigned;
 
    sensitive << r.multi_residual_high;
    sensitive << r.multiclock_ena;
    sensitive << r.multiclock_ena;
 
    sensitive << r.multi_a1;
 
    sensitive << r.multi_a2;
 
    sensitive << r.hazard_addr0;
 
    sensitive << r.hazard_addr1;
 
    sensitive << r.hazard_depth;
 
    sensitive << r.ext_irq_pulser;
    sensitive << r.trap_ena;
    sensitive << r.trap_ena;
    sensitive << r.breakpoint;
    sensitive << r.breakpoint;
 
    sensitive << r.trap_code;
 
    sensitive << r.trap_pc;
 
    sensitive << r.call;
 
    sensitive << r.ret;
 
    sensitive << w_hazard_detected;
    sensitive << wb_arith_res.arr[Multi_MUL];
    sensitive << wb_arith_res.arr[Multi_MUL];
    sensitive << wb_arith_res.arr[Multi_DIV];
    sensitive << wb_arith_res.arr[Multi_DIV];
    sensitive << w_arith_valid[Multi_MUL];
    sensitive << w_arith_valid[Multi_MUL];
    sensitive << w_arith_valid[Multi_DIV];
    sensitive << w_arith_valid[Multi_DIV];
 
    sensitive << w_arith_busy[Multi_MUL];
 
    sensitive << w_arith_busy[Multi_DIV];
 
    sensitive << wb_shifter_a1;
 
    sensitive << wb_shifter_a2;
    sensitive << wb_sll;
    sensitive << wb_sll;
    sensitive << wb_sllw;
    sensitive << wb_sllw;
    sensitive << wb_srl;
    sensitive << wb_srl;
    sensitive << wb_srlw;
    sensitive << wb_srlw;
    sensitive << wb_sra;
    sensitive << wb_sra;
Line 189... Line 219...
    bool w_memop_store;
    bool w_memop_store;
    bool w_memop_sign_ext;
    bool w_memop_sign_ext;
    sc_uint<2> wb_memop_size;
    sc_uint<2> wb_memop_size;
    sc_uint<BUS_ADDR_WIDTH> wb_memop_addr;
    sc_uint<BUS_ADDR_WIDTH> wb_memop_addr;
    sc_bv<Instr_Total> wv;
    sc_bv<Instr_Total> wv;
 
    int opcode_len;
 
 
    bool w_pc_valid;
    bool w_pc_valid;
    bool w_d_acceptable;
    bool w_d_acceptable;
    bool w_multi_valid;
    bool w_multi_valid;
    bool w_multi_ena;
    bool w_multi_ena;
Line 335... Line 366...
        w_gr_equal = 1;
        w_gr_equal = 1;
    }
    }
 
 
    // Relative Branch on some condition:
    // Relative Branch on some condition:
    w_pc_branch = 0;
    w_pc_branch = 0;
    if ((wv[Instr_BEQ] & (wb_sub64 == 0))
    if ((wv[Instr_BEQ].to_bool() & (wb_sub64 == 0))
        || (wv[Instr_BGE] & (wb_sub64[63] == 0))
        || (wv[Instr_BGE].to_bool() & (wb_sub64[63] == 0))
        || (wv[Instr_BGEU] & (w_gr_equal))
        || (wv[Instr_BGEU].to_bool() & (w_gr_equal))
        || (wv[Instr_BLT] & (wb_sub64[63] == 1))
        || (wv[Instr_BLT].to_bool() & (wb_sub64[63] == 1))
        || (wv[Instr_BLTU] & (w_less))
        || (wv[Instr_BLTU].to_bool() & (w_less))
        || (wv[Instr_BNE] & (wb_sub64 != 0))) {
        || (wv[Instr_BNE].to_bool() & (wb_sub64 != 0))) {
        w_pc_branch = 1;
        w_pc_branch = 1;
    }
    }
 
 
 
    opcode_len = 4;
 
    if (i_compressed.read()) {
 
        opcode_len = 2;
 
    }
 
 
    if (w_pc_branch) {
    if (w_pc_branch) {
        wb_npc = i_d_pc.read() + wb_off(BUS_ADDR_WIDTH-1, 0);
        wb_npc = i_d_pc.read() + wb_off(BUS_ADDR_WIDTH-1, 0);
    } else if (wv[Instr_JAL].to_bool()) {
    } else if (wv[Instr_JAL].to_bool()) {
        wb_res = i_d_pc.read() + 4;
        wb_res = i_d_pc.read() + opcode_len;
        wb_npc = wb_rdata1(BUS_ADDR_WIDTH-1, 0) + wb_off(BUS_ADDR_WIDTH-1, 0);
        wb_npc = wb_rdata1(BUS_ADDR_WIDTH-1, 0) + wb_off(BUS_ADDR_WIDTH-1, 0);
    } else if (wv[Instr_JALR].to_bool()) {
    } else if (wv[Instr_JALR].to_bool()) {
        wb_res = i_d_pc.read() + 4;
        wb_res = i_d_pc.read() + opcode_len;
        wb_npc = wb_rdata1(BUS_ADDR_WIDTH-1, 0) + wb_rdata2(BUS_ADDR_WIDTH-1, 0);
        wb_npc = wb_rdata1(BUS_ADDR_WIDTH-1, 0) + wb_rdata2(BUS_ADDR_WIDTH-1, 0);
        wb_npc[0] = 0;
        wb_npc[0] = 0;
    } else if ((wv[Instr_MRET] | wv[Instr_URET]).to_bool()) {
    } else if ((wv[Instr_MRET] | wv[Instr_URET]).to_bool()) {
        wb_res = i_d_pc.read() + 4;
        wb_res = i_d_pc.read() + opcode_len;
        w_xret = i_d_valid;
        w_xret = i_d_valid.read() && w_pc_valid;
        w_csr_wena = 0;
        w_csr_wena = 0;
        if (wv[Instr_URET].to_bool()) {
        if (wv[Instr_URET].to_bool()) {
            wb_csr_addr = CSR_uepc;
            wb_csr_addr = CSR_uepc;
        } else {
        } else {
            wb_csr_addr = CSR_mepc;
            wb_csr_addr = CSR_mepc;
        }
        }
        wb_npc = i_csr_rdata;
        wb_npc = i_csr_rdata;
    } else {
    } else {
        // Instr_HRET, Instr_SRET, Instr_FENCE, Instr_FENCE_I:
        // Instr_HRET, Instr_SRET, Instr_FENCE, Instr_FENCE_I:
        wb_npc = i_d_pc.read() + 4;
        wb_npc = i_d_pc.read() + opcode_len;
    }
    }
 
 
    if (i_memop_load) {
    if (i_memop_load) {
        wb_memop_addr =
        wb_memop_addr =
            wb_rdata1(BUS_ADDR_WIDTH-1, 0) + wb_rdata2(BUS_ADDR_WIDTH-1, 0);
            wb_rdata1(BUS_ADDR_WIDTH-1, 0) + wb_rdata2(BUS_ADDR_WIDTH-1, 0);
Line 401... Line 437...
        || (wv[Instr_URET] && i_mode.read() != PRV_U)) {
        || (wv[Instr_URET] && i_mode.read() != PRV_U)) {
        w_exception_xret = 1;
        w_exception_xret = 1;
    }
    }
 
 
    w_exception = w_d_acceptable
    w_exception = w_d_acceptable
        & (i_unsup_exception.read() || w_exception_load || w_exception_store
        & ((i_unsup_exception.read() & w_pc_valid) || w_exception_load
           || w_exception_xret || wv[Instr_ECALL] || wv[Instr_EBREAK]);
           || w_exception_store || w_exception_xret
 
           || wv[Instr_ECALL] || wv[Instr_EBREAK]);
 
 
    /** Default number of cycles per instruction = 0 (1 clock per instr)
    /** Default number of cycles per instruction = 0 (1 clock per instr)
     *  If instruction is multicycle then modify this value.
     *  If instruction is multicycle then modify this value.
     */
     */
    v.multi_ena[Multi_MUL] = 0;
    v.multi_ena[Multi_MUL] = 0;
Line 519... Line 556...
    }
    }
 
 
    wb_exception_code = 0;
    wb_exception_code = 0;
    if (i_ext_irq & i_ie & !r.ext_irq_pulser) { // Maskable traps (interrupts)
    if (i_ext_irq & i_ie & !r.ext_irq_pulser) { // Maskable traps (interrupts)
        v.trap_code_waiting[4] = 1;
        v.trap_code_waiting[4] = 1;
        v.trap_code_waiting(3, 0) = INTERRUPT_MExternal;
        // INTERRUPT_MExternal - INTERRUPT_USoftware
 
        v.trap_code_waiting(3, 0) = 11;
    } else if (w_exception) {      // Unmaskable traps (exceptions)
    } else if (w_exception) {      // Unmaskable traps (exceptions)
        wb_exception_code[4] = 0;
        wb_exception_code[4] = 0;
        if (w_exception_load) {
        if (w_exception_load) {
            wb_exception_code(3, 0) = EXCEPTION_LoadMisalign;
            wb_exception_code(3, 0) = EXCEPTION_LoadMisalign;
        } else if (w_exception_store) {
        } else if (w_exception_store) {

powered by: WebSVN 2.1.0

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