Exemple #1
0
def write_posp(f):
    belre = re.compile(r"R(\d+)C(\d+)_(SLICE|IOB)(\w)")
    namere = re.compile(r"\W+")
    for name, cell in ctx.cells:
        row, col, typ, idx = belre.match(cell.bel).groups()
        row = int(row)
        col = int(col)
        name = namere.sub('_', name)
        if typ == 'SLICE':
            idx = int(idx)
            cls = idx // 2
            side = ['A', 'B'][idx % 2]
            lutname = name + "_LUT"
            f.write(f"{lutname} PLACE_R{row}C{col}[{cls}][{side}]\n")

            lut = codegen.Primitive("LUT4", lutname)
            #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[lutname] = lut

            if int(cell.params['FF_USED'], 2):
                dffname = name + "_DFF"
                f.write(f"{dffname} PLACE_R{row}C{col}[{cls}][{side}]\n")

                lut = codegen.Primitive("DFF", dffname)
                lut.portmap['D'] = f"R{row}C{col}_F{idx}"
                lut.portmap['Q'] = f"R{row}C{col}_Q{idx}"
                lut.portmap['CLK'] = f"R{row}C{col}_CLK{idx}"
                mod.wires.update(lut.portmap.values())
                mod.primitives[dffname] = lut
        elif typ == 'IOB':
            if row == 1:
                edge = 'T'
                num = col
            elif col == 1:
                edge = 'L'
                num = row
            elif col == 47:  #TODO parameterize
                edge = 'R'
                num = row
            else:
                edge = 'B'
                num = col
            f.write(f"{name} PLACE_IO{edge}{num}[{idx}]\n")

            iob = codegen.Primitive("IOBUF", name)
            iob.portmap['I'] = f"R{row}C{col}_I{idx}"
            iob.portmap['O'] = f"R{row}C{col}_O{idx}"
            iob.portmap['IO'] = f"R{row}C{col}_IO{idx}"
            iob.portmap['OEN'] = f"R{row}C{col}_OEN{idx}"
            mod.wires.update(iob.portmap.values())
            mod.inouts.add(f"R{row}C{col}_IO{idx}")
            mod.primitives[name] = iob
Exemple #2
0
def dff(locations):
    for ttyp in range(12, 17):  # for each tile type
        mod = codegen.Module()
        cst = codegen.Constraints()
        try:
            # get all tiles of this type
            # iter causes the loop to not repeat the same locs per cls
            locs = iter(locations[ttyp])
        except KeyError:
            continue

        for cls in range(3):  # for each cls
            for typ, port in dffmap.items():  # for each bel type
                try:
                    loc = next(locs)  # get the next unused tile
                except StopIteration:
                    yield ttyp, mod, cst, {}
                    locs = iter(locations[ttyp])
                    loc = next(locs)
                    mod = codegen.Module()
                    cst = codegen.Constraints()

                lutname = make_name("DUMMY", "LUT4")
                lut = codegen.Primitive("LUT4", lutname)
                lut.params["INIT"] = "16'hffff"
                lut.portmap['F'] = lutname + "_F"
                lut.portmap['I0'] = lutname + "_I0"
                lut.portmap['I1'] = lutname + "_I1"
                lut.portmap['I2'] = lutname + "_I2"
                lut.portmap['I3'] = lutname + "_I3"

                mod.wires.update(lut.portmap.values())
                mod.primitives[lutname] = lut
                name = make_name("DFF", typ)
                dff = codegen.Primitive(typ, name)
                dff.portmap['CLK'] = name + "_CLK"
                dff.portmap['D'] = lutname + "_F"
                dff.portmap['Q'] = name + "_Q"
                if port:
                    dff.portmap[port] = name + "_" + port
                mod.wires.update(dff.portmap.values())
                mod.primitives[name] = dff

                row = loc[0] + 1
                col = loc[1] + 1
                cst.cells[lutname] = f"R{row}C{col}[{cls}]"
                cst.cells[name] = f"R{row}C{col}[{cls}]"
        yield ttyp, mod, cst, {}
Exemple #3
0
    def primitives(self, mod, bits):
        "Generate verilog for a LUT4 and DFF"
        for location, bits in self.location_chunks(bits):
            if bits[0]:
                name = self.location_to_name(location)
                location_a = location + "[A]_LUT"
                name_a_lut = self.location_to_name(location_a)
                lut = codegen.Primitive("LUT4", name_a_lut)
                lut.params["INIT"] = "16'hffff"
                lut.portmap['F'] = name_a_lut + "_F"
                lut.portmap['I0'] = name_a_lut + "_I0"
                lut.portmap['I1'] = name_a_lut + "_I1"
                lut.portmap['I2'] = name_a_lut + "_I2"
                lut.portmap['I3'] = name_a_lut + "_I3"
                mod.wires.update(lut.portmap.values())
                mod.primitives[name_a_lut] = lut

                location_b = location + "[B]_LUT"
                name_b_lut = self.location_to_name(location_b)
                lut = codegen.Primitive("LUT4", name_b_lut)
                lut.params["INIT"] = "16'hffff"
                lut.portmap['F'] = name_b_lut + "_F"
                lut.portmap['I0'] = name_b_lut + "_I0"
                lut.portmap['I1'] = name_b_lut + "_I1"
                lut.portmap['I2'] = name_b_lut + "_I2"
                lut.portmap['I3'] = name_b_lut + "_I3"
                mod.wires.update(lut.portmap.values())
                mod.primitives[name_b_lut] = lut

                location_a = location + "[A]_DFF"
                name_a_dff = self.location_to_name(location_a)
                dff = codegen.Primitive("DFF", name_a_dff)
                dff.portmap['CLK'] = name + "_CLK"  # share clk
                dff.portmap['D'] = name_a_lut + "_F"
                dff.portmap['Q'] = name_a_dff + "_Q"
                mod.wires.update(dff.portmap.values())
                mod.primitives[name_a_dff] = dff

                location_a = location + "[B]_DFF"
                name_b_dff = self.location_to_name(location_a)
                dff = codegen.Primitive("DFF", name_b_dff)
                dff.portmap['CLK'] = name + "_CLK"
                dff.portmap['D'] = name_b_lut + "_F"
                dff.portmap['Q'] = name_b_dff + "_Q"
                mod.wires.update(dff.portmap.values())
                mod.primitives[name_b_dff] = dff
Exemple #4
0
def iob(locations, corners):
    cnt = Counter()  # keep track of how many runs are needed
    for ttyp, tiles in locations.items():  # for each tile of this type
        mod = codegen.Module()
        cst = codegen.Constraints()
        # get bels in this ttyp
        bels = {name[-1] for loc in tiles.values() for name in loc}
        locs = tiles.copy()
        for pin in bels:  # [A, B, C, D, ...]
            for typ, conn in iobmap.items():
                # find the next location that has pin
                # or make a new module
                for tile, names in locs.items():
                    name = tile + pin
                    if name in names:
                        del locs[tile]
                        loc = name
                        break
                else:  # no usable tiles
                    yield ttyp, mod, cst, {}
                    cnt[ttyp] += 1
                    locs = tiles.copy()
                    mod = codegen.Module()
                    cst = codegen.Constraints()
                    for tile, names in locs.items():
                        name = tile + pin
                        if name in names:
                            del locs[tile]
                            loc = name
                            break

                name = make_name("IOB", typ)
                iob = codegen.Primitive(typ, name)
                for port in chain.from_iterable(conn.values()):
                    iob.portmap[port] = name + "_" + port

                for direction, wires in conn.items():
                    wnames = [name + "_" + w for w in wires]
                    getattr(mod, direction).update(wnames)
                mod.primitives[name] = iob
                cst.ports[name] = loc

            yield ttyp, mod, cst, {}
            cnt[ttyp] += 1
    # insert dummie in the corners to detect the bank enable bits
    runs = cnt.most_common(1)[0][1]
    for n in range(runs):
        for ttyp in corners:
            mod = codegen.Module()
            cst = codegen.Constraints()
            cfg = {}
            yield ttyp, mod, cst, cfg
Exemple #5
0
    def primitives(self, mod, bits):
        "Generate verilog for an IOB at this location"
        for location, bits in self.location_chunks(bits):
            if bits[0]:
                name = "IOB{}".format(location)
                dff = codegen.Primitive(self.kind, name)
                for port in chain.from_iterable(self.ports.values()):
                    dff.portmap[port] = name + "_" + port

                for direction, wires in self.ports.items():
                    wnames = [name + "_" + w for w in wires]
                    getattr(mod, direction).update(wnames)
                mod.primitives[name] = dff
Exemple #6
0
 def primitives(self, mod, bits):
     "Generate verilog for a DFF at this location"
     for location, bits in self.location_chunks(bits):
         prim, port = self.ffmap[tuple(bits)]
         name = self.location_to_name(location)
         dff = codegen.Primitive(prim, name)
         dff.portmap['CLK'] = name + "_CLK"
         dff.portmap['D'] = name + "_F"
         dff.portmap['Q'] = name + "_Q"
         dff.portmap['CE'] = name + "_CE"
         dff.portmap[port] = name + "_" + port
         mod.wires.update(dff.portmap.values())
         mod.primitives[name] = dff
Exemple #7
0
 def primitives(self, mod, bits):
     "Generate verilog for LUT4s"
     for location, bits in self.location_chunks(bits):
         name = self.location_to_name(location)
         lut = codegen.Primitive("LUT4", name)
         lut.params["INIT"] = np_to_vector(1 ^ bits)  # inverted
         lut.portmap['F'] = name + "_F"
         lut.portmap['I0'] = name + "_I0"
         lut.portmap['I1'] = name + "_I1"
         lut.portmap['I2'] = name + "_I2"
         lut.portmap['I3'] = name + "_I3"
         mod.wires.update(lut.portmap.values())
         mod.primitives[name] = lut
Exemple #8
0
    def primitives(self, mod, bits):
        "Generate verilog for LUT4s"
        for location, bits in self.location_chunks(bits):
            name = self.location_to_name(location)
            lut = codegen.Primitive("LUT4", name)
            lut.params["INIT"] = "16'h0000"
            lut.portmap['F'] = name + "_F"
            neigh = self.neighbours(location)
            for i, ne, bit in zip(count(), neigh, bits):
                if bit:
                    ne_name = self.location_to_name(ne)
                    lut.portmap['I{}'.format(i)] = ne_name + "_F"
                else:
                    lut.portmap['I{}'.format(i)] = name + "_I{}".format(i)

            mod.wires.update(lut.portmap.values())
            mod.primitives[name] = lut
Exemple #9
0
def iob(locations):
    for ttyp, tiles in locations.items():  # for each tile of this type
        mod = codegen.Module()
        cst = codegen.Constraints()
        # get bels in this ttyp
        bels = {name[-1] for loc in tiles.values() for name in loc}
        locs = tiles.copy()
        for pin in bels:  # [A, B, C, D, ...]
            for typ, conn in iobmap.items():
                # find the next location that has pin
                # or make a new module
                for tile, names in locs.items():
                    name = tile + pin
                    if name in names:
                        del locs[tile]
                        loc = name
                        break
                else:  # no usable tiles
                    yield ttyp, mod, cst
                    locs = tiles.copy()
                    mod = codegen.Module()
                    cst = codegen.Constraints()
                    for tile, names in locs.items():
                        name = tile + pin
                        if name in names:
                            del locs[tile]
                            loc = name
                            break

                name = make_name("IOB", typ)
                iob = codegen.Primitive(typ, name)
                for port in chain.from_iterable(conn.values()):
                    iob.portmap[port] = name + "_" + port

                for direction, wires in conn.items():
                    wnames = [name + "_" + w for w in wires]
                    getattr(mod, direction).update(wnames)
                mod.primitives[name] = iob
                cst.ports[name] = loc

            yield ttyp, mod, cst
Exemple #10
0
def tile2verilog(dbrow, dbcol, bels, 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()):
        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