def addAlias(row, col, srcname, destname): gsrcname = chipdb.wire2global(row, col, db, srcname) gdestname = chipdb.wire2global(row, col, db, destname) pipname = f"R{row}C{col}_{srcname}_{destname}" #print("alias", pipname) ctx.addPip(name=pipname + "_ALIAS", type=destname, srcWire=gsrcname, dstWire=gdestname, delay=ctx.getDelayFromNS(0), loc=Loc(col, row, 0))
def addWire(row, col, wire): gname = chipdb.wire2global(row, col, db, wire) #print("wire", gname) try: ctx.addWire(name=gname, type=wire, y=row, x=col) except AssertionError: pass
def addPip(row, col, srcname, destname): gsrcname = chipdb.wire2global(row, col, db, srcname) gdestname = chipdb.wire2global(row, col, db, destname) pipname = f"R{row}C{col}_{srcname}_{destname}" #print("pip", pipname, srcname, gsrcname, destname, gdestname) try: # delay is crude fudge from vendor critical path ctx.addPip(name=pipname, type=destname, srcWire=gsrcname, dstWire=gdestname, delay=wiredelay(destname), loc=Loc(col, row, 0)) except IndexError: pass #print("Wire not found", gsrcname, gdestname) except AssertionError: pass
def tile2verilog(dbrow, dbcol, bels, pips, clock_pips, mod, db): # db is 0-based, floorplanner is 1-based row = dbrow + 1 col = dbcol + 1 aliases = db.grid[dbrow][dbcol].aliases for dest, src in chain(pips.items(), aliases.items(), clock_pips.items()): srcg = chipdb.wire2global(row, col, db, src) destg = chipdb.wire2global(row, col, db, dest) mod.wires.update({srcg, destg}) mod.assigns.append((destg, srcg)) belre = re.compile(r"(IOB|LUT|DFF|BANK|CFG)(\w*)") for bel, flags in bels.items(): typ, idx = belre.match(bel).groups() if typ == "LUT": val = sum(1 << f for f in flags) name = f"R{row}C{col}_LUT4_{idx}" lut = codegen.Primitive("LUT4", name) lut.params["INIT"] = f"16'b{val:016b}" lut.portmap['F'] = f"R{row}C{col}_F{idx}" lut.portmap['I0'] = f"R{row}C{col}_A{idx}" lut.portmap['I1'] = f"R{row}C{col}_B{idx}" lut.portmap['I2'] = f"R{row}C{col}_C{idx}" lut.portmap['I3'] = f"R{row}C{col}_D{idx}" mod.wires.update(lut.portmap.values()) mod.primitives[name] = lut elif typ == "DFF": kind, = flags # DFF only have one flag idx = int(idx) port = dffmap[kind] name = f"R{row}C{col}_{typ}E_{idx}" dff = codegen.Primitive(kind + "E", name) dff.portmap['CLK'] = f"R{row}C{col}_CLK{idx//2}" dff.portmap['D'] = f"R{row}C{col}_F{idx}" dff.portmap['Q'] = f"R{row}C{col}_Q{idx}" dff.portmap['CE'] = f"R{row}C{col}_CE{idx//2}" if port: dff.portmap[port] = f"R{row}C{col}_LSR{idx//2}" mod.wires.update(dff.portmap.values()) mod.primitives[name] = dff elif typ == "IOB": try: kind, = flags.intersection(iobmap.keys()) except ValueError: continue portmap = db.grid[dbrow][dbcol].bels[bel].portmap name = f"R{row}C{col}_{kind}_{idx}" wires = set(iobmap[kind]['wires']) ports = set(chain.from_iterable(iobmap[kind].values())) - wires iob = codegen.Primitive(kind, name) for port in wires: wname = portmap[port] iob.portmap[port] = f"R{row}C{col}_{wname}" for port in ports: iob.portmap[port] = f"R{row}C{col}_{port}{idx}" for wires in iobmap[kind]['wires']: wnames = [f"R{row}C{col}_{portmap[w]}" for w in wires] mod.wires.update(wnames) for direction in ['inputs', 'outputs', 'inouts']: for wires in iobmap[kind].get(direction, []): wnames = [f"R{row}C{col}_{w}{idx}" for w in wires] getattr(mod, direction).update(wnames) mod.primitives[name] = iob # gnd = codegen.Primitive("GND", "mygnd") # gnd.portmap["G"] = "VSS" # mod.primitives["mygnd"] = gnd # vcc = codegen.Primitive("VCC", "myvcc") # vcc.portmap["V"] = "VCC" # mod.primitives["myvcc"] = vcc mod.assigns.append(("VCC", "1")) mod.assigns.append(("GND", "0"))
def tile2verilog(dbrow, dbcol, bels, pips, clock_pips, mod, cfg, cst, db): # db is 0-based, floorplanner is 1-based row = dbrow+1 col = dbcol+1 aliases = db.grid[dbrow][dbcol].aliases for dest, src in chain(pips.items(), aliases.items(), clock_pips.items()): srcg = chipdb.wire2global(row, col, db, src) destg = chipdb.wire2global(row, col, db, dest) mod.wires.update({srcg, destg}) mod.assigns.append((destg, srcg)) belre = re.compile(r"(IOB|LUT|DFF|BANK|CFG|ALU|RAM16)(\w*)") for bel, flags in bels.items(): typ, idx = belre.match(bel).groups() if typ == "LUT": val = 0xffff - sum(1<<f for f in flags) if val == 0: mod.assigns.append((f"R{row}C{col}_F{idx}", "VSS")) else: name = f"R{row}C{col}_LUT4_{idx}" lut = codegen.Primitive("LUT4", name) lut.params["INIT"] = f"16'b{val:016b}" lut.portmap['F'] = f"R{row}C{col}_F{idx}" lut.portmap['I0'] = f"R{row}C{col}_A{idx}" lut.portmap['I1'] = f"R{row}C{col}_B{idx}" lut.portmap['I2'] = f"R{row}C{col}_C{idx}" lut.portmap['I3'] = f"R{row}C{col}_D{idx}" mod.wires.update(lut.portmap.values()) mod.primitives[name] = lut cst.cells[name] = (row, col, int(idx) // 2, _sides[int(idx) % 2]) make_muxes(row, col, idx, db, mod) elif typ == "ALU": #print(flags) kind, = flags # ALU only have one flag idx = int(idx) name = f"R{row}C{col}_ALU_{idx}" if kind in "012346789": # main ALU alu = codegen.Primitive("ALU", name) alu.params["ALU_MODE"] = kind alu.portmap['SUM'] = f"R{row}C{col}_F{idx}" alu.portmap['CIN'] = f"R{row}C{col}_CIN{idx}" if idx != 5: alu.portmap['COUT'] = f"R{row}C{col}_CIN{idx+1}" else: alu.portmap['COUT'] = f"R{row}C{col + 1}_CIN{0}" if kind in "2346789": alu.portmap['I0'] = f"R{row}C{col}_A{idx}" alu.portmap['I1'] = f"R{row}C{col}_B{idx}" if kind in "28": alu.portmap['I3'] = f"R{row}C{col}_D{idx}" elif kind == "0": alu.portmap['I0'] = f"R{row}C{col}_B{idx}" alu.portmap['I1'] = f"R{row}C{col}_D{idx}" else: alu.portmap['I0'] = f"R{row}C{col}_A{idx}" alu.portmap['I1'] = f"R{row}C{col}_D{idx}" mod.wires.update(alu.portmap.values()) mod.primitives[name] = alu elif typ == "RAM16": val0 = sum(1<<x for x in range(0,16) if not x in flags) val1 = sum(1<<(x-16) for x in range(16,32) if not x in flags) val2 = sum(1<<(x-32) for x in range(32,48) if not x in flags) val3 = sum(1<<(x-48) for x in range(48,64) if not x in flags) name = f"R{row}C{col}_RAM16" ram16 = codegen.Primitive("RAM16SDP4", name) ram16.params["INIT_0"] = f"16'b{val0:016b}" ram16.params["INIT_1"] = f"16'b{val1:016b}" ram16.params["INIT_2"] = f"16'b{val2:016b}" ram16.params["INIT_3"] = f"16'b{val3:016b}" ram16.portmap['DI'] = [f"R{row}C{col}_{x}5" for x in "ABCD"] ram16.portmap['CLK'] = f"R{row}C{col}_CLK2" ram16.portmap['WRE'] = f"R{row}C{col}_LSR2" ram16.portmap['WAD'] = [f"R{row}C{col}_{x}4" for x in "ABCD"] ram16.portmap['RAD'] = [f"R{row}C{col}_{x}0" for x in "ABCD"] ram16.portmap['DO'] = [f"R{row}C{col}_F{x}" for x in range(4)] mod.wires.update(chain.from_iterable([x if isinstance(x, list) else [x] for x in ram16.portmap.values()])) mod.primitives[name] = ram16 elif typ == "DFF": #print(flags) kind, = flags # DFF only have one flag idx = int(idx) port = dffmap[kind] name = f"R{row}C{col}_{typ}E_{idx}" dff = codegen.Primitive(kind+"E", name) dff.portmap['CLK'] = f"R{row}C{col}_CLK{idx//2}" dff.portmap['D'] = f"R{row}C{col}_F{idx}" dff.portmap['Q'] = f"R{row}C{col}_Q{idx}" dff.portmap['CE'] = f"R{row}C{col}_CE{idx//2}" if port: dff.portmap[port] = f"R{row}C{col}_LSR{idx//2}" mod.wires.update(dff.portmap.values()) mod.primitives[name] = dff cst.cells[name] = (row, col, int(idx) // 2, _sides[int(idx) % 2]) elif typ == "IOB": try: kind, = flags.intersection(iobmap.keys()) except ValueError: continue flags.remove(kind) portmap = db.grid[dbrow][dbcol].bels[bel].portmap name = f"R{row}C{col}_{kind}_{idx}" wires = set(iobmap[kind]['wires']) ports = set(chain.from_iterable(iobmap[kind].values())) - wires iob = codegen.Primitive(kind, name) for port in wires: wname = portmap[port] iob.portmap[portname(port)] = f"R{row}C{col}_{wname}" for port in ports: iob.portmap[port] = f"R{row}C{col}_{port}{idx}" wnames = [f"R{row}C{col}_{portmap[w]}" for w in iobmap[kind]['wires']] mod.wires.update(wnames) for direction in ['inputs', 'outputs', 'inouts']: wnames = [f"R{row}C{col}_{w}{idx}" for w in iobmap[kind].get(direction, [])] getattr(mod, direction).update(wnames) mod.primitives[name] = iob # constraints pos = chipdb.loc2pin_name(db, dbrow, dbcol) bank = chipdb.loc2bank(db, dbrow, dbcol) cst.ports[name] = f"{pos}{idx}" iostd = _banks.get(bank) if iostd: cst.attrs.setdefault(name, {}).update({"IO_TYPE" : iostd}) for flg in flags: name_val = flg.split('=') cst.attrs.setdefault(name, {}).update({name_val[0] : name_val[1]}) elif typ == "CFG": for flag in flags: for name in cfg.settings.keys(): if name.startswith(flag): cfg.settings[name] = 'true' # gnd = codegen.Primitive("GND", "mygnd") # gnd.portmap["G"] = "VSS" # mod.primitives["mygnd"] = gnd # vcc = codegen.Primitive("VCC", "myvcc") # vcc.portmap["V"] = "VCC" # mod.primitives["myvcc"] = vcc mod.assigns.append(("VCC", "1")) mod.assigns.append(("VSS", "0"))