From a55449dd50d6a1658aec74625b3cbdb0fa17e8f9 Mon Sep 17 00:00:00 2001 From: Jacob Lifshay Date: Tue, 25 Aug 2020 11:54:51 -0700 Subject: [PATCH] fix broken remainder for div FSM --- src/soc/fu/div/fsm.py | 8 +++++++- src/soc/fu/div/test/test_pipe_caller.py | 18 ++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/soc/fu/div/fsm.py b/src/soc/fu/div/fsm.py index befb463d..a761dfbc 100644 --- a/src/soc/fu/div/fsm.py +++ b/src/soc/fu/div/fsm.py @@ -171,7 +171,13 @@ class FSMDivCoreStage(ControlBase): m.d.comb += data_o.eq_without_core(self.saved_input_data) m.d.comb += core_o.quotient_root.eq(self.div_state_next.o.quotient) - m.d.comb += core_o.remainder.eq(self.div_state_next.o.remainder) + # fract width of `DivPipeCoreOutputData.remainder` + remainder_fract_width = 64 * 3 + # fract width of `DivPipeCoreInputData.dividend` + dividend_fract_width = 64 * 2 + rem_start = remainder_fract_width - dividend_fract_width + m.d.comb += core_o.remainder.eq(self.div_state_next.o.remainder + << rem_start) m.d.comb += self.n.valid_o.eq(~self.empty & self.div_state_next.o.done) m.d.comb += self.p.ready_o.eq(self.empty) m.d.sync += self.saved_state.eq(self.div_state_next.o) diff --git a/src/soc/fu/div/test/test_pipe_caller.py b/src/soc/fu/div/test/test_pipe_caller.py index 4fb31567..ee8e5b95 100644 --- a/src/soc/fu/div/test/test_pipe_caller.py +++ b/src/soc/fu/div/test/test_pipe_caller.py @@ -11,6 +11,24 @@ from soc.fu.div.test.helper import (log_rand, get_cu_inputs, class DivTestCases(TestAccumulatorBase): + def case_divw_regression(self): + # simulator is wrong, FSM and power-instruction-analyzer are both correct + lst = [f"divw 0, 1, 2"] + initial_regs = [0] * 32 + initial_regs[2] = 0x2 + initial_regs[1] = 0x80000000 + with Program(lst, bigendian) as prog: + self.add_case(prog, initial_regs) + + # modulo + def case_modsd_regression2(self): + lst = [f"modsd 0, 1, 2"] + initial_regs = [0] * 32 + initial_regs[2] = 0xff + initial_regs[1] = 0x7fffffffffffffff + with Program(lst, bigendian) as prog: + self.add_case(prog, initial_regs) + # modulo def case_modsd_regression(self): lst = [f"modsd 17, 27, 0"] -- 2.30.2