From f9f502cad611e7dd9fa28abec41f14b59469501d Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Wed, 29 May 2019 21:46:40 +0100 Subject: [PATCH] do dependency row as multi-bit SRLatch --- src/scoreboard/dependence_cell.py | 200 +++++------------------------- 1 file changed, 32 insertions(+), 168 deletions(-) diff --git a/src/scoreboard/dependence_cell.py b/src/scoreboard/dependence_cell.py index e12f2163..f5b85184 100644 --- a/src/scoreboard/dependence_cell.py +++ b/src/scoreboard/dependence_cell.py @@ -1,6 +1,6 @@ from nmigen.compat.sim import run_simulation from nmigen.cli import verilog, rtlil -from nmigen import Module, Signal, Elaboratable, Array, Cat +from nmigen import Module, Signal, Elaboratable, Array, Cat, Repl from nmutil.latch import SRLatch @@ -25,34 +25,35 @@ class DepCell(Elaboratable): asynchronous) would be reset at the exact moment that GO was requested, and the RSEL would be garbage. """ - def __init__(self): + def __init__(self, llen): + self.llen = llen # inputs - self.reg_i = Signal(reset_less=True) # reg bit in (top) + self.reg_i = Signal(llen, reset_less=True) # reg bit in (top) self.issue_i = Signal(reset_less=True) # Issue in (top) - self.hazard_i = Signal(reset_less=True) # to check hazard + self.hazard_i = Signal(llen, reset_less=True) # to check hazard self.go_i = Signal(reset_less=True) # Go read/write in (left) self.die_i = Signal(reset_less=True) # Die in (left) - self.q_o = Signal(reset_less=True) # Latch out (register active) + self.q_o = Signal(llen, reset_less=True) # Latch out (reg active) # for Register File Select Lines (vertical) - self.rsel_o = Signal(reset_less=True) # reg sel (bottom) + self.rsel_o = Signal(llen, reset_less=True) # reg sel (bottom) # for Function Unit "forward progress" (horizontal) - self.fwd_o = Signal(reset_less=True) # FU forard progress (right) + self.fwd_o = Signal(llen, reset_less=True) # FU forard progress (right) def elaborate(self, platform): m = Module() - m.submodules.l = l = SRLatch(sync=False) # async latch + m.submodules.l = l = SRLatch(sync=False, llen=self.llen) # async latch # 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 | self.die_i) + m.d.comb += l.s.eq(Repl(self.issue_i, self.llen) & self.reg_i) + m.d.comb += l.r.eq(Repl(self.go_i | self.die_i, self.llen)) # Function Unit "Forward Progress". m.d.comb += self.fwd_o.eq((l.q) & self.hazard_i) # & ~self.issue_i) # Register Select. Activated on go read/write and *current* latch set m.d.comb += self.q_o.eq(l.qlq) - m.d.comb += self.rsel_o.eq(l.qlq & self.go_i) + m.d.comb += self.rsel_o.eq(l.qlq & Repl(self.go_i, self.llen)) return m @@ -70,40 +71,41 @@ class DepCell(Elaboratable): return list(self) -class DependenceCell(Elaboratable): +class DependencyRow(Elaboratable): """ implements 11.4.7 mitch alsup dependence cell, p27 """ - def __init__(self): + def __init__(self, n_reg): + self.n_reg = n_reg # inputs - self.dest_i = Signal(reset_less=True) # Dest in (top) - self.src1_i = Signal(reset_less=True) # oper1 in (top) - self.src2_i = Signal(reset_less=True) # oper2 in (top) + self.dest_i = Signal(n_reg, reset_less=True) # Dest in (top) + self.src1_i = Signal(n_reg, reset_less=True) # oper1 in (top) + self.src2_i = Signal(n_reg, reset_less=True) # oper2 in (top) self.issue_i = Signal(reset_less=True) # Issue in (top) - self.rd_pend_i = Signal(reset_less=True) # Read pending in (top) - self.wr_pend_i = Signal(reset_less=True) # Write pending in (top) - self.rd_rsel_o = Signal(reset_less=True) # Read pending out (bottom) - self.wr_rsel_o = Signal(reset_less=True) # Write pending out (bottom) + self.rd_pend_i = Signal(n_reg, reset_less=True) # Read pend in (top) + self.wr_pend_i = Signal(n_reg, reset_less=True) # Write pend in (top) + self.rd_rsel_o = Signal(n_reg, reset_less=True) # Read pend out (bot) + self.wr_rsel_o = Signal(n_reg, reset_less=True) # Write pend out (bot) self.go_wr_i = Signal(reset_less=True) # Go Write in (left) self.go_rd_i = Signal(reset_less=True) # Go Read in (left) self.go_die_i = Signal(reset_less=True) # Go Die in (left) # for Register File Select Lines (vertical) - self.dest_rsel_o = Signal(reset_less=True) # dest reg sel (bottom) - self.src1_rsel_o = Signal(reset_less=True) # src1 reg sel (bottom) - self.src2_rsel_o = Signal(reset_less=True) # src2 reg sel (bottom) + self.dest_rsel_o = Signal(n_reg, reset_less=True) # dest reg sel (bot) + self.src1_rsel_o = Signal(n_reg, reset_less=True) # src1 reg sel (bot) + self.src2_rsel_o = Signal(n_reg, reset_less=True) # src2 reg sel (bot) # for Function Unit "forward progress" (horizontal) - self.dest_fwd_o = Signal(reset_less=True) # dest FU fw (right) - self.src1_fwd_o = Signal(reset_less=True) # src1 FU fw (right) - self.src2_fwd_o = Signal(reset_less=True) # src2 FU fw (right) + self.dest_fwd_o = Signal(n_reg, reset_less=True) # dest FU fw (right) + self.src1_fwd_o = Signal(n_reg, reset_less=True) # src1 FU fw (right) + self.src2_fwd_o = Signal(n_reg, reset_less=True) # src2 FU fw (right) def elaborate(self, platform): m = Module() - m.submodules.dest_c = dest_c = DepCell() - m.submodules.src1_c = src1_c = DepCell() - m.submodules.src2_c = src2_c = DepCell() + m.submodules.dest_c = dest_c = DepCell(self.n_reg) + m.submodules.src1_c = src1_c = DepCell(self.n_reg) + m.submodules.src2_c = src2_c = DepCell(self.n_reg) # connect issue and die for c in [dest_c, src1_c, src2_c]: @@ -123,7 +125,7 @@ class DependenceCell(Elaboratable): # wark-wark: yes, writing to the same reg you are reading is *NOT* # a write-after-read hazard. - selfhazard = Signal(reset_less=False) + selfhazard = Signal(self.n_reg, reset_less=False) m.d.comb += selfhazard.eq((self.dest_i & self.src1_i) | (self.dest_i & self.src2_i)) @@ -168,139 +170,6 @@ class DependenceCell(Elaboratable): 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.rd_pend_i = Signal(n_reg_col, reset_less=True) - self.wr_pend_i = Signal(n_reg_col, reset_less=True) - - self.rd_rsel_o = Signal(n_reg_col, reset_less=True) - self.wr_rsel_o = 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.go_die_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 - # --- - rd_pend_i = [] - wr_pend_i = [] - rd_rsel_o = [] - wr_rsel_o = [] - dest_i = [] - src1_i = [] - src2_i = [] - for rn in range(self.n_reg_col): - dc = rcell[rn] - # accumulate cell inputs dest/src1/src2 - rd_pend_i.append(dc.rd_pend_i) - wr_pend_i.append(dc.wr_pend_i) - rd_rsel_o.append(dc.rd_rsel_o) - wr_rsel_o.append(dc.wr_rsel_o) - 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), - Cat(*rd_pend_i).eq(self.rd_pend_i), - Cat(*wr_pend_i).eq(self.wr_pend_i), - self.rd_rsel_o.eq(Cat(*rd_rsel_o)), - self.wr_rsel_o.eq(Cat(*wr_rsel_o)), - ] - - # --- - # connect Dep die/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), - dc.go_die_i.eq(self.go_die_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.go_die_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) yield dut.issue_i.eq(1) @@ -329,11 +198,6 @@ def test_dcell(): 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: - f.write(vl) - run_simulation(dut, dcell_sim(dut), vcd_name='test_dcell.vcd') if __name__ == '__main__': -- 2.30.2