fix CSR read operations (side effects) (#1145)
Some checks are pending
Processor / processor simulation (push) Waiting to run

This commit is contained in:
stnolting 2025-01-09 23:48:58 +01:00 committed by GitHub
commit 6d69d61012
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 14 additions and 4 deletions

View file

@ -29,6 +29,7 @@ mimpid = 0x01040312 -> Version 01.04.03.12 -> v1.4.3.12
| Date | Version | Comment | Ticket |
|:----:|:-------:|:--------|:------:|
| 09.01.2025 | 1.10.9.1 | fix side-effects of CSR read instructions | [#1145](https://github.com/stnolting/neorv32/pull/1145) |
| 08.01.2025 | [**:rocket:1.10.9**](https://github.com/stnolting/neorv32/releases/tag/v1.10.9) | **New release** | |
| 07.01.2025 | 1.10.8.9 | rtl edits and cleanups; add dedicated "core complex" wrapper (CPU + L1 caches + bus switch) | [#1144](https://github.com/stnolting/neorv32/pull/1144) |
| 04.01.2025 | 1.10.8.8 | :sparkles: add inter-core communication (ICC) for the SMP dual-core setup | [#1142](https://github.com/stnolting/neorv32/pull/1142) |

View file

@ -210,6 +210,7 @@ architecture neorv32_cpu_control_rtl of neorv32_cpu_control is
type csr_t is record
addr : std_ulogic_vector(11 downto 0); -- physical access address
we, we_nxt : std_ulogic; -- write enable
re, re_nxt : std_ulogic; -- read enable
operand : std_ulogic_vector(XLEN-1 downto 0); -- write operand
wdata : std_ulogic_vector(XLEN-1 downto 0); -- write data
rdata : std_ulogic_vector(XLEN-1 downto 0); -- read data
@ -598,6 +599,7 @@ begin
trap_ctrl.ebreak <= '0';
trap_ctrl.hwtrig <= '0';
csr.we_nxt <= '0';
csr.re_nxt <= '0';
ctrl_nxt <= ctrl_bus_zero_c; -- all zero/off by default (ALU operation = ZERO, ALU.adder_out = ADD)
-- ALU sign control --
@ -766,6 +768,11 @@ begin
-- environment/CSR operation or ILLEGAL opcode --
when others =>
if ((funct3_v = funct3_csrrw_c) or (funct3_v = funct3_csrrwi_c)) and (exe_engine.ir(instr_rd_msb_c downto instr_rd_lsb_c) = "00000") then
csr.re_nxt <= '0'; -- no read if CSRRW[I] and rd = 0
else
csr.re_nxt <= '1';
end if;
exe_engine_nxt.state <= EX_SYSTEM;
end case; -- /EX_EXECUTE
@ -836,7 +843,7 @@ begin
if (funct3_v = funct3_csrrw_c) or (funct3_v = funct3_csrrwi_c) or (exe_engine.ir(instr_rs1_msb_c downto instr_rs1_lsb_c) /= "00000") then
csr.we_nxt <= '1'; -- CSRRW[I]: always write CSR; CSRR[S/C][I]: write CSR if rs1/imm5 is NOT zero
end if;
-- always write to RF; ENVIRONMENT operations have rd = zero so this does not hurt --
-- always write to RF (even if csr.re = 0, but then we have rd = 0); ENVIRONMENT operations have rd = zero so this does not hurt --
ctrl_nxt.rf_wb_en <= '1'; -- won't happen if exception
end case;
@ -1334,7 +1341,7 @@ begin
-- External CSR Interface -----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
xcsr_we_o <= csr.we;
xcsr_re_o <= '1' when (exe_engine.state = EX_SYSTEM) else '0';
xcsr_re_o <= csr.re;
xcsr_addr_o <= csr.addr;
xcsr_wdata_o <= csr.wdata;
@ -1637,10 +1644,12 @@ begin
csr_read_access: process(rstn_i, clk_i)
begin
if (rstn_i = '0') then
csr.re <= '0';
csr.rdata <= (others => '0');
elsif rising_edge(clk_i) then
csr.re <= csr.re_nxt and (not trap_ctrl.exc_buf(exc_illegal_c)); -- read if not an illegal instruction
csr.rdata <= (others => '0'); -- default; output all-zero if there is no explicit CSR read operation
if (exe_engine.state = EX_SYSTEM) then -- always read from CSR file in EX_SYSTEM state
if (csr.re = '1') then
case csr.addr is -- address is zero if there is no CSR operation
-- --------------------------------------------------------------------

View file

@ -29,7 +29,7 @@ package neorv32_package is
-- Architecture Constants -----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01100900"; -- hardware version
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01100901"; -- hardware version
constant archid_c : natural := 19; -- official RISC-V architecture ID
constant XLEN : natural := 32; -- native data path width