Merge pull request #169 from mithro/patch-1

Update README to be clearer
diff --git a/icebox/icebox_hlc2asc.py b/icebox/icebox_hlc2asc.py
index c26b173..f33b2b0 100755
--- a/icebox/icebox_hlc2asc.py
+++ b/icebox/icebox_hlc2asc.py
@@ -293,7 +293,7 @@
         for i, xy in enumerate(GLB_NETWK_INTERNAL_TILES):
             if net == 'glb_netwk_%d' % i and (x, y) == xy:
                 return 'fabout'
-        raise ParseError("{} is a global netowrk, but not at an expectd location {} {}".format(net, x, y))
+        raise ParseError("{} is a global network, but not at an expected location {} {}".format(net, x, y))
 
     return net
 
@@ -509,6 +509,46 @@
                                          for j in range(len(args)))) else '0'
                    for i in range(1 << len(args)))
 
+def parse_verilog_bitvector_to_bits(in_str):
+    #replace x with 0
+    in_str = re.sub('[xX]', '0', in_str)
+
+    m = re.match("([0-9]+)'([hdob])([0-9a-fA-F]+)", in_str)
+    if m:
+        num_bits = int(m.group(1))
+        prefix = m.group(2)
+        val_str = m.group(3)
+
+        if prefix == 'h':
+            val = eval('0x' + val_str)
+        elif prefix == 'd':
+            val = eval(val_str.lstrip('0'))
+        elif prefix == 'o' or prefix =='b':
+            val = eval('0' + prefix + val_str)
+
+        if val.bit_length() > num_bits:
+            raise ParseError("Number of bits({}) given don't match expected ({})"
+                             .format(val.bit_length(), num_bits))
+    else:
+        val = eval('0x' + in_str)
+        num_bits = len(in_str) * 4
+
+    bit_str = bin(val)[2:]
+    # zero pad
+    nz = num_bits - len(bit_str)
+    bit_vec = nz*['0'] + list(bit_str)
+    return bit_vec
+
+def parse_verilog_bitvector_to_hex(in_str):
+    if type(in_str) == str:
+        bits = parse_verilog_bitvector_to_bits(in_str)
+    else:
+        bits = in_str
+    # pad to 4
+    bits = ((4-len(bits)) % 4) * ['0'] + bits
+    res = ''.join([hex(eval('0b' + ''.join(bits[ii:ii+4])))[2:] for ii in range(0, len(bits), 4)])
+    return res
+
 class ParseError(Exception):
     pass
 
@@ -835,13 +875,7 @@
         elif fields[0] == 'out' and len(fields) >= 3 and fields[1] == '=':
             m = re.match("([0-9]+)'b([01]+)", fields[2])
             if m:
-                lut_bits = m.group(2)
-                if len(lut_bits) != int(m.group(1)):
-                    raise ParseError("Number of bits({}) given don't match expected ({})"
-                                     .format(len(lut_bits), int(m.group(1))))
-                m = len(lut_bits)
-                if m < 16:
-                    lut_bits = (16-m) * "0" + lut_bits
+                lut_bits = parse_verilog_bitvector_to_bits(fields[2])
                 # Verilog 16'bXXXX is MSB first but the bitstream wants LSB.
                 self.lut_bits = list(lut_bits[::-1])
             else:
@@ -904,7 +938,7 @@
 
     def read(self, fields):
         if len(fields) == 1:
-            self.data.append(fields[0])
+            self.data.append(parse_verilog_bitvector_to_hex(fields[0]))
         else:
             raise ParseError("Unepxected format in {}".format(type(self).__name__))
 
@@ -956,7 +990,7 @@
         if fields == ['io_1'] and self.blocks[1] is None:
             self.blocks[1] = IOBlock(self, 1)
             return self.blocks[1]
-        raise ParseError("Unepxected new block in {}".format(type(self).__name__))
+        raise ParseError("Unexpected new block in {}".format(type(self).__name__))
 
 class IOBlock:
     def __init__(self, tile, index):
@@ -1006,7 +1040,9 @@
             self.enable_input = True
         elif fields == ['disable_pull_up'] and not self.disable_pull_up:
             self.disable_pull_up = True
-        elif fields[0] == 'GLOBAL_BUFFER_OUTPUT' and fields[1] == '->' \
+        elif fields[0] in ('GLOBAL_BUFFER_OUTPUT',
+                           'io_%d/GLOBAL_BUFFER_OUTPUT' % self.index) \
+                and fields[1] == '->' \
                 and fields[2].startswith('glb_netwk_'):
             if GLB_NETWK_EXTERNAL_BLOCKS[int(fields[2][10:])] \
                     != (self.tile.x, self.tile.y, self.index):
diff --git a/icebox/icebox_vlog.py b/icebox/icebox_vlog.py
index a86f11e..0080f34 100755
--- a/icebox/icebox_vlog.py
+++ b/icebox/icebox_vlog.py
@@ -345,21 +345,21 @@
             else:
                 net_segs.add(s)
 
-    count_drivers = 0
+    count_drivers = []
     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 re.match(r"lutff_./lout", s[2]): count_drivers += 1
+        if re.match(r"ram/RDATA_", s[2]): count_drivers.append(s[2])
+        if re.match(r"io_./D_IN_", s[2]): count_drivers.append(s[2])
+        if re.match(r"lutff_./out", s[2]): count_drivers.append(s[2])
+        if re.match(r"lutff_./lout", s[2]): count_drivers.append(s[2])
 
-    if count_drivers != 1 and check_driver:
-        failed_drivers_check.append(n)
+    if len(count_drivers) != 1 and check_driver:
+        failed_drivers_check.append((n, count_drivers))
 
     if not strip_comments:
         for s in sorted(net_segs):
                 text_wires.append("// %s" % (s,))
         if count_drivers != 1 and check_driver:
-            text_wires.append("// Number of drivers: %d" % count_drivers)
+            text_wires.append("// Number of drivers: %d %s" % (len(count_drivers), count_drivers))
         text_wires.append("")
 
 def seg_to_net(seg, default=None):
@@ -842,9 +842,9 @@
     else:
         always_stmts.append("/* FF %2d %2d %2d */ assign %s = %s;" % (lut[0], lut[1], lut[2], net_out, net_lout))
     if not "1" in lut_bits:
-        const_assigns.append([net_out, "1'b0"])
+        const_assigns.append([net_lout, "/* LUT   %2d %2d %2d */ 1'b0" % (lut[0], lut[1], lut[2])])
     elif not "0" in lut_bits:
-        const_assigns.append([net_out, "1'b1"])
+        const_assigns.append([net_lout, "/* LUT   %2d %2d %2d */ 1'b1" % (lut[0], lut[1], lut[2])])
     else:
         def make_lut_expr(bits, sigs):
             if not sigs:
@@ -941,7 +941,9 @@
 print()
 
 if failed_drivers_check:
-    print("// Single-driver-check failed for %d nets:" % len(failed_drivers_check))
-    print("// %s" % " ".join(failed_drivers_check))
-    assert False
+    emsg = ["Single-driver-check failed for %d nets:" % len(failed_drivers_check)]
+    for net, drivers in failed_drivers_check:
+        emsg.append("%s has %d drivers: %s" % (net, len(drivers), drivers))
+    print("//", "\n//".join(emsg))
+    assert False, "\n  ".join(emsg)