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