X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fscoreboard%2Fdependence_cell.py;h=1ae81b59a11c12668403d5d672f70322c954560b;hb=e79992af9cba2cb73b0efcf6478a83e52c757ec6;hp=ae552077841baf7e8189b8f7c64892c173bc60e1;hpb=6c6a9e600731146ecc236a60b7ee287863fca9e3;p=soc.git diff --git a/src/scoreboard/dependence_cell.py b/src/scoreboard/dependence_cell.py index ae552077..1ae81b59 100644 --- a/src/scoreboard/dependence_cell.py +++ b/src/scoreboard/dependence_cell.py @@ -1,9 +1,52 @@ from nmigen.compat.sim import run_simulation from nmigen.cli import verilog, rtlil -from nmigen import Module, Signal, Elaboratable +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 + + # reset on go HI, set on dest and issue + m.d.comb += dest_l.s.eq(self.issue_i & self.reg_i) + m.d.comb += dest_l.r.eq(self.go_i) + + # FU "Forward Progress" (read out horizontally) + m.d.sync += self.fwdl_o.eq(l.q & self.reg_i) + + # Register File Select (read out vertically) + m.d.comb += self.rselo.eq(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,9 +72,9 @@ 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 + m.submodules.dest_l = dest_l = SRLatch(sync=False) # clock-sync'd + m.submodules.src1_l = src1_l = SRLatch(sync=False) # clock-sync'd + m.submodules.src2_l = src2_l = SRLatch(sync=False) # 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) @@ -46,14 +89,14 @@ class DependenceCell(Elaboratable): 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) + m.d.comb += self.dest_fwd_o.eq(dest_l.q & self.dest_i) + m.d.comb += self.src1_fwd_o.eq(src1_l.q & self.src1_i) + m.d.comb += self.src2_fwd_o.eq(src2_l.q & self.src2_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.d.sync += self.dest_rsel_o.eq(dest_l.q & ~self.go_wr_i) + m.d.sync += self.src1_rsel_o.eq(src1_l.q & ~self.go_rd_i) + m.d.sync += self.src2_rsel_o.eq(src2_l.q & ~self.go_rd_i) return m @@ -70,7 +113,119 @@ class DependenceCell(Elaboratable): yield self.dest_fwd_o yield self.src1_fwd_o yield self.src2_fwd_o - + + def ports(self): + return list(self) + + +class DependencyRow(Elaboratable): + def __init__(self, n_reg_col): + self.n_reg_col = n_reg_col + + # ---- + # fields all match DependencyCell precisely + + self.dest_i = Signal(n_reg_col, reset_less=True) + self.src1_i = Signal(n_reg_col, reset_less=True) + self.src2_i = Signal(n_reg_col, reset_less=True) + + self.issue_i = Signal(reset_less=True) + self.go_wr_i = Signal(reset_less=True) + self.go_rd_i = Signal(reset_less=True) + + self.dest_rsel_o = Signal(n_reg_col, reset_less=True) + self.src1_rsel_o = Signal(n_reg_col, reset_less=True) + self.src2_rsel_o = Signal(n_reg_col, reset_less=True) + + self.dest_fwd_o = Signal(n_reg_col, reset_less=True) + self.src1_fwd_o = Signal(n_reg_col, reset_less=True) + self.src2_fwd_o = Signal(n_reg_col, reset_less=True) + + def elaborate(self, platform): + m = Module() + rcell = Array(DependenceCell() for f in range(self.n_reg_col)) + for rn in range(self.n_reg_col): + setattr(m.submodules, "dm_r%d" % rn, rcell[rn]) + + # --- + # connect Dep dest/src to module dest/src + # --- + dest_i = [] + src1_i = [] + src2_i = [] + for rn in range(self.n_reg_col): + dc = rcell[rn] + # accumulate cell inputs dest/src1/src2 + dest_i.append(dc.dest_i) + src1_i.append(dc.src1_i) + src2_i.append(dc.src2_i) + # wire up inputs from module to row cell inputs (Cat is gooood) + m.d.comb += [Cat(*dest_i).eq(self.dest_i), + Cat(*src1_i).eq(self.src1_i), + Cat(*src2_i).eq(self.src2_i), + ] + + # --- + # connect Dep issue_i/go_rd_i/go_wr_i to module issue_i/go_rd/go_wr + # --- + for rn in range(self.n_reg_col): + dc = rcell[rn] + m.d.comb += [dc.go_rd_i.eq(self.go_rd_i), + dc.go_wr_i.eq(self.go_wr_i), + dc.issue_i.eq(self.issue_i), + ] + + # --- + # connect Function Unit vector + # --- + dest_fwd_o = [] + src1_fwd_o = [] + src2_fwd_o = [] + for rn in range(self.n_reg_col): + dc = rcell[rn] + # accumulate cell fwd outputs for dest/src1/src2 + dest_fwd_o.append(dc.dest_fwd_o) + src1_fwd_o.append(dc.src1_fwd_o) + src2_fwd_o.append(dc.src2_fwd_o) + # connect cell fwd outputs to FU Vector Out [Cat is gooood] + m.d.comb += [self.dest_fwd_o.eq(Cat(*dest_fwd_o)), + self.src1_fwd_o.eq(Cat(*src1_fwd_o)), + self.src2_fwd_o.eq(Cat(*src2_fwd_o)) + ] + + # --- + # connect Reg Selection vector + # --- + dest_rsel_o = [] + src1_rsel_o = [] + src2_rsel_o = [] + for rn in range(self.n_reg_col): + dc = rcell[rn] + # accumulate cell reg-select outputs dest/src1/src2 + dest_rsel_o.append(dc.dest_rsel_o) + src1_rsel_o.append(dc.src1_rsel_o) + src2_rsel_o.append(dc.src2_rsel_o) + # connect cell reg-select outputs to Reg Vector Out + m.d.comb += self.dest_rsel_o.eq(Cat(*dest_rsel_o)) + m.d.comb += self.src1_rsel_o.eq(Cat(*src1_rsel_o)) + m.d.comb += self.src2_rsel_o.eq(Cat(*src2_rsel_o)) + + 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) @@ -98,6 +253,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: