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

Subversion Repositories neorv32

[/] [neorv32/] [trunk/] [rtl/] [core/] [neorv32_cpu_control.vhd] - Diff between revs 37 and 38

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

Rev 37 Rev 38
Line 519... Line 519...
-- ****************************************************************************************************************************
-- ****************************************************************************************************************************
 
 
 
 
  -- Immediate Generator --------------------------------------------------------------------
  -- Immediate Generator --------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  imm_gen: process(clk_i)
  imm_gen: process(execute_engine.i_reg, clk_i)
    variable opcode_v : std_ulogic_vector(6 downto 0);
    variable opcode_v : std_ulogic_vector(6 downto 0);
  begin
  begin
    if rising_edge(clk_i) then
 
      opcode_v := execute_engine.i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c+2) & "11";
      opcode_v := execute_engine.i_reg(instr_opcode_msb_c downto instr_opcode_lsb_c+2) & "11";
 
    if rising_edge(clk_i) then
      case opcode_v is -- save some bits here, LSBs are always 11 for rv32
      case opcode_v is -- save some bits here, LSBs are always 11 for rv32
        when opcode_store_c => -- S-immediate
        when opcode_store_c => -- S-immediate
          imm_o(31 downto 11) <= (others => execute_engine.i_reg(31)); -- sign extension
          imm_o(31 downto 11) <= (others => execute_engine.i_reg(31)); -- sign extension
          imm_o(10 downto 05) <= execute_engine.i_reg(30 downto 25);
          imm_o(10 downto 05) <= execute_engine.i_reg(30 downto 25);
          imm_o(04 downto 01) <= execute_engine.i_reg(11 downto 08);
          imm_o(04 downto 01) <= execute_engine.i_reg(11 downto 08);
Line 1231... Line 1231...
  -- any illegal condition? --
  -- any illegal condition? --
  trap_ctrl.instr_il <= illegal_instruction or illegal_opcode_lsbs or illegal_register or illegal_compressed;
  trap_ctrl.instr_il <= illegal_instruction or illegal_opcode_lsbs or illegal_register or illegal_compressed;
 
 
 
 
-- ****************************************************************************************************************************
-- ****************************************************************************************************************************
-- Exception and Interrupt Control
-- Exception and Interrupt (= Trap) Control
-- ****************************************************************************************************************************
-- ****************************************************************************************************************************
 
 
 
 
  -- Trap Controller ------------------------------------------------------------------------
  -- Trap Controller ------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
  -- -------------------------------------------------------------------------------------------
Line 1303... Line 1303...
  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)
    -- the following traps are caused by *asynchronous* exceptions (= interrupts)
    -- here we do need a specific acknowledge mask since several sources can trigger at once
    -- here we do need a specific 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 <= trap_mei_c;
      trap_ctrl.cause_nxt <= trap_mei_c;
Line 1343... Line 1343...
    elsif (trap_ctrl.irq_buf(interrupt_firq_3_c) = '1') then
    elsif (trap_ctrl.irq_buf(interrupt_firq_3_c) = '1') then
      trap_ctrl.cause_nxt <= trap_firq3_c;
      trap_ctrl.cause_nxt <= trap_firq3_c;
      trap_ctrl.irq_ack_nxt(interrupt_firq_3_c) <= '1';
      trap_ctrl.irq_ack_nxt(interrupt_firq_3_c) <= '1';
 
 
 
 
    -- the following traps are caused by synchronous exceptions
    -- the following traps are caused by *synchronous* exceptions (= classic exceptions)
    -- here we do not need a specific acknowledge mask since only one exception (the one
    -- here we do not need a specific acknowledge mask since only one exception (the one
    -- with highest priority) can trigger at once
    -- with highest priority) is evaluated at once
 
 
    -- trap/fault: 0.1 instruction access fault --
    -- exception: 0.1 instruction access fault --
    elsif (trap_ctrl.exc_buf(exception_iaccess_c) = '1') then
    elsif (trap_ctrl.exc_buf(exception_iaccess_c) = '1') then
      trap_ctrl.cause_nxt <= trap_iba_c;
      trap_ctrl.cause_nxt <= trap_iba_c;
 
 
    -- trap/fault: 0.2 illegal instruction --
    -- exception: 0.2 illegal instruction --
    elsif (trap_ctrl.exc_buf(exception_iillegal_c) = '1') then
    elsif (trap_ctrl.exc_buf(exception_iillegal_c) = '1') then
      trap_ctrl.cause_nxt <= trap_iil_c;
      trap_ctrl.cause_nxt <= trap_iil_c;
 
 
    -- trap/fault: 0.0 instruction address misaligned --
    -- exception: 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 <= trap_ima_c;
      trap_ctrl.cause_nxt <= trap_ima_c;
 
 
 
 
    -- trap/fault: 0.11 environment call from M-mode --
    -- exception: 0.11 environment call from M-mode --
    elsif (trap_ctrl.exc_buf(exception_m_envcall_c) = '1') then
    elsif (trap_ctrl.exc_buf(exception_m_envcall_c) = '1') then
      trap_ctrl.cause_nxt <= trap_menv_c;
      trap_ctrl.cause_nxt <= trap_menv_c;
 
 
    -- trap/fault: 0.3 breakpoint --
    -- exception: 0.3 breakpoint --
    elsif (trap_ctrl.exc_buf(exception_break_c) = '1') then
    elsif (trap_ctrl.exc_buf(exception_break_c) = '1') then
      trap_ctrl.cause_nxt <= trap_brk_c;
      trap_ctrl.cause_nxt <= trap_brk_c;
 
 
 
 
    -- trap/fault: 0.6 store address misaligned -
    -- exception: 0.6 store address misaligned -
    elsif (trap_ctrl.exc_buf(exception_salign_c) = '1') then
    elsif (trap_ctrl.exc_buf(exception_salign_c) = '1') then
      trap_ctrl.cause_nxt <= trap_sma_c;
      trap_ctrl.cause_nxt <= trap_sma_c;
 
 
    -- trap/fault: 0.4 load address misaligned --
    -- exception: 0.4 load address misaligned --
    elsif (trap_ctrl.exc_buf(exception_lalign_c) = '1') then
    elsif (trap_ctrl.exc_buf(exception_lalign_c) = '1') then
      trap_ctrl.cause_nxt <= trap_lma_c;
      trap_ctrl.cause_nxt <= trap_lma_c;
 
 
    -- trap/fault: 0.7 store access fault --
    -- exception: 0.7 store access fault --
    elsif (trap_ctrl.exc_buf(exception_saccess_c) = '1') then
    elsif (trap_ctrl.exc_buf(exception_saccess_c) = '1') then
      trap_ctrl.cause_nxt <= trap_sbe_c;
      trap_ctrl.cause_nxt <= trap_sbe_c;
 
 
    -- trap/fault: 0.5 load access fault --
    -- exception: 0.5 load access fault --
    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;
 
 
    -- undefined / not implemented --
    -- undefined / not implemented --
    else
    else
Line 1405... Line 1405...
    variable csr_operand_v : std_ulogic_vector(data_width_c-1 downto 0);
    variable csr_operand_v : std_ulogic_vector(data_width_c-1 downto 0);
  begin
  begin
    -- CSR operand source --
    -- CSR operand source --
    if (execute_engine.i_reg(instr_funct3_msb_c) = '1') then -- immediate
    if (execute_engine.i_reg(instr_funct3_msb_c) = '1') then -- immediate
      csr_operand_v := (others => '0');
      csr_operand_v := (others => '0');
      csr_operand_v(4 downto 0) := execute_engine.i_reg(19 downto 15);
      csr_operand_v(4 downto 0) := execute_engine.i_reg(19 downto 15); -- uimm5
    else -- register
    else -- register
      csr_operand_v := rs1_i;
      csr_operand_v := rs1_i;
    end if;
    end if;
    -- "mini ALU" for CSR update operations --
    -- tiny ALU for CSR access operations --
    case execute_engine.i_reg(instr_funct3_lsb_c+1 downto instr_funct3_lsb_c) is
    case execute_engine.i_reg(instr_funct3_lsb_c+1 downto instr_funct3_lsb_c) is
      when "10"   => csr.wdata <= csr.rdata or csr_operand_v; -- CSRRS(I)
      when "10"   => csr.wdata <= csr.rdata or csr_operand_v; -- CSRRS(I)
      when "11"   => csr.wdata <= csr.rdata and (not csr_operand_v); -- CSRRC(I)
      when "11"   => csr.wdata <= csr.rdata and (not csr_operand_v); -- CSRRC(I)
      when others => csr.wdata <= csr_operand_v; -- CSRRW(I)
      when others => csr.wdata <= csr_operand_v; -- CSRRW(I)
    end case;
    end case;
Line 1678... Line 1678...
            csr.rdata(12) <= csr.mstatus_mpp(1); -- MPP: machine previous privilege mode high
            csr.rdata(12) <= csr.mstatus_mpp(1); -- MPP: machine previous privilege mode high
          when csr_misa_c => -- R/-: misa - ISA and extensions
          when csr_misa_c => -- R/-: misa - ISA and extensions
            csr.rdata(00) <= '0';                                         -- A CPU extension
            csr.rdata(00) <= '0';                                         -- A CPU extension
            csr.rdata(01) <= '0';                                         -- B CPU extension
            csr.rdata(01) <= '0';                                         -- B CPU extension
            csr.rdata(02) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_C);     -- C CPU extension
            csr.rdata(02) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_C);     -- C CPU extension
 
            csr.rdata(03) <= '0';                                         -- D CPU extension
            csr.rdata(04) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_E);     -- E CPU extension
            csr.rdata(04) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_E);     -- E CPU extension
 
            csr.rdata(05) <= '0';                                         -- F CPU extension
            csr.rdata(08) <= not bool_to_ulogic_f(CPU_EXTENSION_RISCV_E); -- I CPU extension (if not E)
            csr.rdata(08) <= not bool_to_ulogic_f(CPU_EXTENSION_RISCV_E); -- I CPU extension (if not E)
            csr.rdata(12) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_M);     -- M CPU extension
            csr.rdata(12) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_M);     -- M CPU extension
            csr.rdata(20) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_U);     -- U CPU extension
            csr.rdata(20) <= bool_to_ulogic_f(CPU_EXTENSION_RISCV_U);     -- U CPU extension
            csr.rdata(23) <= '1';                                         -- X CPU extension (non-std extensions)
            csr.rdata(23) <= '1';                                         -- X CPU extension (non-std extensions)
            csr.rdata(30) <= '1'; -- 32-bit architecture (MXL lo)
            csr.rdata(30) <= '1'; -- 32-bit architecture (MXL lo)

powered by: WebSVN 2.1.0

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