convert to use PrevControl and NextControl instead of Trigger class
[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, FPOpIn, Overflow, FPBase, FPNumBase
11 from fpbase import MultiShiftRMerge, Trigger
12 from singlepipe import (ControlBase, StageChain, SimpleHandshake,
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 = 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.o_ready) & \
29 (self.in_op.i_valid_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.o_ready.eq(0),
63 self.out_op.eq(self.mod.out_op)
64 ]
65 with m.Else():
66 m.d.sync += self.in_op.o_ready.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(Trigger):
100 def __init__(self, width, id_wid):
101 Trigger.__init__(self)
102 self.width = width
103 self.id_wid = id_wid
104 self.i = self.ispec()
105 self.o = self.ospec()
106
107 def ispec(self):
108 return FPADDBaseData(self.width, self.id_wid)
109
110 def ospec(self):
111 return FPADDBaseData(self.width, self.id_wid)
112
113 def process(self, i):
114 return self.o
115
116 def elaborate(self, platform):
117 m = Trigger.elaborate(self, platform)
118 with m.If(self.trigger):
119 m.d.comb += [
120 self.o.eq(self.i),
121 ]
122 return m
123
124
125 class FPGet2Op(FPState):
126 """ gets operands
127 """
128
129 def __init__(self, in_state, out_state, width, id_wid):
130 FPState.__init__(self, in_state)
131 self.out_state = out_state
132 self.mod = FPGet2OpMod(width, id_wid)
133 self.o = self.ospec()
134 self.in_stb = Signal(reset_less=True)
135 self.out_ack = Signal(reset_less=True)
136 self.out_decode = Signal(reset_less=True)
137
138 def ispec(self):
139 return self.mod.ispec()
140
141 def ospec(self):
142 return self.mod.ospec()
143
144 def trigger_setup(self, m, in_stb, in_ack):
145 """ links stb/ack
146 """
147 m.d.comb += self.mod.stb.eq(in_stb)
148 m.d.comb += in_ack.eq(self.mod.ack)
149
150 def setup(self, m, i):
151 """ links module to inputs and outputs
152 """
153 m.submodules.get_ops = self.mod
154 m.d.comb += self.mod.i.eq(i)
155 m.d.comb += self.out_ack.eq(self.mod.ack)
156 m.d.comb += self.out_decode.eq(self.mod.trigger)
157
158 def process(self, i):
159 return self.o
160
161 def action(self, m):
162 with m.If(self.out_decode):
163 m.next = self.out_state
164 m.d.sync += [
165 self.mod.ack.eq(0),
166 self.o.eq(self.mod.o),
167 ]
168 with m.Else():
169 m.d.sync += self.mod.ack.eq(1)
170
171