convert fpdiv to pspec
[ieee754fpu.git] / src / ieee754 / fpdiv / divstages.py
1 """IEEE754 Floating Point pipelined Divider
2
3 Relevant bugreport: http://bugs.libre-riscv.org/show_bug.cgi?id=99
4
5 """
6
7 from nmigen import Module
8 from nmigen.cli import main, verilog
9
10 from nmutil.singlepipe import (StageChain, SimpleHandshake)
11
12 from ieee754.fpcommon.fpbase import FPState
13 from ieee754.fpcommon.denorm import FPSCData
14 from ieee754.fpcommon.postcalc import FPAddStage1Data
15
16 # TODO: write these
17 from .div0 import FPDivStage0Mod
18 from .div1 import FPDivStage1Mod
19 from .div2 import FPDivStage2Mod
20 from .div0 import FPDivStage0Data
21
22
23 class FPDivStages(FPState, SimpleHandshake):
24
25 def __init__(self, width, pspec, n_stages, begin, end):
26 FPState.__init__(self, "align")
27 self.width = width
28 self.pspec = pspec
29 self.n_stages = n_stages # number of combinatorial stages
30 self.begin = begin # "begin" mode
31 self.end = end # "end" mode
32 SimpleHandshake.__init__(self, self) # pipeline is its own stage
33 self.m1o = self.ospec()
34
35 def ispec(self):
36 if self.begin:
37 return FPSCData(self.width, self.pspec, False) # from denorm
38 return FPDivStage0Data(self.width, self.pspec) # DIV ispec (loop)
39
40 def ospec(self):
41 if self.end: # TODO
42 return FPAddStage1Data(self.width, self.pspec) # to post-norm
43 return FPDivStage0Data(self.width, self.pspec) # DIV ospec (loop)
44
45 def setup(self, m, i):
46 """ links module to inputs and outputs
47 """
48
49 # start mode accepts data from the FP normalisation stage
50 # and does a bit of munging of the data. it will be chained
51 # into the first DIV combinatorial block,
52
53 # end mode takes the DIV pipeline/chain data and munges it
54 # into the format that the normalisation can accept.
55
56 # neither start nor end mode simply takes the exact same
57 # data in as out, this is where the Q/Rem comes in and Q/Rem goes out
58
59 divstages = []
60
61 if self.begin: # XXX check this
62 divstages.append(FPDivStage0Mod(self.width, self.pspec))
63
64 for count in range(self.n_stages): # number of combinatorial stages
65 divstages.append(FPDivStage1Mod(self.width, self.pspec))
66
67 if self.end: # XXX check this
68 divstages.append(FPDivStage2Mod(self.width, self.pspec))
69
70 chain = StageChain(divstages)
71 chain.setup(m, i)
72
73 # output is from the last pipe stage
74 self.o = divstages[-1].o
75
76 def process(self, i):
77 return self.o
78
79 def action(self, m):
80 m.d.sync += self.m1o.eq(self.process(None))
81 m.next = "normalise_1"
82
83