scoreboard 6600 experimentation
[soc.git] / src / scoreboard / fn_unit.py
index a21911d300fa9e665a14de93a0141e970579332b..3edabbde16eb2c2dc41eb4b5f9e8a4d508835090 100644 (file)
@@ -1,9 +1,10 @@
 from nmigen.compat.sim import run_simulation
 from nmigen.cli import verilog, rtlil
 from nmigen import Module, Signal, Cat, Array, Const, Elaboratable
-from nmutil.latch import SRLatch
 from nmigen.lib.coding import Decoder
 
+from nmutil.latch import SRLatch, latchregister
+
 from .shadow_fn import ShadowFn
 
 
@@ -125,6 +126,7 @@ class FnUnit(Elaboratable):
         for i in range(self.n_dests):
             m.d.comb += self.xx_pend_o[i].eq(0)  # initialise all array
             m.d.comb += self.writable_o[i].eq(0) # to zero
+            m.d.comb += self.readable_o[i].eq(0) # to zero
 
         # go_wr latch: reset on go_wr HI, set on issue
         m.d.comb += wr_l.s.eq(self.issue_i)
@@ -134,16 +136,25 @@ class FnUnit(Elaboratable):
         m.d.comb += rd_l.s.eq(self.issue_i)
         m.d.comb += rd_l.r.eq(self.go_rd_i | recover)
 
-        # dest decoder: write-pending out
-        m.d.comb += dest_d.i.eq(self.dest_i)
+        # latch/registers for dest / src1 / src2
+        dest_r = Signal(max=self.reg_width, reset_less=True)
+        src1_r = Signal(max=self.reg_width, reset_less=True)
+        src2_r = Signal(max=self.reg_width, reset_less=True)
+        # XXX latch based on *issue* rather than !latch (as in book)
+        latchregister(m, self.dest_i, dest_r, self.issue_i) #wr_l.qn)
+        latchregister(m, self.src1_i, src1_r, self.issue_i) #wr_l.qn)
+        latchregister(m, self.src2_i, src2_r, self.issue_i) #wr_l.qn)
+
+        # dest decoder (use dest reg as input): write-pending out
+        m.d.comb += dest_d.i.eq(dest_r)
         m.d.comb += dest_d.n.eq(wr_l.qn) # decode is inverted
         m.d.comb += self.busy_o.eq(wr_l.q) # busy if set
         m.d.comb += xx_pend_o.eq(dest_d.o)
 
-        # src1/src2 decoder: read-pending out
-        m.d.comb += src1_d.i.eq(self.src1_i)
+        # src1/src2 decoder (use src1/2 regs as input): read-pending out
+        m.d.comb += src1_d.i.eq(src1_r)
         m.d.comb += src1_d.n.eq(rd_l.qn) # decode is inverted
-        m.d.comb += src2_d.i.eq(self.src2_i)
+        m.d.comb += src2_d.i.eq(src2_r)
         m.d.comb += src2_d.n.eq(rd_l.qn) # decode is inverted
         m.d.comb += self.src1_pend_o.eq(src1_d.o)
         m.d.comb += self.src2_pend_o.eq(src2_d.o)
@@ -151,8 +162,10 @@ class FnUnit(Elaboratable):
 
         # readable output signal
         g_rd = Signal(self.reg_width, reset_less=True)
+        ro = Signal(reset_less=True)
         m.d.comb += g_rd.eq(self.g_wr_pend_i & self.rd_pend_o)
-        m.d.comb += self.readable_o.eq(g_rd.bool())
+        m.d.comb += ro.eq(~g_rd.bool())
+        m.d.comb += self.readable_o.eq(ro & rd_l.q)
 
         # writable output signal
         g_wr_v = Signal(self.reg_width, reset_less=True)
@@ -160,7 +173,7 @@ class FnUnit(Elaboratable):
         wo = Signal(reset_less=True)
         m.d.comb += g_wr_v.eq(g_pend_i & xx_pend_o)
         m.d.comb += g_wr.eq(~g_wr_v.bool())
-        m.d.comb += wo.eq(g_wr & rd_l.q & self.req_rel_i & shadown)
+        m.d.comb += wo.eq(g_wr & rd_l.qn & self.req_rel_i & shadown)
         m.d.comb += writable_o.eq(wo)
 
         return m