icestorm/icebox/icebox_vlog.py

558 lines
22 KiB
Python
Raw Normal View History

2015-07-18 13:05:02 +02:00
#!/usr/bin/python
#
# Copyright (C) 2015 Clifford Wolf <clifford@clifford.at>
#
# Permission to use, copy, modify, and/or distribute this software for any
# purpose with or without fee is hereby granted, provided that the above
# copyright notice and this permission notice appear in all copies.
#
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
from __future__ import division
from __future__ import print_function
import icebox
import getopt, sys, re
strip_comments = False
strip_interconn = False
lookup_pins = False
2015-07-18 13:06:48 +02:00
check_ieren = False
check_driver = False
2015-07-18 13:05:02 +02:00
pcf_data = dict()
portnames = set()
unmatched_ports = set()
2015-07-18 13:06:48 +02:00
modname = "chip"
2015-07-18 13:05:02 +02:00
def usage():
print("""
2015-07-18 13:06:48 +02:00
Usage: icebox_vlog [options] [bitmap.txt]
2015-07-18 13:05:02 +02:00
-s
strip comments from output
-S
strip comments about interconn wires from output
-l
convert io tile port names to chip pin numbers
2015-07-18 13:06:48 +02:00
-n <module-name>
name for the exported module (default: "chip")
2015-07-18 13:05:02 +02:00
-p <pcf-file>
use the set_io command from the specified pcf file
-P <pcf-file>
like -p, enable some hacks for pcf files created
by the iCEcube2 placer.
2015-07-18 13:06:48 +02:00
-R
enable IeRen database checks
-D
enable exactly-one-driver checks
2015-07-18 13:05:02 +02:00
""")
sys.exit(0)
try:
2015-07-18 13:06:48 +02:00
opts, args = getopt.getopt(sys.argv[1:], "sSlap:P:n:RD")
2015-07-18 13:05:02 +02:00
except:
usage()
for o, a in opts:
if o == "-s":
strip_comments = True
elif o == "-S":
strip_interconn = True
elif o == "-l":
lookup_pins = True
2015-07-18 13:06:48 +02:00
elif o == "-n":
modname = a
2015-07-18 13:05:02 +02:00
elif o == "-a":
2015-07-18 13:06:48 +02:00
pass # ignored for backward compatibility
2015-07-18 13:05:02 +02:00
elif o in ("-p", "-P"):
with open(a, "r") as f:
for line in f:
2015-07-18 13:06:48 +02:00
if o == "-P" and not re.search(" # ICE_(GB_)?IO", line):
continue
2015-07-18 13:05:02 +02:00
line = re.sub(r"#.*", "", line.strip()).split()
if len(line) and line[0] == "set_io":
p = line[1]
if o == "-P":
p = p.lower()
p = p.replace("_ibuf", "")
2015-07-18 13:06:48 +02:00
p = p.replace("_obuft", "")
2015-07-18 13:05:02 +02:00
p = p.replace("_obuf", "")
p = p.replace("_gb_io", "")
portnames.add(p)
if not re.match(r"[a-zA-Z_][a-zA-Z0-9_]*$", p):
p = "\\%s " % p
unmatched_ports.add(p)
pinloc = tuple([int(s) for s in line[2:]])
pcf_data[pinloc] = p
2015-07-18 13:06:48 +02:00
elif o == "-R":
check_ieren = True
elif o == "-D":
check_driver = True
2015-07-18 13:05:02 +02:00
else:
usage()
2015-07-18 13:06:48 +02:00
if len(args) == 0:
args.append("/dev/stdin")
if len(args) != 1:
usage()
2015-07-18 13:05:02 +02:00
if not strip_comments:
print("// Reading file '%s'.." % args[0])
ic = icebox.iceconfig()
ic.read_file(args[0])
print()
text_wires = list()
text_ports = list()
luts_queue = set()
text_func = list()
2015-07-18 13:06:48 +02:00
failed_drivers_check = list()
2015-07-18 13:05:02 +02:00
netidx = [0]
nets = dict()
seg2net = dict()
2015-07-18 13:06:48 +02:00
iocells = set()
iocells_in = set()
iocells_out = set()
iocells_special = set()
iocells_type = dict()
iocells_negclk = set()
iocells_inbufs = set()
2015-07-18 13:05:02 +02:00
def is_interconn(netname):
if netname.startswith("sp4_"): return True
if netname.startswith("sp12_"): return True
if netname.startswith("span4_"): return True
if netname.startswith("span12_"): return True
if netname.startswith("logic_op_"): return True
if netname.startswith("neigh_op_"): return True
if netname.startswith("local_"): return True
return False
2015-07-18 13:06:48 +02:00
extra_connections = list()
extra_segments = list()
for bit in ic.extra_bits:
entry = ic.lookup_extra_bit(bit)
if entry[0] == "padin_glb_netwk":
glb = int(entry[1])
pin_entry = ic.padin_pio_db()[glb]
iocells.add((pin_entry[0], pin_entry[1], pin_entry[2]))
iocells_in.add((pin_entry[0], pin_entry[1], pin_entry[2]))
s1 = (pin_entry[0], pin_entry[1], "io_%d/PAD" % pin_entry[2])
s2 = (pin_entry[0], pin_entry[1], "wire_gbuf/padin_%d" % pin_entry[2])
extra_connections.append((s1, s2))
for idx, tile in ic.io_tiles.items():
tc = icebox.tileconfig(tile)
iocells_type[(idx[0], idx[1], 0)] = ["0" for i in range(6)]
iocells_type[(idx[0], idx[1], 1)] = ["0" for i in range(6)]
for entry in ic.tile_db(idx[0], idx[1]):
if check_ieren and entry[1] == "IoCtrl" and entry[2].startswith("IE_") and not tc.match(entry[0]):
iren_idx = (idx[0], idx[1], 0 if entry[2] == "IE_0" else 1)
for iren_entry in ic.ieren_db():
if iren_idx[0] == iren_entry[3] and iren_idx[1] == iren_entry[4] and iren_idx[2] == iren_entry[5]:
iocells_inbufs.add((iren_entry[0], iren_entry[1], iren_entry[2]))
if entry[1] == "NegClk" and tc.match(entry[0]):
iocells_negclk.add((idx[0], idx[1], 0))
iocells_negclk.add((idx[0], idx[1], 1))
if entry[1].startswith("IOB_") and entry[2].startswith("PINTYPE_") and tc.match(entry[0]):
match1 = re.match("IOB_(\d+)", entry[1])
match2 = re.match("PINTYPE_(\d+)", entry[2])
assert match1 and match2
iocells_type[(idx[0], idx[1], int(match1.group(1)))][int(match2.group(1))] = "1"
iocells_type[(idx[0], idx[1], 0)] = "".join(iocells_type[(idx[0], idx[1], 0)])
iocells_type[(idx[0], idx[1], 1)] = "".join(iocells_type[(idx[0], idx[1], 1)])
2015-07-18 13:05:02 +02:00
for segs in sorted(ic.group_segments()):
2015-07-18 13:06:48 +02:00
for seg in segs:
if ic.tile_type(seg[0], seg[1]) == "IO":
match = re.match("io_(\d+)/D_(IN|OUT)_(\d+)", seg[2])
if match:
cell = (seg[0], seg[1], int(match.group(1)))
iocells.add(cell)
if match.group(2) == "IN":
if check_ieren:
assert cell in iocells_inbufs
if iocells_type[cell] != "100000" or match.group(3) != "0":
iocells_special.add(cell)
iocells_in.add(cell)
if match.group(2) == "OUT" and iocells_type[cell][2:6] != "0000":
if iocells_type[cell] != "100110" or match.group(3) != "0":
iocells_special.add(cell)
iocells_out.add(cell)
extra_segments.append((seg[0], seg[1], "io_%d/PAD" % int(match.group(1))))
for cell in iocells:
if iocells_type[cell] == "100110" and not cell in iocells_special:
s1 = (cell[0], cell[1], "io_%d/PAD" % cell[2])
s2 = (cell[0], cell[1], "io_%d/D_OUT_0" % cell[2])
extra_connections.append((s1, s2))
del iocells_type[cell]
elif iocells_type[cell] == "100000" and not cell in iocells_special:
s1 = (cell[0], cell[1], "io_%d/PAD" % cell[2])
s2 = (cell[0], cell[1], "io_%d/D_IN_0" % cell[2])
extra_connections.append((s1, s2))
del iocells_type[cell]
def next_netname():
2015-07-18 13:05:02 +02:00
while True:
netidx[0] += 1
n = "n%d" % netidx[0]
2015-07-18 13:06:48 +02:00
if n not in portnames:
return n
2015-07-18 13:05:02 +02:00
2015-07-18 13:06:48 +02:00
for segs in sorted(ic.group_segments(extra_connections=extra_connections, extra_segments=extra_segments)):
n = next_netname()
2015-07-18 13:05:02 +02:00
net_segs = set()
renamed_net_to_port = False
for s in segs:
2015-07-18 13:06:48 +02:00
match = re.match("io_(\d+)/PAD", s[2])
2015-07-18 13:05:02 +02:00
if match:
2015-07-18 13:06:48 +02:00
idx = (s[0], s[1], int(match.group(1)))
p = "io_%d_%d_%d" % idx
net_segs.add(p)
2015-07-18 13:05:02 +02:00
if lookup_pins or pcf_data:
for entry in icebox.pinloc_db:
2015-07-18 13:06:48 +02:00
if idx[0] == entry[1] and idx[1] == entry[2] and idx[2] == entry[3]:
2015-07-18 13:05:02 +02:00
if (entry[0],) in pcf_data:
p = pcf_data[(entry[0],)]
unmatched_ports.discard(p)
elif (entry[1], entry[2], entry[3]) in pcf_data:
p = pcf_data[(entry[1], entry[2], entry[3])]
unmatched_ports.discard(p)
elif lookup_pins:
p = "pin_%d" % entry[0]
if not renamed_net_to_port:
n = p
2015-07-18 13:06:48 +02:00
if idx in iocells_in and idx not in iocells_out:
2015-07-18 13:05:02 +02:00
text_ports.append("input %s" % p)
2015-07-18 13:06:48 +02:00
elif idx not in iocells_in and idx in iocells_out:
2015-07-18 13:05:02 +02:00
text_ports.append("output %s" % p)
2015-07-18 13:06:48 +02:00
else:
text_ports.append("inout %s" % p)
2015-07-18 13:05:02 +02:00
text_wires.append("wire %s;" % n)
renamed_net_to_port = True
2015-07-18 13:06:48 +02:00
elif idx in iocells_in and idx not in iocells_out:
2015-07-18 13:05:02 +02:00
text_ports.append("input %s" % p)
text_wires.append("assign %s = %s;" % (n, p))
2015-07-18 13:06:48 +02:00
elif idx not in iocells_in and idx in iocells_out:
2015-07-18 13:05:02 +02:00
text_ports.append("output %s" % p)
text_wires.append("assign %s = %s;" % (p, n))
2015-07-18 13:06:48 +02:00
else:
text_ports.append("inout %s" % p)
text_wires.append("assign %s = %s;" % (p, n))
2015-07-18 13:05:02 +02:00
match = re.match("lutff_(\d+)/", s[2])
if match:
luts_queue.add((s[0], s[1], int(match.group(1))))
nets[n] = segs
for s in segs:
seg2net[s] = n
if not renamed_net_to_port:
text_wires.append("wire %s;" % n)
for s in segs:
if not strip_interconn or not is_interconn(s[2]):
if s[2].startswith("glb_netwk_"):
net_segs.add((0, 0, s[2]))
else:
net_segs.add(s)
2015-07-18 13:06:48 +02:00
count_drivers = 0
for s in segs:
if re.match(r"ram/RDATA_", s[2]): count_drivers += 1
if re.match(r"io_./D_IN_", s[2]): count_drivers += 1
if re.match(r"lutff_./out", s[2]): count_drivers += 1
if count_drivers != 1 and check_driver:
failed_drivers_check.append(n)
2015-07-18 13:05:02 +02:00
if not strip_comments:
for s in sorted(net_segs):
text_wires.append("// %s" % (s,))
2015-07-18 13:06:48 +02:00
if count_drivers != 1 and check_driver:
text_wires.append("// Number of drivers: %d" % count_drivers)
2015-07-18 13:05:02 +02:00
text_wires.append("")
def seg_to_net(seg, default=None):
if seg not in seg2net:
if default is not None:
return default
2015-07-18 13:06:48 +02:00
n = next_netname()
2015-07-18 13:05:02 +02:00
nets[n] = set([seg])
seg2net[seg] = n
text_wires.append("wire %s;" % n)
if not strip_comments:
if not strip_interconn or not is_interconn(seg[2]):
text_wires.append("// %s" % (seg,))
text_wires.append("")
return seg2net[seg]
2015-07-18 13:06:48 +02:00
for cell in iocells:
if cell in iocells_type:
net_pad = seg_to_net((cell[0], cell[1], "io_%d/PAD" % cell[2]))
net_din0 = seg_to_net((cell[0], cell[1], "io_%d/D_IN_0" % cell[2]), "")
net_din1 = seg_to_net((cell[0], cell[1], "io_%d/D_IN_1" % cell[2]), "")
net_dout0 = seg_to_net((cell[0], cell[1], "io_%d/D_OUT_0" % cell[2]), "0")
net_dout1 = seg_to_net((cell[0], cell[1], "io_%d/D_OUT_1" % cell[2]), "0")
net_oen = seg_to_net((cell[0], cell[1], "io_%d/OUT_ENB" % cell[2]), "1")
net_cen = seg_to_net((cell[0], cell[1], "io_global/cen"), "1")
net_iclk = seg_to_net((cell[0], cell[1], "io_global/inclk"), "0")
net_oclk = seg_to_net((cell[0], cell[1], "io_global/outclk"), "0")
net_latch = seg_to_net((cell[0], cell[1], "io_global/latch"), "0")
iotype = iocells_type[cell]
if cell in iocells_negclk:
posedge = "negedge"
negedge = "posedge"
else:
posedge = "posedge"
negedge = "negedge"
text_func.append("// IO Cell %s" % (cell,))
if not strip_comments:
text_func.append("// PAD = %s" % net_pad)
text_func.append("// D_IN_0 = %s" % net_din0)
text_func.append("// D_IN_1 = %s" % net_din1)
text_func.append("// D_OUT_0 = %s" % net_dout0)
text_func.append("// D_OUT_1 = %s" % net_dout1)
text_func.append("// OUT_ENB = %s" % net_oen)
text_func.append("// CLK_EN = %s" % net_cen)
text_func.append("// IN_CLK = %s" % net_iclk)
text_func.append("// OUT_CLK = %s" % net_oclk)
text_func.append("// LATCH = %s" % net_latch)
text_func.append("// TYPE = %s (LSB:MSB)" % iotype)
if net_din0 != "" or net_din1 != "":
if net_cen == "1":
icen_cond = ""
else:
icen_cond = "if (%s) " % net_cen
if net_din0 != "":
if iotype[1] == "0" and iotype[0] == "0":
reg_din0 = next_netname()
text_func.append("reg %s;" % reg_din0)
text_func.append("always @(%s %s) %s%s <= %s;" % (posedge, net_iclk, icen_cond, reg_din0, net_pad))
text_func.append("assign %s = %s;" % (net_din0, reg_din0))
if iotype[1] == "0" and iotype[0] == "1":
text_func.append("assign %s = %s;" % (net_din0, net_pad))
if iotype[1] == "1" and iotype[0] == "0":
reg_din0 = next_netname()
reg_din0_latched = next_netname()
text_func.append("reg %s, %s;" % (reg_din0, reg_din0_latched))
text_func.append("always @(%s %s) %s%s <= %s;" % (posedge, net_iclk, icen_cond, reg_din0, net_pad))
text_func.append("always @* if (!%s) %s = %s;" % (net_latch, reg_din0_latched, reg_din0))
text_func.append("assign %s = %s;" % (net_din0, reg_din0_latched))
if iotype[1] == "1" and iotype[0] == "1":
reg_din0 = next_netname()
text_func.append("reg %s;" % reg_din0)
text_func.append("always @* if (!%s) %s = %s;" % (net_latch, reg_din0, net_pad))
text_func.append("assign %s = %s;" % (net_din0, reg_din0))
if net_din1 != "":
reg_din1 = next_netname()
text_func.append("reg %s;" % reg_din1)
text_func.append("always @(%s %s) %s%s <= %s;" % (negedge, net_iclk, icen_cond, reg_din1, net_pad))
text_func.append("assign %s = %s;" % (net_din1, reg_din1))
if iotype[5] != "0" or iotype[4] != "0":
if net_cen == "1":
ocen_cond = ""
else:
ocen_cond = "if (%s) " % net_cen
# effective OEN: iotype[4], iotype[5]
if iotype[5] == "0" and iotype[4] == "1":
eff_oen = "1"
if iotype[5] == "1" and iotype[4] == "0":
eff_oen = net_oen
if iotype[5] == "1" and iotype[4] == "1":
eff_oen = next_netname()
text_func.append("reg %s;" % eff_oen)
text_func.append("always @(%s %s) %s%s <= %s;" % (posedge, net_oclk, ocen_cond, eff_oen, net_oen))
# effective DOUT: iotype[2], iotype[3]
if iotype[2] == "0" and iotype[3] == "0":
ddr_posedge = next_netname()
ddr_negedge = next_netname()
text_func.append("reg %s, %s;" % (ddr_posedge, ddr_negedge))
text_func.append("always @(%s %s) %s%s <= %s;" % (posedge, net_oclk, ocen_cond, ddr_posedge, net_dout0))
text_func.append("always @(%s %s) %s%s <= %s;" % (negedge, net_oclk, ocen_cond, ddr_negedge, net_dout1))
eff_dout = next_netname()
text_func.append("wire %s;" % (eff_dout))
if cell in iocells_negclk:
text_func.append("assign %s = %s ? %s : %s;" % (eff_dout, net_oclk, ddr_negedge, ddr_posedge))
else:
text_func.append("assign %s = %s ? %s : %s;" % (eff_dout, net_oclk, ddr_posedge, ddr_negedge))
if iotype[2] == "0" and iotype[3] == "1":
eff_dout = net_dout0
if iotype[2] == "1" and iotype[3] == "0":
eff_dout = next_netname()
text_func.append("reg %s;" % eff_dout)
text_func.append("always @(%s %s) %s%s <= %s;" % (posedge, net_oclk, ocen_cond, eff_dout, net_dout0))
if iotype[2] == "1" and iotype[3] == "1":
eff_dout = next_netname()
text_func.append("reg %s;" % eff_dout)
text_func.append("always @(%s %s) %s%s <= !%s;" % (posedge, net_oclk, ocen_cond, eff_dout, net_dout0))
if eff_oen == "1":
text_func.append("assign %s = %s;" % (net_pad, eff_dout))
else:
text_func.append("assign %s = %s ? %s : 1'bz;" % (net_pad, eff_oen, eff_dout))
text_func.append("")
for p in unmatched_ports:
text_ports.append("input %s" % p)
2015-07-18 13:05:02 +02:00
wire_to_reg = set()
lut_assigns = list()
const_assigns = list()
carry_assigns = list()
always_stmts = list()
max_net_len = 0
for lut in luts_queue:
seq_bits = icebox.get_lutff_seq_bits(ic.logic_tiles[(lut[0], lut[1])], lut[2])
if seq_bits[0] == "1":
seg_to_net((lut[0], lut[1], "lutff_%d/cout" % lut[2]))
for lut in luts_queue:
tile = ic.logic_tiles[(lut[0], lut[1])]
lut_bits = icebox.get_lutff_lut_bits(tile, lut[2])
seq_bits = icebox.get_lutff_seq_bits(tile, lut[2])
net_in0 = seg_to_net((lut[0], lut[1], "lutff_%d/in_0" % lut[2]), "0")
net_in1 = seg_to_net((lut[0], lut[1], "lutff_%d/in_1" % lut[2]), "0")
net_in2 = seg_to_net((lut[0], lut[1], "lutff_%d/in_2" % lut[2]), "0")
net_in3 = seg_to_net((lut[0], lut[1], "lutff_%d/in_3" % lut[2]), "0")
net_out = seg_to_net((lut[0], lut[1], "lutff_%d/out" % lut[2]))
if seq_bits[0] == "1":
net_cout = seg_to_net((lut[0], lut[1], "lutff_%d/cout" % lut[2]))
net_in1 = seg_to_net((lut[0], lut[1], "lutff_%d/in_1" % lut[2]), "0")
net_in2 = seg_to_net((lut[0], lut[1], "lutff_%d/in_2" % lut[2]), "0")
if lut[2] == 0:
net_cin = seg_to_net((lut[0], lut[1], "carry_in_mux"))
if icebox.get_carry_cascade_bit(tile) == "0":
if not strip_comments:
text_wires.append("// Carry-In for (%d %d)" % (lut[0], lut[1]))
text_wires.append("assign %s = %s;" % (net_cin, icebox.get_carry_bit(tile)))
if not strip_comments:
text_wires.append("")
else:
net_cin = seg_to_net((lut[0], lut[1], "lutff_%d/cout" % (lut[2]-1)), "0")
carry_assigns.append([net_cout, "/* CARRY %2d %2d %2d */ (%s & %s) | ((%s | %s) & %s)" %
(lut[0], lut[1], lut[2], net_in1, net_in2, net_in1, net_in2, net_cin)])
if seq_bits[1] == "1":
2015-07-18 13:06:48 +02:00
n = next_netname()
2015-07-18 13:05:02 +02:00
text_wires.append("wire %s;" % n)
if not strip_comments:
text_wires.append("// FF %s" % (lut,))
text_wires.append("")
net_cen = seg_to_net((lut[0], lut[1], "lutff_global/cen"), "1")
net_clk = seg_to_net((lut[0], lut[1], "lutff_global/clk"), "0")
net_sr = seg_to_net((lut[0], lut[1], "lutff_global/s_r"), "0")
if seq_bits[3] == "0":
always_stmts.append("/* FF %2d %2d %2d */ always @(%sedge %s) if (%s) %s <= %s ? %s : %s;" %
(lut[0], lut[1], lut[2], "neg" if icebox.get_negclk_bit(tile) == "1" else "pos",
net_clk, net_cen, net_out, net_sr, seq_bits[2], n))
else:
always_stmts.append("/* FF %2d %2d %2d */ always @(%sedge %s, posedge %s) if (%s) %s <= %s; else if (%s) %s <= %s;" %
(lut[0], lut[1], lut[2], "neg" if icebox.get_negclk_bit(tile) == "1" else "pos",
net_clk, net_sr, net_sr, net_out, seq_bits[2], net_cen, net_out, n))
wire_to_reg.add(net_out)
net_out = n
if not "1" in lut_bits:
const_assigns.append([net_out, "1'b0"])
elif not "0" in lut_bits:
const_assigns.append([net_out, "1'b1"])
else:
def make_lut_expr(bits, sigs):
if not sigs:
return "%s" % bits[0]
l_expr = make_lut_expr(bits[0:len(bits)//2], sigs[1:])
h_expr = make_lut_expr(bits[len(bits)//2:len(bits)], sigs[1:])
if h_expr == l_expr: return h_expr
if sigs[0] == "0": return l_expr
if sigs[0] == "1": return h_expr
if h_expr == "1" and l_expr == "0": return sigs[0]
if h_expr == "0" and l_expr == "1": return "!" + sigs[0]
return "%s ? %s : %s" % (sigs[0], h_expr, l_expr)
lut_expr = make_lut_expr(lut_bits, [net_in3, net_in2, net_in1, net_in0])
lut_assigns.append([net_out, "/* LUT %2d %2d %2d */ %s" % (lut[0], lut[1], lut[2], lut_expr)])
max_net_len = max(max_net_len, len(net_out))
for a in const_assigns + lut_assigns + carry_assigns:
text_func.append("assign %-*s = %s;" % (max_net_len, a[0], a[1]))
2015-07-18 13:06:48 +02:00
print("module %s (%s);\n" % (modname, ", ".join(text_ports)))
2015-07-18 13:05:02 +02:00
new_text_wires = list()
for line in text_wires:
match = re.match(r"wire ([^ ;]+)(.*)", line)
if match and match.group(1) in wire_to_reg:
line = "reg " + match.group(1) + match.group(2)
if strip_comments:
if new_text_wires and new_text_wires[-1].split()[0] == line.split()[0] and new_text_wires[-1][-1] == ";":
new_text_wires[-1] = new_text_wires[-1][0:-1] + "," + line[len(line.split()[0]):]
else:
new_text_wires.append(line)
else:
print(line)
for line in new_text_wires:
print(line)
if strip_comments:
print()
for line in text_func:
print(line)
for line in always_stmts:
print(line)
print()
for p in unmatched_ports:
print("// Warning: unmatched port '%s'" %p)
if unmatched_ports:
print()
print("endmodule")
print()
2015-07-18 13:06:48 +02:00
if failed_drivers_check:
print("// Single-driver-check failed for %d nets:" % len(failed_drivers_check))
print("// %s" % " ".join(failed_drivers_check))
assert False