From: Luke Kenneth Casson Leighton Date: Tue, 7 Jul 2020 13:14:46 +0000 (+0100) Subject: add core start/stop capability, and OP_ATTN support X-Git-Tag: div_pipeline~162^2~13 X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=9111ba8618e5945892dc0e2f6ec764bfe7ffbe71;p=soc.git add core start/stop capability, and OP_ATTN support --- diff --git a/src/soc/simple/core.py b/src/soc/simple/core.py index faaee956..f2e1a1de 100644 --- a/src/soc/simple/core.py +++ b/src/soc/simple/core.py @@ -78,6 +78,11 @@ class NonProductionCore(Elaboratable): self.bigendian_i = self.pdecode2.dec.bigendian self.raw_opcode_i = self.pdecode2.dec.raw_opcode_in + # start/stop and terminated signalling + self.core_start_i = Signal(reset_less=True) + self.core_stop_i = Signal(reset_less=True) + self.core_terminated_o = Signal(reset=1) # indicates stopped + def elaborate(self, platform): m = Module() @@ -88,13 +93,24 @@ class NonProductionCore(Elaboratable): regs = self.regs fus = self.fus.fus - fu_bitdict = self.connect_instruction(m) + # core start/stopped state + core_stopped = Signal(reset=1) # begins in stopped state + + # start/stop signalling + with m.If(self.core_start_i): + m.d.sync += core_stopped.eq(1) + with m.If(self.core_stop_i): + m.d.sync += core_stopped.eq(0) + m.d.comb += self.core_terminated_o.eq(core_stopped) + + # connect up Function Units, then read/write ports + fu_bitdict = self.connect_instruction(m, core_stopped) self.connect_rdports(m, fu_bitdict) self.connect_wrports(m, fu_bitdict) return m - def connect_instruction(self, m): + def connect_instruction(self, m, core_stopped): comb, sync = m.d.comb, m.d.sync fus = self.fus.fus dec2 = self.pdecode2 @@ -105,19 +121,30 @@ class NonProductionCore(Elaboratable): for i, funame in enumerate(fus.keys()): fu_bitdict[funame] = fu_enable[i] + # only run when allowed and when instruction is valid + can_run = Signal(reset_less=True) + comb += can_run.eq(self.ivalid_i & ~core_stopped) + # connect up instructions. only one is enabled at any given time for funame, fu in fus.items(): fnunit = fu.fnunit.value enable = Signal(name="en_%s" % funame, reset_less=True) - comb += enable.eq(self.ivalid_i & - (dec2.e.do.fn_unit & fnunit).bool()) + comb += enable.eq((dec2.e.do.fn_unit & fnunit).bool() & can_run) + + # run this FunctionUnit if enabled, except if the instruction + # is "attn" in which case we HALT. with m.If(enable): - comb += fu.oper_i.eq_from_execute1(dec2.e) - comb += fu.issue_i.eq(self.issue_i) - comb += self.busy_o.eq(fu.busy_o) - rdmask = dec2.rdflags(fu) - comb += fu.rdmaskn.eq(~rdmask) - comb += fu_bitdict[funame].eq(enable) + with m.If(dec2.e.op.internal_op == InternalOp.OP_ATTN): + # check for ATTN: halt if true + m.d.sync += core_stopped.eq(1) + with m.Else(): + # route operand, issue, busy, read flags and mask to FU + comb += fu.oper_i.eq_from_execute1(dec2.e) + comb += fu.issue_i.eq(self.issue_i) + comb += self.busy_o.eq(fu.busy_o) + rdmask = dec2.rdflags(fu) + comb += fu.rdmaskn.eq(~rdmask) + comb += fu_bitdict[funame].eq(enable) return fu_bitdict diff --git a/src/soc/simple/issuer.py b/src/soc/simple/issuer.py index e787df5f..d0d1c5e2 100644 --- a/src/soc/simple/issuer.py +++ b/src/soc/simple/issuer.py @@ -70,14 +70,14 @@ class TestIssuer(Elaboratable): # PC and instruction from I-Memory current_insn = Signal(32) # current fetched instruction (note sync) - current_pc = Signal(64) # current PC (note it is reset/sync) + cur_pc = Signal(64) # current PC (note it is reset/sync) pc_changed = Signal() # note write to PC - comb += self.pc_o.eq(current_pc) + comb += self.pc_o.eq(cur_pc) ilatch = Signal(32) # next instruction (+4 on current) nia = Signal(64, reset_less=True) - comb += nia.eq(current_pc + 4) + comb += nia.eq(cur_pc + 4) # temporaries core_busy_o = core.busy_o # core is busy @@ -86,65 +86,65 @@ class TestIssuer(Elaboratable): core_be_i = core.bigendian_i # bigendian mode core_opcode_i = core.raw_opcode_i # raw opcode - # actually use a nmigen FSM for the first time (w00t) - with m.FSM() as fsm: - - # waiting (zzz) - with m.State("IDLE"): - sync += pc_changed.eq(0) - with m.If(self.go_insn_i): - # instruction allowed to go: start by reading the PC - pc = Signal(64, reset_less=True) - with m.If(self.pc_i.ok): - # incoming override (start from pc_i) - comb += pc.eq(self.pc_i.data) + # only run if not in halted state + with m.If(~core.core_terminated_o): + + # actually use a nmigen FSM for the first time (w00t) + with m.FSM() as fsm: + + # waiting (zzz) + with m.State("IDLE"): + sync += pc_changed.eq(0) + with m.If(self.go_insn_i): + # instruction allowed to go: start by reading the PC + pc = Signal(64, reset_less=True) + with m.If(self.pc_i.ok): + # incoming override (start from pc_i) + comb += pc.eq(self.pc_i.data) + with m.Else(): + # otherwise read FastRegs regfile for PC + comb += self.fast_rd1.ren.eq(1<