Begin adding FPCMP module (FEQ, FLT, FLE)
authorMichael Nolan <mtnolan2640@gmail.com>
Sun, 2 Feb 2020 16:21:01 +0000 (11:21 -0500)
committerMichael Nolan <mtnolan2640@gmail.com>
Sun, 2 Feb 2020 16:21:01 +0000 (11:21 -0500)
src/ieee754/fpcmp/fpcmp.py [new file with mode: 0644]
src/ieee754/fpcmp/pipeline.py [new file with mode: 0644]
src/ieee754/fpcmp/test/test_fpcmp_pipe.py [new file with mode: 0644]

diff --git a/src/ieee754/fpcmp/fpcmp.py b/src/ieee754/fpcmp/fpcmp.py
new file mode 100644 (file)
index 0000000..1b0629f
--- /dev/null
@@ -0,0 +1,55 @@
+# IEEE Floating Point Conversion, FSGNJ
+# Copyright (C) 2019 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
+# Copyright (C) 2020 Michael Nolan <mtnolan2640@gmail.com>
+
+
+from nmigen import Module, Signal, Mux
+
+from nmutil.pipemodbase import PipeModBase
+from ieee754.fpcommon.basedata import FPBaseData
+from ieee754.fpcommon.packdata import FPPackData
+from ieee754.fpcommon.fpbase import FPNumDecode, FPNumBaseRecord
+
+
+class FPCMPPipeMod(PipeModBase):
+    """
+    Floating point comparison: FEQ, FLT, FLE
+    Opcodes (funct3):
+       - 0b00 - FLE - floating point less than or equal to
+       - 0b01 - FLT - floating point less than
+       - 0b10 - FEQ - floating equals
+    """
+    def __init__(self, in_pspec):
+        self.in_pspec = in_pspec
+        super().__init__(in_pspec, "fpcmp")
+
+    def ispec(self):
+        return FPBaseData(self.in_pspec)
+
+    def ospec(self):
+        return FPPackData(self.in_pspec)
+
+    def elaborate(self, platform):
+        m = Module()
+
+        # useful clarity variables
+        comb = m.d.comb
+        width = self.pspec.width
+        opcode = self.i.ctx.op
+        z1 = self.o.z
+
+        a1 = FPNumBaseRecord(width, False)
+        b1 = FPNumBaseRecord(width, False)
+        m.submodules.sc_decode_a = a1 = FPNumDecode(None, a1)
+        m.submodules.sc_decode_b = b1 = FPNumDecode(None, b1)
+
+        m.d.comb += [a1.v.eq(self.i.a),
+                     b1.v.eq(self.i.b)]
+
+
+        comb += z1.eq(0)
+
+        # copy the context (muxid, operator)
+        comb += self.o.ctx.eq(self.i.ctx)
+
+        return m
diff --git a/src/ieee754/fpcmp/pipeline.py b/src/ieee754/fpcmp/pipeline.py
new file mode 100644 (file)
index 0000000..57fa910
--- /dev/null
@@ -0,0 +1,56 @@
+"""IEEE754 Floating Point Conversion
+
+Copyright (C) 2019 Luke Kenneth Casson Leighton <lkcl@lkcl.net>
+Copyright (C) 2020 Michael Nolan <mtnolan2640@gmail.com>
+
+"""
+
+from nmutil.singlepipe import ControlBase
+from nmutil.concurrentunit import ReservationStations, num_bits
+
+from ieee754.pipeline import PipelineSpec, DynamicPipe
+
+from ieee754.fpcmp.fpcmp import FPCMPPipeMod
+
+
+class FPCMPStage(DynamicPipe):
+    """ FPConversion and De-norm
+    """
+
+    def __init__(self, in_pspec):
+        stage = FPCMPPipeMod(in_pspec)
+        in_pspec.stage = stage
+        super().__init__(in_pspec)
+
+
+class FPCMPBasePipe(ControlBase):
+    def __init__(self, pspec):
+        ControlBase.__init__(self)
+        self.pipe1 = FPCMPStage(pspec)
+        self._eqs = self.connect([self.pipe1, ])
+
+    def elaborate(self, platform):
+        m = ControlBase.elaborate(self, platform)
+        m.submodules.fpcmp = self.pipe1
+        m.d.comb += self._eqs
+        return m
+
+
+class FPCMPMuxInOut(ReservationStations):
+    """ Reservation-Station version of FPCVT pipeline.
+
+        * fan-in on inputs (an array of FPBaseData: a,b,mid)
+        * converter pipeline (alu)
+        * fan-out on outputs (an array of FPPackData: z,mid)
+
+        Fan-in and Fan-out are combinatorial.
+    """
+
+    def __init__(self, in_width, num_rows, op_wid=1):
+        self.op_wid = op_wid
+        self.id_wid = num_bits(num_rows)
+
+        self.in_pspec = PipelineSpec(in_width, self.id_wid, self.op_wid)
+
+        self.alu = FPCMPBasePipe(self.in_pspec)
+        ReservationStations.__init__(self, num_rows)
diff --git a/src/ieee754/fpcmp/test/test_fpcmp_pipe.py b/src/ieee754/fpcmp/test/test_fpcmp_pipe.py
new file mode 100644 (file)
index 0000000..5fd0594
--- /dev/null
@@ -0,0 +1,32 @@
+""" test of FPCVTMuxInOut
+"""
+
+from ieee754.fpcmp.pipeline import (FPCMPMuxInOut)
+from ieee754.fpcommon.test.fpmux import runfp
+
+from sfpy import Float16, Float32, Float64
+import math
+
+
+def fpcmp_eq(a, b):
+    return Float32(a.eq(b))
+
+def fpcmp_lt(a, b):
+    return Float32(a.lt(b))
+
+
+def test_fpcmp_eq():
+    dut = FPCMPMuxInOut(32, 4)
+    runfp(dut, 32, "test_fpcmp_eq", Float32, fpcmp_eq,
+          n_vals=100, opcode=0b10)
+
+def test_fpcmp_lt():
+    dut = FPCMPMuxInOut(32, 4)
+    runfp(dut, 32, "test_fpcmp_lt", Float32, fpcmp_lt,
+          n_vals=100, opcode=0b00)
+
+
+if __name__ == '__main__':
+    for i in range(50):
+        test_fpcmp_lt()
+        test_fpcmp_eq()