From c35ff9b081aa62155e06d702e365ae7887b24f16 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Sat, 30 May 2020 16:23:46 +0100 Subject: [PATCH] mess - but a functional mess. ALU-MultiCompUnit semi-functional using pipeline --- src/soc/experiment/compalu_multi.py | 26 +++++++++---------- .../fu/compunits/test/test_alu_compunit.py | 25 ++++++++++++++++-- 2 files changed, 36 insertions(+), 15 deletions(-) diff --git a/src/soc/experiment/compalu_multi.py b/src/soc/experiment/compalu_multi.py index efe56241..d87fbc85 100644 --- a/src/soc/experiment/compalu_multi.py +++ b/src/soc/experiment/compalu_multi.py @@ -168,15 +168,6 @@ class MultiCompUnit(RegSpecALUAPI, Elaboratable): m.d.comb += all_rd.eq(self.busy_o & rok_l.q & (((~self.rd.rel) | self.rd.go).all())) - # write_requests all done - # req_done works because any one of the last of the writes - # is enough, when combined with when read-phase is done (rst_l.q) - wr_any = Signal(reset_less=True) - req_done = Signal(reset_less=True) - m.d.comb += self.done_o.eq(self.busy_o & ~(self.wr.rel.bool())) - m.d.comb += wr_any.eq(self.wr.go.bool()) - m.d.comb += req_done.eq(rst_l.q & wr_any) - # create rising pulse from alu valid condition. alu_done = Signal(reset_less=True) alu_done_dly = Signal(reset_less=True) @@ -187,6 +178,15 @@ class MultiCompUnit(RegSpecALUAPI, Elaboratable): m.d.comb += alu_pulse.eq(alu_done & ~alu_done_dly) m.d.comb += alu_pulsem.eq(Repl(alu_pulse, self.n_dst)) + # write_requests all done + # req_done works because any one of the last of the writes + # is enough, when combined with when read-phase is done (rst_l.q) + wr_any = Signal(reset_less=True) + req_done = Signal(reset_less=True) + m.d.comb += self.done_o.eq(self.busy_o & ~(self.wr.rel.bool())) + m.d.comb += wr_any.eq(self.wr.go.bool()) + m.d.comb += req_done.eq(wr_any & ~self.alu.n.ready_i & (req_l.q == 0)) + # shadow/go_die reset = Signal(reset_less=True) rst_r = Signal(reset_less=True) # reset latch off @@ -199,7 +199,7 @@ class MultiCompUnit(RegSpecALUAPI, Elaboratable): # read-done,wr-proceed latch m.d.comb += rok_l.s.eq(self.issue_i) # set up when issue starts - m.d.comb += rok_l.r.eq(self.alu.n.valid_o) # off when ALU acknowledges + m.d.comb += rok_l.r.eq(self.alu.n.valid_o & self.busy_o) # off when ALU acknowledges # wr-done, back-to-start latch m.d.comb += rst_l.s.eq(all_rd) # set when read-phase is fully done @@ -207,7 +207,7 @@ class MultiCompUnit(RegSpecALUAPI, Elaboratable): # opcode latch (not using go_rd_i) - inverted so that busy resets to 0 m.d.sync += opc_l.s.eq(self.issue_i) # set on issue - m.d.sync += opc_l.r.eq(self.alu.n.valid_o & req_done) # reset on ALU + m.d.sync += opc_l.r.eq(req_done) # reset on ALU # src operand latch (not using go_wr_i) m.d.sync += src_l.s.eq(Repl(self.issue_i, self.n_src)) @@ -215,7 +215,7 @@ class MultiCompUnit(RegSpecALUAPI, Elaboratable): # dest operand latch (not using issue_i) m.d.comb += req_l.s.eq(alu_pulsem) - m.d.sync += req_l.r.eq(reset_w) + m.d.comb += req_l.r.eq(reset_w) # create a latch/register for the operand oper_r = self.opsubsetkls(name="oper_r") @@ -292,7 +292,7 @@ class MultiCompUnit(RegSpecALUAPI, Elaboratable): # ALU output "ready" side. alu "ready" indication stays hi until # ALU says "valid". m.submodules.alu_l = alu_l = SRLatch(False, name="alu") - m.d.comb += self.alu.n.ready_i.eq(alu_l.qn) + m.d.comb += self.alu.n.ready_i.eq(alu_l.q) m.d.sync += alu_l.r.eq(self.alu.n.valid_o & alu_l.q) m.d.comb += alu_l.s.eq(all_rd_pulse) diff --git a/src/soc/fu/compunits/test/test_alu_compunit.py b/src/soc/fu/compunits/test/test_alu_compunit.py index c133ecdb..1e62545c 100644 --- a/src/soc/fu/compunits/test/test_alu_compunit.py +++ b/src/soc/fu/compunits/test/test_alu_compunit.py @@ -160,15 +160,31 @@ class TestRunner(FHDLTestCase): index = sim.pc.CIA.value//4 out_reg_valid = yield pdecode2.e.write_reg.ok + yield + yield + yield if out_reg_valid: write_reg_idx = yield pdecode2.e.write_reg.data expected = sim.gpr(write_reg_idx).value cu_out = yield from get_cu_output(cu, 0) print(f"expected {expected:x}, actual: {cu_out:x}") self.assertEqual(expected, cu_out, code) + yield + yield + yield yield from self.check_extra_cu_outputs(cu, pdecode2, sim, code) + yield Settle() + busy_o = yield cu.busy_o + if busy_o: + for i in range(cu.n_dst): + wr_rel_o = yield cu.wr.rel[i] + if wr_rel_o: + print ("discard output", i) + discard = yield from get_cu_output(cu, i) + yield + sim.add_sync_process(process) with sim.write_vcd("simulator.vcd", "simulator.gtkw", traces=[]): @@ -176,12 +192,17 @@ class TestRunner(FHDLTestCase): def check_extra_cu_outputs(self, cu, dec2, sim, code): rc = yield dec2.e.rc.data - if rc: + op = yield dec2.e.insn_type + + if rc or \ + op == InternalOp.OP_CMP.value or \ + op == InternalOp.OP_CMPEQB.value: cr_actual = yield from get_cu_output(cu, 1) + + if rc: cr_expected = sim.crl[0].get_range().value self.assertEqual(cr_expected, cr_actual, code) - op = yield dec2.e.insn_type if op == InternalOp.OP_CMP.value or \ op == InternalOp.OP_CMPEQB.value: bf = yield dec2.dec.BF -- 2.30.2