1 from nmutil
.concurrentunit
import PipeContext
2 from nmutil
.dynamicpipe
import SimpleHandshakeRedir
3 from nmigen
import Signal
4 from soc
.decoder
.power_decoder2
import Data
5 from soc
.fu
.regspec
import get_regspec_bitwidth
9 """IntegerData: base class for all pipeline data structures
11 this class auto-constructs parameters (placing them in self.data)
12 based on "regspecs". this is conceptually similar to nmigen Record
13 (Layout, actually) except that Layout does not contain the right type
14 of information for connecting up to Register Files.
16 by having a base class that handles creation of pipeline input/output
17 in a structured fashion, CompUnits may conform to that same structured
18 API, and when it comes to actually connecting up to regfiles, the same
21 the alternative is mountains of explicit code (which quickly becomes
24 note the mode parameter - output. output pipeline data structures
25 need to have an "ok" flag added, which is used by the CompUnit and
26 by the Register File to determine if the output shall in fact be
27 written to the register file or not.
29 input data has *already* been determined to have had to have been read,
30 this by PowerDecoder2.
33 def __init__(self
, pspec
, output
):
34 self
.ctx
= PipeContext(pspec
) # context for ReservationStation usage
35 self
.muxid
= self
.ctx
.muxid
37 self
.is_output
= output
38 for i
, (regfile
, regname
, widspec
) in enumerate(self
.regspec
):
39 wid
= get_regspec_bitwidth([self
.regspec
], 0, i
)
41 sig
= Data(wid
, name
=regname
)
43 sig
= Signal(wid
, name
=regname
, reset_less
=True)
44 setattr(self
, regname
, sig
)
52 eqs
= [self
.ctx
.eq(i
.ctx
)]
53 assert len(self
.data
) == len(i
.data
), \
54 "length of %s mismatch against %s: %s %s" % \
55 (repr(self
), repr(i
), repr(self
.data
), repr(i
.data
))
56 for j
in range(len(self
.data
)):
57 assert type(self
.data
[j
]) == type(i
.data
[j
]), \
58 "type mismatch in IntegerData %s %s" % \
59 (repr(self
.data
[j
]), repr(i
.data
[j
]))
60 eqs
.append(self
.data
[j
].eq(i
.data
[j
]))
64 return self
.ctx
.ports() # TODO: include self.data
67 # hmmm there has to be a better way than this
68 def get_rec_width(rec
):
70 # Setup random inputs for dut.op
78 def __init__(self
, id_wid
):
79 self
.pipekls
= SimpleHandshakeRedir
81 self
.opkls
= lambda _
: self
.opsubsetkls(name
="op")
82 self
.op_wid
= get_rec_width(self
.opkls(None)) # hmm..