add regression test for div overflow case
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 9 Jul 2020 23:18:53 +0000 (00:18 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 9 Jul 2020 23:18:53 +0000 (00:18 +0100)
see https://bugs.libre-soc.org/show_bug.cgi?id=425

src/soc/fu/common_output_stage.py
src/soc/fu/div/output_stage.py
src/soc/fu/div/test/test_pipe_caller.py

index 34d3b70df92e755f1748b274be2fd50d8c0f7885..4a9f391d5cfff47487b4d6b925f3effef7ce2749 100644 (file)
@@ -17,7 +17,7 @@ class CommonOutputStage(PipeModBase):
         if hasattr(self.o, "xer_so"):
             xer_so_o = self.o.xer_so.data[0]
         else:
-            xer_so_o = Const(0)
+            xer_so_o = Const(0, 1)
 
         # op requests inversion of the output...
         o = Signal.like(self.i.o)
index 39a3bce1df2e88271ae378668d8a63b46782d08a..80968ea500c7919edbfdb2a4bc414b6abcfa5cf6 100644 (file)
@@ -1,5 +1,8 @@
 # This stage is the setup stage that converts the inputs
 # into the values expected by DivPipeCore
+"""
+* https://bugs.libre-soc.org/show_bug.cgi?id=424
+"""
 
 from nmigen import (Module, Signal, Cat, Repl, Mux, Const, Array)
 from nmutil.pipemodbase import PipeModBase
@@ -68,17 +71,22 @@ class DivOutputStage(PipeModBase):
         self.o.xer_ov.ok.eq(1)
         xer_ov = self.o.xer_ov.data
 
+        # see test_6_regression in div test_pipe_caller.py
+        # https://bugs.libre-soc.org/show_bug.cgi?id=425
         def calc_overflow(dive_abs_overflow, sign_bit_mask):
             nonlocal comb
             overflow = dive_abs_overflow | self.i.div_by_zero
+            ov = Signal(reset_less=True)
             with m.If(op.is_signed):
-                comb += xer_ov.eq(overflow
+                comb += ov.eq(overflow
                                   | (abs_quotient > sign_bit_mask)
                                   | ((abs_quotient == sign_bit_mask)
                                      & ~self.quotient_neg))
             with m.Else():
-                comb += xer_ov.eq(Repl(overflow, 2)) # set OV _and_ OV32
+                comb += ov.eq(overflow)
+            comb += xer_ov.eq(Repl(ov, 2)) # set OV _and_ OV32
 
+        # check 32/64 bit version of overflow
         with m.If(op.is_32bit):
             calc_overflow(self.i.dive_abs_ov32, 0x80000000)
         with m.Else():
index 2814669c90446370e323bcefed4658491066fb5b..6b80fcc1fc300e5508f32e2222143f677f14fb98 100644 (file)
@@ -75,7 +75,7 @@ class DIVTestCase(FHDLTestCase):
         tc = TestCase(prog, self.test_name, initial_regs, initial_sprs)
         self.test_data.append(tc)
 
-    def test_0_regression(self):
+    def tst_0_regression(self):
         for i in range(40):
             lst = ["divwo 3, 1, 2"]
             initial_regs = [0] * 32
@@ -83,35 +83,35 @@ class DIVTestCase(FHDLTestCase):
             initial_regs[2] = 0xcdf69a7f7042db66
             self.run_tst_program(Program(lst), initial_regs)
 
-    def test_1_regression(self):
+    def tst_1_regression(self):
         lst = ["divwo 3, 1, 2"]
         initial_regs = [0] * 32
         initial_regs[1] = 0x10000000000000000-4
         initial_regs[2] = 0x10000000000000000-2
         self.run_tst_program(Program(lst), initial_regs)
 
-    def test_2_regression(self):
+    def tst_2_regression(self):
         lst = ["divwo 3, 1, 2"]
         initial_regs = [0] * 32
         initial_regs[1] = 0xffffffffffff9321
         initial_regs[2] = 0xffffffffffff7012
         self.run_tst_program(Program(lst), initial_regs)
 
-    def test_3_regression(self):
+    def tst_3_regression(self):
         lst = ["divwo. 3, 1, 2"]
         initial_regs = [0] * 32
         initial_regs[1] = 0x1b8e32f2458746af
         initial_regs[2] = 0x6b8aee2ccf7d62e9
         self.run_tst_program(Program(lst), initial_regs)
 
-    def test_4_regression(self):
+    def tst_4_regression(self):
         lst = ["divw 3, 1, 2"]
         initial_regs = [0] * 32
         initial_regs[1] = 0x1c4e6c2f3aa4a05c
         initial_regs[2] = 0xe730c2eed6cc8dd7
         self.run_tst_program(Program(lst), initial_regs)
 
-    def test_5_regression(self):
+    def tst_5_regression(self):
         lst = ["divw 3, 1, 2",
                "divwo. 6, 4, 5"]
         initial_regs = [0] * 32
@@ -123,13 +123,16 @@ class DIVTestCase(FHDLTestCase):
 
     def test_6_regression(self):
         # CR0 not getting set properly for this one
+        # turns out that overflow is not set correctly in
+        # fu/div/output_stage.py calc_overflow
+        # https://bugs.libre-soc.org/show_bug.cgi?id=425
         lst = ["divw. 3, 1, 2"]
         initial_regs = [0] * 32
         initial_regs[1] = 0x61c1cc3b80f2a6af
         initial_regs[2] = 0x9dc66a7622c32bc0
         self.run_tst_program(Program(lst), initial_regs)
 
-    def test_rand_divw(self):
+    def tst_rand_divw(self):
         insns = ["divw", "divw.", "divwo", "divwo."]
         for i in range(40):
             choice = random.choice(insns)
@@ -139,7 +142,7 @@ class DIVTestCase(FHDLTestCase):
             initial_regs[2] = random.randint(0, (1<<64)-1)
             self.run_tst_program(Program(lst), initial_regs)
 
-    def test_ilang(self):
+    def tst_ilang(self):
         pspec = DIVPipeSpec(id_wid=2)
         alu = DIVBasePipe(pspec)
         vl = rtlil.convert(alu, ports=alu.ports())