# test is SVP64 is to be enabled
self.svp64_en = hasattr(pspec, "svp64") and (pspec.svp64 == True)
+ # and if regfiles are reduced
+ self.regreduce_en = (hasattr(pspec, "regreduce") and
+ (pspec.regreduce == True))
+
# JTAG interface. add this right at the start because if it's
# added it *modifies* the pspec, by adding enable/disable signals
# for parts of the rest of the core
self.cur_state = CoreState("cur") # current state (MSR/PC/SVSTATE)
self.pdecode2 = PowerDecode2(pdecode, state=self.cur_state,
opkls=IssuerDecode2ToOperand,
- svp64_en=self.svp64_en)
+ svp64_en=self.svp64_en,
+ regreduce_en=self.regreduce_en)
if self.svp64_en:
self.svp64 = SVP64PrefixDecoder() # for decoding SVP64 prefix
self.cr_r = crrf.r_ports['full_cr_dbg'] # CR read
self.xer_r = xerrf.r_ports['full_xer'] # XER read
- # for predication
- self.int_pred = intrf.r_ports['pred'] # INT predicate read
- self.cr_pred = crrf.r_ports['cr_pred'] # CR predicate read
+ if self.svp64_en:
+ # for predication
+ self.int_pred = intrf.r_ports['pred'] # INT predicate read
+ self.cr_pred = crrf.r_ports['cr_pred'] # CR predicate read
# hack method of keeping an eye on whether branch/trap set the PC
self.state_nia = self.core.regs.rf['state'].w_ports['nia']
later, a faster way would be to use the 32-bit-wide CR port but
this is more complex decoding, here. equivalent code used in
ISACaller is "from soc.decoder.isa.caller import get_predcr"
+
+ note: this ENTIRE FSM is not to be called when svp64 is disabled
"""
comb = m.d.comb
sync = m.d.sync
comb += update_svstate.eq(1)
sync += sv_changed.eq(1)
- # decode the instruction when it arrives
+ # wait for an instruction to arrive from Fetch
with m.State("INSN_WAIT"):
comb += fetch_insn_ready_i.eq(1)
with m.If(fetch_insn_valid_o):
- # decode the instruction
- sync += core.e.eq(pdecode2.e)
- sync += core.state.eq(cur_state)
- sync += core.raw_insn_i.eq(dec_opcode_i)
- sync += core.bigendian_i.eq(self.core_bigendian_i)
- # set RA_OR_ZERO detection in satellite decoders
- sync += core.sv_a_nz.eq(pdecode2.sv_a_nz)
# loop into ISSUE_START if it's a SVP64 instruction
# and VL == 0. this because VL==0 is a for-loop
# from 0 to 0 i.e. always, always a NOP.
if self.svp64_en:
m.next = "PRED_START" # start fetching predicate
else:
- m.next = "INSN_EXECUTE" # skip predication
+ m.next = "DECODE_SV" # skip predication
with m.State("PRED_START"):
comb += pred_insn_valid_i.eq(1) # tell fetch_pred to start
with m.State("MASK_WAIT"):
comb += pred_mask_ready_i.eq(1) # ready to receive the masks
with m.If(pred_mask_valid_o): # predication masks are ready
- m.next = "INSN_EXECUTE"
-
- # handshake with execution FSM, move to "wait" once acknowledged
- with m.State("INSN_EXECUTE"):
- # with m.If(is_svp64_mode):
- # TODO advance src/dst step to "skip" over predicated-out
- # from self.srcmask and self.dstmask
- # https://bugs.libre-soc.org/show_bug.cgi?id=617#c3
- # but still without exceeding VL in either case
- # IMPORTANT: when changing src/dest step, have to
- # jump to m.next = "DECODE_SV" to deal with the change in
- # SVSTATE
+ # with m.If(is_svp64_mode):
+ # TODO advance src/dst step to "skip" over predicated-out
+ # from self.srcmask and self.dstmask
+ # https://bugs.libre-soc.org/show_bug.cgi?id=617#c3
+ # but still without exceeding VL in either case
+ # IMPORTANT: when changing src/dest step, have to
+ # jump to m.next = "DECODE_SV" to deal with the change in
+ # SVSTATE
+
+ with m.If(is_svp64_mode):
+ if self.svp64_en:
+ pred_src_zero = pdecode2.rm_dec.pred_sz
+ pred_dst_zero = pdecode2.rm_dec.pred_dz
- with m.If(is_svp64_mode):
+ """
+ TODO: actually, can use
+ PriorityEncoder(self.srcmask | (1<<cur_srcstep))
- if self.svp64_en:
- pred_src_zero = pdecode2.rm_dec.pred_sz
- pred_dst_zero = pdecode2.rm_dec.pred_dz
+ if not pred_src_zero:
+ if (((1<<cur_srcstep) & self.srcmask) == 0) and
+ (cur_srcstep != vl):
+ comb += update_svstate.eq(1)
+ comb += new_svstate.srcstep.eq(next_srcstep)
- """
- TODO: actually, can use
- PriorityEncoder(self.srcmask | (1<<cur_srcstep))
+ if not pred_dst_zero:
+ if (((1<<cur_dststep) & self.dstmask) == 0) and
+ (cur_dststep != vl):
+ comb += new_svstate.dststep.eq(next_dststep)
+ comb += update_svstate.eq(1)
- if not pred_src_zero:
- if (((1<<cur_srcstep) & self.srcmask) == 0) and
- (cur_srcstep != vl):
- comb += update_svstate.eq(1)
- comb += new_svstate.srcstep.eq(next_srcstep)
+ if update_svstate:
+ m.next = "DECODE_SV"
+ """
- if not pred_dst_zero:
- if (((1<<cur_dststep) & self.dstmask) == 0) and
- (cur_dststep != vl):
- comb += new_svstate.dststep.eq(next_dststep)
- comb += update_svstate.eq(1)
+ m.next = "DECODE_SV"
- if update_svstate:
- m.next = "DECODE_SV"
- """
+ # after src/dst step have been updated, we are ready
+ # to decode the instruction
+ with m.State("DECODE_SV"):
+ # decode the instruction
+ sync += core.e.eq(pdecode2.e)
+ sync += core.state.eq(cur_state)
+ sync += core.raw_insn_i.eq(dec_opcode_i)
+ sync += core.bigendian_i.eq(self.core_bigendian_i)
+ # set RA_OR_ZERO detection in satellite decoders
+ sync += core.sv_a_nz.eq(pdecode2.sv_a_nz)
+ m.next = "INSN_EXECUTE" # move to "execute"
+ # handshake with execution FSM, move to "wait" once acknowledged
+ with m.State("INSN_EXECUTE"):
comb += exec_insn_valid_i.eq(1) # trigger execute
with m.If(exec_insn_ready_o): # execute acknowledged us
m.next = "EXECUTE_WAIT"
comb += update_svstate.eq(1)
sync += sv_changed.eq(1)
- # need to decode the instruction again, after updating SRCSTEP
- # in the previous state.
- # mostly a copy of INSN_WAIT, but without the actual wait
- with m.State("DECODE_SV"):
- # decode the instruction
- sync += core.e.eq(pdecode2.e)
- sync += core.state.eq(cur_state)
- sync += core.bigendian_i.eq(self.core_bigendian_i)
- sync += core.sv_a_nz.eq(pdecode2.sv_a_nz)
- m.next = "INSN_EXECUTE" # move to "execute"
-
# check if svstate needs updating: if so, write it to State Regfile
with m.If(update_svstate):
comb += self.state_w_sv.wen.eq(1<<StateRegs.SVSTATE)