fb7f3b26998679b624b5a03c255a0b063ce2e4d0
1 # IEEE Floating Point Adder (Single Precision)
2 # Copyright (C) Jonathan P Dawson 2013
5 from nmigen
import Module
, Signal
, Cat
, Mux
, Array
, Const
, Elaboratable
6 from nmigen
.lib
.coding
import PriorityEncoder
7 from nmigen
.cli
import main
, verilog
10 from ieee754
.fpcommon
.fpbase
import FPNumIn
, FPNumOut
, FPOpIn
, Overflow
, FPBase
, FPNumBase
11 from ieee754
.fpcommon
.fpbase
import MultiShiftRMerge
, Trigger
12 from nmutil
.singlepipe
import (ControlBase
, StageChain
, SimpleHandshake
,
13 PassThroughStage
, PrevControl
)
14 from nmutil
.multipipe
import CombMuxOutPipe
15 from nmutil
.multipipe
import PriorityCombMuxInPipe
17 from ieee754
.fpcommon
.fpbase
import FPState
18 from nmutil
import nmoperator
21 class FPGetOpMod(Elaboratable
):
22 def __init__(self
, width
):
23 self
.in_op
= FPOpIn(width
)
24 self
.in_op
.data_i
= Signal(width
)
25 self
.out_op
= Signal(width
)
26 self
.out_decode
= Signal(reset_less
=True)
28 def elaborate(self
, platform
):
30 m
.d
.comb
+= self
.out_decode
.eq((self
.in_op
.ready_o
) & \
31 (self
.in_op
.valid_i_test
))
32 m
.submodules
.get_op_in
= self
.in_op
33 #m.submodules.get_op_out = self.out_op
34 with m
.If(self
.out_decode
):
36 self
.out_op
.eq(self
.in_op
.v
),
41 class FPGetOp(FPState
):
45 def __init__(self
, in_state
, out_state
, in_op
, width
):
46 FPState
.__init
__(self
, in_state
)
47 self
.out_state
= out_state
48 self
.mod
= FPGetOpMod(width
)
50 self
.out_op
= Signal(width
)
51 self
.out_decode
= Signal(reset_less
=True)
53 def setup(self
, m
, in_op
):
54 """ links module to inputs and outputs
56 setattr(m
.submodules
, self
.state_from
, self
.mod
)
57 m
.d
.comb
+= nmoperator
.eq(self
.mod
.in_op
, in_op
)
58 m
.d
.comb
+= self
.out_decode
.eq(self
.mod
.out_decode
)
61 with m
.If(self
.out_decode
):
62 m
.next
= self
.out_state
64 self
.in_op
.ready_o
.eq(0),
65 self
.out_op
.eq(self
.mod
.out_op
)
68 m
.d
.sync
+= self
.in_op
.ready_o
.eq(1)
73 def __init__(self
, width
, id_wid
, m_extra
=True):
74 self
.a
= FPNumBase(width
, m_extra
)
75 self
.b
= FPNumBase(width
, m_extra
)
76 self
.muxid
= Signal(id_wid
, reset_less
=True)
79 return [self
.a
.eq(i
.a
), self
.b
.eq(i
.b
), self
.muxid
.eq(i
.muxid
)]
82 return [self
.a
, self
.b
, self
.muxid
]
87 def __init__(self
, pspec
):
88 """ creates a pipeline context. currently: operator (op) and muxid
90 opkls (within pspec) - the class to create that will be the
91 "operator". instance must have an "eq"
94 self
.id_wid
= pspec
.id_wid
95 self
.op_wid
= pspec
.op_wid
96 self
.muxid
= Signal(self
.id_wid
, reset_less
=True) # RS multiplex ID
99 self
.op
= Signal(self
.op_wid
, reset_less
=True)
101 self
.op
= opkls(pspec
)
104 ret
= [self
.muxid
.eq(i
.muxid
)]
105 ret
.append(self
.op
.eq(i
.op
))
118 def __init__(self
, pspec
, n_ops
=2):
120 self
.ctx
= FPPipeContext(pspec
)
122 for i
in range(n_ops
):
123 name
= chr(ord("a")+i
)
124 operand
= Signal(width
, name
=name
)
125 setattr(self
, name
, operand
)
127 self
.muxid
= self
.ctx
.muxid
# make muxid available here: complicated
132 for op1
, op2
in zip(self
.ops
, i
.ops
):
133 ret
.append(op1
.eq(op2
))
134 ret
.append(self
.ctx
.eq(i
.ctx
))
146 class FPGet2OpMod(PrevControl
):
147 def __init__(self
, width
, id_wid
, op_wid
=None):
148 PrevControl
.__init
__(self
)
151 self
.data_i
= self
.ispec()
153 self
.o
= self
.ospec()
156 return FPADDBaseData(self
.width
, self
.id_wid
, self
.op_wid
)
159 return FPADDBaseData(self
.width
, self
.id_wid
, self
.op_wid
)
161 def process(self
, i
):
164 def elaborate(self
, platform
):
165 m
= PrevControl
.elaborate(self
, platform
)
166 with m
.If(self
.trigger
):
168 self
.o
.eq(self
.data_i
),
173 class FPGet2Op(FPState
):
177 def __init__(self
, in_state
, out_state
, width
, id_wid
, op_wid
=None):
178 FPState
.__init
__(self
, in_state
)
179 self
.out_state
= out_state
180 self
.mod
= FPGet2OpMod(width
, id_wid
, op_wid
)
181 self
.o
= self
.ospec()
182 self
.in_stb
= Signal(reset_less
=True)
183 self
.out_ack
= Signal(reset_less
=True)
184 self
.out_decode
= Signal(reset_less
=True)
187 return self
.mod
.ispec()
190 return self
.mod
.ospec()
192 def trigger_setup(self
, m
, in_stb
, in_ack
):
195 m
.d
.comb
+= self
.mod
.valid_i
.eq(in_stb
)
196 m
.d
.comb
+= in_ack
.eq(self
.mod
.ready_o
)
198 def setup(self
, m
, i
):
199 """ links module to inputs and outputs
201 m
.submodules
.get_ops
= self
.mod
202 m
.d
.comb
+= self
.mod
.i
.eq(i
)
203 m
.d
.comb
+= self
.out_ack
.eq(self
.mod
.ready_o
)
204 m
.d
.comb
+= self
.out_decode
.eq(self
.mod
.trigger
)
206 def process(self
, i
):
210 with m
.If(self
.out_decode
):
211 m
.next
= self
.out_state
213 self
.mod
.ready_o
.eq(0),
214 self
.o
.eq(self
.mod
.o
),
217 m
.d
.sync
+= self
.mod
.ready_o
.eq(1)