b966ecbd09f5861f502399a7a62c8a7a042962b6
[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
19
20 class FPGetOpMod(Elaboratable):
21 def __init__(self, width):
22 self.in_op = FPOpIn(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.ready_o) & \
29 (self.in_op.valid_i_test))
30 m.submodules.get_op_in = self.in_op
31 #m.submodules.get_op_out = self.out_op
32 with m.If(self.out_decode):
33 m.d.comb += [
34 self.out_op.eq(self.in_op.v),
35 ]
36 return m
37
38
39 class FPGetOp(FPState):
40 """ gets operand
41 """
42
43 def __init__(self, in_state, out_state, in_op, width):
44 FPState.__init__(self, in_state)
45 self.out_state = out_state
46 self.mod = FPGetOpMod(width)
47 self.in_op = in_op
48 self.out_op = Signal(width)
49 self.out_decode = Signal(reset_less=True)
50
51 def setup(self, m, in_op):
52 """ links module to inputs and outputs
53 """
54 setattr(m.submodules, self.state_from, self.mod)
55 m.d.comb += self.mod.in_op.eq(in_op)
56 m.d.comb += self.out_decode.eq(self.mod.out_decode)
57
58 def action(self, m):
59 with m.If(self.out_decode):
60 m.next = self.out_state
61 m.d.sync += [
62 self.in_op.ready_o.eq(0),
63 self.out_op.eq(self.mod.out_op)
64 ]
65 with m.Else():
66 m.d.sync += self.in_op.ready_o.eq(1)
67
68
69 class FPNumBase2Ops:
70
71 def __init__(self, width, id_wid, m_extra=True):
72 self.a = FPNumBase(width, m_extra)
73 self.b = FPNumBase(width, m_extra)
74 self.mid = Signal(id_wid, reset_less=True)
75
76 def eq(self, i):
77 return [self.a.eq(i.a), self.b.eq(i.b), self.mid.eq(i.mid)]
78
79 def ports(self):
80 return [self.a, self.b, self.mid]
81
82
83 class FPADDBaseData:
84
85 def __init__(self, width, id_wid):
86 self.width = width
87 self.id_wid = id_wid
88 self.a = Signal(width)
89 self.b = Signal(width)
90 self.mid = Signal(id_wid, reset_less=True)
91
92 def eq(self, i):
93 return [self.a.eq(i.a), self.b.eq(i.b), self.mid.eq(i.mid)]
94
95 def ports(self):
96 return [self.a, self.b, self.mid]
97
98
99 class FPGet2OpMod(PrevControl):
100 def __init__(self, width, id_wid):
101 PrevControl.__init__(self)
102 self.width = width
103 self.id_wid = id_wid
104 self.i_data = self.ispec()
105 self.i = self.i_data
106 self.o = self.ospec()
107
108 def ispec(self):
109 return FPADDBaseData(self.width, self.id_wid)
110
111 def ospec(self):
112 return FPADDBaseData(self.width, self.id_wid)
113
114 def process(self, i):
115 return self.o
116
117 def elaborate(self, platform):
118 m = PrevControl.elaborate(self, platform)
119 with m.If(self.trigger):
120 m.d.comb += [
121 self.o.eq(self.i_data),
122 ]
123 return m
124
125
126 class FPGet2Op(FPState):
127 """ gets operands
128 """
129
130 def __init__(self, in_state, out_state, width, id_wid):
131 FPState.__init__(self, in_state)
132 self.out_state = out_state
133 self.mod = FPGet2OpMod(width, id_wid)
134 self.o = self.ospec()
135 self.in_stb = Signal(reset_less=True)
136 self.out_ack = Signal(reset_less=True)
137 self.out_decode = Signal(reset_less=True)
138
139 def ispec(self):
140 return self.mod.ispec()
141
142 def ospec(self):
143 return self.mod.ospec()
144
145 def trigger_setup(self, m, in_stb, in_ack):
146 """ links stb/ack
147 """
148 m.d.comb += self.mod.valid_i.eq(in_stb)
149 m.d.comb += in_ack.eq(self.mod.ready_o)
150
151 def setup(self, m, i):
152 """ links module to inputs and outputs
153 """
154 m.submodules.get_ops = self.mod
155 m.d.comb += self.mod.i.eq(i)
156 m.d.comb += self.out_ack.eq(self.mod.ready_o)
157 m.d.comb += self.out_decode.eq(self.mod.trigger)
158
159 def process(self, i):
160 return self.o
161
162 def action(self, m):
163 with m.If(self.out_decode):
164 m.next = self.out_state
165 m.d.sync += [
166 self.mod.ready_o.eq(0),
167 self.o.eq(self.mod.o),
168 ]
169 with m.Else():
170 m.d.sync += self.mod.ready_o.eq(1)
171
172