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

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [rtl/] [core/] [neorv32_cpu_control.vhd] - Diff between revs 68 and 69

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

Rev 68 Rev 69
Line 285... Line 285...
    mie_msie          : std_ulogic; -- mie.MSIE: machine software interrupt enable (R/W)
    mie_msie          : std_ulogic; -- mie.MSIE: machine software interrupt enable (R/W)
    mie_meie          : std_ulogic; -- mie.MEIE: machine external interrupt enable (R/W)
    mie_meie          : std_ulogic; -- mie.MEIE: machine external interrupt enable (R/W)
    mie_mtie          : std_ulogic; -- mie.MEIE: machine timer interrupt enable (R/W)
    mie_mtie          : std_ulogic; -- mie.MEIE: machine timer interrupt enable (R/W)
    mie_firqe         : std_ulogic_vector(15 downto 0); -- mie.firq*e: fast interrupt enabled (R/W)
    mie_firqe         : std_ulogic_vector(15 downto 0); -- mie.firq*e: fast interrupt enabled (R/W)
    --
    --
 
    mip_clr           : std_ulogic_vector(15 downto 0); -- clear pending FIRQ
 
    --
    mcounteren_cy     : std_ulogic; -- mcounteren.cy: allow cycle[h] access from user-mode
    mcounteren_cy     : std_ulogic; -- mcounteren.cy: allow cycle[h] access from user-mode
    mcounteren_tm     : std_ulogic; -- mcounteren.tm: allow time[h] access from user-mode
    mcounteren_tm     : std_ulogic; -- mcounteren.tm: allow time[h] access from user-mode
    mcounteren_ir     : std_ulogic; -- mcounteren.ir: allow instret[h] access from user-mode
    mcounteren_ir     : std_ulogic; -- mcounteren.ir: allow instret[h] access from user-mode
    --
    --
    mcountinhibit_cy  : std_ulogic; -- mcounterinhibit.cy: enable auto-increment for [m]cycle[h]
    mcountinhibit_cy  : std_ulogic; -- mcounterinhibit.cy: enable auto-increment for [m]cycle[h]
Line 390... Line 392...
      fetch_engine.restart    <= '1';
      fetch_engine.restart    <= '1';
      fetch_engine.pc         <= (others => def_rst_val_c);
      fetch_engine.pc         <= (others => def_rst_val_c);
    elsif rising_edge(clk_i) then
    elsif rising_edge(clk_i) then
      fetch_engine.state      <= fetch_engine.state_nxt;
      fetch_engine.state      <= fetch_engine.state_nxt;
      fetch_engine.state_prev <= fetch_engine.state;
      fetch_engine.state_prev <= fetch_engine.state;
      fetch_engine.restart    <= fetch_engine.restart_nxt;
      fetch_engine.restart    <= fetch_engine.restart_nxt or fetch_engine.reset;
      if (fetch_engine.restart = '1') then
      if (fetch_engine.restart = '1') then
        fetch_engine.pc <= execute_engine.pc(data_width_c-1 downto 1) & '0'; -- initialize with "real" application PC
        fetch_engine.pc <= execute_engine.pc(data_width_c-1 downto 1) & '0'; -- initialize with "real" application PC
      else
      else
        fetch_engine.pc <= fetch_engine.pc_nxt;
        fetch_engine.pc <= fetch_engine.pc_nxt;
      end if;
      end if;
Line 412... Line 414...
    -- arbiter defaults --
    -- arbiter defaults --
    bus_fast_ir              <= '0';
    bus_fast_ir              <= '0';
    fetch_engine.state_nxt   <= fetch_engine.state;
    fetch_engine.state_nxt   <= fetch_engine.state;
    fetch_engine.pc_nxt      <= fetch_engine.pc;
    fetch_engine.pc_nxt      <= fetch_engine.pc;
    fetch_engine.bus_err_ack <= '0';
    fetch_engine.bus_err_ack <= '0';
    fetch_engine.restart_nxt <= fetch_engine.restart or fetch_engine.reset;
    fetch_engine.restart_nxt <= fetch_engine.restart;
 
 
    -- instruction prefetch buffer interface --
    -- instruction prefetch buffer defaults --
    ipb.we    <= '0';
    ipb.we    <= '0';
    ipb.wdata <= be_instr_i & ma_instr_i & instr_i(31 downto 0); -- store exception info and instruction word
    ipb.wdata <= be_instr_i & ma_instr_i & instr_i(31 downto 0); -- store exception info and instruction word
    ipb.clear <= fetch_engine.restart;
    ipb.clear <= fetch_engine.restart;
 
 
    -- state machine --
    -- state machine --
Line 428... Line 430...
      -- ------------------------------------------------------------
      -- ------------------------------------------------------------
        if (ipb.free = '1') and (fetch_engine.restart = '0') then -- free entry in buffer AND no reset request?
        if (ipb.free = '1') and (fetch_engine.restart = '0') then -- free entry in buffer AND no reset request?
          bus_fast_ir            <= '1'; -- fast instruction fetch request
          bus_fast_ir            <= '1'; -- fast instruction fetch request
          fetch_engine.state_nxt <= IFETCH_ISSUE;
          fetch_engine.state_nxt <= IFETCH_ISSUE;
        end if;
        end if;
        if (fetch_engine.restart = '1') then -- reset request?
 
          fetch_engine.restart_nxt <= '0';
          fetch_engine.restart_nxt <= '0';
        end if;
 
 
 
      when IFETCH_ISSUE => -- store instruction data to prefetch buffer
      when IFETCH_ISSUE => -- store instruction data to prefetch buffer
      -- ------------------------------------------------------------
      -- ------------------------------------------------------------
        fetch_engine.bus_err_ack <= be_instr_i or ma_instr_i; -- ACK bus/alignment errors
        fetch_engine.bus_err_ack <= be_instr_i or ma_instr_i; -- ACK bus/alignment errors
        if (bus_i_wait_i = '0') or (be_instr_i = '1') or (ma_instr_i = '1') then -- wait for bus response
        if (bus_i_wait_i = '0') or (be_instr_i = '1') or (ma_instr_i = '1') then -- wait for bus response
          fetch_engine.pc_nxt <= std_ulogic_vector(unsigned(fetch_engine.pc) + 4);
          fetch_engine.pc_nxt <= std_ulogic_vector(unsigned(fetch_engine.pc) + 4);
          ipb.we              <= not fetch_engine.restart; -- write to IPB if not being reset
          ipb.we              <= not fetch_engine.restart; -- write to IPB if not being reset
          if (fetch_engine.restart = '1') then -- reset request?
 
            fetch_engine.restart_nxt <= '0';
            fetch_engine.restart_nxt <= '0';
          end if;
 
          fetch_engine.state_nxt <= IFETCH_REQUEST;
          fetch_engine.state_nxt <= IFETCH_REQUEST;
        end if;
        end if;
 
 
      when others => -- undefined
      when others => -- undefined
      -- ------------------------------------------------------------
      -- ------------------------------------------------------------
Line 502... Line 500...
        if (CPU_EXTENSION_RISCV_C = true) and (execute_engine.pc(1) = '1') then -- branch to unaligned address?
        if (CPU_EXTENSION_RISCV_C = true) and (execute_engine.pc(1) = '1') then -- branch to unaligned address?
          issue_engine.state <= ISSUE_REALIGN;
          issue_engine.state <= ISSUE_REALIGN;
          issue_engine.align <= '1'; -- aligned on 16-bit boundary
          issue_engine.align <= '1'; -- aligned on 16-bit boundary
        else
        else
          issue_engine.state <= issue_engine.state_nxt;
          issue_engine.state <= issue_engine.state_nxt;
          issue_engine.align <= '0'; -- always aligned on 32-bit boundaries
          issue_engine.align <= '0'; -- aligned on 32-bit boundary
        end if;
        end if;
      else
      else
        issue_engine.state <= issue_engine.state_nxt;
        issue_engine.state <= issue_engine.state_nxt;
        issue_engine.align <= issue_engine.align_nxt;
        issue_engine.align <= issue_engine.align_nxt;
      end if;
      end if;
Line 539... Line 537...
      -- ------------------------------------------------------------
      -- ------------------------------------------------------------
        if (ipb.avail = '1') then -- instructions available?
        if (ipb.avail = '1') then -- instructions available?
 
 
          if (issue_engine.align = '0') or (CPU_EXTENSION_RISCV_C = false) then -- begin check in LOW instruction half-word
          if (issue_engine.align = '0') or (CPU_EXTENSION_RISCV_C = false) then -- begin check in LOW instruction half-word
            if (execute_engine.state = DISPATCH) then -- ready to issue new command?
            if (execute_engine.state = DISPATCH) then -- ready to issue new command?
 
              ipb.re               <= '1';
              cmd_issue.valid      <= '1';
              cmd_issue.valid      <= '1';
              issue_engine.buf_nxt <= ipb.rdata(33 downto 32) & ipb.rdata(31 downto 16); -- store high half-word - we might need it for an unaligned uncompressed instruction
              issue_engine.buf_nxt <= ipb.rdata(33 downto 32) & ipb.rdata(31 downto 16); -- store high half-word - we might need it for an unaligned uncompressed instruction
              if (ipb.rdata(1 downto 0) = "11") or (CPU_EXTENSION_RISCV_C = false) then -- uncompressed and "aligned"
              if (ipb.rdata(1 downto 0) = "11") or (CPU_EXTENSION_RISCV_C = false) then -- uncompressed and "aligned"
                ipb.re <= '1';
 
                cmd_issue.data <= '0' & ipb.rdata(33 downto 32) & '0' & ipb.rdata(31 downto 0);
                cmd_issue.data <= '0' & ipb.rdata(33 downto 32) & '0' & ipb.rdata(31 downto 0);
              else -- compressed
              else -- compressed
                ipb.re <= '1';
 
                cmd_issue.data <= ci_illegal & ipb.rdata(33 downto 32) & '1' & ci_instr32;
                cmd_issue.data <= ci_illegal & ipb.rdata(33 downto 32) & '1' & ci_instr32;
                issue_engine.align_nxt <= '1';
                issue_engine.align_nxt <= '1';
              end if;
              end if;
            end if;
            end if;
 
 
Line 785... Line 782...
    ctrl_o(ctrl_priv_lvl_msb_c downto ctrl_priv_lvl_lsb_c) <= csr.privilege_rd;
    ctrl_o(ctrl_priv_lvl_msb_c downto ctrl_priv_lvl_lsb_c) <= csr.privilege_rd;
    -- register addresses --
    -- register addresses --
    ctrl_o(ctrl_rf_rs1_adr4_c downto ctrl_rf_rs1_adr0_c) <= execute_engine.i_reg(instr_rs1_msb_c downto instr_rs1_lsb_c);
    ctrl_o(ctrl_rf_rs1_adr4_c downto ctrl_rf_rs1_adr0_c) <= execute_engine.i_reg(instr_rs1_msb_c downto instr_rs1_lsb_c);
    ctrl_o(ctrl_rf_rs2_adr4_c downto ctrl_rf_rs2_adr0_c) <= execute_engine.i_reg(instr_rs2_msb_c downto instr_rs2_lsb_c);
    ctrl_o(ctrl_rf_rs2_adr4_c downto ctrl_rf_rs2_adr0_c) <= execute_engine.i_reg(instr_rs2_msb_c downto instr_rs2_lsb_c);
    ctrl_o(ctrl_rf_rd_adr4_c  downto ctrl_rf_rd_adr0_c)  <= execute_engine.i_reg(instr_rd_msb_c  downto instr_rd_lsb_c);
    ctrl_o(ctrl_rf_rd_adr4_c  downto ctrl_rf_rd_adr0_c)  <= execute_engine.i_reg(instr_rd_msb_c  downto instr_rd_lsb_c);
    -- fast bus access requests --
    -- instruction fetch request --
    ctrl_o(ctrl_bus_if_c) <= bus_fast_ir;
    ctrl_o(ctrl_bus_if_c) <= bus_fast_ir;
    -- bus error control --
    -- bus error control --
    ctrl_o(ctrl_bus_ierr_ack_c) <= fetch_engine.bus_err_ack; -- instruction fetch bus access error ACK
    ctrl_o(ctrl_bus_ierr_ack_c) <= fetch_engine.bus_err_ack; -- instruction fetch bus access error ACK
    ctrl_o(ctrl_bus_derr_ack_c) <= trap_ctrl.env_start_ack; -- data access bus error access ACK
    ctrl_o(ctrl_bus_derr_ack_c) <= trap_ctrl.env_start_ack; -- data access bus error access ACK
    -- memory access size / sign --
    -- memory access size / sign --
Line 1038... Line 1035...
                ctrl_nxt(ctrl_alu_op2_c downto ctrl_alu_op0_c) <= alu_op_or_c;
                ctrl_nxt(ctrl_alu_op2_c downto ctrl_alu_op0_c) <= alu_op_or_c;
              when others => -- AND(I), multi-cycle / co-processor operations
              when others => -- AND(I), multi-cycle / co-processor operations
                ctrl_nxt(ctrl_alu_op2_c downto ctrl_alu_op0_c) <= alu_op_and_c;
                ctrl_nxt(ctrl_alu_op2_c downto ctrl_alu_op0_c) <= alu_op_and_c;
            end case;
            end case;
 
 
            -- Check if single-cycle or multi-cycle (co-processor) operation --
            -- co-processor MULDIV operation (multi-cycle)? --
            -- co-processor MULDIV operation? --
 
            if ((CPU_EXTENSION_RISCV_M = true) and ((decode_aux.is_m_mul = '1') or (decode_aux.is_m_div = '1'))) or -- MUL/DIV
            if ((CPU_EXTENSION_RISCV_M = true) and ((decode_aux.is_m_mul = '1') or (decode_aux.is_m_div = '1'))) or -- MUL/DIV
               ((CPU_EXTENSION_RISCV_Zmmul = true) and (decode_aux.is_m_mul = '1')) then -- MUL
               ((CPU_EXTENSION_RISCV_Zmmul = true) and (decode_aux.is_m_mul = '1')) then -- MUL
              ctrl_nxt(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) <= cp_sel_muldiv_c; -- use MULDIV CP
              ctrl_nxt(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) <= cp_sel_muldiv_c; -- use MULDIV CP
              ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_copro_c;
              ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_copro_c;
              execute_engine.state_nxt                           <= ALU_WAIT;
              execute_engine.state_nxt                           <= ALU_WAIT;
            -- co-processor BIT-MANIPULATION operation? --
            -- co-processor BIT-MANIPULATION operation (multi-cycle)? --
            elsif (CPU_EXTENSION_RISCV_B = true) and
            elsif (CPU_EXTENSION_RISCV_B = true) and
                  (((execute_engine.i_reg(instr_opcode_lsb_c+5) = opcode_alu_c(5))  and (decode_aux.is_bitmanip_reg = '1')) or -- register operation
                  (((execute_engine.i_reg(instr_opcode_lsb_c+5) = opcode_alu_c(5))  and (decode_aux.is_bitmanip_reg = '1')) or -- register operation
                   ((execute_engine.i_reg(instr_opcode_lsb_c+5) = opcode_alui_c(5)) and (decode_aux.is_bitmanip_imm = '1'))) then -- immediate operation
                   ((execute_engine.i_reg(instr_opcode_lsb_c+5) = opcode_alui_c(5)) and (decode_aux.is_bitmanip_imm = '1'))) then -- immediate operation
              ctrl_nxt(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) <= cp_sel_bitmanip_c; -- use BITMANIP CP
              ctrl_nxt(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) <= cp_sel_bitmanip_c; -- use BITMANIP CP
              ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_copro_c;
              ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_copro_c;
              execute_engine.state_nxt                           <= ALU_WAIT;
              execute_engine.state_nxt                           <= ALU_WAIT;
            -- co-processor SHIFT operation? --
            -- co-processor SHIFT operation (multi-cycle)? --
            elsif (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sll_c) or
            elsif (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sll_c) or
                  (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sr_c) then
                  (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_sr_c) then
              ctrl_nxt(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) <= cp_sel_shifter_c; -- use SHIFTER CP (only relevant for shift operations)
              ctrl_nxt(ctrl_cp_id_msb_c downto ctrl_cp_id_lsb_c) <= cp_sel_shifter_c; -- use SHIFTER CP (only relevant for shift operations)
              ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_copro_c;
              ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_copro_c;
              execute_engine.state_nxt                           <= ALU_WAIT;
              execute_engine.state_nxt                           <= ALU_WAIT;
            -- ALU core operations (single-cycle) --
            -- ALU CORE operation (single-cycle) --
            else
            else
              ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_core_c;
              ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_core_c;
              ctrl_nxt(ctrl_rf_wb_en_c)                          <= '1'; -- valid RF write-back
              ctrl_nxt(ctrl_rf_wb_en_c)                          <= '1'; -- valid RF write-back
              execute_engine.state_nxt                           <= DISPATCH;
              execute_engine.state_nxt                           <= DISPATCH;
            end if;
            end if;
Line 1175... Line 1171...
      -- ------------------------------------------------------------
      -- ------------------------------------------------------------
        -- CSR write access --
        -- CSR write access --
        if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrw_c) or
        if (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrw_c) or
           (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrwi_c) then -- CSRRW(I)
           (execute_engine.i_reg(instr_funct3_msb_c downto instr_funct3_lsb_c) = funct3_csrrwi_c) then -- CSRRW(I)
          csr.we_nxt <= '1'; -- always write CSR
          csr.we_nxt <= '1'; -- always write CSR
        else -- CSRRS(I) / CSRRC(I) [invalid CSR instruction are already checked by the illegal instruction logic]
        else -- CSRRS(I) / CSRRC(I) [invalid CSR instructions are already checked by the illegal instruction logic]
          csr.we_nxt <= not decode_aux.rs1_zero; -- write CSR if rs1/imm is not zero
          csr.we_nxt <= not decode_aux.rs1_zero; -- write CSR if rs1/imm is not zero
        end if;
        end if;
        -- register file write back --
        -- register file write back --
        ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_csrr_c;
        ctrl_nxt(ctrl_alu_func1_c downto ctrl_alu_func0_c) <= alu_func_csrr_c;
        ctrl_nxt(ctrl_rf_wb_en_c) <= '1'; -- valid RF write-back
        ctrl_nxt(ctrl_rf_wb_en_c) <= '1'; -- valid RF write-back
Line 1292... Line 1288...
        csr_acc_valid <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zfinx); -- full access for everyone if FPU implemented
        csr_acc_valid <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_Zfinx); -- full access for everyone if FPU implemented
 
 
      -- machine trap setup/handling & counters --
      -- machine trap setup/handling & counters --
      when csr_mstatus_c | csr_mstatush_c | csr_misa_c | csr_mie_c | csr_mtvec_c | csr_mscratch_c | csr_mepc_c | csr_mcause_c | csr_mip_c | csr_mtval_c |
      when csr_mstatus_c | csr_mstatush_c | csr_misa_c | csr_mie_c | csr_mtvec_c | csr_mscratch_c | csr_mepc_c | csr_mcause_c | csr_mip_c | csr_mtval_c |
           csr_mcycle_c | csr_mcycleh_c | csr_minstret_c | csr_minstreth_c | csr_mcountinhibit_c =>
           csr_mcycle_c | csr_mcycleh_c | csr_minstret_c | csr_minstreth_c | csr_mcountinhibit_c =>
        -- NOTE: MISA, MIP and MTVAL are read-only in the NEORV32 but we do not cause an exception here for compatibility.
        -- NOTE: MISA and MTVAL are read-only in the NEORV32 but we do not cause an exception here for compatibility.
        -- Machine-level code should read-back those CSRs after writing them to realize they are read-only.
        -- Machine-level code should read-back those CSRs after writing them to realize they are read-only.
        csr_acc_valid <= csr.priv_m_mode; -- M-mode only 
        csr_acc_valid <= csr.priv_m_mode; -- M-mode only 
 
 
      -- machine information registers, read-only --
      -- machine information registers, read-only --
      when csr_mvendorid_c | csr_marchid_c | csr_mimpid_c | csr_mhartid_c | csr_mconfigptr_c =>
      when csr_mvendorid_c | csr_marchid_c | csr_mimpid_c | csr_mhartid_c | csr_mconfigptr_c =>
Line 1630... Line 1626...
        -- interrupt buffer: machine software/external/timer interrupt --
        -- interrupt buffer: machine software/external/timer interrupt --
        trap_ctrl.irq_buf(interrupt_msw_irq_c)   <= csr.mie_msie and msw_irq_i;
        trap_ctrl.irq_buf(interrupt_msw_irq_c)   <= csr.mie_msie and msw_irq_i;
        trap_ctrl.irq_buf(interrupt_mext_irq_c)  <= csr.mie_meie and mext_irq_i;
        trap_ctrl.irq_buf(interrupt_mext_irq_c)  <= csr.mie_meie and mext_irq_i;
        trap_ctrl.irq_buf(interrupt_mtime_irq_c) <= csr.mie_mtie and mtime_irq_i;
        trap_ctrl.irq_buf(interrupt_mtime_irq_c) <= csr.mie_mtie and mtime_irq_i;
 
 
        -- interrupt buffer: NEORV32-specific fast interrupts (FIRQ) --
        -- interrupt queue: NEORV32-specific fast interrupts (FIRQ) --
        trap_ctrl.irq_buf(interrupt_firq_15_c downto interrupt_firq_0_c) <= csr.mie_firqe(15 downto 0) and firq_i(15 downto 0);
        trap_ctrl.irq_buf(interrupt_firq_15_c downto interrupt_firq_0_c) <= (trap_ctrl.irq_buf(interrupt_firq_15_c downto interrupt_firq_0_c) or (csr.mie_firqe and firq_i)) and (not csr.mip_clr);
 
 
        -- trap environment control --
        -- trap environment control --
        if (trap_ctrl.env_start = '0') then -- no started trap handler
        if (trap_ctrl.env_start = '0') then -- no started trap handler
          if (trap_ctrl.exc_fire = '1') or ((trap_ctrl.irq_fire = '1') and -- exception triggered!
          if (trap_ctrl.exc_fire = '1') or ((trap_ctrl.irq_fire = '1') and -- exception triggered!
             ((execute_engine.state = EXECUTE) or (execute_engine.state = TRAP_ENTER))) then -- fire IRQs in EXECUTE or TRAP state only to continue execution even on permanent IRQ
             ((execute_engine.state = EXECUTE) or (execute_engine.state = TRAP_ENTER))) then -- fire IRQs in EXECUTE or TRAP state only to continue execution even on permanent IRQ
Line 1720... Line 1716...
    elsif (trap_ctrl.exc_buf(exception_laccess_c) = '1') then
    elsif (trap_ctrl.exc_buf(exception_laccess_c) = '1') then
      trap_ctrl.cause_nxt <= trap_lbe_c;
      trap_ctrl.cause_nxt <= trap_lbe_c;
 
 
 
 
    -- ----------------------------------------------------------------------------------------
    -- ----------------------------------------------------------------------------------------
    -- (re-)enter debug mode requests; basically, these are standard traps that have some
    -- (re-)enter debug mode requests: basically, these are standard traps that have some
    -- special handling - they have the highest INTERRUPT priority in order to go to debug when requested
    -- special handling - they have the highest INTERRUPT priority in order to go to debug when requested
    -- even if other IRQs are pending right now
    -- even if other IRQs are pending right now
    -- ----------------------------------------------------------------------------------------
    -- ----------------------------------------------------------------------------------------
 
 
    -- break instruction --
    -- break instruction --
Line 1876... Line 1872...
      csr.mtvec             <= (others => def_rst_val_c);
      csr.mtvec             <= (others => def_rst_val_c);
      csr.mscratch          <= x"19880704";
      csr.mscratch          <= x"19880704";
      csr.mepc              <= (others => def_rst_val_c);
      csr.mepc              <= (others => def_rst_val_c);
      csr.mcause            <= (others => def_rst_val_c);
      csr.mcause            <= (others => def_rst_val_c);
      csr.mtval             <= (others => def_rst_val_c);
      csr.mtval             <= (others => def_rst_val_c);
 
      csr.mip_clr           <= (others => def_rst_val_c);
      --
      --
      csr.pmpcfg            <= (others => (others => '0'));
      csr.pmpcfg            <= (others => (others => '0'));
      csr.pmpaddr           <= (others => (others => def_rst_val_c));
      csr.pmpaddr           <= (others => (others => def_rst_val_c));
      --
      --
      csr.mhpmevent         <= (others => (others => def_rst_val_c));
      csr.mhpmevent         <= (others => (others => def_rst_val_c));
Line 1905... Line 1902...
 
 
    elsif rising_edge(clk_i) then
    elsif rising_edge(clk_i) then
      -- write access? --
      -- write access? --
      csr.we <= csr.we_nxt;
      csr.we <= csr.we_nxt;
 
 
 
      -- defaults --
 
      csr.mip_clr <= (others => '0');
 
 
      if (CPU_EXTENSION_RISCV_Zicsr = true) then
      if (CPU_EXTENSION_RISCV_Zicsr = true) then
        -- --------------------------------------------------------------------------------
        -- --------------------------------------------------------------------------------
        -- CSR access by application software
        -- CSR access by application software
        -- --------------------------------------------------------------------------------
        -- --------------------------------------------------------------------------------
        if (csr.we = '1') and (trap_ctrl.exc_buf(exception_iillegal_c) = '0') then -- manual write access and not illegal instruction
        if (csr.we = '1') and (trap_ctrl.exc_buf(exception_iillegal_c) = '0') then -- manual write access and not illegal instruction
Line 1963... Line 1963...
            end if;
            end if;
          end if;
          end if;
 
 
          -- machine trap handling --
          -- machine trap handling --
          -- --------------------------------------------------------------------
          -- --------------------------------------------------------------------
          if (csr.addr(11 downto 3) = csr_class_trap_c) then -- machine trap handling CSR class
          if (csr.addr(11 downto 4) = csr_class_trap_c) then -- machine trap handling CSR class
            -- R/W: mscratch - machine scratch register --
            -- R/W: mscratch - machine scratch register --
            if (csr.addr(2 downto 0) = csr_mscratch_c(2 downto 0)) then
            if (csr.addr(3 downto 0) = csr_mscratch_c(3 downto 0)) then
              csr.mscratch <= csr.wdata;
              csr.mscratch <= csr.wdata;
            end if;
            end if;
            -- R/W: mepc - machine exception program counter --
            -- R/W: mepc - machine exception program counter --
            if (csr.addr(2 downto 0) = csr_mepc_c(2 downto 0)) then
            if (csr.addr(3 downto 0) = csr_mepc_c(3 downto 0)) then
              csr.mepc <= csr.wdata;
              csr.mepc <= csr.wdata;
            end if;
            end if;
            -- R/W: mcause - machine trap cause --
            -- R/W: mcause - machine trap cause --
            if (csr.addr(2 downto 0) = csr_mcause_c(2 downto 0)) then
            if (csr.addr(3 downto 0) = csr_mcause_c(3 downto 0)) then
              csr.mcause(csr.mcause'left) <= csr.wdata(31); -- 1: async/interrupt, 0: sync/exception
              csr.mcause(csr.mcause'left) <= csr.wdata(31); -- 1: async/interrupt, 0: sync/exception
              csr.mcause(4 downto 0)      <= csr.wdata(4 downto 0); -- identifier
              csr.mcause(4 downto 0)      <= csr.wdata(4 downto 0); -- identifier
            end if;
            end if;
 
            -- R/W: mip - machine interrupt pending --
 
            if (csr.addr(3 downto 0) =  csr_mip_c(3 downto 0)) then
 
              csr.mip_clr <= csr.wdata(31 downto 16);
 
            end if;
          end if;
          end if;
 
 
          -- physical memory protection: R/W: pmpcfg* - PMP configuration registers --
          -- physical memory protection: R/W: pmpcfg* - PMP configuration registers --
          -- --------------------------------------------------------------------
          -- --------------------------------------------------------------------
          if (PMP_NUM_REGIONS > 0) then
          if (PMP_NUM_REGIONS > 0) then
Line 2489... Line 2493...
          when csr_mcause_c => -- mcause (r/w): machine trap cause
          when csr_mcause_c => -- mcause (r/w): machine trap cause
            csr.rdata(31) <= csr.mcause(csr.mcause'left);
            csr.rdata(31) <= csr.mcause(csr.mcause'left);
            csr.rdata(csr.mcause'left-1 downto 0) <= csr.mcause(csr.mcause'left-1 downto 0);
            csr.rdata(csr.mcause'left-1 downto 0) <= csr.mcause(csr.mcause'left-1 downto 0);
          when csr_mtval_c => -- mtval (r/-): machine bad address or instruction
          when csr_mtval_c => -- mtval (r/-): machine bad address or instruction
            csr.rdata <= csr.mtval;
            csr.rdata <= csr.mtval;
          when csr_mip_c => -- mip (r/-): machine interrupt pending
          when csr_mip_c => -- mip (r/w): machine interrupt pending
            csr.rdata(03) <= trap_ctrl.irq_buf(interrupt_msw_irq_c);
            csr.rdata(03) <= trap_ctrl.irq_buf(interrupt_msw_irq_c);
            csr.rdata(07) <= trap_ctrl.irq_buf(interrupt_mtime_irq_c);
            csr.rdata(07) <= trap_ctrl.irq_buf(interrupt_mtime_irq_c);
            csr.rdata(11) <= trap_ctrl.irq_buf(interrupt_mext_irq_c);
            csr.rdata(11) <= trap_ctrl.irq_buf(interrupt_mext_irq_c);
            for i in 0 to 15 loop -- fast interrupt channels 0..15 pending
            for i in 0 to 15 loop -- fast interrupt channels 0..15 pending
              csr.rdata(16+i) <= trap_ctrl.irq_buf(interrupt_firq_0_c+i);
              csr.rdata(16+i) <= trap_ctrl.irq_buf(interrupt_firq_0_c+i);

powered by: WebSVN 2.1.0

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