add regressions and corner cases
[ieee754fpu.git] / src / ieee754 / fpcommon / test / fpmux.py
index 239c822d7b64bdcde52a93358377b470db2d702a..15441fe7ef6fd38a3f1c57d48e92a645f0f9e626 100644 (file)
@@ -11,41 +11,41 @@ from nmigen.cli import verilog, rtlil
 
 
 class InputTest:
-    def __init__(self, dut, width, fpkls, fpop):
+    def __init__(self, dut, width, fpkls, fpop, vals, single_op):
         self.dut = dut
         self.fpkls = fpkls
         self.fpop = fpop
+        self.single_op = single_op
         self.di = {}
         self.do = {}
-        self.tlen = 10
+        self.tlen = len(vals) // dut.num_rows
         self.width = width
         for muxid in range(dut.num_rows):
             self.di[muxid] = {}
             self.do[muxid] = []
             for i in range(self.tlen):
-                op1 = randint(0, (1<<self.width)-1)
-                op2 = randint(0, (1<<self.width)-1)
-                #op1 = 0x513ba448
-                #op2 = 0xfff5c7fe 
-                #op1 = 0xffcaeefa
-                #op2 = 0x3f803262
-                #op1 = 0xae430313
-                #op2 = 0x901c3214
-                #op1 = 0xa4504d7
-                #op2 = 0xb4658540 # expect 0x8016147c
-                #op1 = 0x40900000
-                #op2 = 0x40200000
-                res = self.fpop(self.fpkls(op1), self.fpkls(op2))
-                self.di[muxid][i] = (op1, op2)
+                if self.single_op:
+                    (op1, ) = vals.pop(0)
+                    res = self.fpop(self.fpkls(op1))
+                    self.di[muxid][i] = (op1, )
+                else:
+                    (op1, op2, ) = vals.pop(0)
+                    print ("test", hex(op1), hex(op2))
+                    res = self.fpop(self.fpkls(op1), self.fpkls(op2))
+                    self.di[muxid][i] = (op1, op2)
                 self.do[muxid].append(res.bits)
 
     def send(self, muxid):
         for i in range(self.tlen):
-            op1, op2 = self.di[muxid][i]
+            if self.single_op:
+                op1, = self.di[muxid][i]
+            else:
+                op1, op2 = self.di[muxid][i]
             rs = self.dut.p[muxid]
             yield rs.valid_i.eq(1)
             yield rs.data_i.a.eq(op1)
-            yield rs.data_i.b.eq(op2)
+            if not self.single_op:
+                yield rs.data_i.b.eq(op2)
             yield rs.data_i.muxid.eq(muxid)
             yield
             o_p_ready = yield rs.ready_o
@@ -53,11 +53,17 @@ class InputTest:
                 yield
                 o_p_ready = yield rs.ready_o
 
-            fop1 = self.fpkls(op1)
-            fop2 = self.fpkls(op2)
-            res = self.fpop(fop1, fop2)
-            print ("send", muxid, i, hex(op1), hex(op2), hex(res.bits),
-                           fop1, fop2, res)
+            if self.single_op:
+                fop1 = self.fpkls(op1)
+                res = self.fpop(fop1)
+                print ("send", muxid, i, hex(op1), hex(res.bits),
+                               fop1, res)
+            else:
+                fop1 = self.fpkls(op1)
+                fop2 = self.fpkls(op2)
+                res = self.fpop(fop1, fop2)
+                print ("send", muxid, i, hex(op1), hex(op2), hex(res.bits),
+                               fop1, fop2, res)
 
             yield rs.valid_i.eq(0)
             # wait random period of time before queueing another value
@@ -114,12 +120,56 @@ class InputTest:
         print ("recv ended", muxid)
 
 
-def runfp(dut, width, name, fpkls, fpop):
+def create_random(num_rows, width, single_op=False, n_vals=10):
+    vals = []
+    for muxid in range(num_rows):
+        for i in range(n_vals):
+            if single_op:
+                op1 = randint(0, (1<<width)-1)
+                #op1 = 0x40900000
+                #op1 = 0x94607b66
+                #op1 = 0x889cd8c
+                #op1 = 0xe98646d7
+                #op1 = 0x3340f2a7
+                #op1 = 0xfff13f05
+                #op1 = 0x453eb000
+                #op1 = 0x3a05de50
+                #op1 = 0xc27ff989
+                #op1 = 0x41689000
+                #op1 = 0xbbc0edec
+                #op1 = 0x2EDBE6FF
+                #op1 = 0x358637BD
+                #op1 = 0x3340f2a7
+                #op1 = 0x33D6BF95
+                #op1 = 0x9885020648d8c0e8
+                vals.append((op1,))
+            else:
+                op1 = randint(0, (1<<width)-1)
+                op2 = randint(0, (1<<width)-1)
+                vals.append((op1, op2,))
+    return vals
+
+
+def repeat(num_rows, vals):
+    """ bit of a hack: repeats the last value to create a list
+        that will be accepted by the muxer, all mux lists to be
+        of equal length
+    """
+    vals = list(vals)
+    n_to_repeat = len(vals) % num_rows
+    print (vals, vals[-1])
+    return vals + [vals[-1]] * n_to_repeat
+
+
+def runfp(dut, width, name, fpkls, fpop, single_op=False, n_vals=10, vals=None):
     vl = rtlil.convert(dut, ports=dut.ports())
     with open("%s.il" % name, "w") as f:
         f.write(vl)
 
-    test = InputTest(dut, width, fpkls, fpop)
+    if vals is None:
+        vals = create_random(dut.num_rows, width, single_op, n_vals)
+
+    test = InputTest(dut, width, fpkls, fpop, vals, single_op)
     run_simulation(dut, [test.rcv(1), test.rcv(0),
                          test.rcv(3), test.rcv(2),
                          test.send(0), test.send(1),