removed mtinst CSR since it is not ratified by the official RISC-V specs yet

This commit is contained in:
stnolting 2020-07-06 19:32:20 +02:00
parent 16636c4353
commit d38509fc92
6 changed files with 30 additions and 42 deletions

View file

@ -142,7 +142,7 @@ The CPU is compliant to the [official RISC-V specifications](https://raw.githubu
* CSR access instructions: `CSRRW` `CSRRS` `CSRRC` `CSRRWI` `CSRRSI` `CSRRCI`
* System instructions: `ECALL` `EBREAK` `MRET` `WFI`
* Counter CSRs: `cycle` `cycleh` `time` `timeh` `instret` `instreth` `mcycle` `mcycleh` `minstret` `minstreth`
* Machine CSRs: `mstatus` `misa` `mie` `mtvec` `mscratch` `mepc` `mcause` `mtval` `mip` `mtinst` `mimpid` `mhartid`
* Machine CSRs: `mstatus` `misa` `mie` `mtvec` `mscratch` `mepc` `mcause` `mtval` `mip` `mimpid` `mhartid`
* Custom CSRs: `mfeatures` `mclock` `mispacebase` `mdspacebase` `mispacesize` `mdspacesize`
* Supported exceptions and interrupts:
* Misaligned instruction address

Binary file not shown.

View file

@ -192,7 +192,6 @@ architecture neorv32_cpu_control_rtl of neorv32_cpu_control is
irq_ack_nxt : std_ulogic_vector(interrupt_width_c-1 downto 0);
cause : std_ulogic_vector(data_width_c-1 downto 0); -- trap ID (for "mcause")
cause_nxt : std_ulogic_vector(data_width_c-1 downto 0);
instr : std_ulogic_vector(31 downto 0); -- faulting instruction
exc_src : std_ulogic_vector(exception_width_c-1 downto 0);
--
env_start : std_ulogic; -- start trap handler env
@ -232,7 +231,6 @@ architecture neorv32_cpu_control_rtl of neorv32_cpu_control is
mtvec : std_ulogic_vector(data_width_c-1 downto 0); -- mtvec: machine trap-handler base address (R/W)
mtval : std_ulogic_vector(data_width_c-1 downto 0); -- mtval: machine bad address or isntruction (R/-)
mscratch : std_ulogic_vector(data_width_c-1 downto 0); -- mscratch: scratch register (R/W)
mtinst : std_ulogic_vector(data_width_c-1 downto 0); -- mtinst: machine trap instruction (transformed) (R/-)
cycle : std_ulogic_vector(32 downto 0); -- cycle, mtime (R/-), plus carry bit
instret : std_ulogic_vector(32 downto 0); -- instret (R/-), plus carry bit
cycleh : std_ulogic_vector(31 downto 0); -- cycleh, mtimeh (R/-)
@ -1044,7 +1042,6 @@ begin
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"342") or -- mcause
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"343") or -- mtval
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"344") or -- mip
(execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"34a") or -- mtinst
--
((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"c00") and (CPU_EXTENSION_RISCV_E = false) and (CSR_COUNTERS_USE = true)) or -- cycle
((execute_engine.i_reg(instr_funct12_msb_c downto instr_funct12_lsb_c) = x"c01") and (CPU_EXTENSION_RISCV_E = false) and (CSR_COUNTERS_USE = true)) or -- time
@ -1121,7 +1118,6 @@ begin
trap_ctrl.exc_ack <= '0';
trap_ctrl.irq_ack <= (others => '0');
trap_ctrl.cause <= (others => '0');
trap_ctrl.instr <= (others => '0');
trap_ctrl.exc_src <= (others => '0');
trap_ctrl.env_start <= '0';
elsif rising_edge(clk_i) then
@ -1147,13 +1143,11 @@ begin
if (trap_ctrl.env_start = '0') then -- no started trap handler
if (trap_ctrl.exc_fire = '1') or ((trap_ctrl.irq_fire = '1') and
((execute_engine.state = EXECUTE) or (execute_engine.state = TRAP))) then -- exception/IRQ detected!
trap_ctrl.cause <= trap_ctrl.cause_nxt; -- capture source ID for program
trap_ctrl.instr <= execute_engine.i_reg; -- FIXME mtinst transformation not fully implemented yet!
trap_ctrl.instr(1) <= not execute_engine.is_ci; -- bit is set for uncompressed instruction
trap_ctrl.exc_src <= trap_ctrl.exc_buf; -- capture exception source for hardware
trap_ctrl.exc_ack <= '1'; -- clear execption
trap_ctrl.irq_ack <= trap_ctrl.irq_ack_nxt; -- capture and clear with interrupt ACK mask
trap_ctrl.env_start <= '1'; -- now we want to start the trap handler
trap_ctrl.cause <= trap_ctrl.cause_nxt; -- capture source ID for program
trap_ctrl.exc_src <= trap_ctrl.exc_buf; -- capture exception source for hardware
trap_ctrl.exc_ack <= '1'; -- clear execption
trap_ctrl.irq_ack <= trap_ctrl.irq_ack_nxt; -- capture and clear with interrupt ACK mask
trap_ctrl.env_start <= '1'; -- now we want to start the trap handler
end if;
else -- trap waiting to get started
if (trap_ctrl.env_start_ack = '1') then -- start of trap handler acknowledged by execution engine
@ -1175,7 +1169,6 @@ begin
-- exception/interrupt/status ID visible for program --
csr.mcause <= trap_ctrl.cause;
csr.mtinst <= trap_ctrl.instr;
-- Trap Priority Detector -----------------------------------------------------------------
@ -1412,8 +1405,6 @@ begin
csr_rdata_o(03) <= trap_ctrl.irq_buf(interrupt_msw_irq_c);
csr_rdata_o(07) <= trap_ctrl.irq_buf(interrupt_mtime_irq_c);
csr_rdata_o(11) <= trap_ctrl.irq_buf(interrupt_mext_irq_c);
when x"34a" => -- R/-: mtinst - machine trap instruction (transformed)
csr_rdata_o <= csr.mtinst;
-- counter and timers --
when x"c00" | x"c01" | x"b00" => -- R/-: cycle/time/mcycle: Cycle counter LOW / Timer LOW
csr_rdata_o <= csr.cycle(31 downto 0);

View file

@ -42,9 +42,6 @@
.global _start
// standard CSRs
.set mtinst, 0x34a
// custom CSRs
.set CSR_MISPACEBASE, 0xfc4 // CUSTOM (r/-): Base address of instruction memory space (via MEM_ISPACE_BASE generic) */
.set CSR_MDSPACEBASE, 0xfc5 // CUSTOM (r/-): Base address of data memory space (via MEM_DSPACE_BASE generic) */
@ -295,12 +292,16 @@ __crt0_neorv32_rte:
// --------------------------------------------
__crt0_neorv32_rte_is_exc:
// is faulting instruction compressed?
csrr t0, mtinst
andi t0, t0, 2 // get compression flag (bit #1): 0=compressed, 1=uncompressed
// check if faulting instruction is compressed and adjust return address
lh t0, 0(ra) // get compressed instruction or lower 16 bits of uncompressed instruction that caused exception
addi t2, zero, 3 // mask
and t0, t0, t2 // isolate lowest 2 opcode bits (= 11 for uncompressed instructions)
addi ra, ra, +2 // only this for compressed instructions
add ra, ra, t0 // add another 2 (making +4) for uncompressed instructions
bne t0, t2, __crt0_neorv32_rte_execute // jump if compressed instruction
addi ra, ra, +2 // add another 2 (making +4) for uncompressed instructions
j __crt0_neorv32_rte_execute

View file

@ -70,7 +70,6 @@ enum NEORV32_CPU_CSRS_enum {
CSR_MCAUSE = 0x342, /**< 0x342 - mcause (r/-): Machine trap cause */
CSR_MTVAL = 0x343, /**< 0x343 - mtval (r/-): Machine bad address or instruction */
CSR_MIP = 0x344, /**< 0x344 - mip (r/w): Machine interrupt pending register */
CSR_MTINST = 0x34a, /**< 0x34a - mtinst (r/-): Machine trap instruction (transformed) */
CSR_MCYCLE = 0xb00, /**< 0xb00 - mcycle (r/-): Machine cycle counter low word */
CSR_MINSTRET = 0xb02, /**< 0xb02 - minstret (r/-): Machine instructions-retired counter low word */

View file

@ -157,26 +157,29 @@ static void __neorv32_rte_debug_exc_handler(void) {
neorv32_uart_printf("System time: 0x%x_%x\n", neorv32_cpu_csr_read(CSR_TIMEH), neorv32_cpu_csr_read(CSR_TIME));
register uint32_t exc_cause = neorv32_cpu_csr_read(CSR_MCAUSE);
register uint32_t return_addr = neorv32_cpu_csr_read(CSR_MEPC);
register uint32_t trans_cmd = neorv32_cpu_csr_read(CSR_MTINST);
register uint32_t trap_cause = neorv32_cpu_csr_read(CSR_MCAUSE);
register uint32_t trap_addr = neorv32_cpu_csr_read(CSR_MEPC);
register uint32_t trap_inst;
if (exc_cause & 0x80000000) {
// get faulting instruction
asm volatile ("lh %[result], 0(%[input_i])" : [result] "=r" (trap_inst) : [input_i] "r" (trap_addr));
if (trap_cause & 0x80000000) {
neorv32_uart_printf("INTERRUPT");
}
else {
neorv32_uart_printf("EXCEPTION");
if ((trans_cmd & (1 << 1)) == 0) {
return_addr -= 4;
if ((trap_inst & 3) == 3) {
trap_addr -= 4;
}
else {
return_addr -= 2;
trap_addr -= 2;
}
}
neorv32_uart_printf(" at instruction address: 0x%x\n", return_addr);
neorv32_uart_printf(" at instruction address: 0x%x\n", trap_addr);
neorv32_uart_printf("Cause: ");
switch (exc_cause) {
switch (trap_cause) {
case 0x00000000: neorv32_uart_printf("Instruction address misaligned"); break;
case 0x00000001: neorv32_uart_printf("Instruction access fault"); break;
case 0x00000002: neorv32_uart_printf("Illegal instruction"); break;
@ -189,20 +192,14 @@ static void __neorv32_rte_debug_exc_handler(void) {
case 0x80000003: neorv32_uart_printf("Machine software interrupt"); break;
case 0x80000007: neorv32_uart_printf("Machine timer interrupt (via MTIME)"); break;
case 0x8000000B: neorv32_uart_printf("Machine external interrupt (via CLIC)"); break;
default: neorv32_uart_printf("Unknown (0x%x)", exc_cause); break;
default: neorv32_uart_printf("Unknown (0x%x)", trap_cause); break;
}
// fault address
if (exc_cause == 0x00000002) {
neorv32_uart_printf("\nFaulting instruction");
}
else {
neorv32_uart_printf("\nFaulting address");
}
neorv32_uart_printf(": 0x%x\n", neorv32_cpu_csr_read(CSR_MTVAL));
neorv32_uart_printf("Transf. instruction: 0x%x ", trans_cmd);
neorv32_uart_printf("\nFaulting instruction: 0x%x\n", trap_inst);
neorv32_uart_printf("MTVAL: 0x%x\n", neorv32_cpu_csr_read(CSR_MTVAL));
if ((trans_cmd & (1 << 1)) == 0) {
if ((trap_inst & 3) != 3) {
neorv32_uart_printf("(decompressed)\n");
}