current_insn = Signal(32) # current fetched instruction (note sync)
current_pc = Signal(64) # current PC (note it is reset/sync)
comb += self.pc_o.eq(current_pc)
+ ilatch = Signal(32)
# next instruction (+4 on current)
nia = Signal(64, reset_less=True)
- comb += nia.eq(current_insn + 4)
+ comb += nia.eq(current_pc + 4)
# temporaries
core_busy_o = core.busy_o # core is busy
# capture the PC and also drop it into Insn Memory
# we have joined a pair of combinatorial memory
# lookups together. this is Generally Bad.
- sync += current_pc.eq(pc)
- comb += self.i_rd.addr.eq(pc)
- #comb += self.i_rd.en.eq(1) # comb-read (no need to set)
- sync += current_insn.eq(self.i_rd.data)
+ comb += self.i_rd.addr.eq(pc[2:]) # ignore last 2 bits
+ comb += current_insn.eq(self.i_rd.data)
+ comb += current_pc.eq(pc)
m.next = "INSN_READ" # move to "issue" phase
# got the instruction: start issue
with m.State("INSN_READ"):
+ comb += current_insn.eq(self.i_rd.data)
comb += core_ivalid_i.eq(1) # say instruction is valid
comb += core_issue_i.eq(1) # and issued (ivalid_i redundant)
comb += core_be_i.eq(0) # little-endian mode
comb += core_opcode_i.eq(current_insn) # actual opcode
+ sync += ilatch.eq(current_insn)
m.next = "INSN_ACTIVE" # move to "wait for completion" phase
# instruction started: must wait till it finishes
with m.State("INSN_ACTIVE"):
comb += core_ivalid_i.eq(1) # say instruction is valid
- comb += core_opcode_i.eq(current_insn) # actual opcode
+ comb += core_opcode_i.eq(ilatch) # actual opcode
#sync += core_issue_i.eq(0) # issue raises for only one cycle
with m.If(~core_busy_o): # instruction done!
#sync += core_ivalid_i.eq(0) # say instruction is invalid
m = Module()
comb = m.d.comb
go_insn_i = Signal()
+ pc_i = Signal(32)
m.submodules.issuer = issuer = TestIssuer()
imem = issuer.imem.mem
pdecode2 = core.pdecode2
l0 = core.l0
+ comb += issuer.pc_i.data.eq(pc_i)
comb += issuer.go_insn_i.eq(go_insn_i)
# nmigen Simulation
yield from setup_test_memory(l0, sim)
yield from setup_regs(core, test)
- yield issuer.pc_i.data.eq(pc)
+ yield pc_i.eq(pc)
yield issuer.pc_i.ok.eq(1)
index = sim.pc.CIA.value//4
# Memory check
yield from check_sim_memory(self, l0, sim, code)
+ yield
+
sim.add_sync_process(process)
with sim.write_vcd("issuer_simulator.vcd",
traces=[]):