self.pc_o = Signal(64, reset_less=True)
self.pc_i = Data(64, "pc_i") # set "ok" to indicate "please change me"
self.core_start_i = Signal()
+ self.core_stop_i = Signal()
self.core_bigendian_i = Signal()
self.busy_o = Signal(reset_less=True)
self.halted_o = Signal(reset_less=True)
self.memerr_o = Signal(reset_less=True)
# FAST regfile read /write ports for PC and MSR
- self.fast_r_pc = self.core.regs.rf['fast'].r_ports['d_rd1'] # PC rd
+ self.fast_r_pc = self.core.regs.rf['fast'].r_ports['cia'] # PC rd
self.fast_w_pc = self.core.regs.rf['fast'].w_ports['d_wr1'] # PC wr
- self.fast_r_msr = self.core.regs.rf['fast'].r_ports['d_rd2'] # MSR rd
+ self.fast_r_msr = self.core.regs.rf['fast'].r_ports['msr'] # MSR rd
# hack method of keeping an eye on whether branch/trap set the PC
self.fast_nia = self.core.regs.rf['fast'].w_ports['nia']
# busy/halted signals from core
comb += self.busy_o.eq(core.busy_o)
comb += self.halted_o.eq(core.core_terminated_o)
- comb += self.core_start_i.eq(core.core_start_i)
- comb += self.core_bigendian_i.eq(core.bigendian_i)
+ comb += core.core_start_i.eq(self.core_start_i)
+ comb += core.core_stop_i.eq(self.core_stop_i)
+ comb += core.bigendian_i.eq(self.core_bigendian_i)
# temporary hack: says "go" immediately for both address gen and ST
l0 = core.l0
ldst = core.fus.fus['ldst0']
- m.d.comb += ldst.ad.go.eq(ldst.ad.rel) # link addr-go direct to rel
- m.d.comb += ldst.st.go.eq(ldst.st.rel) # link store-go direct to rel
+ m.d.comb += ldst.ad.go_i.eq(ldst.ad.rel_o) # link addr-go direct to rel
+ m.d.comb += ldst.st.go_i.eq(ldst.st.rel_o) # link store-go direct to rel
# PC and instruction from I-Memory
current_insn = Signal(32) # current fetched instruction (note sync)
insn_type = core.pdecode2.e.do.insn_type
insn_msr = core.pdecode2.msr
+ insn_cia = core.pdecode2.cia
# only run if not in halted state
with m.If(~core.core_terminated_o):
comb += self.imem.f_valid_i.eq(1)
with m.Else():
# not busy: instruction fetched
- insn = self.imem.f_instr_o.word_select(cur_pc[2], 32)
+ f_instr_o = self.imem.f_instr_o
+ if f_instr_o.width == 32:
+ insn = f_instr_o
+ else:
+ insn = f_instr_o.word_select(cur_pc[2], 32)
comb += current_insn.eq(insn)
comb += core_ivalid_i.eq(1) # instruction is valid
comb += core_issue_i.eq(1) # and issued
comb += core_opcode_i.eq(current_insn) # actual opcode
sync += ilatch.eq(current_insn) # latch current insn
- # read MSR
+ # read MSR, latch it, and put it in decode "state"
comb += self.fast_r_msr.ren.eq(1<<FastRegs.MSR)
comb += msr.eq(self.fast_r_msr.data_o)
comb += insn_msr.eq(msr)
sync += cur_msr.eq(msr) # latch current MSR
+ # also drop PC into decode "state"
+ comb += insn_cia.eq(cur_pc)
+
m.next = "INSN_ACTIVE" # move to "wait completion"
# instruction started: must wait till it finishes
comb += core_ivalid_i.eq(1) # instruction is valid
comb += core_opcode_i.eq(ilatch) # actual opcode
comb += insn_msr.eq(cur_msr) # and MSR
+ comb += insn_cia.eq(cur_pc) # and PC
with m.If(self.fast_nia.wen):
sync += pc_changed.eq(1)
with m.If(~core_busy_o): # instruction done!
yield self.memerr_o
yield from self.core.ports()
yield from self.imem.ports()
+ yield self.core_start_i
+ yield self.core_stop_i
+ yield self.core_bigendian_i
+ yield self.busy_o
+ yield self.halted_o
+
+ def ports(self):
+ return list(self)
+
+ def external_ports(self):
+ return self.pc_i.ports() + [self.pc_o,
+ self.go_insn_i,
+ self.memerr_o,
+ self.core_start_i,
+ self.core_stop_i,
+ self.core_bigendian_i,
+ self.busy_o,
+ self.halted_o,
+ ] + \
+ list(self.imem.ibus.fields.values()) + \
+ list(self.core.l0.cmpi.lsmem.lsi.dbus.fields.values())
+
def ports(self):
return list(self)
vl = main(dut, ports=dut.ports(), name="test_issuer")
if len(sys.argv) == 1:
- vl = rtlil.convert(dut, ports=dut.ports(), name="test_issuer")
+ vl = rtlil.convert(dut, ports=dut.external_ports(), name="test_issuer")
with open("test_issuer.il", "w") as f:
f.write(vl)