so_i, ov_i, ca_i = self.i.xer_so, self.i.xer_ov, self.i.xer_ca
so_o, ov_o, ca_o = self.o.xer_so, self.o.xer_ov, self.o.xer_ca
o, spr1_o, fast1_o = self.o.o, self.o.spr1, self.o.fast1
+ state1_i, state1_o = self.i.state1, self.o.state1
# take copy of D-Form TO field
x_fields = self.fields.FormXFX
with m.Case(MicrOp.OP_MTSPR):
with m.Switch(spr):
# fast SPRs first
+ with m.Case(SPR.DEC, SPR.TB):
+ comb += state1_o.data.eq(a_i)
+ comb += state1_o.ok.eq(1)
+
+ # state SPRs second
with m.Case(SPR.CTR, SPR.LR, SPR.TAR, SPR.SRR0,
SPR.SRR1, SPR.XER, SPR.DEC, SPR.TB):
comb += fast1_o.data.eq(a_i)
with m.Case(MicrOp.OP_MFSPR):
comb += o.ok.eq(1)
with m.Switch(spr):
- # fast SPRs first
+ # state SPRs first
+ with m.Case(SPR.DEC, SPR.TB):
+ comb += o.data.eq(fast1_i)
+
+ # fast SPRs second
with m.Case(SPR.CTR, SPR.LR, SPR.TAR, SPR.SRR0, SPR.SRR1,
- SPR.XER, SPR.DEC, SPR.TB):
+ SPR.XER):
comb += o.data.eq(fast1_i)
with m.If(spr == SPR.XER):
# bits 0:31 and 35:43 are treated as reserved
regspec = [('INT', 'ra', '0:63'), # RA
('SPR', 'spr1', '0:63'), # SPR (slow)
('FAST', 'fast1', '0:63'), # SPR (fast: LR, CTR etc)
+ ('STATE', 'state1', '0:63'), # SPR (DEC/TB)
('XER', 'xer_so', '32'), # XER bit 32: SO
('XER', 'xer_ov', '33,44'), # XER bit 34/45: CA/CA32
('XER', 'xer_ca', '34,45')] # bit0: ov, bit1: ov32
regspec = [('INT', 'o', '0:63'), # RT
('SPR', 'spr1', '0:63'), # SPR (slow)
('FAST', 'fast1', '0:63'), # SPR (fast: LR, CTR etc)
+ ('STATE', 'state1', '0:63'), # SPR (DEC/TB)
('XER', 'xer_so', '32'), # XER bit 32: SO
('XER', 'xer_ov', '33,44'), # XER bit 34/45: CA/CA32
('XER', 'xer_ca', '34,45')] # bit0: ov, bit1: ov32
'nia': "nia",
'msr': "msr",
'svstate': "svstate",
+ 'issue': "issue", # writing DEC/TB
+ 'state1': "state1", # SPR pipeline
# these 3 allow writing state by Issuer
'sv': "sv", # writing SVSTATE
'd_wr1': "d_wr1", # writing PC
'cia': "cia", # reading PC (issuer)
'msr': "msr", # reading MSR (issuer)
'sv': "sv", # reading SV (issuer)
+ # SPR and DEC/TB FSM
+ 'issue': "issue", # reading DEC/TB
+ 'state1': "state1", # SPR pipeline
}
return w_port_spec, r_port_spec
class FastRegs(RegFileMem, FastRegsEnum): #RegFileArray):
"""FastRegs
- FAST regfile - CTR, LR, TAR, SRR1, SRR2, XER, TB, DEC, SVSRR0
+ FAST regfile - CTR, LR, TAR, SRR1, SRR2, XER, SVSRR0
* QTY 6of 64-bit registers
* 3R2W
def get_port_specs(self):
w_port_spec = {'fast1': "dest1",
- 'issue': "issue", # writing DEC/TB
}
r_port_spec = {'fast1': "src1",
- 'issue': "issue", # reading DEC/TB
'dmi': "dmi" # needed for Debug (DMI)
}
if not self.regreduce_en:
if __name__ == '__main__':
m = Module()
from soc.config.test.test_loadstore import TestMemPspec
- pspec = TestMemPspec()
+ pspec = TestMemPspec(regreduce_en=True)
rf = RegFiles(pspec, make_hazard_vecs=True)
rf.elaborate_into(m, None)
vl = rtlil.convert(m)
self.msr_at_reset = pspec.msr_reset
state_resets = [0x0, # PC at reset
self.msr_at_reset, # MSR at reset
- 0x0] # SVSTATE at reset
+ 0x0, # SVSTATE at reset
+ 0x0, # DEC at reset
+ 0x0] # TB at reset
# register files (yes plural)
self.regs = RegFiles(pspec, make_hazard_vecs=self.make_hazard_vecs,
value to DEC, however the regfile has "passthrough" on it so this
*should* be ok.
- see v3.0B p1097-1099 for Timeer Resource and p1065 and p1076
+ see v3.0B p1097-1099 for Timer Resource and p1065 and p1076
"""
comb, sync = m.d.comb, m.d.sync
- fast_rf = self.core.regs.rf['fast']
- fast_r_dectb = fast_rf.r_ports['issue'] # DEC/TB
- fast_w_dectb = fast_rf.w_ports['issue'] # DEC/TB
+ state_rf = self.core.regs.rf['state']
+ state_r_dectb = state_rf.r_ports['issue'] # DEC/TB
+ state_w_dectb = state_rf.w_ports['issue'] # DEC/TB
with m.FSM() as fsm:
# initiates read of current DEC
with m.State("DEC_READ"):
- comb += fast_r_dectb.addr.eq(FastRegs.DEC)
- comb += fast_r_dectb.ren.eq(1)
+ comb += state_r_dectb.ren.eq(1<<StateRegs.DEC)
with m.If(~self.pause_dec_tb):
m.next = "DEC_WRITE"
with m.Else():
new_dec = Signal(64)
# TODO: MSR.LPCR 32-bit decrement mode
- comb += new_dec.eq(fast_r_dectb.o_data - 1)
- comb += fast_w_dectb.addr.eq(FastRegs.DEC)
- comb += fast_w_dectb.wen.eq(1)
- comb += fast_w_dectb.i_data.eq(new_dec)
+ comb += new_dec.eq(state_r_dectb.o_data - 1)
+ comb += state_w_dectb.wen.eq(1<<StateRegs.DEC)
+ comb += state_w_dectb.i_data.eq(new_dec)
# copy to cur_state for decoder, for an interrupt
sync += spr_dec.eq(new_dec)
m.next = "TB_READ"
# initiates read of current TB
with m.State("TB_READ"):
- comb += fast_r_dectb.addr.eq(FastRegs.TB)
- comb += fast_r_dectb.ren.eq(1)
+ comb += state_r_dectb.ren.eq(1<<StateRegs.TB)
with m.If(~self.pause_dec_tb):
m.next = "TB_WRITE"
m.next = "TB_READ"
with m.Else():
new_tb = Signal(64)
- comb += new_tb.eq(fast_r_dectb.o_data + 1)
- comb += fast_w_dectb.addr.eq(FastRegs.TB)
- comb += fast_w_dectb.wen.eq(1)
- comb += fast_w_dectb.i_data.eq(new_tb)
+ comb += new_tb.eq(state_r_dectb.o_data + 1)
+ comb += state_w_dectb.wen.eq(1<<StateRegs.TB)
+ comb += state_w_dectb.i_data.eq(new_tb)
m.next = "DEC_READ"
return m
from soc.fu.ldst.test.test_pipe_caller import LDSTTestCase
from openpower.test.general.overlap_hazards import (HazardTestCase,
RandomHazardTestCase)
-from openpower.util import spr_to_fast_reg
+from openpower.util import spr_to_fast_reg, spr_to_state_reg
from openpower.consts import StateRegsEnum
# setting both fast and slow SPRs from test data
fregs = core.regs.fast
+ stateregs = core.regs.state
sregs = core.regs.spr
for sprname, val in test.sprs.items():
if isinstance(val, SelectableInt):
print ('set spr %s val %x' % (sprname, val))
fast = spr_to_fast_reg(sprname)
+ state = spr_to_state_reg(sprname)
- if fast is None:
+ if fast is None and state is None:
# match behaviour of SPRMap in power_decoder2.py
for i, x in enumerate(SPR):
if sprname == x.name:
yield from set_ldst_spr(sprname, x.value, val, core)
else:
yield sregs.memory._array[i].eq(val)
+ elif state is not None:
+ print("setting state reg %d (%s) to %x" %
+ (state, sprname, val))
+ if stateregs.unary:
+ rval = stateregs.int.regs[state].reg
+ else:
+ rval = stateregs.memory._array[state]
+ yield rval.eq(val)
else:
print("setting fast reg %d (%s) to %x" %
(fast, sprname, val))