class CoreOutput:
def __init__(self):
# start/stop and terminated signalling
- self.core_terminate_o = Signal(reset=0) # indicates stopped
+ self.core_terminate_o = Signal() # indicates stopped
+ self.busy_o = Signal(name="corebusy_o") # at least one ALU busy
self.exc_happened = Signal() # exception happened
def eq(self, i):
self.core_terminate_o.eq(i.core_terminate_o)
+ self.busy_o.eq(i.busy_o)
self.exc_happened.eq(i.exc_happened)
fus = self.fus.fus
# indicate if core is busy
- busy_o = Signal(name="corebusy_o", reset_less=True)
+ busy_o = self.o.busy_o
# enable/busy-signals for each FU, get one bit for each FU (by name)
fu_enable = Signal(len(fus), reset_less=True)
# now create a PriorityPicker per FU-type such that only one
# non-busy FU will be picked
issue_pps = {}
+ fu_found = Signal() # take a note if no Function Unit was available
for fname, fu_list in by_fnunit.items():
i_pp = PriorityPicker(len(fu_list))
m.submodules['i_pp_%s' % fname] = i_pp
comb += po.eq(i_pp.o[i] & i_pp.en_o)
comb += fu_bitdict[funame].eq(po)
comb += fu_selected[funame].eq(fu.busy_o | po)
+ # if we don't do this, then when there are no FUs available,
+ # the "p.o_ready" signal will go back "ok we accepted this
+ # instruction" which of course isn't true.
+ comb += fu_found.eq(~fnmatch | i_pp.en_o)
# for each input, Cat them together and drop them into the picker
comb += i_pp.i.eq(Cat(*i_l))
busys = map(lambda fu: fu.busy_o, fus.values())
comb += busy_o.eq(Cat(*busys).bool())
- # set ready/valid signalling. if busy, means refuse incoming issue
- # XXX note: for an in-order core this is far too simple. busy must
- # be gated with the *availability* of the incoming (requested)
- # instruction, where Core must be prepared to store-and-hold
- # an instruction if no FU is available.
- comb += self.p.o_ready.eq(~busy_o)
+ # ready/valid signalling. if busy, means refuse incoming issue.
+ # (this is a global signal, TODO, change to one which allows
+ # overlapping instructions)
+ # also, if there was no fu found we must not send back a valid
+ # indicator. BUT, of course, when there is no instruction
+ # we must ignore the fu_found flag, otherwise o_ready will never
+ # be set when everything is idle
+ comb += self.p.o_ready.eq(fu_found | ~self.p.i_valid)
# return both the function unit "enable" dict as well as the "busy".
# the "busy-or-issued" can be passed in to the Read/Write port
pdecode2 = self.pdecode2
# temporaries
- core_busy_o = ~core.p.o_ready # core is busy
+ core_busy_o = ~core.p.o_ready | core.n.o_data.busy_o # core is busy
core_ivalid_i = core.p.i_valid # instruction is valid
with m.FSM(name="exec_fsm"):
comb += dbg_rst.eq(ResetSignal())
# busy/halted signals from core
- core_busy_o = ~core.p.o_ready # core is busy
+ core_busy_o = ~core.p.o_ready | core.n.o_data.busy_o # core is busy
comb += self.busy_o.eq(core_busy_o)
comb += pdecode2.dec.bigendian.eq(self.core_bigendian_i)