document concurrentunit
[ieee754fpu.git] / src / nmutil / concurrentunit.py
1 """ concurrent unit from mitch alsup augmentations to 6600 scoreboard
2
3 * data fans in
4 * data goes through a pipeline
5 * results fan back out.
6
7 the output data format has to have a member "mid", which is used
8 as the array index on fan-out
9 """
10
11 from math import log
12 from nmigen import Module
13 from nmigen.cli import main, verilog
14
15 from nmutil.singlepipe import PassThroughStage
16 from nmutil.multipipe import CombMuxOutPipe
17 from nmutil.multipipe import PriorityCombMuxInPipe
18
19
20 def num_bits(n):
21 return int(log(n) / log(2))
22
23
24 class FPADDInMuxPipe(PriorityCombMuxInPipe):
25 def __init__(self, num_rows, iospecfn):
26 self.num_rows = num_rows
27 stage = PassThroughStage(iospecfn)
28 PriorityCombMuxInPipe.__init__(self, stage, p_len=self.num_rows)
29
30
31 class FPADDMuxOutPipe(CombMuxOutPipe):
32 def __init__(self, num_rows, iospecfn):
33 self.num_rows = num_rows
34 stage = PassThroughStage(iospecfn)
35 CombMuxOutPipe.__init__(self, stage, n_len=self.num_rows)
36
37
38 class ReservationStations:
39 """ Reservation-Station pipeline
40
41 Input: num_rows - number of input and output Reservation Stations
42
43 Requires: the addition of an "alu" object, an i_specfn and an o_specfn
44
45 * fan-in on inputs (an array of FPADDBaseData: a,b,mid)
46 * ALU pipeline
47 * fan-out on outputs (an array of FPPackData: z,mid)
48
49 Fan-in and Fan-out are combinatorial.
50 """
51 def __init__(self, num_rows):
52 self.num_rows = num_rows
53 self.inpipe = FPADDInMuxPipe(num_rows, self.i_specfn) # fan-in
54 self.outpipe = FPADDMuxOutPipe(num_rows, self.o_specfn) # fan-out
55
56 self.p = self.inpipe.p # kinda annoying,
57 self.n = self.outpipe.n # use pipe in/out as this class in/out
58 self._ports = self.inpipe.ports() + self.outpipe.ports()
59
60 def elaborate(self, platform):
61 m = Module()
62 m.submodules.inpipe = self.inpipe
63 m.submodules.alu = self.alu
64 m.submodules.outpipe = self.outpipe
65
66 m.d.comb += self.inpipe.n.connect_to_next(self.alu.p)
67 m.d.comb += self.alu.connect_to_next(self.outpipe)
68
69 return m
70
71 def ports(self):
72 return self._ports
73
74