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

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [rtl/] [core/] [neorv32_cpu_control.vhd] - Diff between revs 8 and 9

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

Rev 8 Rev 9
Line 890... Line 890...
            NULL;
            NULL;
        end case;
        end case;
        -- RF write back --
        -- RF write back --
        ctrl_nxt(ctrl_rf_in_mux_msb_c downto ctrl_rf_in_mux_lsb_c) <= "11"; -- RF input = CSR output register
        ctrl_nxt(ctrl_rf_in_mux_msb_c downto ctrl_rf_in_mux_lsb_c) <= "11"; -- RF input = CSR output register
        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; -- FIXME should be SYS_WAIT? have another cycle to let side-effects kick in
 
 
      when ALU_WAIT => -- wait for multi-cycle ALU operation to finish
      when ALU_WAIT => -- wait for multi-cycle ALU operation to finish
      -- ------------------------------------------------------------
      -- ------------------------------------------------------------
        ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_operation_v; -- actual ALU operation
        ctrl_nxt(ctrl_alu_cmd2_c downto ctrl_alu_cmd0_c) <= alu_operation_v; -- actual ALU operation
        ctrl_nxt(ctrl_rf_in_mux_msb_c downto ctrl_rf_in_mux_lsb_c) <= "00"; -- RF input = ALU result
        ctrl_nxt(ctrl_rf_in_mux_msb_c downto ctrl_rf_in_mux_lsb_c) <= "00"; -- RF input = ALU result
Line 1197... Line 1197...
  begin
  begin
    -- defaults --
    -- defaults --
    trap_ctrl.cause_nxt   <= (others => '0');
    trap_ctrl.cause_nxt   <= (others => '0');
    trap_ctrl.irq_ack_nxt <= (others => '0');
    trap_ctrl.irq_ack_nxt <= (others => '0');
 
 
 
    -- the following traps are caused by asynchronous exceptions (-> interrupts)
 
    -- here we do need an acknowledge mask since several sources can trigger at once
 
 
    -- interrupt: 1.11 machine external interrupt --
    -- interrupt: 1.11 machine external interrupt --
    if (trap_ctrl.irq_buf(interrupt_mext_irq_c) = '1') then
    if (trap_ctrl.irq_buf(interrupt_mext_irq_c) = '1') then
      trap_ctrl.cause_nxt(data_width_c-1) <= '1';
      trap_ctrl.cause_nxt(data_width_c-1) <= '1';
      trap_ctrl.cause_nxt(3 downto 0) <= "1011";
      trap_ctrl.cause_nxt(3 downto 0) <= "1011";
      trap_ctrl.irq_ack_nxt(interrupt_mext_irq_c) <= '1';
      trap_ctrl.irq_ack_nxt(interrupt_mext_irq_c) <= '1';
Line 1217... Line 1220...
      trap_ctrl.cause_nxt(3 downto 0) <= "0011";
      trap_ctrl.cause_nxt(3 downto 0) <= "0011";
      trap_ctrl.irq_ack_nxt(interrupt_msw_irq_c) <= '1';
      trap_ctrl.irq_ack_nxt(interrupt_msw_irq_c) <= '1';
 
 
 
 
    -- the following traps are caused by synchronous exceptions
    -- the following traps are caused by synchronous exceptions
    -- here we do not need an acknowledge mask since only one exception can trigger at the same time
    -- here we do not need an acknowledge mask since only one exception (the one
 
    -- with highest priority) can trigger at once
 
 
    -- trap/fault: 0.0 instruction address misaligned --
    -- trap/fault: 0.0 instruction address misaligned --
    elsif (trap_ctrl.exc_buf(exception_ialign_c) = '1') then
    elsif (trap_ctrl.exc_buf(exception_ialign_c) = '1') then
      trap_ctrl.cause_nxt(data_width_c-1) <= '0';
      trap_ctrl.cause_nxt(data_width_c-1) <= '0';
      trap_ctrl.cause_nxt(3 downto 0) <= "0000";
      trap_ctrl.cause_nxt(3 downto 0) <= "0000";
Line 1319... Line 1323...
            if (execute_engine.i_reg(23 downto 20) = x"0") then -- R/W: mstatus - machine status register
            if (execute_engine.i_reg(23 downto 20) = x"0") then -- R/W: mstatus - machine status register
              csr.mstatus_mie  <= csr_wdata_i(03);
              csr.mstatus_mie  <= csr_wdata_i(03);
              csr.mstatus_mpie <= csr_wdata_i(07);
              csr.mstatus_mpie <= csr_wdata_i(07);
            end if;
            end if;
            if (execute_engine.i_reg(23 downto 20) = x"1") then -- R/W: misa - machine instruction set extensions
            if (execute_engine.i_reg(23 downto 20) = x"1") then -- R/W: misa - machine instruction set extensions
              csr.misa_c_en <= csr_wdata_i(02); -- C extension enable/disable
              csr.misa_c_en <= csr_wdata_i(02); -- C extension enable/disable during runtime
              csr.misa_m_en <= csr_wdata_i(12); -- M extension enable/disable
              csr.misa_m_en <= csr_wdata_i(12); -- M extension enable/disable during runtime
            end if;
            end if;
            if (execute_engine.i_reg(23 downto 20) = x"4") then -- R/W: mie - machine interrupt-enable register
            if (execute_engine.i_reg(23 downto 20) = x"4") then -- R/W: mie - machine interrupt-enable register
              csr.mie_msie <= csr_wdata_i(03); -- SW IRQ enable
              csr.mie_msie <= csr_wdata_i(03); -- SW IRQ enable
              csr.mie_mtie <= csr_wdata_i(07); -- TIMER IRQ enable
              csr.mie_mtie <= csr_wdata_i(07); -- TIMER IRQ enable
              csr.mie_meie <= csr_wdata_i(11); -- EXT IRQ enable
              csr.mie_meie <= csr_wdata_i(11); -- EXT IRQ enable
Line 1346... Line 1350...
              csr.mip_msip <= csr_wdata_i(03); -- manual SW IRQ trigger
              csr.mip_msip <= csr_wdata_i(03); -- manual SW IRQ trigger
            end if;
            end if;
          end if;
          end if;
 
 
        else -- automatic update by hardware
        else -- automatic update by hardware
 
 
          -- machine exception PC & exception value register --
          -- machine exception PC & exception value register --
          if (trap_ctrl.env_start_ack = '1') then -- trap handler started?
          if (trap_ctrl.env_start_ack = '1') then -- trap handler started?
            if (csr.mcause(data_width_c-1) = '1') then -- for INTERRUPTS only (mtval not defined for interrupts)
            if (csr.mcause(data_width_c-1) = '1') then -- for INTERRUPTS only (mtval not defined for interrupts)
              csr.mepc  <= execute_engine.pc(data_width_c-1 downto 1) & '0'; -- this is the CURRENT pc = interrupted instruction
              csr.mepc  <= execute_engine.pc(data_width_c-1 downto 1) & '0'; -- this is the CURRENT pc = interrupted instruction
              csr.mtval <= (others => '0');
              csr.mtval <= (others => '0');
            else -- for EXCEPTIONs
            else -- for EXCEPTIONS (according to their priority)
              csr.mepc <= execute_engine.last_pc(data_width_c-1 downto 1) & '0'; -- this is the LAST pc = last executed instruction
              csr.mepc <= execute_engine.last_pc(data_width_c-1 downto 1) & '0'; -- this is the LAST pc = last executed instruction
              if ((trap_ctrl.exc_src(exception_iaccess_c) or trap_ctrl.exc_src(exception_ialign_c)) = '1') then -- instruction access error OR misaligned instruction
              if ((trap_ctrl.exc_src(exception_iaccess_c) or trap_ctrl.exc_src(exception_ialign_c)) = '1') then -- instruction access error OR misaligned instruction
                csr.mtval <= execute_engine.pc(data_width_c-1 downto 1) & '0';
                csr.mtval <= execute_engine.pc(data_width_c-1 downto 1) & '0'; -- address of faulting instruction
              elsif (trap_ctrl.exc_src(exception_iillegal_c) = '1') then -- illegal instruction
              elsif (trap_ctrl.exc_src(exception_iillegal_c) = '1') then -- illegal instruction
                csr.mtval <= execute_engine.i_reg;
                csr.mtval <= execute_engine.i_reg; -- the faulting instruction itself
              else -- everything else
              else -- load/store msialignments/access errors
              --elsif ((trap_ctrl.exc_src(exception_lalign_c)  or trap_ctrl.exc_src(exception_salign_c) or
                csr.mtval <= mar_i; -- faulting data access address
              --        trap_ctrl.exc_src(exception_laccess_c) or trap_ctrl.exc_src(exception_saccess_c)) = '1') then -- load/store misaligned / access error
 
                csr.mtval <= mar_i;
 
              end if;
              end if;
            end if;
            end if;
          end if;
          end if;
 
 
          -- context switch in mstatus --
          -- context switch in mstatus --
          if (trap_ctrl.env_start_ack = '1') then -- actually entering trap
          if (trap_ctrl.env_start_ack = '1') then -- actually entering trap
            csr.mstatus_mie <= '0';
            csr.mstatus_mie <= '0';
            if (csr.mstatus_mpie = '0') then -- FIXME: prevent loosing the prev MIE state after several traps
            if (csr.mstatus_mpie = '0') then -- prevent loosing the prev MIE state in nested traps
              csr.mstatus_mpie <= csr.mstatus_mie;
              csr.mstatus_mpie <= csr.mstatus_mie;
            end if;
            end if;
          elsif (trap_ctrl.env_end = '1') then -- return from exception
          elsif (trap_ctrl.env_end = '1') then -- return from exception
            csr.mstatus_mie <= csr.mstatus_mpie;
            csr.mstatus_mie <= csr.mstatus_mpie;
          end if;
          end if;
 
 
        end if;
        end if;
      end if;
      end if;
    end if;
    end if;
  end process csr_write_access;
  end process csr_write_access;
 
 

powered by: WebSVN 2.1.0

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