call property data_r not data
[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, Elaboratable
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 nmoperator import eq
12 from singlepipe import SimpleHandshake, ControlBase
13 from 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.in_a = FPOpIn(width)
23 self.out_z = FPOpOut(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 = self.in_a
41 m.submodules.out_z = self.out_z
42 m.submodules.a = a
43 m.submodules.z = z
44
45 m.d.comb += a.v.eq(self.in_a.v)
46
47 with m.FSM() as fsm:
48
49 # ******
50 # gets operand a
51
52 with m.State("get_a"):
53 res = self.get_op(m, self.in_a, a, "add_1")
54 m.d.sync += eq([a, self.in_a.ready_o], res)
55
56 with m.State("add_1"):
57 m.next = "pack"
58 m.d.sync += [
59 z.s.eq(a.s), # sign
60 z.e.eq(a.e), # exponent
61 z.m.eq(a.m + 1), # mantissa
62 ]
63
64 # ******
65 # pack stage
66
67 with m.State("pack"):
68 self.pack(m, z, "put_z")
69
70 # ******
71 # put_z stage
72
73 with m.State("put_z"):
74 self.put_z(m, z, self.out_z, "get_a")
75
76 return m
77
78 class FPDIVPipe(ControlBase):
79
80 def __init__(self, width):
81 self.width = width
82 self.fpdiv = FPDIV(width=width)
83 ControlBase.__init__(self, self)
84
85 def ispec(self):
86 return Signal(self.width, name="a")
87
88 def ospec(self):
89 return Signal(self.width, name="z")
90
91 def setup(self, m, i):
92 m.d.comb += self.fpdiv.in_a.v.eq(i) # connect input
93
94 def process(self, i):
95 return self.fpdiv.out_z.v # return z output
96
97 def elaborate(self, platform):
98 self.m = m = ControlBase.elaborate(self, platform)
99
100 m.submodules.fpdiv = self.fpdiv
101
102 # see if connecting to stb/ack works
103 m.d.comb += self.p.ready_o.eq(self.fpdiv.in_a.ready_o)
104 m.d.comb += self.fpdiv.in_a.valid_i.eq(self.p.valid_i_test)
105
106 m.d.comb += self.n.valid_o.eq(self.fpdiv.out_z.valid_o)
107 m.d.comb += self.fpdiv.out_z.ready_i.eq(self.n.ready_i_test)
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