start splitting out common code from nmigen_add_experiment.py
[ieee754fpu.git] / src / add / fpcommon / getop.py
1 # IEEE Floating Point Adder (Single Precision)
2 # Copyright (C) Jonathan P Dawson 2013
3 # 2013-12-12
4
5 from nmigen import Module, Signal, Cat, Mux, Array, Const
6 from nmigen.lib.coding import PriorityEncoder
7 from nmigen.cli import main, verilog
8 from math import log
9
10 from fpbase import FPNumIn, FPNumOut, FPOp, Overflow, FPBase, FPNumBase
11 from fpbase import MultiShiftRMerge, Trigger
12 from singlepipe import (ControlBase, StageChain, UnbufferedPipeline,
13 PassThroughStage)
14 from multipipe import CombMuxOutPipe
15 from multipipe import PriorityCombMuxInPipe
16
17 from fpbase import FPState
18
19
20 class FPGetOpMod:
21 def __init__(self, width):
22 self.in_op = FPOp(width)
23 self.out_op = Signal(width)
24 self.out_decode = Signal(reset_less=True)
25
26 def elaborate(self, platform):
27 m = Module()
28 m.d.comb += self.out_decode.eq((self.in_op.ack) & (self.in_op.stb))
29 m.submodules.get_op_in = self.in_op
30 #m.submodules.get_op_out = self.out_op
31 with m.If(self.out_decode):
32 m.d.comb += [
33 self.out_op.eq(self.in_op.v),
34 ]
35 return m
36
37
38 class FPGetOp(FPState):
39 """ gets operand
40 """
41
42 def __init__(self, in_state, out_state, in_op, width):
43 FPState.__init__(self, in_state)
44 self.out_state = out_state
45 self.mod = FPGetOpMod(width)
46 self.in_op = in_op
47 self.out_op = Signal(width)
48 self.out_decode = Signal(reset_less=True)
49
50 def setup(self, m, in_op):
51 """ links module to inputs and outputs
52 """
53 setattr(m.submodules, self.state_from, self.mod)
54 m.d.comb += self.mod.in_op.eq(in_op)
55 m.d.comb += self.out_decode.eq(self.mod.out_decode)
56
57 def action(self, m):
58 with m.If(self.out_decode):
59 m.next = self.out_state
60 m.d.sync += [
61 self.in_op.ack.eq(0),
62 self.out_op.eq(self.mod.out_op)
63 ]
64 with m.Else():
65 m.d.sync += self.in_op.ack.eq(1)
66
67
68 class FPNumBase2Ops:
69
70 def __init__(self, width, id_wid, m_extra=True):
71 self.a = FPNumBase(width, m_extra)
72 self.b = FPNumBase(width, m_extra)
73 self.mid = Signal(id_wid, reset_less=True)
74
75 def eq(self, i):
76 return [self.a.eq(i.a), self.b.eq(i.b), self.mid.eq(i.mid)]
77
78 def ports(self):
79 return [self.a, self.b, self.mid]
80
81
82 class FPADDBaseData:
83
84 def __init__(self, width, id_wid):
85 self.width = width
86 self.id_wid = id_wid
87 self.a = Signal(width)
88 self.b = Signal(width)
89 self.mid = Signal(id_wid, reset_less=True)
90
91 def eq(self, i):
92 return [self.a.eq(i.a), self.b.eq(i.b), self.mid.eq(i.mid)]
93
94 def ports(self):
95 return [self.a, self.b, self.mid]
96
97
98 class FPGet2OpMod(Trigger):
99 def __init__(self, width, id_wid):
100 Trigger.__init__(self)
101 self.width = width
102 self.id_wid = id_wid
103 self.i = self.ispec()
104 self.o = self.ospec()
105
106 def ispec(self):
107 return FPADDBaseData(self.width, self.id_wid)
108
109 def ospec(self):
110 return FPADDBaseData(self.width, self.id_wid)
111
112 def process(self, i):
113 return self.o
114
115 def elaborate(self, platform):
116 m = Trigger.elaborate(self, platform)
117 with m.If(self.trigger):
118 m.d.comb += [
119 self.o.eq(self.i),
120 ]
121 return m
122
123
124 class FPGet2Op(FPState):
125 """ gets operands
126 """
127
128 def __init__(self, in_state, out_state, width, id_wid):
129 FPState.__init__(self, in_state)
130 self.out_state = out_state
131 self.mod = FPGet2OpMod(width, id_wid)
132 self.o = self.ospec()
133 self.in_stb = Signal(reset_less=True)
134 self.out_ack = Signal(reset_less=True)
135 self.out_decode = Signal(reset_less=True)
136
137 def ispec(self):
138 return self.mod.ispec()
139
140 def ospec(self):
141 return self.mod.ospec()
142
143 def trigger_setup(self, m, in_stb, in_ack):
144 """ links stb/ack
145 """
146 m.d.comb += self.mod.stb.eq(in_stb)
147 m.d.comb += in_ack.eq(self.mod.ack)
148
149 def setup(self, m, i):
150 """ links module to inputs and outputs
151 """
152 m.submodules.get_ops = self.mod
153 m.d.comb += self.mod.i.eq(i)
154 m.d.comb += self.out_ack.eq(self.mod.ack)
155 m.d.comb += self.out_decode.eq(self.mod.trigger)
156
157 def process(self, i):
158 return self.o
159
160 def action(self, m):
161 with m.If(self.out_decode):
162 m.next = self.out_state
163 m.d.sync += [
164 self.mod.ack.eq(0),
165 self.o.eq(self.mod.o),
166 ]
167 with m.Else():
168 m.d.sync += self.mod.ack.eq(1)
169
170