Skip to content

Commit

Permalink
Merge branch 'main' into mmu_dev
Browse files Browse the repository at this point in the history
  • Loading branch information
stnolting committed Feb 3, 2024
2 parents 9600c33 + 89d9f1b commit 715715b
Show file tree
Hide file tree
Showing 4 changed files with 93 additions and 18 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ mimpid = 0x01040312 -> Version 01.04.03.12 -> v1.4.3.12

| Date | Version | Comment | Link |
|:----:|:-------:|:--------|:----:|
| 03.02.2024 | 1.9.4.3 | :bug: fix minor bug: CPU instruction bus privilege signal was hardwired to "user-mode" | [#790](https://github.com/stnolting/neorv32/pull/790) |
| 01.02.2024 | 1.9.4.2 | :sparkles: add support for page fault exceptions (yet unused) | [#786](https://github.com/stnolting/neorv32/pull/786) |
| 31.01.2024 | 1.9.4.1 | fix trap priority | [#784](https://github.com/stnolting/neorv32/pull/784) |
| 31.01.2024 | [**:rocket:1.9.4**](https://github.com/stnolting/neorv32/releases/tag/v1.9.4) | **New release** | |
Expand Down
6 changes: 3 additions & 3 deletions rtl/core/neorv32_cpu_control.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -429,7 +429,7 @@ begin
ipb.we(1) <= '1' when (fetch_engine.state = IF_PENDING) and (fetch_engine.resp = '1') else '0';

-- bus access type --
bus_req_o.priv <= ctrl.cpu_priv; -- current privilege mode
bus_req_o.priv <= csr.privilege_eff; -- current effective privilege level
bus_req_o.data <= (others => '0'); -- read-only
bus_req_o.ben <= (others => '0'); -- read-only
bus_req_o.rw <= '0'; -- read-only
Expand Down Expand Up @@ -1045,8 +1045,8 @@ begin
ctrl_nxt.rf_mux <= rf_mux_mem_c; -- RF input = memory read data
if (lsu_wait_i = '0') or -- bus system has completed the transaction
(trap_ctrl.exc_buf(exc_saccess_c) = '1') or (trap_ctrl.exc_buf(exc_laccess_c) = '1') or -- access exception
(trap_ctrl.exc_buf(exc_salign_c) = '1') or (trap_ctrl.exc_buf(exc_lalign_c) = '1') or -- alignment exception
(trap_ctrl.exc_buf(exc_spage_c) = '1') or (trap_ctrl.exc_buf(exc_lpage_c) = '1') then -- page exception
(trap_ctrl.exc_buf(exc_salign_c) = '1') or (trap_ctrl.exc_buf(exc_lalign_c) = '1') or -- alignment exception
(trap_ctrl.exc_buf(exc_spage_c) = '1') or (trap_ctrl.exc_buf(exc_lpage_c) = '1') then -- page exception
if ((CPU_EXTENSION_RISCV_A = true) and (decode_aux.opcode(2) = opcode_amo_c(2))) or -- atomic operation
(execute_engine.ir(instr_opcode_msb_c-1) = '0') then -- normal load
ctrl_nxt.rf_wb_en <= '1'; -- allow write-back to register file (won't happen in case of exception)
Expand Down
98 changes: 86 additions & 12 deletions rtl/core/neorv32_cpu_cp_fpu.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -923,27 +923,82 @@ begin
if (fpu_operands.rs1(31) = fpu_operands.rs2(31)) then -- identical signs
addsub.res_sign <= fpu_operands.rs1(31);
else -- different signs
if (addsub.exp_comp(1) = '1') then -- exp are equal (also check relation of mantissas)
addsub.res_sign <= fpu_operands.rs1(31) xor (not addsub.man_comp);
else
addsub.res_sign <= fpu_operands.rs1(31) xor addsub.exp_comp(0);
-- if the result is not 0.0 set the sign normally
if ((to_integer(unsigned(addsub.add_stage))) /= 0 ) then
if (addsub.exp_comp(1) = '1') then -- exp are equal (also check relation of mantissas)
addsub.res_sign <= fpu_operands.rs1(31) xor (not addsub.man_comp);
else
addsub.res_sign <= fpu_operands.rs1(31) xor addsub.exp_comp(0);
end if;
else
-- roundTowardNegative; under that attribute, the sign of an exact zero sum (or difference) shall be −0
if (fpu_operands.frm = "010") then -- round down (towards -infinity)
addsub.res_sign <= '1'; -- set the sign to 0 to generate a +0.0 result
else
addsub.res_sign <= '0'; -- set the sign to 0 to generate a +0.0 result
end if;
end if;
end if;
else -- sub
if (fpu_operands.rs1(31) = fpu_operands.rs2(31)) then -- identical signs
if (addsub.exp_comp(1) = '1') then -- exp are equal (also check relation of mantissas)
addsub.res_sign <= fpu_operands.rs1(31) xor (not addsub.man_comp);
else
addsub.res_sign <= fpu_operands.rs1(31) xor addsub.exp_comp(0);
-- identical signs
-- if the result is not 0.0 set the sign normally
if (fpu_operands.rs1(31) = fpu_operands.rs2(31)) then
if ((to_integer(unsigned(addsub.add_stage))) /= 0 ) then
if (addsub.exp_comp(1) = '1') then -- exp are equal (also check relation of mantissas)
addsub.res_sign <= fpu_operands.rs1(31) xor (not addsub.man_comp);
else
addsub.res_sign <= fpu_operands.rs1(31) xor addsub.exp_comp(0);
end if;
else
-- roundTowardNegative; under that attribute, the sign of an exact zero sum (or difference) shall be −0
if (fpu_operands.frm = "010") then -- round down (towards -infinity)
addsub.res_sign <= '1'; -- set the sign to 0 to generate a +0.0 result
else
addsub.res_sign <= '0'; -- set the sign to 0 to generate a +0.0 result
end if;
end if;
else -- different signs
addsub.res_sign <= fpu_operands.rs1(31);
end if;
end if;

-- exception flags --
addsub.flags(fp_exc_nv_c) <= ((fpu_operands.rs1_class(fp_class_pos_inf_c) or fpu_operands.rs1_class(fp_class_neg_inf_c)) and
(fpu_operands.rs2_class(fp_class_pos_inf_c) or fpu_operands.rs2_class(fp_class_neg_inf_c))); -- +/-inf +/- +/-inf
-- Infinities decoder ring
-- fadd:
-- Rs1 \ Rs2 | +inf | -inf | <- Rs2
-- --------------------------------
-- +inf | +inf | NV |
-- --------------------------------
-- -inf | NV | -inf |
-- --------------------------------
-- ^
-- |
-- Rs1
--
-- fsub:
-- Rs1 \ Rs2 | +inf | -inf | <- Rs2
-- --------------------------------
-- +inf | NV | +inf |
-- --------------------------------
-- -inf | -inf | NV |
-- --------------------------------
-- ^
-- |
-- Rs1
-- Assume the operation is valid
addsub.flags(fp_exc_nv_c) <= '0';
if (ctrl_i.ir_funct12(7) = '0') then -- add
-- Do we have 2 infinities of opposite sign?
if (((fpu_operands.rs1_class(fp_class_pos_inf_c) and fpu_operands.rs2_class(fp_class_neg_inf_c)) or
(fpu_operands.rs1_class(fp_class_neg_inf_c) and fpu_operands.rs2_class(fp_class_pos_inf_c))) = '1') then
addsub.flags(fp_exc_nv_c) <= '1';
end if;
else -- sub
-- Do we have 2 infinities of same sign?
if (((fpu_operands.rs1_class(fp_class_pos_inf_c) and fpu_operands.rs2_class(fp_class_pos_inf_c)) or
(fpu_operands.rs1_class(fp_class_neg_inf_c) and fpu_operands.rs2_class(fp_class_neg_inf_c))) = '1') then
addsub.flags(fp_exc_nv_c) <= '1';
end if;
end if;
end if;
end process adder_subtractor_core;

Expand Down Expand Up @@ -1497,6 +1552,9 @@ begin
sreg.upper(31 downto 02) <= (others => '0');
sreg.upper(01 downto 00) <= round.output(24 downto 23);
sreg.lower <= round.output(22 downto 00);
-- If after the first shift we get a bit in any of the guard bitsthen independent of rounding mode
-- the end result will be inexact as we are truncating away information
ctrl.flags(fp_exc_nx_c) <= sreg.ext_g or sreg.ext_r or sreg.ext_s;
sreg.ext_g <= '0';
sreg.ext_r <= '0';
sreg.ext_s <= '0';
Expand All @@ -1506,12 +1564,28 @@ begin
-- ------------------------------------------------------------
if (ctrl.cnt_uf = '1') then -- underflow
ctrl.flags(fp_exc_uf_c) <= '1';
-- As is defined in '754, under default exception handling, underflow is
-- only signalled when the result is tiny and inexact. In such a case,
-- both the underflow and inexact flags are raised.
ctrl.flags(fp_exc_nx_c) <= '1';
elsif (ctrl.cnt_of = '1') then -- overflow
ctrl.flags(fp_exc_of_c) <= '1';
-- As is defined in '754, under default exception handling, overflow is
-- only signalled when the result is large and inexact. In such a case,
-- both the underflow and inexact flags are raised.
ctrl.flags(fp_exc_nx_c) <= '1';
elsif (ctrl.cnt(7 downto 0) = x"00") then -- subnormal
ctrl.flags(fp_exc_uf_c) <= '1';
-- As is defined in '754, under default exception handling, underflow is
-- only signalled when the result is tiny and inexact. In such a case,
-- both the underflow and inexact flags are raised.
ctrl.flags(fp_exc_nx_c) <= '1';
elsif (ctrl.cnt(7 downto 0) = x"FF") then -- infinity
ctrl.flags(fp_exc_of_c) <= '1';
-- As is defined in '754, under default exception handling, overflow is
-- only signalled when the result is large and inexact. In such a case,
-- both the underflow and inexact flags are raised.
ctrl.flags(fp_exc_nx_c) <= '1';
end if;
ctrl.state <= S_FINALIZE;

Expand Down
6 changes: 3 additions & 3 deletions rtl/core/neorv32_package.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ package neorv32_package is

-- Architecture Constants -----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01090402"; -- hardware version
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01090403"; -- hardware version
constant archid_c : natural := 19; -- official RISC-V architecture ID
constant XLEN : natural := 32; -- native data path width

Expand Down Expand Up @@ -461,7 +461,7 @@ package neorv32_package is
constant csr_mhpmcounter15h_c : std_ulogic_vector(11 downto 0) := x"b8f";
-- user counters/timers --
constant csr_cycle_c : std_ulogic_vector(11 downto 0) := x"c00";
constant csr_time_c : std_ulogic_vector(11 downto 0) := x"c01";
--constant csr_time_c : std_ulogic_vector(11 downto 0) := x"c01";
constant csr_instret_c : std_ulogic_vector(11 downto 0) := x"c02";
constant csr_hpmcounter3_c : std_ulogic_vector(11 downto 0) := x"c03";
constant csr_hpmcounter4_c : std_ulogic_vector(11 downto 0) := x"c04";
Expand All @@ -478,7 +478,7 @@ package neorv32_package is
constant csr_hpmcounter15_c : std_ulogic_vector(11 downto 0) := x"c0f";
--
constant csr_cycleh_c : std_ulogic_vector(11 downto 0) := x"c80";
constant csr_timeh_c : std_ulogic_vector(11 downto 0) := x"c81";
--constant csr_timeh_c : std_ulogic_vector(11 downto 0) := x"c81";
constant csr_instreth_c : std_ulogic_vector(11 downto 0) := x"c82";
constant csr_hpmcounter3h_c : std_ulogic_vector(11 downto 0) := x"c83";
constant csr_hpmcounter4h_c : std_ulogic_vector(11 downto 0) := x"c84";
Expand Down

0 comments on commit 715715b

Please sign in to comment.