1 from nmutil
.concurrentunit
import PipeContext
2 from nmutil
.dynamicpipe
import SimpleHandshakeRedir
3 from nmigen
import Signal
4 from openpower
.decoder
.power_decoder2
import Data
5 from soc
.fu
.regspec
import get_regspec_bitwidth
9 """FUBaseData: base class for all pipeline data structures
11 see README.md for explanation of parameters and purpose.
13 note the mode parameter - output. XXXInputData specs must
14 have this set to "False", and XXXOutputData specs (and anything
15 that creates intermediary outputs which propagate through a
16 pipeline *to* output) must have it set to "True".
19 def __init__(self
, pspec
, output
, exc_kls
=None):
21 self
.ctx
= PipeContext(pspec
) # context for ReservationStation usage
22 self
.muxid
= self
.ctx
.muxid
24 self
.is_output
= output
25 # take regspec and create data attributes (in or out)
26 # TODO: use widspec to create reduced bit mapping.
28 for i
, (regfile
, regname
, widspec
) in enumerate(self
.regspec
):
29 wid
= get_regspec_bitwidth([self
.regspec
], 0, i
)
31 sig
= Data(wid
, name
=regname
)
33 sig
= Signal(wid
, name
=regname
, reset_less
=True)
34 setattr(self
, regname
, sig
)
36 # optional exception type
37 if exc_kls
is not None:
38 name
= "exc_o" if output
else "exc_i"
39 self
.exception
= exc_kls(name
=name
)
44 if hasattr(self
, "exception"):
45 yield from self
.exception
.ports()
47 # convenience function to return 0:63 if XLEN=64, 0:31 if XLEN=32 etc.
50 return "0:%d" % (self
.pspec
.XLEN
-1)
53 eqs
= [self
.ctx
.eq(i
.ctx
)]
54 assert len(self
.data
) == len(i
.data
), \
55 "length of %s mismatch against %s: %s %s" % \
56 (repr(self
), repr(i
), repr(self
.data
), repr(i
.data
))
57 for j
in range(len(self
.data
)):
58 assert type(self
.data
[j
]) == type(i
.data
[j
]), \
59 "type mismatch in FUBaseData %s %s" % \
60 (repr(self
.data
[j
]), repr(i
.data
[j
]))
61 eqs
.append(self
.data
[j
].eq(i
.data
[j
]))
62 if hasattr(self
, "exception"):
63 eqs
.append(self
.exception
.eq(i
.exception
))
67 return self
.ctx
.ports() # TODO: include self.data
70 # hmmm there has to be a better way than this
71 def get_rec_width(rec
):
73 # Setup random inputs for dut.op
81 """CommonPipeSpec: base class for all pipeline specifications
82 see README.md for explanation of members.
85 def __init__(self
, id_wid
, parent_pspec
):
86 self
.pipekls
= SimpleHandshakeRedir
88 self
.opkls
= lambda _
: self
.opsubsetkls()
89 self
.op_wid
= get_rec_width(self
.opkls(None)) # hmm..
91 self
.parent_pspec
= parent_pspec
93 # forward attributes from parent_pspec
94 def __getattr__(self
, name
):
95 return getattr(self
.parent_pspec
, name
)
98 def get_pspec_draft_bitmanip(pspec
):
99 """ True if the draft bitmanip instructions are enabled in the provided
100 pspec. The instructions enabled by this are draft instructions -- they are
101 not official OpenPower instructions, they are intended to be eventually
102 submitted to the OpenPower ISA WG.
104 https://libre-soc.org/openpower/sv/bitmanip/
106 # use `is True` to account for Mock absurdities
107 return getattr(pspec
, "draft_bitmanip", False) is True