1 # IEEE Floating Point Divider (Single Precision)
2 # Copyright (C) Jonathan P Dawson 2013
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
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
16 class FPDIV(FPBase
, Elaboratable
):
18 def __init__(self
, width
):
22 self
.in_a
= FPOpIn(width
)
23 self
.out_z
= FPOpOut(width
)
27 def add_state(self
, state
):
28 self
.states
.append(state
)
31 def elaborate(self
, platform
=None):
32 """ creates the HDL code-fragment for FPDiv
37 a
= FPNumIn(None, self
.width
, False)
38 z
= FPNumOut(self
.width
, False)
40 m
.submodules
.in_a
= self
.in_a
41 m
.submodules
.out_z
= self
.out_z
45 m
.d
.comb
+= a
.v
.eq(self
.in_a
.v
)
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
)
56 with m
.State("add_1"):
60 z
.e
.eq(a
.e
), # exponent
61 z
.m
.eq(a
.m
+ 1), # mantissa
68 self
.pack(m
, z
, "put_z")
73 with m
.State("put_z"):
74 self
.put_z(m
, z
, self
.out_z
, "get_a")
78 class FPDIVPipe(ControlBase
):
80 def __init__(self
, width
):
82 self
.fpdiv
= FPDIV(width
=width
)
83 ControlBase
.__init
__(self
, self
)
86 return Signal(self
.width
, name
="a")
89 return Signal(self
.width
, name
="z")
91 def setup(self
, m
, i
):
92 m
.d
.comb
+= self
.fpdiv
.in_a
.v
.eq(i
) # connect input
95 return self
.fpdiv
.out_z
.v
# return z output
97 def elaborate(self
, platform
):
98 self
.m
= m
= ControlBase
.elaborate(self
, platform
)
100 m
.submodules
.fpdiv
= self
.fpdiv
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
)
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
)
112 def resultfn(data_o
, expected
, i
, o
):
114 assert data_o
== res
, \
115 "%d-%d received data %x not match expected %x\n" \
116 % (i
, o
, data_o
, res
)
119 if __name__
== "__main__":
120 dut
= FPDIVPipe(width
=16)
123 vl
= rtlil
.convert(dut
, ports
=ports
)
124 with
open("test_fsm_experiment.il", "w") as f
:
126 test
= Test5(dut
, resultfn
, data
=data
)
127 run_simulation(dut
, [test
.send
, test
.rcv
],
128 vcd_name
="test_fsm_experiment.vcd")