1 # IEEE Floating Point Adder (Single Precision)
2 # Copyright (C) Jonathan P Dawson 2013
5 from nmigen
import Module
, Signal
, Cat
, Mux
, Array
, Const
6 from nmigen
.lib
.coding
import PriorityEncoder
7 from nmigen
.cli
import main
, verilog
10 from fpbase
import FPNumIn
, FPNumOut
, FPOp
, Overflow
, FPBase
, FPNumBase
11 from fpbase
import MultiShiftRMerge
, Trigger
12 from singlepipe
import (ControlBase
, StageChain
, UnbufferedPipeline
,
14 from multipipe
import CombMuxOutPipe
15 from multipipe
import PriorityCombMuxInPipe
17 from fpbase
import FPState
, FPID
18 from fpcommon
.roundz
import FPRoundData
23 def __init__(self
, width
, id_wid
):
24 self
.z
= Signal(width
, reset_less
=True)
25 self
.mid
= Signal(id_wid
, reset_less
=True)
28 return [self
.z
.eq(i
.z
), self
.mid
.eq(i
.mid
)]
31 return [self
.z
, self
.mid
]
36 def __init__(self
, width
, id_wid
):
43 return FPRoundData(self
.width
, self
.id_wid
)
46 return FPPackData(self
.width
, self
.id_wid
)
51 def setup(self
, m
, in_z
):
52 """ links module to inputs and outputs
54 m
.submodules
.pack
= self
55 m
.d
.comb
+= self
.i
.eq(in_z
)
57 def elaborate(self
, platform
):
59 z
= FPNumOut(self
.width
, False)
60 m
.submodules
.pack_in_z
= self
.i
.z
61 m
.submodules
.pack_out_z
= z
62 m
.d
.comb
+= self
.o
.mid
.eq(self
.i
.mid
)
63 with m
.If(~self
.i
.out_do_z
):
64 with m
.If(self
.i
.z
.is_overflowed
):
65 m
.d
.comb
+= z
.inf(self
.i
.z
.s
)
67 m
.d
.comb
+= z
.create(self
.i
.z
.s
, self
.i
.z
.e
, self
.i
.z
.m
)
69 m
.d
.comb
+= z
.v
.eq(self
.i
.oz
)
70 m
.d
.comb
+= self
.o
.z
.eq(z
.v
)
74 class FPPack(FPState
):
76 def __init__(self
, width
, id_wid
):
77 FPState
.__init
__(self
, "pack")
78 self
.mod
= FPPackMod(width
)
79 self
.out_z
= self
.ospec()
82 return self
.mod
.ispec()
85 return self
.mod
.ospec()
87 def setup(self
, m
, in_z
):
88 """ links module to inputs and outputs
90 self
.mod
.setup(m
, in_z
)
92 m
.d
.sync
+= self
.out_z
.v
.eq(self
.mod
.out_z
.v
)
93 m
.d
.sync
+= self
.out_z
.mid
.eq(self
.mod
.o
.mid
)