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