Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🧪 try to fix *_reduce_f functions usage for gate-level simulation #290

Merged
merged 4 commits into from
Mar 20, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ The version number is globally defined by the `hw_version_c` constant in the mai

| Date (*dd.mm.yyyy*) | Version | Comment |
|:----------:|:-------:|:--------|
| 19.03.2022 | 1.6.9.4 | :test_tube: change usage of VHDL `*_reduce_f` functions for signals that might effect gate-level simulations; [PR #290](https://github.com/stnolting/neorv32/pull/290) |
| 19.03.2022 | 1.6.9.3 | :bug: fixed minor bug in **FPU** - incorrect/missing reset (even if reset to `'-'`) of some registers |
| 18.03.2022 | 1.6.9.2 | fixed minor bug in **TRNG** hand shake (that marked the same RND value as valid for several times); minor optimization of **processor's reset generator** |
| 14.03.2022 | 1.6.9.1 | `mtval` CSR is set to zero for software breakpoints (`[c.]ebreak` instruction(s)) - this is permitted by the RISC-V machine ISA spec. v1.12; [PR #289](https://github.com/stnolting/neorv32/pull/289) |
Expand Down
6 changes: 3 additions & 3 deletions rtl/core/neorv32_cpu_bus.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -486,9 +486,9 @@ begin
end process pmp_check_permission;

-- final PMP access fault signals --
if_pmp_fault <= or_reduce_f(pmp.if_fault) when (PMP_NUM_REGIONS > 0) else '0';
ld_pmp_fault <= or_reduce_f(pmp.ld_fault) when (PMP_NUM_REGIONS > 0) else '0';
st_pmp_fault <= or_reduce_f(pmp.st_fault) when (PMP_NUM_REGIONS > 0) else '0';
if_pmp_fault <= '1' when (or_reduce_f(pmp.if_fault) = '1') and (PMP_NUM_REGIONS > 0) else '0';
ld_pmp_fault <= '1' when (or_reduce_f(pmp.ld_fault) = '1') and (PMP_NUM_REGIONS > 0) else '0';
st_pmp_fault <= '1' when (or_reduce_f(pmp.st_fault) = '1') and (PMP_NUM_REGIONS > 0) else '0';


end neorv32_cpu_bus_rtl;
23 changes: 18 additions & 5 deletions rtl/core/neorv32_cpu_control.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -902,8 +902,16 @@ begin
end if;

-- register/uimm5 checks --
decode_aux.rs1_zero <= not or_reduce_f(execute_engine.i_reg(instr_rs1_msb_c downto instr_rs1_lsb_c));
decode_aux.rd_zero <= not or_reduce_f(execute_engine.i_reg(instr_rd_msb_c downto instr_rd_lsb_c));
if (execute_engine.i_reg(instr_rs1_msb_c downto instr_rs1_lsb_c) = "00000") then
decode_aux.rs1_zero <= '1';
else
decode_aux.rs1_zero <= '0';
end if;
if (execute_engine.i_reg(instr_rd_msb_c downto instr_rd_lsb_c) = "00000") then
decode_aux.rd_zero <= '1';
else
decode_aux.rd_zero <= '0';
end if;
end process decode_helper;


Expand Down Expand Up @@ -1667,8 +1675,9 @@ begin
end process trap_controller;

-- any exception/interrupt? --
trap_ctrl.exc_fire <= or_reduce_f(trap_ctrl.exc_buf); -- sync. exceptions CANNOT be masked
trap_ctrl.irq_fire <= (or_reduce_f(trap_ctrl.irq_buf) and csr.mstatus_mie and trap_ctrl.db_irq_en) or trap_ctrl.db_irq_fire; -- interrupts CAN be masked (but not the DEBUG halt IRQ)
trap_ctrl.exc_fire <= '1' when (or_reduce_f(trap_ctrl.exc_buf) = '1') else '0'; -- sync. exceptions CANNOT be masked
trap_ctrl.irq_fire <= '1' when ((or_reduce_f(trap_ctrl.irq_buf) = '1') and (csr.mstatus_mie = '1') and (trap_ctrl.db_irq_en = '1')) or -- interrupts CAN be masked
(trap_ctrl.db_irq_fire = '1') else '0'; -- but not the DEBUG halt IRQ

-- debug mode (entry) interrupts --
trap_ctrl.db_irq_en <= '0' when (CPU_EXTENSION_RISCV_DEBUG = true) and ((debug_ctrl.running = '1') or (csr.dcsr_step = '1')) else '1'; -- no interrupts when IN debug mode or IN single-step mode
Expand Down Expand Up @@ -2659,7 +2668,11 @@ begin
if (HPM_NUM_CNTS /= 0) then
for i in 0 to HPM_NUM_CNTS-1 loop
-- do not increment if CPU is in debug mode --
hpmcnt_trigger(i) <= or_reduce_f(cnt_event and csr.mhpmevent(i)(cnt_event'left downto 0)) and (not debug_ctrl.running);
if (or_reduce_f(cnt_event and csr.mhpmevent(i)(cnt_event'left downto 0)) = '1') and (debug_ctrl.running = '0') then
hpmcnt_trigger(i) <= '1';
else
hpmcnt_trigger(i) <= '0';
end if;
end loop; -- i
end if;
end if;
Expand Down
4 changes: 2 additions & 2 deletions rtl/core/neorv32_cpu_cp_bitmanip.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -470,7 +470,7 @@ begin
clmul.rs2 <= bit_rev_f(rs2_reg) when (cmd_buf(op_clmulr_c) = '1') else rs2_reg;

-- multiplier busy? --
clmul.busy <= or_reduce_f(clmul.cnt);
clmul.busy <= '1' when (or_reduce_f(clmul.cnt) = '1') else '0';


-- Operation Results ----------------------------------------------------------------------
Expand Down Expand Up @@ -522,7 +522,7 @@ begin
-- single-bit instructions --
res_int(op_bclr_c) <= rs1_reg and (not one_hot_core);
res_int(op_bext_c)(data_width_c-1 downto 1) <= (others => '0');
res_int(op_bext_c)(0) <= or_reduce_f(rs1_reg and one_hot_core);
res_int(op_bext_c)(0) <= '1' when (or_reduce_f(rs1_reg and one_hot_core) = '1') else '0';
res_int(op_binv_c) <= rs1_reg xor one_hot_core;
res_int(op_bset_c) <= rs1_reg or one_hot_core;

Expand Down
29 changes: 22 additions & 7 deletions rtl/core/neorv32_cpu_cp_fpu.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -312,9 +312,18 @@ begin
begin
for i in 0 to 1 loop -- for rs1 and rs2 inputs
-- check for all-zero/all-one --
op_m_all_zero_v := not or_reduce_f(op_data(i)(22 downto 00));
op_e_all_zero_v := not or_reduce_f(op_data(i)(30 downto 23));
op_e_all_one_v := and_reduce_f(op_data(i)(30 downto 23));
op_m_all_zero_v := '0';
op_e_all_zero_v := '0';
op_e_all_one_v := '0';
if (or_reduce_f(op_data(i)(22 downto 00)) = '0') then
op_m_all_zero_v := '1';
end if;
if (or_reduce_f(op_data(i)(30 downto 23)) = '0') then
op_e_all_zero_v := '1';
end if;
if (and_reduce_f(op_data(i)(30 downto 23)) = '1') then
op_e_all_one_v := '1';
end if;

-- check special cases --
op_is_zero_v := op_e_all_zero_v and op_m_all_zero_v; -- zero
Expand Down Expand Up @@ -1351,7 +1360,11 @@ begin
sreg.lower <= mantissa_i(45 downto 23);
sreg.ext_g <= mantissa_i(22);
sreg.ext_r <= mantissa_i(21);
sreg.ext_s <= or_reduce_f(mantissa_i(20 downto 0));
if (or_reduce_f(mantissa_i(20 downto 0)) = '1') then
sreg.ext_s <= '1';
else
sreg.ext_s <= '0';
end if;
-- check for special cases --
if ((ctrl.class(fp_class_snan_c) or ctrl.class(fp_class_qnan_c) or -- NaN
ctrl.class(fp_class_neg_zero_c) or ctrl.class(fp_class_pos_zero_c) or -- zero
Expand Down Expand Up @@ -1466,10 +1479,10 @@ begin
end process ctrl_engine;

-- stop shifting when normalized --
sreg.done <= (not or_reduce_f(sreg.upper(sreg.upper'left downto 1))) and sreg.upper(0); -- input is zero, hidden one is set
sreg.done <= '1' when (or_reduce_f(sreg.upper(sreg.upper'left downto 1)) = '0') and (sreg.upper(0) = '1') else '0'; -- input is zero, hidden one is set

-- all-zero including hidden bit --
sreg.zero <= not or_reduce_f(sreg.upper);
sreg.zero <= '1' when (or_reduce_f(sreg.upper) = '0') else '0';

-- result --
result_o(31) <= ctrl.res_sgn;
Expand Down Expand Up @@ -1708,7 +1721,9 @@ begin

when S_NORMALIZE_BUSY => -- running normalization cycle
-- ------------------------------------------------------------
sreg.ext_s <= sreg.ext_s or or_reduce_f(sreg.mant(sreg.mant'left-2 downto 0)); -- sticky bit
if (or_reduce_f(sreg.mant(sreg.mant'left-2 downto 0)) = '1') then
sreg.ext_s <= '1'; -- sticky bit
end if;
if (or_reduce_f(ctrl.cnt(ctrl.cnt'left-1 downto 0)) = '0') then
if (ctrl.unsign = '0') then -- signed conversion
ctrl.over <= ctrl.over or sreg.int(sreg.int'left); -- update overrun flag again to check for numerical overflow into sign bit
Expand Down
6 changes: 5 additions & 1 deletion rtl/core/neorv32_cpu_cp_muldiv.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ architecture neorv32_cpu_cp_muldiv_rtl of neorv32_cpu_cp_muldiv is
signal rs2_is_signed : std_ulogic;
signal div_res_corr : std_ulogic;
signal out_en : std_ulogic;
signal rs2_zero : std_ulogic;

-- divider core --
signal remainder : std_ulogic_vector(data_width_c-1 downto 0);
Expand Down Expand Up @@ -152,7 +153,7 @@ begin
when DIV_PREPROCESS =>
-- check relevant input signs for result sign compensation --
if (cp_op = cp_op_div_c) then -- signed div operation
div_res_corr <= (rs1_i(rs1_i'left) xor rs2_i(rs2_i'left)) and or_reduce_f(rs2_i); -- different signs AND rs2 not zero
div_res_corr <= (rs1_i(rs1_i'left) xor rs2_i(rs2_i'left)) and (not rs2_zero); -- different signs AND rs2 not zero
elsif (cp_op = cp_op_rem_c) then -- signed rem operation
div_res_corr <= rs1_i(rs1_i'left);
else
Expand Down Expand Up @@ -183,6 +184,9 @@ begin
end if;
end process coprocessor_ctrl;

-- rs2 zero? --
rs2_zero <= '1' when (or_reduce_f(rs2_i) = '0') else '0';

-- co-processor command --
cp_op <= ctrl_i(ctrl_ir_funct3_2_c downto ctrl_ir_funct3_0_c);

Expand Down
2 changes: 1 addition & 1 deletion rtl/core/neorv32_cpu_cp_shifter.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ begin
-- shift control/output --
serial_shifter_ctrl:
if (FAST_SHIFT_EN = false) generate
shifter.done <= not or_reduce_f(shifter.cnt(shifter.cnt'left downto 1));
shifter.done <= '1' when (or_reduce_f(shifter.cnt(shifter.cnt'left downto 1)) = '0') else '0';
valid_o <= shifter.busy and shifter.done;
res_o <= shifter.sreg when (shifter.busy = '0') and (shifter.busy_ff = '1') else (others => '0');
end generate;
Expand Down
4 changes: 2 additions & 2 deletions rtl/core/neorv32_cpu_regfile.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ begin
end process rf_access;

-- writing to x0? --
rd_is_x0 <= not or_reduce_f(ctrl_i(ctrl_rf_rd_adr4_c downto ctrl_rf_rd_adr0_c));
rd_is_x0 <= '1' when (ctrl_i(ctrl_rf_rd_adr4_c downto ctrl_rf_rd_adr0_c) = "00000") else '0';
end generate;

reg_file_rv32e: -- embedded register file with 16 registers
Expand All @@ -133,7 +133,7 @@ begin
end process rf_access;

-- writing to x0? --
rd_is_x0 <= not or_reduce_f(ctrl_i(ctrl_rf_rd_adr3_c downto ctrl_rf_rd_adr0_c));
rd_is_x0 <= '1' when (ctrl_i(ctrl_rf_rd_adr3_c downto ctrl_rf_rd_adr0_c) = "0000") else '0';
end generate;

-- access addresses --
Expand Down
2 changes: 1 addition & 1 deletion rtl/core/neorv32_icache.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -545,7 +545,7 @@ begin
end process comparator;

-- global hit --
hit_o <= or_reduce_f(hit);
hit_o <= '1' when (or_reduce_f(hit) = '1') else '0';


-- Cache Data Memory ----------------------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion rtl/core/neorv32_package.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ package neorv32_package is
-- Architecture Constants (do not modify!) ------------------------------------------------
-- -------------------------------------------------------------------------------------------
constant data_width_c : natural := 32; -- native data path width - do not change!
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01060903"; -- no touchy!
constant hw_version_c : std_ulogic_vector(31 downto 0) := x"01060904"; -- no touchy!
constant archid_c : natural := 19; -- official NEORV32 architecture ID - hands off!

-- Check if we're inside the Matrix -------------------------------------------------------
Expand Down
22 changes: 16 additions & 6 deletions rtl/core/neorv32_slink.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. #
-- # Copyright (c) 2022, Stephan Nolting. All rights reserved. #
-- # #
-- # Redistribution and use in source and binary forms, with or without modification, are #
-- # permitted provided that the following conditions are met: #
Expand Down Expand Up @@ -208,7 +208,9 @@ begin
end if;
ack_write <= '1';
else -- TX links
ack_write <= or_reduce_f(link_sel and tx_fifo_free);
if (or_reduce_f(link_sel and tx_fifo_free) = '1') then
ack_write <= '1';
end if;
end if;
end if;

Expand Down Expand Up @@ -243,8 +245,10 @@ begin
data_o <= (others => '0');
end case;
else -- RX links
data_o <= rx_fifo_rdata(to_integer(unsigned(addr(4 downto 2))));
ack_read <= or_reduce_f(link_sel and rx_fifo_avail);
data_o <= rx_fifo_rdata(to_integer(unsigned(addr(4 downto 2))));
if (or_reduce_f(link_sel and rx_fifo_avail) = '1') then
ack_read <= '1';
end if;
end if;
end if;
end if;
Expand Down Expand Up @@ -328,8 +332,14 @@ begin
irq_generator: process(clk_i)
begin
if rising_edge(clk_i) then
irq_rx_o <= or_reduce_f(rx_irq.set);
irq_tx_o <= or_reduce_f(tx_irq.set);
irq_rx_o <= '0';
irq_tx_o <= '0';
if (or_reduce_f(rx_irq.set) = '1') then
irq_rx_o <= '1';
end if;
if (or_reduce_f(tx_irq.set) = '1') then
irq_tx_o <= '1';
end if;
end if;
end process irq_generator;

Expand Down
24 changes: 16 additions & 8 deletions rtl/core/neorv32_top.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,11 @@ begin
-- keep internal reset active for at least <ext_rstn_sync'size> clock cycles --
ext_rstn_sync <= ext_rstn_sync(ext_rstn_sync'left-1 downto 0) & '1';
-- beautified external reset signal --
ext_rstn <= and_reduce_f(ext_rstn_sync);
if (and_reduce_f(ext_rstn_sync) = '1') then
ext_rstn <= '1';
else
ext_rstn <= '0';
end if;
-- system reset: can also be triggered by watchdog and debug module --
sys_rstn <= ext_rstn and wdt_rstn and dci_ndmrstn;
end if;
Expand All @@ -436,15 +440,19 @@ begin
clock_generator: process(sys_rstn, clk_i)
begin
if (sys_rstn = '0') then
clk_gen_en_ff <= '-';
clk_div_ff <= (others => '-');
clk_gen_en_ff <= '0'; -- reset required
clk_div <= (others => '0'); -- reset required
clk_div_ff <= (others => '-');
elsif rising_edge(clk_i) then
clk_gen_en_ff <= or_reduce_f(clk_gen_en);
clk_div_ff <= clk_div;
if (clk_gen_en_ff = '1') then -- actual clock generator
if (or_reduce_f(clk_gen_en) = '0') then
clk_gen_en_ff <= '0';
else
clk_gen_en_ff <= '1';
end if;
if (clk_gen_en_ff = '1') then
clk_div <= std_ulogic_vector(unsigned(clk_div) + 1);
end if;
clk_div_ff <= clk_div;
end if;
end process clock_generator;

Expand Down Expand Up @@ -944,8 +952,8 @@ begin
-- IO Access? -----------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
io_acc <= '1' when (p_bus.addr(data_width_c-1 downto index_size_f(io_size_c)) = io_base_c(data_width_c-1 downto index_size_f(io_size_c))) else '0';
io_rden <= io_acc and p_bus.re;
io_wren <= io_acc and p_bus.we and and_reduce_f(p_bus.ben); -- only full-word write accesses are allowed (reduces HW complexity)
io_rden <= '1' when (io_acc = '1') and (p_bus.re = '1') else '0';
io_wren <= '1' when (io_acc = '1') and (p_bus.we = '1') and (p_bus.ben = "1111") else '0'; -- only full-word write accesses are allowed (reduces HW complexity)


-- Custom Functions Subsystem (CFS) -------------------------------------------------------
Expand Down
4 changes: 2 additions & 2 deletions rtl/core/neorv32_xirq.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
-- # ********************************************************************************************* #
-- # BSD 3-Clause License #
-- # #
-- # Copyright (c) 2021, Stephan Nolting. All rights reserved. #
-- # Copyright (c) 2022, Stephan Nolting. All rights reserved. #
-- # #
-- # Redistribution and use in source and binary forms, with or without modification, are #
-- # permitted provided that the following conditions are met: #
Expand Down Expand Up @@ -186,7 +186,7 @@ begin
end process irq_buffer;

-- anyone firing? --
irq_fire <= or_reduce_f(irq_buf);
irq_fire <= '1' when (or_reduce_f(irq_buf) = '1') else '0';


-- IRQ Priority Encoder -----------------------------------------------------
Expand Down