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)
|