1 """ concurrent unit from mitch alsup augmentations to 6600 scoreboard
4 * data goes through a pipeline
5 * results fan back out.
7 the output data format has to have a member "muxid", which is used
8 as the array index on fan-out
12 from nmigen
import Module
, Elaboratable
13 from nmigen
.cli
import main
, verilog
15 from nmutil
.singlepipe
import PassThroughStage
16 from nmutil
.multipipe
import CombMuxOutPipe
17 from nmutil
.multipipe
import PriorityCombMuxInPipe
21 return int(log(n
) / log(2))
24 class InMuxPipe(PriorityCombMuxInPipe
):
25 def __init__(self
, num_rows
, iospecfn
, maskwid
=0):
26 self
.num_rows
= num_rows
27 stage
= PassThroughStage(iospecfn
)
28 PriorityCombMuxInPipe
.__init
__(self
, stage
, p_len
=self
.num_rows
,
32 class MuxOutPipe(CombMuxOutPipe
):
33 def __init__(self
, num_rows
, iospecfn
, maskwid
=0):
34 self
.num_rows
= num_rows
35 stage
= PassThroughStage(iospecfn
)
36 CombMuxOutPipe
.__init
__(self
, stage
, n_len
=self
.num_rows
,
40 class ReservationStations(Elaboratable
):
41 """ Reservation-Station pipeline
43 Input: num_rows - number of input and output Reservation Stations
45 Requires: the addition of an "alu" object, from which ispec and ospec
46 are taken, and inpipe and outpipe are connected to it
48 * fan-in on inputs (an array of BaseData: a,b,mid)
50 * fan-out on outputs (an array of FPPackData: z,mid)
52 Fan-in and Fan-out are combinatorial.
54 def __init__(self
, num_rows
, maskwid
=0, feedback_width
=None):
55 self
.num_rows
= nr
= num_rows
56 self
.feedback_width
= feedback_width
57 self
.inpipe
= InMuxPipe(nr
, self
.i_specfn
, maskwid
) # fan-in
58 self
.outpipe
= MuxOutPipe(nr
, self
.o_specfn
, maskwid
) # fan-out
60 self
.p
= self
.inpipe
.p
# kinda annoying,
61 self
.n
= self
.outpipe
.n
# use pipe in/out as this class in/out
62 self
._ports
= self
.inpipe
.ports() + self
.outpipe
.ports()
64 def elaborate(self
, platform
):
66 m
.submodules
.inpipe
= self
.inpipe
67 m
.submodules
.alu
= self
.alu
68 m
.submodules
.outpipe
= self
.outpipe
70 m
.d
.comb
+= self
.inpipe
.n
.connect_to_next(self
.alu
.p
)
71 m
.d
.comb
+= self
.alu
.connect_to_next(self
.outpipe
)
73 if self
.feedback_width
is None:
76 # connect all outputs above the feedback width back to their inputs
77 # (hence, feedback). pipeline stages are then expected to *modify*
78 # the muxid (with care) in order to use the "upper numbered" RSes
79 # for storing partially-completed results. micro-coding, basically
81 for i
in range(self
.feedback_width
, self
.num_rows
):
82 self
.outpipe
.n
[i
].connect_to_next(self
.inpipe
.p
[i
])
90 return self
.alu
.ispec()
93 return self
.alu
.ospec()