X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fscoreboard%2Fdependence_cell.py;h=be0359c9657ded696413bf1c00b1a2626827a98d;hb=3896acf98b2696031f23c9c6884b436815ee6dbf;hp=67694813250882ff6def24186fb909eb28a72132;hpb=339aaa6f522358532929e7c23c546c49725707f9;p=soc.git diff --git a/src/scoreboard/dependence_cell.py b/src/scoreboard/dependence_cell.py index 67694813..be0359c9 100644 --- a/src/scoreboard/dependence_cell.py +++ b/src/scoreboard/dependence_cell.py @@ -4,6 +4,53 @@ from nmigen import Module, Signal, Elaboratable, Array, Cat from nmutil.latch import SRLatch +class DepCell(Elaboratable): + """ implements 11.4.7 mitch alsup dependence cell, p27 + adjusted to be clock-sync'd on rising edge only. + mitch design (as does 6600) requires alternating rising/falling clock + """ + def __init__(self): + # inputs + self.reg_i = Signal(reset_less=True) # reg bit in (top) + self.issue_i = Signal(reset_less=True) # Issue in (top) + self.go_i = Signal(reset_less=True) # Go read/write in (left) + + # for Register File Select Lines (vertical) + self.rsel_o = Signal(reset_less=True) # reg sel (bottom) + # for Function Unit "forward progress" (horizontal) + self.fwd_o = Signal(reset_less=True) # FU forard progress (right) + + def elaborate(self, platform): + m = Module() + m.submodules.l = l = SRLatch(sync=False) # async latch + + # record current version of q in a sync'd register + cq = Signal() # resets to 0 + m.d.sync += cq.eq(l.q) + + # reset on go HI, set on dest and issue + m.d.comb += l.s.eq(self.issue_i & self.reg_i) + m.d.comb += l.r.eq(self.go_i) + + # Function Unit "Forward Progress". + m.d.comb += self.fwd_o.eq((cq | l.q) & self.reg_i & ~self.issue_i) + + # Register Select. Activated on go read/write and *current* latch set + m.d.comb += self.rsel_o.eq((cq | l.q) & self.go_i) + + return m + + def __iter__(self): + yield self.regt_i + yield self.issue_i + yield self.go_i + yield self.rsel_o + yield self.fwd_o + + def ports(self): + return list(self) + + class DependenceCell(Elaboratable): """ implements 11.4.7 mitch alsup dependence cell, p27 """ @@ -29,31 +76,31 @@ class DependenceCell(Elaboratable): def elaborate(self, platform): m = Module() - m.submodules.dest_l = dest_l = SRLatch() # clock-sync'd - m.submodules.src1_l = src1_l = SRLatch() # clock-sync'd - m.submodules.src2_l = src2_l = SRLatch() # clock-sync'd - - # destination latch: reset on go_wr HI, set on dest and issue - m.d.comb += dest_l.s.eq(self.issue_i & self.dest_i) - m.d.comb += dest_l.r.eq(self.go_wr_i) - - # src1 latch: reset on go_rd HI, set on src1_i and issue - m.d.comb += src1_l.s.eq(self.issue_i & self.src1_i) - m.d.comb += src1_l.r.eq(self.go_rd_i) - - # src2 latch: reset on go_rd HI, set on op2_i and issue - m.d.comb += src2_l.s.eq(self.issue_i & self.src2_i) - m.d.comb += src2_l.r.eq(self.go_rd_i) - - # FU "Forward Progress" (read out horizontally) - m.d.comb += self.dest_fwd_o.eq(dest_l.q & self.go_wr_i) - m.d.comb += self.src1_fwd_o.eq(src1_l.q & self.go_rd_i) - m.d.comb += self.src2_fwd_o.eq(src2_l.q & self.go_rd_i) - - # Register File Select (read out vertically) - m.d.comb += self.dest_rsel_o.eq(dest_l.q & self.dest_i) - m.d.comb += self.src1_rsel_o.eq(src1_l.q & self.src1_i) - m.d.comb += self.src2_rsel_o.eq(src2_l.q & self.src2_i) + m.submodules.dest_c = dest_c = DepCell() + m.submodules.src1_c = src1_c = DepCell() + m.submodules.src2_c = src2_c = DepCell() + + # connect issue + for c in [dest_c, src1_c, src2_c]: + m.d.comb += c.issue_i.eq(self.issue_i) + + # connect go_rd / go_wr (dest->wr, src->rd) + m.d.comb += dest_c.go_i.eq(self.go_wr_i) + m.d.comb += src1_c.go_i.eq(self.go_rd_i) + m.d.comb += src2_c.go_i.eq(self.go_rd_i) + + # connect input reg bit (unary) + for c, reg in [(dest_c, self.dest_i), + (src1_c, self.src1_i), + (src2_c, self.src2_i)]: + m.d.comb += c.reg_i.eq(reg) + + # connect fwd / reg-sel outputs + for c, fwd, rsel in [(dest_c, self.dest_fwd_o, self.dest_rsel_o), + (src1_c, self.src1_fwd_o, self.src1_rsel_o), + (src2_c, self.src2_fwd_o, self.src2_rsel_o)]: + m.d.comb += fwd.eq(c.fwd_o) + m.d.comb += rsel.eq(c.rsel_o) return m @@ -153,11 +200,11 @@ class DependencyRow(Elaboratable): # --- # connect Reg Selection vector # --- + dest_rsel_o = [] + src1_rsel_o = [] + src2_rsel_o = [] for rn in range(self.n_reg_col): dc = rcell[rn] - dest_rsel_o = [] - src1_rsel_o = [] - src2_rsel_o = [] # accumulate cell reg-select outputs dest/src1/src2 dest_rsel_o.append(dc.dest_rsel_o) src1_rsel_o.append(dc.src1_rsel_o) @@ -169,6 +216,23 @@ class DependencyRow(Elaboratable): return m + def __iter__(self): + yield self.dest_i + yield self.src1_i + yield self.src2_i + yield self.issue_i + yield self.go_wr_i + yield self.go_rd_i + yield self.dest_rsel_o + yield self.src1_rsel_o + yield self.src2_rsel_o + yield self.dest_fwd_o + yield self.src1_fwd_o + yield self.src2_fwd_o + + def ports(self): + return list(self) + def dcell_sim(dut): yield dut.dest_i.eq(1) @@ -193,6 +257,11 @@ def dcell_sim(dut): yield def test_dcell(): + dut = DependencyRow(4) + vl = rtlil.convert(dut, ports=dut.ports()) + with open("test_drow.il", "w") as f: + f.write(vl) + dut = DependenceCell() vl = rtlil.convert(dut, ports=dut.ports()) with open("test_dcell.il", "w") as f: