Also generate strength wrappers.
diff --git a/scripts/python-skywater-pdk/generate_symbols.sh b/scripts/python-skywater-pdk/generate_symbols.sh
index 9b45617..a063313 100755
--- a/scripts/python-skywater-pdk/generate_symbols.sh
+++ b/scripts/python-skywater-pdk/generate_symbols.sh
@@ -5,12 +5,13 @@
 	exit 1
 fi
 
-find $1/skywater-pdk/ -name *.blackbox.v -delete
-find $1/skywater-pdk/ -name *.symbol.v -delete
+find $1/skywater-pdk/ -name *.v -delete
 
 ./generate_verilog_blackbox.py $1/skywater-pdk/libraries/*/*/cells/*
 
-exit 0
+(cd $1/ ; git diff --no-renames --name-only --diff-filter=D -z | xargs -0 git checkout --)
+
+exit
 
 for LIB in $1/skywater-pdk/libraries/*; do
 	LIBNAME=$(basename $LIB)
diff --git a/scripts/python-skywater-pdk/generate_verilog_blackbox.py b/scripts/python-skywater-pdk/generate_verilog_blackbox.py
index 05c7882..7675c3e 100755
--- a/scripts/python-skywater-pdk/generate_verilog_blackbox.py
+++ b/scripts/python-skywater-pdk/generate_verilog_blackbox.py
@@ -521,6 +521,19 @@
         sys.stdout.flush()
 
 
+
+def seek_backwards(f):
+    start_pos = f.tell()
+    current_pos = f.tell()-1
+    while True:
+        f.seek(current_pos)
+        d = f.read(1)
+        if d not in '\n ,':
+            break
+        current_pos -= 1
+    f.seek(current_pos+1)
+
+
 def drive_strengths(basename, cellpath):
     drives = []
     for f in os.listdir(cellpath):
@@ -532,7 +545,8 @@
         drive = modname.replace(basename, '')
         if not drive:
             continue
-        drives.append(drive)
+        assert drive.startswith('_'), drive
+        drives.append(drive[1:])
     return drives
 
 def wrap(s):
@@ -544,9 +558,19 @@
 """
 
 
-def write_verilog_header(desc, f, define_data):
+def file_guard(fname):
+    fname = re.sub('[^A-Za-z_0-9]', '_', fname)
+    return fname.upper()
+
+
+def write_verilog_header(f, desc, define_data):
+    assert f.name, f
+    guard = file_guard(os.path.basename(f.name))
     f.write(copyright_header)
     f.write('\n')
+    f.write(f'`ifndef {guard}\n')
+    f.write(f'`define {guard}\n')
+    f.write('\n')
     f.write(f"/**\n")
     f.write(wrap(f"{define_data['name']}: {define_data['description']}"))
     f.write('\n')
@@ -558,6 +582,20 @@
     f.write('\n')
     f.write(f" */\n")
     f.write('\n')
+    f.write('`timescale 1ns / 1ps\n')
+    f.write('\n')
+
+
+def write_verilog_footer(f):
+    assert f.name, f
+    guard = file_guard(os.path.basename(f.name))
+    f.write('\n')
+    f.write(f'`endif  // {guard}\n')
+    f.close()
+
+
+
+def write_module_header(f, define_data):
     f.write('(* blackbox *)\n')
     f.write(f"module {define_data['library']}__{define_data['name']} (")
 
@@ -595,41 +633,84 @@
     f.write('\n')
 
 
-# def maxlen(ports, groups, filter=None):
-#     if filter is None:
-#         filter = {}
-#     maxl = {}
-#     for g in groups:
-#         maxl[g] = 0
-#     for p in ports:
-#         if not p:
-#             continue
-#         for i, g in enumerate(groups):
-#             if g is None:
-#                 continue
-#             if g in filter:
-#                 if p[0] not in filter[g]:
-#                     continue
-#             if not p[i]:
-#                 continue
-#             maxl[g] = max(maxl[g], len(p[i]))
-#     return maxl
-
-
-def ports_by_class(define_data):
-    ports = {
-        'power': [],
-        'signal': [],
-    }
+def write_verilog_ports(f, ports):
     maxlen = {}
-    maxlen['power']  = defaultdict(lambda: 0)
-    maxlen['signal'] = defaultdict(lambda: 0)
+    maxlen['pname'] = max([0]+[len(p[1]) for p in ports])
+    maxlen['pdir']  = max([0]+[len(p[2]) for p in ports])
+    maxlen['ptype'] = max([0]+[len(p[3]) for p in ports if p[0] != 'power'])
+
+    for pclass, pname, pdir, ptype in ports:
+        pname = pname.ljust(maxlen['pname'])
+
+        if maxlen['pdir']:
+            pdir = pdir.ljust(maxlen['pdir'])+' '
+        else:
+            pdir = ''
+
+        if maxlen['ptype']:
+            ptype = ptype.ljust(maxlen['ptype'])+ ' '
+        else:
+            ptype = ''
+
+        f.write(f"\n    {pdir}{ptype}{pname},")
+    seek_backwards(f)
+    if ports:
+        f.write("\n")
+    f.write(");\n")
+
+
+def write_verilog_symbol_ports(f, pports):
+    maxlen = {}
+    maxlen['pname'] = max([0]+[len(p[2]) for p in pports if p])
+    maxlen['pdir']  = max([0]+[len(p[3]) for p in pports if p])
+    maxlen['ptype'] = max([0]+[len(p[4]) for p in pports if p and p[1] != 'power'])
+
+    for i, p in enumerate(pports):
+        if not p:
+            np = pports[i+1]
+            if i > 0:
+                f.write('\n')
+            f.write('\n    //# {{'+np[0].type+'|'+np[0].desc+'}}')
+            continue
+        pg, pclass, pname, pdir, ptype = p
+        if pclass == 'power':
+            ptype = ''
+
+        pname = pname.ljust(maxlen['pname'])
+
+        if maxlen['pdir']:
+            pdir = pdir.ljust(maxlen['pdir'])+' '
+        else:
+            pdir = ''
+
+        if maxlen['ptype']:
+            ptype = ptype.ljust(maxlen['ptype'])+ ' '
+        else:
+            ptype = ''
+
+        f.write(f"\n    {pdir}{ptype}{pname},")
+    seek_backwards(f)
+    if pports:
+        f.write("\n")
+    f.write(");\n")
+
+
+def nonpp_ports(define_data):
+    ports = []
     for pclass, pname, pdir, ptype in define_data['ports']:
-        ports[pclass].append((pclass, pname, pdir, ptype))
-        maxlen[pclass]['pname'] = max(maxlen[pclass]['pname'], len(pname))
-        maxlen[pclass]['pdir']  = max(maxlen[pclass]['pdir'],  len(pdir))
-        maxlen[pclass]['ptype'] = max(maxlen[pclass]['ptype'], len(ptype))
-    return ports, maxlen
+        if pclass != 'signal':
+            continue
+        ports.append((pclass, pname, pdir, ptype))
+    return ports
+
+
+def pp_ports(define_data):
+    ports = []
+    for pclass, pname, pdir, ptype in define_data['ports']:
+        if pclass == 'power':
+            ptype = ''
+        ports.append((pclass, pname, pdir, ptype))
+    return ports
 
 
 def write_blackbox(cellpath, define_data):
@@ -638,33 +719,15 @@
     print("Creating", outpath)
     with open(outpath, "w+") as f:
         write_verilog_header(
+            f,
             "Verilog stub definition (black box without power pins).",
-            f, define_data)
-
-        ports, maxlen = ports_by_class(define_data)
-        maxlen = maxlen['signal']
-        for pclass, pname, pdir, ptype in ports['signal']:
-            pname = pname.ljust(maxlen['pname'])
-
-            if maxlen['pdir']:
-                pdir = pdir.ljust(maxlen['pdir'])+' '
-            else:
-                pdir = ''
-
-            if maxlen['ptype']:
-                ptype = ptype.ljust(maxlen['ptype'])+ ' '
-            else:
-                ptype = ''
-
-            f.write(f"\n    {pdir}{ptype}{pname},")
-        if ports['signal']:
-            f.seek(f.tell()-1)
-            f.write("\n")
-        f.write(");\n")
-
+            define_data)
+        write_module_header(f, define_data)
+        write_verilog_ports(f, nonpp_ports(define_data))
         write_verilog_parameters(f, define_data)
         write_verilog_supplies(f, define_data)
         f.write('endmodule\n')
+        write_verilog_footer(f)
 
 
 def write_blackbox_pp(cellpath, define_data):
@@ -673,37 +736,14 @@
     print("Creating", outpath)
     with open(outpath, "w+") as f:
         write_verilog_header(
+            f,
             "Verilog stub definition (black box with power pins).",
-            f, define_data)
-
-        maxlen = {}
-        maxlen['pname'] = max([0]+[len(p[1]) for p in define_data['ports']])
-        maxlen['pdir']  = max([0]+[len(p[2]) for p in define_data['ports']])
-        maxlen['ptype'] = max([0]+[len(p[3]) for p in define_data['ports'] if p[0] == 'signal'])
-
-        for pclass, pname, pdir, ptype in define_data['ports']:
-            if pclass == 'power':
-                ptype = ''
-
-            pname = pname.ljust(maxlen['pname'])
-
-            if maxlen['pdir']:
-                pdir = pdir.ljust(maxlen['pdir'])+' '
-            else:
-                pdir = ''
-
-            if maxlen['ptype']:
-                ptype = ptype.ljust(maxlen['ptype'])+ ' '
-            else:
-                ptype = ''
-
-            f.write(f"\n    {pdir}{ptype}{pname},")
-        if define_data['ports']:
-            f.seek(f.tell()-1)
-            f.write("\n")
-        f.write(");\n")
+            define_data)
+        write_module_header(f, define_data)
+        write_verilog_ports(f, pp_ports(define_data))
         write_verilog_parameters(f, define_data)
         f.write('endmodule\n')
+        write_verilog_footer(f)
 
 
 def group_ports_for_symbol(define_data, only):
@@ -738,45 +778,15 @@
 
     with open(outpath, "w+") as f:
         write_verilog_header(
+            f,
             "Verilog stub (without power pins) for graphical symbol definition generation.",
-            f, define_data)
-
-        maxlen = {}
-        maxlen['pname'] = max([0]+[len(p[1]) for p in define_data['ports'] if p[0] == 'signal'])
-        maxlen['pdir']  = max([0]+[len(p[2]) for p in define_data['ports'] if p[0] == 'signal'])
-        maxlen['ptype'] = max([0]+[len(p[3]) for p in define_data['ports'] if p[0] == 'signal'])
-
-        for i, p in enumerate(pports):
-            if not p:
-                np = pports[i+1]
-                if i > 0:
-                    f.write('\n')
-                f.write('\n    //# {{'+np[0].type+'|'+np[0].desc+'}}')
-                continue
-            pg, pclass, pname, pdir, ptype = p
-            if pclass != 'signal':
-                continue
-
-            pname = pname.ljust(maxlen['pname'])
-
-            if maxlen['pdir']:
-                pdir = pdir.ljust(maxlen['pdir'])+' '
-            else:
-                pdir = ''
-
-            if maxlen['ptype']:
-                ptype = ptype.ljust(maxlen['ptype'])+ ' '
-            else:
-                ptype = ''
-
-            f.write(f"\n    {pdir}{ptype}{pname},")
-        if pports:
-            f.seek(f.tell()-1)
-            f.write("\n")
-        f.write(");\n")
+            define_data)
+        write_module_header(f, define_data)
+        write_verilog_symbol_ports(f, pports)
         write_verilog_parameters(f, define_data)
         write_verilog_supplies(f, define_data)
         f.write('endmodule\n')
+        write_verilog_footer(f)
 
 
 def write_symbol_pp(cellpath, define_data):
@@ -789,46 +799,74 @@
 
     with open(outpath, "w+") as f:
         write_verilog_header(
+            f,
             "Verilog stub (with power pins) for graphical symbol definition generation.",
-            f, define_data)
-
-        maxlen = {}
-        maxlen['pname'] = max([0]+[len(p[1]) for p in define_data['ports']])
-        maxlen['pdir']  = max([0]+[len(p[2]) for p in define_data['ports']])
-        maxlen['ptype'] = max([0]+[len(p[3]) for p in define_data['ports'] if p[0] == 'signal'])
-
-        for i, p in enumerate(pports):
-            if not p:
-                np = pports[i+1]
-                if i > 0:
-                    f.write('\n')
-                f.write('\n    //# {{'+np[0].type+'|'+np[0].desc+'}}')
-                continue
-            pg, pclass, pname, pdir, ptype = p
-            if pclass == 'power':
-                ptype = ''
-
-            pname = pname.ljust(maxlen['pname'])
-
-            if maxlen['pdir']:
-                pdir = pdir.ljust(maxlen['pdir'])+' '
-            else:
-                pdir = ''
-
-            if maxlen['ptype']:
-                ptype = ptype.ljust(maxlen['ptype'])+ ' '
-            else:
-                ptype = ''
-
-            f.write(f"\n    {pdir}{ptype}{pname},")
-        if pports:
-            f.seek(f.tell()-1)
-            f.write("\n")
-        f.write(");\n")
+            define_data)
+        write_module_header(f, define_data)
+        write_verilog_symbol_ports(f, pports)
         write_verilog_parameters(f, define_data)
         f.write('endmodule\n')
+        write_verilog_footer(f)
 
 
+def write_verilog_wrapper(f, extra, supplies, ports, define_data):
+    f.write('\n')
+    f.write('`celldefine\n')
+    f.write(f"module {define_data['library']}__{define_data['name']}{extra} (")
+    write_verilog_ports(f, pp_ports(define_data))
+    write_verilog_parameters(f, define_data)
+    if supplies:
+        write_verilog_supplies(f, define_data)
+
+    param_str = ''
+    if define_data['parameters']:
+        param_str += '#('
+        param_str += " ".join('.{0}({0})'.format(p[0]) for p in define_data['parameters'])
+        param_str += ') '
+
+    ports_str = ''
+    if ports:
+        ports_str += ",\n        ".join('.{0}({0})'.format(p[1]) for p in ports);
+
+    f.write(f"    {define_data['library']}__{define_data['name']} cell ")
+    f.write(param_str)
+    f.write('(\n        ')
+    f.write(ports_str)
+    seek_backwards(f)
+    if ports:
+        f.write("\n    );\n")
+    else:
+        f.write(");\n")
+    f.write('\n')
+    f.write('endmodule\n')
+    f.write('`endcelldefine\n')
+    f.write('\n')
+
+
+def write_drive_wrapper(drive, cellpath, define_data):
+    outpath = os.path.join(cellpath, f"{define_data['library']}__{define_data['name']}_{drive}.v")
+    basefile = f"{define_data['library']}__{define_data['name']}"
+    assert not os.path.exists(outpath), outpath
+    print("Creating", outpath)
+
+    with open(outpath, "w+") as f:
+        write_verilog_header(
+            f,
+            f"Verilog wrapper for {define_data['name']} drive {drive}.",
+            define_data)
+        f.write(f'`include "{basefile}.v"\n')
+        f.write('\n')
+        f.write('`ifdef USE_POWER_PINS\n')
+        f.write('/*********************************************************/\n')
+        write_verilog_wrapper(f, '_'+drive, False, pp_ports(define_data), define_data)
+        f.write('/*********************************************************/\n')
+        f.write('`else // If not USE_POWER_PINS\n')
+        f.write('/*********************************************************/\n')
+        write_verilog_wrapper(f, '_'+drive, True, nonpp_ports(define_data), define_data)
+        f.write('/*********************************************************/\n')
+        f.write('`endif // USE_POWER_PINS\n')
+        write_verilog_footer(f)
+
 
 
 def process(cellpath):
@@ -846,35 +884,11 @@
 
     write_symbol(cellpath, define_data)
     write_symbol_pp(cellpath, define_data)
-    pprint.pprint(drive_strengths(define_data['name'], cellpath))
+
+    for d in drive_strengths(define_data['name'], cellpath):
+        write_drive_wrapper(d, cellpath, define_data)
 
     return
-    drives = define_data.get('drives', [])
-    for d in drives:
-        assert len(d) == 1, d
-        drive_name = list(d.keys())[0]
-        drive_value = list(d.values())[0]
-        if drive_name == 'units':
-            pass
-        elif drive_name == 'lp_variant':
-            if drive_value == 0:
-                drive_value = 'lp'
-            else:
-                drive_value = 'lp'+str(drive_value+1)
-        elif drive_name == "minimum":
-            assert drive_value is None
-            drive_value = "m"
-        else:
-            raise TypeError("Unknown drive:"+repr(d))
-
-        dvfile = os.path.join(cellpath, "{}_{}.v".format(define_data['fullname'], drive_value))
-        write_verilog(define_data, dvfile, list(d.items())[0])
-        echo_file(dvfile)
-
-    if not drives:
-        outfile = os.path.join(cellpath, "{}.v".format(define_data['fullname']))
-        write_verilog(define_data, outfile)
-        echo_file(outfile)
 
 
 def main(args):