Skip to content

Commit

Permalink
[cpu] add hardware reset for all FFs
Browse files Browse the repository at this point in the history
  • Loading branch information
stnolting committed Nov 10, 2023
1 parent aff0493 commit 6b0018d
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 45 deletions.
26 changes: 18 additions & 8 deletions rtl/core/neorv32_cpu_control.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -502,9 +502,11 @@ begin
issue_engine_enabled:
if (CPU_EXTENSION_RISCV_C = true) generate

issue_engine_fsm_sync: process(clk_i)
issue_engine_fsm_sync: process(rstn_i, clk_i)
begin
if rising_edge(clk_i) then
if (rstn_i = '0') then
issue_engine.align <= '0'; -- start aligned after reset
elsif rising_edge(clk_i) then
if (fetch_engine.restart = '1') then
issue_engine.align <= execute_engine.pc(1); -- branch to unaligned address?
elsif (issue_engine.ack = '1') then
Expand Down Expand Up @@ -561,9 +563,11 @@ begin

-- Immediate Generator --------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
imm_gen: process(clk_i)
imm_gen: process(rstn_i, clk_i)
begin
if rising_edge(clk_i) then
if (rstn_i = '0') then
imm_o <= (others => '0');
elsif rising_edge(clk_i) then
-- default = I-immediate: ALU-immediate, load, jump-and-link with register --
imm_o(XLEN-1 downto 11) <= (others => execute_engine.ir(31)); -- sign extension
imm_o(10 downto 01) <= execute_engine.ir(30 downto 21);
Expand Down Expand Up @@ -1460,9 +1464,11 @@ begin

-- Trap Priority Logic --------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
trap_priority: process(clk_i)
trap_priority: process(rstn_i, clk_i)
begin
if rising_edge(clk_i) then
if (rstn_i = '0') then
trap_ctrl.cause <= (others => '0');
elsif rising_edge(clk_i) then
-- standard RISC-V exceptions --
if (trap_ctrl.exc_buf(exc_ialign_c) = '1') then trap_ctrl.cause <= trap_ima_c; -- instruction address misaligned
elsif (trap_ctrl.exc_buf(exc_iaccess_c) = '1') then trap_ctrl.cause <= trap_iaf_c; -- instruction access fault
Expand All @@ -1473,6 +1479,8 @@ begin
elsif (trap_ctrl.exc_buf(exc_lalign_c) = '1') then trap_ctrl.cause <= trap_lma_c; -- load address misaligned
elsif (trap_ctrl.exc_buf(exc_saccess_c) = '1') then trap_ctrl.cause <= trap_saf_c; -- store access fault
elsif (trap_ctrl.exc_buf(exc_laccess_c) = '1') then trap_ctrl.cause <= trap_laf_c; -- load access fault


-- standard RISC-V debug mode exceptions and interrupts --
elsif (trap_ctrl.irq_buf(irq_db_halt_c) = '1') then trap_ctrl.cause <= trap_db_halt_c; -- external halt request (async)
elsif (trap_ctrl.exc_buf(exc_db_hw_c) = '1') then trap_ctrl.cause <= trap_db_trig_c; -- hardware trigger (sync)
Expand Down Expand Up @@ -2243,9 +2251,11 @@ begin

-- Counter Increment Control (Trigger Events) ---------------------------------------------
-- -------------------------------------------------------------------------------------------
counter_event: process(clk_i)
counter_event: process(rstn_i, clk_i)
begin -- increment if an enabled event fires; do not increment if CPU is in debug mode or if counter is inhibited
if rising_edge(clk_i) then
if (rstn_i = '0') then
cnt.inc <= (others => '0');
elsif rising_edge(clk_i) then
cnt.inc <= (others => '0'); -- default
-- base counters --
cnt.inc(0) <= cnt_event(hpmcnt_event_cy_c) and (not csr.mcountinhibit(0)) and (not debug_ctrl.running);
Expand Down
22 changes: 16 additions & 6 deletions rtl/core/neorv32_cpu_cp_bitmanip.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -305,9 +305,14 @@ begin
serial_shifter:
if (FAST_SHIFT_EN = false) generate

shifter_unit: process(clk_i)
shifter_unit: process(rstn_i, clk_i)
begin
if rising_edge(clk_i) then
if (rstn_i = '0') then
shifter.cnt <= (others => '0');
shifter.sreg <= (others => '0');
shifter.cnt_max <= (others => '0');
shifter.bcnt <= (others => '0');
elsif rising_edge(clk_i) then
if (shifter.start = '1') then -- trigger new shift
shifter.cnt <= (others => '0');
-- shift operand --
Expand Down Expand Up @@ -420,9 +425,12 @@ begin

-- Carry-Less Multiplication Core ---------------------------------------------------------
-- -------------------------------------------------------------------------------------------
clmul_core: process(clk_i)
clmul_core: process(rstn_i, clk_i)
begin
if rising_edge(clk_i) then
if (rstn_i = '0') then
clmul.cnt <= (others => '0');
clmul.prod <= (others => '0');
elsif rising_edge(clk_i) then
if (clmul.start = '1') then -- start new multiplication
clmul.cnt <= (others => '0');
clmul.cnt(clmul.cnt'left) <= '1';
Expand Down Expand Up @@ -544,9 +552,11 @@ begin

-- Output Gate ----------------------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
output_gate: process(clk_i)
output_gate: process(rstn_i, clk_i)
begin
if rising_edge(clk_i) then
if (rstn_i = '0') then
res_o <= (others => '0');
elsif rising_edge(clk_i) then
res_o <= (others => '0'); -- default
if (valid = '1') then
res_o <= res_out(op_andn_c) or res_out(op_orn_c) or res_out(op_xnor_c) or
Expand Down
10 changes: 8 additions & 2 deletions rtl/core/neorv32_cpu_cp_cfu.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -320,9 +320,15 @@ begin
madd.done <= madd.sreg(madd.sreg'left);

-- arithmetic core --
madd_core: process(clk_i)
madd_core: process(rstn_i, clk_i)
begin
if rising_edge(clk_i) then
if (rstn_i = '0') then
madd.opa <= (others => '0');
madd.opb <= (others => '0');
madd.opc <= (others => '0');
madd.mul <= (others => '0');
madd.res <= (others => '0');
elsif rising_edge(clk_i) then
-- stage 0: buffer input operands --
madd.opa <= rs1_i;
madd.opb <= rs2_i;
Expand Down
78 changes: 57 additions & 21 deletions rtl/core/neorv32_cpu_cp_fpu.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -495,10 +495,15 @@ begin

-- Floating-Point Comparator --------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
float_comparator: process(clk_i)
float_comparator: process(rstn_i, clk_i)
variable cond_v : std_ulogic_vector(1 downto 0);
begin
if rising_edge(clk_i) then
if (rstn_i = '0') then
comp_equal_ff <= '0';
comp_less_ff <= '0';
fu_compare.done <= '0';
fu_min_max.done <= '0';
elsif rising_edge(clk_i) then
-- equal --
if ((fpu_operands.rs1_class(fp_class_pos_inf_c) = '1') and (fpu_operands.rs2_class(fp_class_pos_inf_c) = '1')) or -- +inf == +inf
((fpu_operands.rs1_class(fp_class_neg_inf_c) = '1') and (fpu_operands.rs2_class(fp_class_neg_inf_c) = '1')) or -- -inf == -inf
Expand Down Expand Up @@ -643,11 +648,15 @@ begin

-- Convert: [unsigned] Integer to Float (FCVT.W.S) ----------------------------------------
-- -------------------------------------------------------------------------------------------
convert_i2f: process(clk_i)
convert_i2f: process(rstn_i, clk_i)
begin
-- this process only computes the absolute input value
-- the actual conversion is done by the normalizer
if rising_edge(clk_i) then
if (rstn_i = '0') then
fu_conv_i2f.result <= (others => '0');
fu_conv_i2f.sign <= '0';
fu_conv_i2f.done <= '0';
elsif rising_edge(clk_i) then
if (ctrl_i.ir_funct12(0) = '0') and (rs1_i(31) = '1') then -- convert signed integer
fu_conv_i2f.result <= std_ulogic_vector(0 - unsigned(rs1_i));
fu_conv_i2f.sign <= rs1_i(31); -- original sign
Expand All @@ -662,9 +671,18 @@ begin

-- Multiplier Core (FMUL) -----------------------------------------------------------------
-- -------------------------------------------------------------------------------------------
multiplier_core: process(clk_i)
multiplier_core: process(rstn_i, clk_i)
begin
if rising_edge(clk_i) then
if (rstn_i = '0') then
multiplier.opa <= (others => '0');
multiplier.opb <= (others => '0');
multiplier.buf_ff <= (others => '0');
multiplier.product <= (others => '0');
multiplier.sign <= '0';
multiplier.exp_res <= (others => '0');
multiplier.flags <= (others => '0');
multiplier.latency <= (others => '0');
elsif rising_edge(clk_i) then
-- multiplier core --
if (multiplier.start = '1') then -- FIXME / TODO remove buffer?
multiplier.opa <= unsigned('1' & fpu_operands.rs1(22 downto 0)); -- append hidden one
Expand Down Expand Up @@ -694,6 +712,10 @@ begin
((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_zero_c) or fpu_operands.rs2_class(fp_class_neg_zero_c))); -- mul(+/-inf, +/-zero)

-- unused exception flags --
multiplier.flags(fp_exc_dz_c) <= '0'; -- division by zero: not possible here
multiplier.flags(fp_exc_nx_c) <= '0'; -- inexcat: not possible here

-- latency shift register --
multiplier.latency <= multiplier.latency(multiplier.latency'left-1 downto 0) & multiplier.start;
end if;
Expand All @@ -707,20 +729,18 @@ begin
multiplier.done <= multiplier.latency(multiplier.latency'left);
fu_mul.done <= multiplier.done;

-- unused exception flags --
multiplier.flags(fp_exc_dz_c) <= '0'; -- division by zero: not possible here
multiplier.flags(fp_exc_nx_c) <= '0'; -- inexcat: not possible here


-- result class --
multiplier_class_core: process(clk_i)
multiplier_class_core: process(rstn_i, clk_i)
variable a_pos_norm_v, a_neg_norm_v, b_pos_norm_v, b_neg_norm_v : std_ulogic;
variable a_pos_subn_v, a_neg_subn_v, b_pos_subn_v, b_neg_subn_v : std_ulogic;
variable a_pos_zero_v, a_neg_zero_v, b_pos_zero_v, b_neg_zero_v : std_ulogic;
variable a_pos_inf_v, a_neg_inf_v, b_pos_inf_v, b_neg_inf_v : std_ulogic;
variable a_snan_v, a_qnan_v, b_snan_v, b_qnan_v : std_ulogic;
begin
if rising_edge(clk_i) then
if (rstn_i = '0') then
multiplier.res_class <= (others => '0');
elsif rising_edge(clk_i) then
-- minions --
a_pos_norm_v := fpu_operands.rs1_class(fp_class_pos_norm_c); b_pos_norm_v := fpu_operands.rs2_class(fp_class_pos_norm_c);
a_neg_norm_v := fpu_operands.rs1_class(fp_class_neg_norm_c); b_neg_norm_v := fpu_operands.rs2_class(fp_class_neg_norm_c);
Expand Down Expand Up @@ -813,9 +833,21 @@ begin

-- Adder/Subtractor Core (FADD, FSUB) -----------------------------------------------------
-- -------------------------------------------------------------------------------------------
adder_subtractor_core: process(clk_i)
adder_subtractor_core: process(rstn_i, clk_i)
begin
if rising_edge(clk_i) then
if (rstn_i = '0') then
addsub.latency <= (others => '0');
addsub.exp_comp <= (others => '0');
addsub.man_sreg <= (others => '0');
addsub.exp_cnt <= (others => '0');
addsub.man_g_ext <= '0';
addsub.man_r_ext <= '0';
addsub.man_s_ext <= '0';
addsub.man_comp <= '0';
addsub.add_stage <= (others => '0');
addsub.res_sign <= '0';
addsub.flags(fp_exc_nv_c) <= '0';
elsif rising_edge(clk_i) then
-- arbitration / latency --
if (ctrl_engine.state = S_IDLE) then -- hacky "reset"
addsub.latency <= (others => '0');
Expand Down Expand Up @@ -948,14 +980,16 @@ begin


-- result class --
adder_subtractor_class_core: process(clk_i)
adder_subtractor_class_core: process(rstn_i, clk_i)
variable a_pos_norm_v, a_neg_norm_v, b_pos_norm_v, b_neg_norm_v : std_ulogic;
variable a_pos_subn_v, a_neg_subn_v, b_pos_subn_v, b_neg_subn_v : std_ulogic;
variable a_pos_zero_v, a_neg_zero_v, b_pos_zero_v, b_neg_zero_v : std_ulogic;
variable a_pos_inf_v, a_neg_inf_v, b_pos_inf_v, b_neg_inf_v : std_ulogic;
variable a_snan_v, a_qnan_v, b_snan_v, b_qnan_v : std_ulogic;
begin
if rising_edge(clk_i) then
if (rstn_i = '0') then
addsub.res_class <= (others => '0');
elsif rising_edge(clk_i) then
-- minions --
a_pos_norm_v := fpu_operands.rs1_class(fp_class_pos_norm_c); b_pos_norm_v := fpu_operands.rs2_class(fp_class_pos_norm_c);
a_neg_norm_v := fpu_operands.rs1_class(fp_class_neg_norm_c); b_neg_norm_v := fpu_operands.rs2_class(fp_class_neg_norm_c);
Expand Down Expand Up @@ -1163,9 +1197,14 @@ begin

-- Output Result to CPU Pipeline ----------------------------------------------------------
-- -------------------------------------------------------------------------------------------
output_gate: process(clk_i)
output_gate: process(rstn_i, clk_i)
begin
if rising_edge(clk_i) then
if (rstn_i = '0') then
res_o <= (others => '0');
fflags <= (others => '0');
elsif rising_edge(clk_i) then
res_o <= (others => '0');
fflags <= (others => '0');
if (ctrl_engine.valid = '1') then
case funct_ff is
when op_class_c =>
Expand All @@ -1187,9 +1226,6 @@ begin
res_o <= normalizer.result;
fflags <= normalizer.flags_out;
end case;
else
res_o <= (others => '0');
fflags <= (others => '0');
end if;
end if;
end process output_gate;
Expand Down
21 changes: 15 additions & 6 deletions rtl/core/neorv32_cpu_cp_muldiv.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -194,9 +194,13 @@ begin
if (FAST_MUL_EN = true) generate

-- direct approach --
multiplier_core: process(clk_i)
multiplier_core: process(rstn_i, clk_i)
begin
if rising_edge(clk_i) then
if (rstn_i = '0') then
mul.dsp_x <= (others => '0');
mul.dsp_y <= (others => '0');
mul.prod <= (others => '0');
elsif rising_edge(clk_i) then
if (mul.start = '1') then
mul.dsp_x <= signed((rs1_i(rs1_i'left) and ctrl.rs1_is_signed) & rs1_i);
mul.dsp_y <= signed((rs2_i(rs2_i'left) and ctrl.rs2_is_signed) & rs2_i);
Expand Down Expand Up @@ -225,9 +229,11 @@ begin
if (FAST_MUL_EN = false) generate

-- shift-and-add algorithm --
multiplier_core: process(clk_i)
multiplier_core: process(rstn_i, clk_i)
begin
if rising_edge(clk_i) then
if (rstn_i = '0') then
mul.prod <= (others => '0');
elsif rising_edge(clk_i) then
if (mul.start = '1') then -- start new multiplication
mul.prod(63 downto 32) <= (others => '0');
mul.prod(31 downto 00) <= rs1_i;
Expand Down Expand Up @@ -271,9 +277,12 @@ begin
if (DIVISION_EN = true) generate

-- restoring division algorithm --
divider_core: process(clk_i)
divider_core: process(rstn_i, clk_i)
begin
if rising_edge(clk_i) then
if (rstn_i = '0') then
div.quotient <= (others => '0');
div.remainder <= (others => '0');
elsif rising_edge(clk_i) then
if (div.start = '1') then -- start new division
if ((rs1_i(rs1_i'left) and ctrl.rs1_is_signed) = '1') then -- signed division?
div.quotient <= std_ulogic_vector(0 - unsigned(rs1_i)); -- make positive
Expand Down
7 changes: 5 additions & 2 deletions rtl/core/neorv32_cpu_cp_shifter.vhd
Original file line number Diff line number Diff line change
Expand Up @@ -150,9 +150,12 @@ begin
end process barrel_shifter_core;

-- pipeline register --
barrel_shifter_buf: process(clk_i)
barrel_shifter_buf: process(rstn_i, clk_i)
begin
if rising_edge(clk_i) then
if (rstn_i = '0') then
bs_start <= '0';
bs_result <= (others => '0');
elsif rising_edge(clk_i) then
bs_start <= start_i;
bs_result <= bs_level(0); -- this register can be moved by the register balancing
end if;
Expand Down

0 comments on commit 6b0018d

Please sign in to comment.