update comments
[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, Elaboratable
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, FPOpIn, Overflow, FPBase, FPNumBase
11 from fpbase import MultiShiftRMerge, Trigger
12 from singlepipe import (ControlBase, StageChain, SimpleHandshake,
13 PassThroughStage, PrevControl)
14 from multipipe import CombMuxOutPipe
15 from multipipe import PriorityCombMuxInPipe
16
17 from fpbase import FPState
18 import nmoperator
19
20
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)
27
28 def elaborate(self, platform):
29 m = Module()
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):
35 m.d.comb += [
36 self.out_op.eq(self.in_op.v),
37 ]
38 return m
39
40
41 class FPGetOp(FPState):
42 """ gets operand
43 """
44
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)
49 self.in_op = in_op
50 self.out_op = Signal(width)
51 self.out_decode = Signal(reset_less=True)
52
53 def setup(self, m, in_op):
54 """ links module to inputs and outputs
55 """
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)
59
60 def action(self, m):
61 with m.If(self.out_decode):
62 m.next = self.out_state
63 m.d.sync += [
64 self.in_op.ready_o.eq(0),
65 self.out_op.eq(self.mod.out_op)
66 ]
67 with m.Else():
68 m.d.sync += self.in_op.ready_o.eq(1)
69
70
71 class FPNumBase2Ops:
72
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.mid = Signal(id_wid, reset_less=True)
77
78 def eq(self, i):
79 return [self.a.eq(i.a), self.b.eq(i.b), self.mid.eq(i.mid)]
80
81 def ports(self):
82 return [self.a, self.b, self.mid]
83
84
85 class FPADDBaseData:
86
87 def __init__(self, width, id_wid):
88 self.width = width
89 self.id_wid = id_wid
90 self.a = Signal(width)
91 self.b = Signal(width)
92 self.mid = Signal(id_wid, reset_less=True)
93
94 def eq(self, i):
95 return [self.a.eq(i.a), self.b.eq(i.b), self.mid.eq(i.mid)]
96
97 def ports(self):
98 return [self.a, self.b, self.mid]
99
100
101 class FPGet2OpMod(PrevControl):
102 def __init__(self, width, id_wid):
103 PrevControl.__init__(self)
104 self.width = width
105 self.id_wid = id_wid
106 self.data_i = self.ispec()
107 self.i = self.data_i
108 self.o = self.ospec()
109
110 def ispec(self):
111 return FPADDBaseData(self.width, self.id_wid)
112
113 def ospec(self):
114 return FPADDBaseData(self.width, self.id_wid)
115
116 def process(self, i):
117 return self.o
118
119 def elaborate(self, platform):
120 m = PrevControl.elaborate(self, platform)
121 with m.If(self.trigger):
122 m.d.comb += [
123 self.o.eq(self.data_i),
124 ]
125 return m
126
127
128 class FPGet2Op(FPState):
129 """ gets operands
130 """
131
132 def __init__(self, in_state, out_state, width, id_wid):
133 FPState.__init__(self, in_state)
134 self.out_state = out_state
135 self.mod = FPGet2OpMod(width, id_wid)
136 self.o = self.ospec()
137 self.in_stb = Signal(reset_less=True)
138 self.out_ack = Signal(reset_less=True)
139 self.out_decode = Signal(reset_less=True)
140
141 def ispec(self):
142 return self.mod.ispec()
143
144 def ospec(self):
145 return self.mod.ospec()
146
147 def trigger_setup(self, m, in_stb, in_ack):
148 """ links stb/ack
149 """
150 m.d.comb += self.mod.valid_i.eq(in_stb)
151 m.d.comb += in_ack.eq(self.mod.ready_o)
152
153 def setup(self, m, i):
154 """ links module to inputs and outputs
155 """
156 m.submodules.get_ops = self.mod
157 m.d.comb += self.mod.i.eq(i)
158 m.d.comb += self.out_ack.eq(self.mod.ready_o)
159 m.d.comb += self.out_decode.eq(self.mod.trigger)
160
161 def process(self, i):
162 return self.o
163
164 def action(self, m):
165 with m.If(self.out_decode):
166 m.next = self.out_state
167 m.d.sync += [
168 self.mod.ready_o.eq(0),
169 self.o.eq(self.mod.o),
170 ]
171 with m.Else():
172 m.d.sync += self.mod.ready_o.eq(1)
173
174