[cpu] add hardware reset for all FFs

This commit is contained in:
stnolting 2023-11-10 10:38:04 +01:00
parent aff0493d4d
commit 6b0018d01d
6 changed files with 119 additions and 45 deletions

View file

@ -502,9 +502,11 @@ begin
issue_engine_enabled: issue_engine_enabled:
if (CPU_EXTENSION_RISCV_C = true) generate if (CPU_EXTENSION_RISCV_C = true) generate
issue_engine_fsm_sync: process(clk_i) issue_engine_fsm_sync: process(rstn_i, clk_i)
begin 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 if (fetch_engine.restart = '1') then
issue_engine.align <= execute_engine.pc(1); -- branch to unaligned address? issue_engine.align <= execute_engine.pc(1); -- branch to unaligned address?
elsif (issue_engine.ack = '1') then elsif (issue_engine.ack = '1') then
@ -561,9 +563,11 @@ begin
-- Immediate Generator -------------------------------------------------------------------- -- Immediate Generator --------------------------------------------------------------------
-- ------------------------------------------------------------------------------------------- -- -------------------------------------------------------------------------------------------
imm_gen: process(clk_i) imm_gen: process(rstn_i, clk_i)
begin 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 -- -- 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(XLEN-1 downto 11) <= (others => execute_engine.ir(31)); -- sign extension
imm_o(10 downto 01) <= execute_engine.ir(30 downto 21); imm_o(10 downto 01) <= execute_engine.ir(30 downto 21);
@ -1460,9 +1464,11 @@ begin
-- Trap Priority Logic -------------------------------------------------------------------- -- Trap Priority Logic --------------------------------------------------------------------
-- ------------------------------------------------------------------------------------------- -- -------------------------------------------------------------------------------------------
trap_priority: process(clk_i) trap_priority: process(rstn_i, clk_i)
begin 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 -- -- standard RISC-V exceptions --
if (trap_ctrl.exc_buf(exc_ialign_c) = '1') then trap_ctrl.cause <= trap_ima_c; -- instruction address misaligned 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 elsif (trap_ctrl.exc_buf(exc_iaccess_c) = '1') then trap_ctrl.cause <= trap_iaf_c; -- instruction access fault
@ -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_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_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 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 -- -- 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.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) elsif (trap_ctrl.exc_buf(exc_db_hw_c) = '1') then trap_ctrl.cause <= trap_db_trig_c; -- hardware trigger (sync)
@ -2243,9 +2251,11 @@ begin
-- Counter Increment Control (Trigger Events) --------------------------------------------- -- 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 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 cnt.inc <= (others => '0'); -- default
-- base counters -- -- base counters --
cnt.inc(0) <= cnt_event(hpmcnt_event_cy_c) and (not csr.mcountinhibit(0)) and (not debug_ctrl.running); cnt.inc(0) <= cnt_event(hpmcnt_event_cy_c) and (not csr.mcountinhibit(0)) and (not debug_ctrl.running);

View file

@ -305,9 +305,14 @@ begin
serial_shifter: serial_shifter:
if (FAST_SHIFT_EN = false) generate if (FAST_SHIFT_EN = false) generate
shifter_unit: process(clk_i) shifter_unit: process(rstn_i, clk_i)
begin 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 if (shifter.start = '1') then -- trigger new shift
shifter.cnt <= (others => '0'); shifter.cnt <= (others => '0');
-- shift operand -- -- shift operand --
@ -420,9 +425,12 @@ begin
-- Carry-Less Multiplication Core --------------------------------------------------------- -- Carry-Less Multiplication Core ---------------------------------------------------------
-- ------------------------------------------------------------------------------------------- -- -------------------------------------------------------------------------------------------
clmul_core: process(clk_i) clmul_core: process(rstn_i, clk_i)
begin 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 if (clmul.start = '1') then -- start new multiplication
clmul.cnt <= (others => '0'); clmul.cnt <= (others => '0');
clmul.cnt(clmul.cnt'left) <= '1'; clmul.cnt(clmul.cnt'left) <= '1';
@ -544,9 +552,11 @@ begin
-- Output Gate ---------------------------------------------------------------------------- -- Output Gate ----------------------------------------------------------------------------
-- ------------------------------------------------------------------------------------------- -- -------------------------------------------------------------------------------------------
output_gate: process(clk_i) output_gate: process(rstn_i, clk_i)
begin 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 res_o <= (others => '0'); -- default
if (valid = '1') then if (valid = '1') then
res_o <= res_out(op_andn_c) or res_out(op_orn_c) or res_out(op_xnor_c) or res_o <= res_out(op_andn_c) or res_out(op_orn_c) or res_out(op_xnor_c) or

View file

@ -320,9 +320,15 @@ begin
madd.done <= madd.sreg(madd.sreg'left); madd.done <= madd.sreg(madd.sreg'left);
-- arithmetic core -- -- arithmetic core --
madd_core: process(clk_i) madd_core: process(rstn_i, clk_i)
begin 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 -- -- stage 0: buffer input operands --
madd.opa <= rs1_i; madd.opa <= rs1_i;
madd.opb <= rs2_i; madd.opb <= rs2_i;

View file

@ -495,10 +495,15 @@ begin
-- Floating-Point Comparator -------------------------------------------------------------- -- Floating-Point Comparator --------------------------------------------------------------
-- ------------------------------------------------------------------------------------------- -- -------------------------------------------------------------------------------------------
float_comparator: process(clk_i) float_comparator: process(rstn_i, clk_i)
variable cond_v : std_ulogic_vector(1 downto 0); variable cond_v : std_ulogic_vector(1 downto 0);
begin 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 -- -- 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 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 ((fpu_operands.rs1_class(fp_class_neg_inf_c) = '1') and (fpu_operands.rs2_class(fp_class_neg_inf_c) = '1')) or -- -inf == -inf
@ -643,11 +648,15 @@ begin
-- Convert: [unsigned] Integer to Float (FCVT.W.S) ---------------------------------------- -- Convert: [unsigned] Integer to Float (FCVT.W.S) ----------------------------------------
-- ------------------------------------------------------------------------------------------- -- -------------------------------------------------------------------------------------------
convert_i2f: process(clk_i) convert_i2f: process(rstn_i, clk_i)
begin begin
-- this process only computes the absolute input value -- this process only computes the absolute input value
-- the actual conversion is done by the normalizer -- 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 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.result <= std_ulogic_vector(0 - unsigned(rs1_i));
fu_conv_i2f.sign <= rs1_i(31); -- original sign fu_conv_i2f.sign <= rs1_i(31); -- original sign
@ -662,9 +671,18 @@ begin
-- Multiplier Core (FMUL) ----------------------------------------------------------------- -- Multiplier Core (FMUL) -----------------------------------------------------------------
-- ------------------------------------------------------------------------------------------- -- -------------------------------------------------------------------------------------------
multiplier_core: process(clk_i) multiplier_core: process(rstn_i, clk_i)
begin 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 -- -- multiplier core --
if (multiplier.start = '1') then -- FIXME / TODO remove buffer? if (multiplier.start = '1') then -- FIXME / TODO remove buffer?
multiplier.opa <= unsigned('1' & fpu_operands.rs1(22 downto 0)); -- append hidden one multiplier.opa <= unsigned('1' & fpu_operands.rs1(22 downto 0)); -- append hidden one
@ -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.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) (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 -- -- latency shift register --
multiplier.latency <= multiplier.latency(multiplier.latency'left-1 downto 0) & multiplier.start; multiplier.latency <= multiplier.latency(multiplier.latency'left-1 downto 0) & multiplier.start;
end if; end if;
@ -707,20 +729,18 @@ begin
multiplier.done <= multiplier.latency(multiplier.latency'left); multiplier.done <= multiplier.latency(multiplier.latency'left);
fu_mul.done <= multiplier.done; 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 -- -- 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_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_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_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_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; variable a_snan_v, a_qnan_v, b_snan_v, b_qnan_v : std_ulogic;
begin begin
if rising_edge(clk_i) then if (rstn_i = '0') then
multiplier.res_class <= (others => '0');
elsif rising_edge(clk_i) then
-- minions -- -- 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_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); 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);
@ -813,9 +833,21 @@ begin
-- Adder/Subtractor Core (FADD, FSUB) ----------------------------------------------------- -- Adder/Subtractor Core (FADD, FSUB) -----------------------------------------------------
-- ------------------------------------------------------------------------------------------- -- -------------------------------------------------------------------------------------------
adder_subtractor_core: process(clk_i) adder_subtractor_core: process(rstn_i, clk_i)
begin 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 -- -- arbitration / latency --
if (ctrl_engine.state = S_IDLE) then -- hacky "reset" if (ctrl_engine.state = S_IDLE) then -- hacky "reset"
addsub.latency <= (others => '0'); addsub.latency <= (others => '0');
@ -948,14 +980,16 @@ begin
-- result class -- -- 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_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_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_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_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; variable a_snan_v, a_qnan_v, b_snan_v, b_qnan_v : std_ulogic;
begin begin
if rising_edge(clk_i) then if (rstn_i = '0') then
addsub.res_class <= (others => '0');
elsif rising_edge(clk_i) then
-- minions -- -- 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_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); 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);
@ -1163,9 +1197,14 @@ begin
-- Output Result to CPU Pipeline ---------------------------------------------------------- -- Output Result to CPU Pipeline ----------------------------------------------------------
-- ------------------------------------------------------------------------------------------- -- -------------------------------------------------------------------------------------------
output_gate: process(clk_i) output_gate: process(rstn_i, clk_i)
begin 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 if (ctrl_engine.valid = '1') then
case funct_ff is case funct_ff is
when op_class_c => when op_class_c =>
@ -1187,9 +1226,6 @@ begin
res_o <= normalizer.result; res_o <= normalizer.result;
fflags <= normalizer.flags_out; fflags <= normalizer.flags_out;
end case; end case;
else
res_o <= (others => '0');
fflags <= (others => '0');
end if; end if;
end if; end if;
end process output_gate; end process output_gate;

View file

@ -194,9 +194,13 @@ begin
if (FAST_MUL_EN = true) generate if (FAST_MUL_EN = true) generate
-- direct approach -- -- direct approach --
multiplier_core: process(clk_i) multiplier_core: process(rstn_i, clk_i)
begin 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 if (mul.start = '1') then
mul.dsp_x <= signed((rs1_i(rs1_i'left) and ctrl.rs1_is_signed) & rs1_i); 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); mul.dsp_y <= signed((rs2_i(rs2_i'left) and ctrl.rs2_is_signed) & rs2_i);
@ -225,9 +229,11 @@ begin
if (FAST_MUL_EN = false) generate if (FAST_MUL_EN = false) generate
-- shift-and-add algorithm -- -- shift-and-add algorithm --
multiplier_core: process(clk_i) multiplier_core: process(rstn_i, clk_i)
begin 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 if (mul.start = '1') then -- start new multiplication
mul.prod(63 downto 32) <= (others => '0'); mul.prod(63 downto 32) <= (others => '0');
mul.prod(31 downto 00) <= rs1_i; mul.prod(31 downto 00) <= rs1_i;
@ -271,9 +277,12 @@ begin
if (DIVISION_EN = true) generate if (DIVISION_EN = true) generate
-- restoring division algorithm -- -- restoring division algorithm --
divider_core: process(clk_i) divider_core: process(rstn_i, clk_i)
begin 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 (div.start = '1') then -- start new division
if ((rs1_i(rs1_i'left) and ctrl.rs1_is_signed) = '1') then -- signed 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 div.quotient <= std_ulogic_vector(0 - unsigned(rs1_i)); -- make positive

View file

@ -150,9 +150,12 @@ begin
end process barrel_shifter_core; end process barrel_shifter_core;
-- pipeline register -- -- pipeline register --
barrel_shifter_buf: process(clk_i) barrel_shifter_buf: process(rstn_i, clk_i)
begin 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_start <= start_i;
bs_result <= bs_level(0); -- this register can be moved by the register balancing bs_result <= bs_level(0); -- this register can be moved by the register balancing
end if; end if;