move test_fsm_experiment.py
[ieee754fpu.git] / src / ieee754 / fpcommon / test / test_fsm_experiment.py
1 # IEEE Floating Point Divider (Single Precision)
2 # Copyright (C) Jonathan P Dawson 2013
3 # 2013-12-12
4
5 from nmigen import Module, Signal, Const, Cat, Elaboratable
6 from nmigen.cli import main, verilog, rtlil
7 from nmigen.compat.sim import run_simulation
8
9 from ieee754.fpcommon.fpbase import (FPNumIn, FPNumOut, FPOpIn,
10 FPOpOut, FPBase)
11 from nmutil.nmoperator import eq
12 from nmutil.singlepipe import SimpleHandshake, ControlBase
13 from nmutil.test.test_buf_pipe import data_chain2, Test5
14
15
16 class FPDIV(FPBase, Elaboratable):
17
18 def __init__(self, width):
19 FPBase.__init__(self)
20 self.width = width
21
22 self.p = FPOpIn(width)
23 self.n = FPOpOut(width)
24
25 self.p.data_i = self.ispec()
26 self.n.data_o = self.ospec()
27
28 self.states = []
29
30 def ispec(self):
31 return Signal(self.width, name="a")
32
33 def ospec(self):
34 return Signal(self.width, name="z")
35
36 def setup(self, m, i):
37 m.d.comb += self.p.v.eq(i) # connect input
38
39 def process(self, i):
40 return self.n.v # return z output
41
42 def add_state(self, state):
43 self.states.append(state)
44 return state
45
46 def elaborate(self, platform=None):
47 """ creates the HDL code-fragment for FPDiv
48 """
49 m = Module()
50
51 # Latches
52 a = FPNumIn(None, self.width, False)
53 z = FPNumOut(self.width, False)
54
55 m.submodules.p = self.p
56 m.submodules.n = self.n
57 m.submodules.a = a
58 m.submodules.z = z
59
60 m.d.comb += a.v.eq(self.p.v)
61
62 with m.FSM() as fsm:
63
64 # ******
65 # gets operand a
66
67 with m.State("get_a"):
68 res = self.get_op(m, self.p, a, "add_1")
69 m.d.sync += eq([a, self.p.ready_o], res)
70
71 with m.State("add_1"):
72 m.next = "pack"
73 m.d.sync += [
74 z.s.eq(a.s), # sign
75 z.e.eq(a.e), # exponent
76 z.m.eq(a.m + 1), # mantissa
77 ]
78
79 # ******
80 # pack stage
81
82 with m.State("pack"):
83 self.pack(m, z, "put_z")
84
85 # ******
86 # put_z stage
87
88 with m.State("put_z"):
89 self.put_z(m, z, self.n, "get_a")
90
91 return m
92
93 class FPDIVPipe(ControlBase):
94
95 def __init__(self, width):
96 self.width = width
97 self.fpdiv = FPDIV(width=width)
98 ControlBase.__init__(self, self.fpdiv)
99
100 def elaborate(self, platform):
101 self.m = m = ControlBase.elaborate(self, platform)
102
103 m.submodules.fpdiv = self.fpdiv
104
105 # see if connecting to stb/ack works
106 m.d.comb += self.fpdiv.p._connect_in(self.p)
107 m.d.comb += self.fpdiv.n._connect_out(self.n, do_data=False)
108 m.d.comb += self.n.data_o.eq(self.data_r)
109
110 return m
111
112 def resultfn(data_o, expected, i, o):
113 res = expected + 1
114 assert data_o == res, \
115 "%d-%d received data %x not match expected %x\n" \
116 % (i, o, data_o, res)
117
118
119 if __name__ == "__main__":
120 dut = FPDIVPipe(width=16)
121 data = data_chain2()
122 ports = dut.ports()
123 vl = rtlil.convert(dut, ports=ports)
124 with open("test_fsm_experiment.il", "w") as f:
125 f.write(vl)
126 test = Test5(dut, resultfn, data=data)
127 run_simulation(dut, [test.send, test.rcv],
128 vcd_name="test_fsm_experiment.vcd")
129