mess - but a functional mess. ALU-MultiCompUnit semi-functional using pipeline
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 30 May 2020 15:23:46 +0000 (16:23 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Sat, 30 May 2020 15:23:46 +0000 (16:23 +0100)
src/soc/experiment/compalu_multi.py
src/soc/fu/compunits/test/test_alu_compunit.py

index efe5624163e1b57395067f9b2de9439fcb8b162b..d87fbc8593ae5215afd3d08425b038e78ec43dd6 100644 (file)
@@ -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)
 
index c133ecdba5e3bef1e28fa06cdf848c7b68a7f457..1e62545cafea529894c6ff4ac0565f49adc32d28 100644 (file)
@@ -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