even more complexity in CompALUMulti, to deal with an edge case where
authorLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 11 Jun 2020 14:29:41 +0000 (15:29 +0100)
committerLuke Kenneth Casson Leighton <lkcl@lkcl.net>
Thu, 11 Jun 2020 14:29:41 +0000 (15:29 +0100)
go-write is requested immediately (same cycle as go-req).
the set and reset on "req_l" happen to come in on the same cycle.
the result: the latch *remains* set high.
solution: record the go signals for one extra cycle (sync) and push
them into the req-reset and wr_any signals

src/soc/experiment/compalu_multi.py
src/soc/fu/compunits/test/test_compunit.py

index a73d305ba6758bc51c6a4e51df128cf37ad43e03..2767a9c3540b7e05397c432cf0409623decdb1d1 100644 (file)
@@ -194,6 +194,11 @@ 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))
 
+        # sigh bug where req_l gets both set and reset raised at same time
+        prev_wr_go = Signal(self.n_dst)
+        brd = Repl(self.busy_o, self.n_dst)
+        m.d.sync += prev_wr_go.eq(self.wr.go & brd)
+
         # 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)
@@ -201,7 +206,7 @@ class MultiCompUnit(RegSpecALUAPI, Elaboratable):
         req_done = Signal(reset_less=True)
         m.d.comb += self.done_o.eq(self.busy_o & \
                                    ~((self.wr.rel & ~self.wrmask).bool()))
-        m.d.comb += wr_any.eq(self.wr.go.bool())
+        m.d.comb += wr_any.eq(self.wr.go.bool() | prev_wr_go.bool())
         m.d.comb += req_done.eq(wr_any & ~self.alu.n.ready_i & \
                 ((req_l.q & self.wrmask) == 0))
         # argh, complicated hack: if there are no regs to write,
@@ -238,8 +243,8 @@ class MultiCompUnit(RegSpecALUAPI, Elaboratable):
         m.d.sync += src_l.r.eq(reset_r)
 
         # dest operand latch (not using issue_i)
-        m.d.comb += req_l.s.eq(alu_pulsem)
-        m.d.comb += req_l.r.eq(reset_w)
+        m.d.comb += req_l.s.eq(alu_pulsem & self.wrmask)
+        m.d.comb += req_l.r.eq(reset_w | prev_wr_go)
 
         # create a latch/register for the operand
         oper_r = self.opsubsetkls(name="oper_r")
index ee3c6fce44905acb3dc4f1eec641b426c909f2d4..5128ca52ff9231ff12244d858dea5f549ac838d2 100644 (file)
@@ -204,7 +204,6 @@ class TestRunner(FHDLTestCase):
                                 "respec %s" % \
                                 (bin(wr_rel_o), cu.rwid[1])
                     yield from set_cu_inputs(cu, inp)
-                    yield
                     rd_rel_o = yield cu.rd.rel
                     wr_rel_o = yield cu.wr.rel
                     wrmask = yield cu.wrmask