From fdb1ba675ace77d850107b14deaf68a4030282e4 Mon Sep 17 00:00:00 2001 From: Luke Kenneth Casson Leighton Date: Sun, 28 Mar 2021 14:53:20 +0100 Subject: [PATCH] add option to reduce number of regfile ports (get DFFs down in ls180) --- src/soc/regfile/regfiles.py | 33 ++++++++++++++++++++------------ src/soc/simple/core.py | 19 +++++++++--------- src/soc/simple/issuer_verilog.py | 10 ++++++++++ 3 files changed, 41 insertions(+), 21 deletions(-) diff --git a/src/soc/regfile/regfiles.py b/src/soc/regfile/regfiles.py index 4f2c23c3..50286b4a 100644 --- a/src/soc/regfile/regfiles.py +++ b/src/soc/regfile/regfiles.py @@ -48,7 +48,7 @@ class StateRegs(RegFileArray): PC = 0 MSR = 1 SVSTATE = 2 - def __init__(self, svp64_en=False): + def __init__(self, svp64_en=False, regreduce_en=False): super().__init__(64, 3) self.w_ports = {'nia': self.write_port("nia"), 'msr': self.write_port("msr"), @@ -69,17 +69,21 @@ class IntRegs(RegFileMem): #class IntRegs(RegFileArray): * Array-based unary-indexed (not binary-indexed) * write-through capability (read on same cycle as write) """ - def __init__(self, svp64_en=False): + def __init__(self, svp64_en=False, regreduce_en=False): super().__init__(64, 32) self.w_ports = {'o': self.write_port("dest1"), - #'o1': self.write_port("dest2") # for now (LD/ST update) } - self.r_ports = {'ra': self.read_port("src1"), - 'rb': self.read_port("src2"), - 'rc': self.read_port("src3"), + self.r_ports = { 'dmi': self.read_port("dmi")} # needed for Debug (DMI) if svp64_en: self.r_ports['pred'] = self.read_port("pred") # for predicate mask + if not regreduce_en: + self.w_ports['o1'] = self.write_port("dest2") # (LD/ST update) + self.r_ports['ra'] = self.read_port("src1") + self.r_ports['rb'] = self.read_port("src2") + self.r_ports['rc'] = self.read_port("src3") + else: + self.r_ports['rabc'] = self.read_port("src") # Fast SPRs Regfile @@ -104,15 +108,16 @@ class FastRegs(RegFileMem): #RegFileArray): DEC = 6 TB = 7 N_REGS = 8 # maximum number of regs - def __init__(self, svp64_en=False): + def __init__(self, svp64_en=False, regreduce_en=False): super().__init__(64, self.N_REGS) self.w_ports = {'fast1': self.write_port("dest1"), 'issue': self.write_port("issue"), # writing DEC/TB } self.r_ports = {'fast1': self.read_port("src1"), - 'fast2': self.read_port("src2"), 'issue': self.read_port("issue"), # reading DEC/TB } + if not regreduce_en: + self.r_ports['fast2'] = self.read_port("src2") # CR Regfile @@ -124,7 +129,7 @@ class CRRegs(VirtualRegPort): * Array-based unary-indexed (not binary-indexed) * write-through capability (read on same cycle as write) """ - def __init__(self, svp64_en=False): + def __init__(self, svp64_en=False, regreduce_en=False): super().__init__(32, 8, rd2=True) self.w_ports = {'full_cr': self.full_wr, # 32-bit (masked, 8-en lines) 'cr_a': self.write_port("dest1"), # 4-bit, unary-indexed @@ -150,7 +155,7 @@ class XERRegs(VirtualRegPort): SO=0 # this is actually 2-bit but we ignore 1 bit of it CA=1 # CA and CA32 OV=2 # OV and OV32 - def __init__(self, svp64_en=False): + def __init__(self, svp64_en=False, regreduce_en=False): super().__init__(6, 3) self.w_ports = {'full_xer': self.full_wr, # 6-bit (masked, 3-en lines) 'xer_so': self.write_port("dest1"), @@ -171,7 +176,7 @@ class SPRRegs(RegFileMem): * binary-indexed but REQUIRES MAPPING * write-through capability (read on same cycle as write) """ - def __init__(self, svp64_en=False): + def __init__(self, svp64_en=False, regreduce_en=False): n_sprs = len(SPR) super().__init__(width=64, depth=n_sprs) self.w_ports = {'spr1': self.write_port("spr1")} @@ -184,6 +189,10 @@ class RegFiles: # test is SVP64 is to be enabled svp64_en = hasattr(pspec, "svp64") and (pspec.svp64 == True) + # and regfile port reduction + regreduce_en = hasattr(pspec, "regreduce") and \ + (pspec.regreduce == True) + self.rf = {} # create regfiles here, Factory style for (name, kls) in [('int', IntRegs), @@ -192,7 +201,7 @@ class RegFiles: ('fast', FastRegs), ('state', StateRegs), ('spr', SPRRegs),]: - rf = self.rf[name] = kls(svp64_en) + rf = self.rf[name] = kls(svp64_en, regreduce_en) # also add these as instances, self.state, self.fast, self.cr etc. setattr(self, name, rf) diff --git a/src/soc/simple/core.py b/src/soc/simple/core.py index 7b2e7b8d..f69fda4e 100644 --- a/src/soc/simple/core.py +++ b/src/soc/simple/core.py @@ -73,7 +73,7 @@ class NonProductionCore(Elaboratable): # test to see if regfile ports should be reduced self.regreduce_en = (hasattr(pspec, "regreduce") and - (pspec.regreduce_en == True)) + (pspec.regreduce == True)) # single LD/ST funnel for memory access self.l0 = TstL0CacheBuffer(pspec, n_units=1) @@ -469,14 +469,15 @@ class NonProductionCore(Elaboratable): fuspecs = byregfiles_wrspec[regfile] wrpickers[regfile] = {} - # argh, more port-merging - if regfile == 'INT': - fuspecs['o'] = [fuspecs.pop('o')] - fuspecs['o'].append(fuspecs.pop('o1')) - if regfile == 'FAST': - fuspecs['fast1'] = [fuspecs.pop('fast1')] - if 'fast2' in fuspecs: - fuspecs['fast1'].append(fuspecs.pop('fast2')) + if self.regreduce_en: + # argh, more port-merging + if regfile == 'INT': + fuspecs['o'] = [fuspecs.pop('o')] + fuspecs['o'].append(fuspecs.pop('o1')) + if regfile == 'FAST': + fuspecs['fast1'] = [fuspecs.pop('fast1')] + if 'fast2' in fuspecs: + fuspecs['fast1'].append(fuspecs.pop('fast2')) for (regname, fspec) in sort_fuspecs(fuspecs): self.connect_wrport(m, fu_bitdict, wrpickers, diff --git a/src/soc/simple/issuer_verilog.py b/src/soc/simple/issuer_verilog.py index a00ec4b1..446b7f41 100644 --- a/src/soc/simple/issuer_verilog.py +++ b/src/soc/simple/issuer_verilog.py @@ -18,6 +18,14 @@ if __name__ == '__main__': parser.add_argument("--disable-xics", dest='xics', action="store_false", help="Disable interrupts", default=False) + parser.add_argument("--enable-lessports", dest='lessports', + action="store_true", + help="Enable less regfile ports", + default=True) + parser.add_argument("--disable-lessports", dest='lessports', + action="store_false", + help="enable more regfile ports", + default=False) parser.add_argument("--enable-core", dest='core', action="store_true", help="Enable main core", default=True) @@ -70,6 +78,7 @@ if __name__ == '__main__': #wb_data_wid=32, xics=args.xics, # XICS interrupt controller nocore=not args.core, # test coriolis2 ioring + regreduce = args.lessports, # less regfile ports use_pll=args.pll, # bypass PLL gpio=args.enable_testgpio, # for test purposes sram4x4kblock=args.enable_sram4x4kblock, # add SRAMs @@ -78,6 +87,7 @@ if __name__ == '__main__': units=units) print("nocore", pspec.__dict__["nocore"]) + print("regreduce", pspec.__dict__["regreduce"]) print("gpio", pspec.__dict__["gpio"]) print("sram4x4kblock", pspec.__dict__["sram4x4kblock"]) print("xics", pspec.__dict__["xics"]) -- 2.30.2