#!/usr/bin/env python3 import sys dev_name = None dev_width = None dev_height = None num_wires = None tiles = dict() wire_uphill = dict() wire_downhill = dict() wire_bidir = dict() bel_name = list() bel_type = list() wire_uphill_belport = dict() wire_downhill_belports = dict() wire_names = dict() wire_names_r = dict() def cmp_wire_names(newname, oldname): return newname < oldname with open(sys.argv[1], "r") as f: mode = None for line in f: line = line.split() if len(line) == 0 or line[0] == "#": continue if line[0] == ".device": dev_name = line[1] dev_width = int(line[2]) dev_height = int(line[3]) num_wires = int(line[4]) continue if line[0] == ".net": mode = ("net", int(line[1])) continue if line[0] == ".buffer": mode = ("buffer", int(line[3])) continue if line[0] == ".routing": mode = ("routing", int(line[3])) continue if line[0] == ".io_tile": tiles[(int(line[1]), int(line[2]))] = "io" mode = None continue if line[0] == ".logic_tile": tiles[(int(line[1]), int(line[2]))] = "logic" mode = None continue if line[0] == ".ramb_tile": tiles[(int(line[1]), int(line[2]))] = "ramb" mode = None continue if line[0] == ".ramt_tile": tiles[(int(line[1]), int(line[2]))] = "ramt" mode = None continue if (line[0][0] == ".") or (mode is None): mode = None continue if mode[0] == "net": wname = (int(line[0]), int(line[1]), line[2]) wire_names[wname] = mode[1] if (mode[1] not in wire_names_r) or cmp_wire_names(wname, wire_names_r[mode[1]]): wire_names_r[mode[1]] = wname continue if mode[0] == "buffer": wire_a = int(line[1]) wire_b = mode[1] if wire_a not in wire_downhill: wire_downhill[wire_a] = set() if wire_b not in wire_uphill: wire_uphill[wire_b] = set() wire_downhill[wire_a].add(wire_b) wire_uphill[wire_b].add(wire_a) continue if mode[0] == "routing": wire_a = int(line[1]) wire_b = mode[1] if wire_a not in wire_bidir: wire_bidir[wire_a] = set() if wire_b not in wire_bidir: wire_bidir[wire_b] = set() wire_bidir[wire_a].add(wire_b) wire_bidir[wire_b].add(wire_b) continue def add_bel_input(bel, wire, port): if wire not in wire_downhill_belports: wire_downhill_belports[wire] = set() wire_downhill_belports[wire].add((bel, port)) def add_bel_output(bel, wire, port): assert wire not in wire_uphill_belport wire_uphill_belport[wire] = (bel, port) def add_bel_lc(x, y, z): bel = len(bel_name) bel_name.append("%d_%d_lc%d" % (x, y, z)) bel_type.append("ICESTORM_LC") wire_cen = wire_names[(x, y, "lutff_global/cen")] wire_clk = wire_names[(x, y, "lutff_global/clk")] wire_s_r = wire_names[(x, y, "lutff_global/s_r")] if z == 0: wire_cin = wire_names[(x, y, "carry_in_mux")] else: wire_cin = wire_names[(x, y, "lutff_%d/cout" % (z-1))] wire_in_0 = wire_names[(x, y, "lutff_%d/in_0" % z)] wire_in_1 = wire_names[(x, y, "lutff_%d/in_1" % z)] wire_in_2 = wire_names[(x, y, "lutff_%d/in_2" % z)] wire_in_3 = wire_names[(x, y, "lutff_%d/in_3" % z)] wire_out = wire_names[(x, y, "lutff_%d/out" % z)] wire_cout = wire_names[(x, y, "lutff_%d/cout" % z)] wire_lout = wire_names[(x, y, "lutff_%d/lout" % z)] if z < 7 else None add_bel_input(bel, wire_cen, "CEN") add_bel_input(bel, wire_clk, "CLK") add_bel_input(bel, wire_s_r, "SR") add_bel_input(bel, wire_cin, "CIN") add_bel_input(bel, wire_in_0, "IN_0") add_bel_input(bel, wire_in_1, "IN_1") add_bel_input(bel, wire_in_2, "IN_2") add_bel_input(bel, wire_in_3, "IN_3") add_bel_output(bel, wire_out, "O") add_bel_output(bel, wire_cout, "COUT") if wire_lout is not None: add_bel_output(bel, wire_lout, "LO") def add_bel_io(x, y, z): bel = len(bel_name) bel_name.append("%d_%d_lc%d" % (x, y, z)) bel_type.append("SB_IO") wire_cen = wire_names[(x, y, "io_global/cen")] wire_iclk = wire_names[(x, y, "io_global/inclk")] wire_oclk = wire_names[(x, y, "io_global/latch")] wire_latch = wire_names[(x, y, "io_global/outclk")] wire_din_0 = wire_names[(x, y, "io_%d/D_IN_0" % z)] wire_din_1 = wire_names[(x, y, "io_%d/D_IN_1" % z)] wire_dout_0 = wire_names[(x, y, "io_%d/D_OUT_0" % z)] wire_dout_1 = wire_names[(x, y, "io_%d/D_OUT_1" % z)] wire_out_en = wire_names[(x, y, "io_%d/OUT_ENB" % z)] add_bel_input(bel, wire_cen, "CLOCK_ENABLE") add_bel_input(bel, wire_iclk, "INPUT_CLK") add_bel_input(bel, wire_oclk, "OUTPUT_CLK") add_bel_input(bel, wire_latch, "LATCH_INPUT_VALUE") add_bel_output(bel, wire_din_0, "D_IN_0") add_bel_output(bel, wire_din_1, "D_IN_1") add_bel_input(bel, wire_dout_0, "D_OUT_0") add_bel_input(bel, wire_dout_1, "D_OUT_1") add_bel_input(bel, wire_out_en, "OUTPUT_ENABLE") def add_bel_ram(x, y): bel = len(bel_name) bel_name.append("%d_%d_ram" % (x, y)) bel_type.append("ICESTORM_RAM") if (x, y, "ram/WE") in wire_names: # iCE40 1K-style memories y0, y1 = y, y+1 else: # iCE40 8K-style memories y1, y0 = y, y+1 for i in range(16): add_bel_input (bel, wire_names[(x, y0 if i < 8 else y1, "ram/MASK_%d" % i)], "MASK_%d" % i) add_bel_input (bel, wire_names[(x, y0 if i < 8 else y1, "ram/WDATA_%d" % i)], "WDATA_%d" % i) add_bel_output(bel, wire_names[(x, y0 if i < 8 else y1, "ram/RDATA_%d" % i)], "RDATA_%d" % i) for i in range(11): add_bel_input(bel, wire_names[(x, y0, "ram/WADDR_%d" % i)], "WADDR_%d" % i) add_bel_input(bel, wire_names[(x, y1, "ram/RADDR_%d" % i)], "RADDR_%d" % i) add_bel_input(bel, wire_names[(x, y0, "ram/WCLK")], "WCLK") add_bel_input(bel, wire_names[(x, y0, "ram/WCLKE")], "WCLKE") add_bel_input(bel, wire_names[(x, y0, "ram/WE")], "WE") add_bel_input(bel, wire_names[(x, y1, "ram/RCLK")], "RCLK") add_bel_input(bel, wire_names[(x, y1, "ram/RCLKE")], "RCLKE") add_bel_input(bel, wire_names[(x, y1, "ram/RE")], "RE") for tile_xy, tile_type in sorted(tiles.items()): if tile_type == "logic": for i in range(8): add_bel_lc(tile_xy[0], tile_xy[1], i) if tile_type == "io": for i in range(2): add_bel_io(tile_xy[0], tile_xy[1], i) if tile_type == "ramb": add_bel_ram(tile_xy[0], tile_xy[1]) print('#include "chip.h"') print("int num_bels_%s = %d;" % (dev_name, num_wires)) print("BelInfoPOD bel_data_%s[%d] = {" % (dev_name, num_wires)) for bel in range(len(bel_name)): print(" {\"%s\", TYPE_%s}%s" % (bel_name[bel], bel_type[bel], "," if bel+1 < len(bel_name) else "")) print("};") wireinfo = list() for wire in range(num_wires): num_uphill = 0 num_downhill = 0 num_bidir = 0 num_bels_downhill = 0 if wire in wire_uphill: num_uphill = len(wire_uphill[wire]) print("static WireDelayPOD wire%d_uphill[] = {" % wire) print(",\n".join([" {%d, 1.0}" % other_wire for other_wire in wire_uphill[wire]])) print("};") if wire in wire_downhill: num_downhill = len(wire_downhill[wire]) print("static WireDelayPOD wire%d_downhill[] = {" % wire) print(",\n".join([" {%d, 1.0}" % other_wire for other_wire in wire_downhill[wire]])) print("};") if wire in wire_bidir: num_bidir = len(wire_bidir[wire]) print("static WireDelayPOD wire%d_bidir[] = {" % wire) print(",\n".join([" {%d, 1.0}" % other_wire for other_wire in wire_bidir[wire]])) print("};") if wire in wire_downhill_belports: num_bels_downhill = len(wire_downhill_belports[wire]) print("static BelPortPOD wire%d_downbels[] = {" % wire) print(",\n".join([" {%d, PIN_%s}" % it for it in wire_downhill_belports[wire]])) print("};") info = " {" info += "\"%d_%d_%s\", " % wire_names_r[wire] info += "%d, %d, %d, " % (num_uphill, num_downhill, num_bidir) info += ("wire%d_uphill, " % wire) if num_uphill > 0 else "nullptr, " info += ("wire%d_downhill, " % wire) if num_downhill > 0 else "nullptr, " info += ("wire%d_bidir, " % wire) if num_bidir > 0 else "nullptr, " info += "%d, " % (num_bels_downhill) if wire in wire_uphill_belport: info += "{%d, PIN_%s}, " % wire_uphill_belport[wire] else: info += "{-1, PIN_NIL}, " info += ("wire%d_downbels" % wire) if num_bels_downhill > 0 else "nullptr" info += "}" wireinfo.append(info) print("int num_wires_%s = %d;" % (dev_name, num_wires)) print("WireInfoPOD wire_data_%s[%d] = {" % (dev_name, num_wires)) print(",\n".join(wireinfo)) print("};")