Run make format.

Signed-off-by: Keith Rothman <537074+litghost@users.noreply.github.com>
diff --git a/docs/conf.py b/docs/conf.py
index df6615c..cff1c98 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -132,10 +132,9 @@
     # Specify the icon name.
     # For details see link.
     # https://material.io/icons/
-    'header_links': [
-        ('Home', 'index', False, 'home'),
-        ("GitHub", "https://github.com/SymbiFlow/prjxray", True, 'link')
-    ],
+    'header_links': [('Home', 'index', False, 'home'),
+                     ("GitHub", "https://github.com/SymbiFlow/prjxray", True,
+                      'link')],
 
     # Customize css colors.
     # For details see link.
@@ -221,18 +220,16 @@
 # (source start file, target name, title,
 #  author, documentclass [howto, manual, or own class]).
 latex_documents = [
-    (
-        master_doc, 'ProjectX-Ray.tex', u'Project X-Ray Documentation',
-        u'SymbiFlow Team', 'manual'),
+    (master_doc, 'ProjectX-Ray.tex', u'Project X-Ray Documentation',
+     u'SymbiFlow Team', 'manual'),
 ]
 
 # -- Options for manual page output ---------------------------------------
 
 # One entry per manual page. List of tuples
 # (source start file, name, description, authors, manual section).
-man_pages = [
-    (master_doc, 'projectx-ray', u'Project X-Ray Documentation', [author], 1)
-]
+man_pages = [(master_doc, 'projectx-ray', u'Project X-Ray Documentation',
+              [author], 1)]
 
 # -- Options for Texinfo output -------------------------------------------
 
@@ -240,9 +237,8 @@
 # (source start file, target name, title, author,
 #  dir menu entry, description, category)
 texinfo_documents = [
-    (
-        master_doc, 'ProjectX-Ray', u'Project X-Ray Documentation', author,
-        'ProjectX-Ray', 'One line description of project.', 'Miscellaneous'),
+    (master_doc, 'ProjectX-Ray', u'Project X-Ray Documentation', author,
+     'ProjectX-Ray', 'One line description of project.', 'Miscellaneous'),
 ]
 
 # Example configuration for intersphinx: refer to the Python standard library.
@@ -256,11 +252,10 @@
     docs_root_dir = os.path.realpath(os.path.dirname(__file__))
     code_root_dir = os.path.realpath(os.path.join(docs_root_dir, ".."))
 
-    MarkdownSymlinksDomain.init_domain(
-        github_code_repo, github_code_branch, docs_root_dir, code_root_dir)
+    MarkdownSymlinksDomain.init_domain(github_code_repo, github_code_branch,
+                                       docs_root_dir, code_root_dir)
     MarkdownSymlinksDomain.find_links()
     app.add_domain(MarkdownSymlinksDomain)
-    app.add_config_value(
-        'recommonmark_config', {
-            'github_code_repo': github_code_repo,
-        }, True)
+    app.add_config_value('recommonmark_config', {
+        'github_code_repo': github_code_repo,
+    }, True)
diff --git a/fuzzers/002-tilegrid/add_tdb.py b/fuzzers/002-tilegrid/add_tdb.py
index b05d219..c15bd60 100644
--- a/fuzzers/002-tilegrid/add_tdb.py
+++ b/fuzzers/002-tilegrid/add_tdb.py
@@ -6,20 +6,22 @@
 
 BITS_PER_WORD = 16
 
+
 def check_frames(tagstr, addrlist):
     frames = set()
     for addrstr in addrlist:
         frame = parse_addr(addrstr, get_base_frame=True)
         frames.add(frame)
-    assert len(frames) == 1, (
-        "{}: More than one base address".format(tagstr), map(hex, frames))
+    assert len(frames) == 1, ("{}: More than one base address".format(tagstr),
+                              map(hex, frames))
 
 
 def parse_addr(line, only_frame=False, get_base_frame=False):
     # 00020027_003_03
     line = line.split("_")
     frame = int(line[0], 16)
-    wordidx = int(line[1], 10) * (32 / BITS_PER_WORD) + int(line[2], 10) // BITS_PER_WORD
+    wordidx = int(line[1], 10) * (32 / BITS_PER_WORD) + int(
+        line[2], 10) // BITS_PER_WORD
     bitidx = int(line[2], 10) % BITS_PER_WORD
 
     if get_base_frame:
@@ -74,8 +76,10 @@
     build_dir = "build_" + os.getenv('URAY_PART')
     tdb_fns = [
         ("cle/" + build_dir + "/segbits_tilegrid.tdb", 36, 3),
-        ("clel_int/" + build_dir + "/segbits_tilegrid.tdb", int_frames, int_words),
-        ("clem_int/" + build_dir + "/segbits_tilegrid.tdb", int_frames, int_words),
+        ("clel_int/" + build_dir + "/segbits_tilegrid.tdb", int_frames,
+         int_words),
+        ("clem_int/" + build_dir + "/segbits_tilegrid.tdb", int_frames,
+         int_words),
     ]
 
     for (tdb_fn, frames, words) in tdb_fns:
diff --git a/fuzzers/002-tilegrid/cle/top.py b/fuzzers/002-tilegrid/cle/top.py
index af6fa48..42d879b 100644
--- a/fuzzers/002-tilegrid/cle/top.py
+++ b/fuzzers/002-tilegrid/cle/top.py
@@ -24,8 +24,7 @@
 
 
 def run():
-    print(
-        '''
+    print('''
 module top();
     ''')
 
@@ -36,8 +35,7 @@
                                              util.gen_fuzz_states(len(sites))):
         params[tile_name] = (site_name, isone)
 
-        print(
-            '''
+        print('''
             (* KEEP, DONT_TOUCH, LOC = "{loc}", LOCK_PINS="I0:A1 I1:A2 I2:A3 I3:A4 I4:A5 I5:A6" *)
             wire loop_{loc};
             LUT6 #(.INIT(64'b{isone}) ) lut_{loc} (
@@ -50,8 +48,8 @@
                 .O(loop_{loc})
                 );
 '''.format(
-        loc=site_name,
-        isone=isone,
+            loc=site_name,
+            isone=isone,
         ))
 
     print("endmodule")
diff --git a/fuzzers/002-tilegrid/clel_int/top.py b/fuzzers/002-tilegrid/clel_int/top.py
index c8c4c2e..63e2963 100644
--- a/fuzzers/002-tilegrid/clel_int/top.py
+++ b/fuzzers/002-tilegrid/clel_int/top.py
@@ -17,7 +17,7 @@
             # Don't fuzz the top and bottom of the grid, the interconnect
             # there behaves differently.
             _, _, y_min, y_max = grid.dims()
-            if loc.grid_y <= y_min+1 or loc.grid_y >= y_max-1:
+            if loc.grid_y <= y_min + 1 or loc.grid_y >= y_max - 1:
                 continue
 
             site_name = sorted(gridinfo.sites.keys())[0]
@@ -53,8 +53,7 @@
                                              util.gen_fuzz_states(len(sites))):
         params[tile_name] = (site_name, isone)
 
-        print(
-            '''
+        print('''
             (* KEEP, DONT_TOUCH, LOC = "{loc}", LOCK_PINS="I0:A1 I1:A2 I2:A3 I3:A4 I4:A5 I5:A6" *)
             wire loop_{loc};
             LUT6 #(.INIT(64'hFFFFFFFFFFFFFFFF) ) luta_{loc} (
diff --git a/fuzzers/002-tilegrid/clem_int/top.py b/fuzzers/002-tilegrid/clem_int/top.py
index 17e93de..d8d694b 100644
--- a/fuzzers/002-tilegrid/clem_int/top.py
+++ b/fuzzers/002-tilegrid/clem_int/top.py
@@ -17,7 +17,7 @@
             # Don't fuzz the top and bottom of the grid, the interconnect
             # there behaves differently.
             _, _, y_min, y_max = grid.dims()
-            if loc.grid_y <= y_min+1 or loc.grid_y >= y_max-1:
+            if loc.grid_y <= y_min + 1 or loc.grid_y >= y_max - 1:
                 continue
 
             site_name = sorted(gridinfo.sites.keys())[0]
@@ -56,8 +56,7 @@
                                              util.gen_fuzz_states(len(sites))):
         params[tile_name] = (site_name, isone)
 
-        print(
-            '''
+        print('''
             (* KEEP, DONT_TOUCH, LOC = "{loc}", LOCK_PINS="I0:A1, I1:A2, I2:A3, I3:A4, I4:A5, I5:A6" *)
             wire loop_{loc};
             LUT6 #(.INIT(64'hFFFFFFFFFFFFFFFF) ) lutc_{loc} (
diff --git a/fuzzers/002-tilegrid/fuzzaddr/generate.py b/fuzzers/002-tilegrid/fuzzaddr/generate.py
index a9e0edd..92fbac7 100644
--- a/fuzzers/002-tilegrid/fuzzaddr/generate.py
+++ b/fuzzers/002-tilegrid/fuzzaddr/generate.py
@@ -3,8 +3,7 @@
 from utils import bitsmaker
 
 
-def run(
-        bits_fn,
+def run(bits_fn,
         design_fn,
         fnout,
         oneval,
@@ -85,8 +84,7 @@
     if args.filter_words is not None:
         filter_words = list(map(int, args.filter_words.split(',')))
 
-    run(
-        args.bits_file,
+    run(args.bits_file,
         args.design,
         args.fnout,
         args.oneval,
diff --git a/fuzzers/002-tilegrid/generate_full.py b/fuzzers/002-tilegrid/generate_full.py
index 3629496..a0f98d3 100644
--- a/fuzzers/002-tilegrid/generate_full.py
+++ b/fuzzers/002-tilegrid/generate_full.py
@@ -73,9 +73,8 @@
             next_tile_type = database[next_tile]['type']
 
             if tile['bits']['CLB_IO_CLK']['offset'] == 0:
-                assert next_tile_type in [
-                    'INT_TERM_B', 'INT_RBRK'
-                ], next_tile_type
+                assert next_tile_type in ['INT_TERM_B',
+                                          'INT_RBRK'], next_tile_type
                 break
 
             baseaddr = int(tile['bits']['CLB_IO_CLK']['baseaddr'], 0)
@@ -84,25 +83,27 @@
             if tile['type'] == 'INT' and next_tile_type == tile['type']:
                 # INT next to INT
                 offset -= int_words
-                localutil.add_tile_bits(
-                    next_tile, database[next_tile], baseaddr, offset,
-                    int_frames, int_words)
+                localutil.add_tile_bits(next_tile, database[next_tile],
+                                        baseaddr, offset, int_frames,
+                                        int_words)
             elif tile['type'] == 'INT':
                 # INT above RCLK
-                assert next_tile_type in ['RCLK_INT_L', 'RCLK_INT_R'], next_tile_type
+                assert next_tile_type in ['RCLK_INT_L',
+                                          'RCLK_INT_R'], next_tile_type
 
                 offset -= rclk_words
-                localutil.add_tile_bits(
-                    next_tile, database[next_tile], baseaddr, offset,
-                    rclk_frames, rclk_words)
+                localutil.add_tile_bits(next_tile, database[next_tile],
+                                        baseaddr, offset, rclk_frames,
+                                        rclk_words)
             else:
                 # RCLK above INT
-                assert tile['type'] in ['RCLK_INT_L', 'RCLK_INT_R'], tile['type']
+                assert tile['type'] in ['RCLK_INT_L',
+                                        'RCLK_INT_R'], tile['type']
                 if next_tile_type == 'INT':
                     offset -= int_words
-                    localutil.add_tile_bits(
-                        next_tile, database[next_tile], baseaddr, offset,
-                        int_frames, int_words)
+                    localutil.add_tile_bits(next_tile, database[next_tile],
+                                            baseaddr, offset, int_frames,
+                                            int_words)
                 else:
                     assert next_tile_type in [], next_tile_type
                     break
@@ -118,9 +119,8 @@
             next_tile_type = database[next_tile]['type']
 
             if tile['bits']['CLB_IO_CLK']['offset'] == 183:
-                assert next_tile_type in [
-                    'INT_TERM_T', 'INT_RBRK'
-                ], next_tile_type
+                assert next_tile_type in ['INT_TERM_T',
+                                          'INT_RBRK'], next_tile_type
                 break
 
             baseaddr = int(tile['bits']['CLB_IO_CLK']['baseaddr'], 0)
@@ -129,26 +129,28 @@
             if tile['type'] == 'INT' and next_tile_type == tile['type']:
                 # INT next to INT
                 offset += int_words
-                localutil.add_tile_bits(
-                    next_tile, database[next_tile], baseaddr, offset,
-                    int_frames, int_words)
+                localutil.add_tile_bits(next_tile, database[next_tile],
+                                        baseaddr, offset, int_frames,
+                                        int_words)
             elif tile['type'] == 'INT':
                 # INT below RCLK
-                assert next_tile_type in ['RCLK_INT_L', 'RCLK_INT_R'], next_tile_type
+                assert next_tile_type in ['RCLK_INT_L',
+                                          'RCLK_INT_R'], next_tile_type
 
                 offset += int_words
-                localutil.add_tile_bits(
-                    next_tile, database[next_tile], baseaddr, offset,
-                    rclk_frames, rclk_words)
+                localutil.add_tile_bits(next_tile, database[next_tile],
+                                        baseaddr, offset, rclk_frames,
+                                        rclk_words)
             else:
                 # RCLK below INT
-                assert tile['type'] in ['RCLK_INT_L', 'RCLK_INT_R'], tile['type']
+                assert tile['type'] in ['RCLK_INT_L',
+                                        'RCLK_INT_R'], tile['type']
                 assert next_tile_type == 'INT', next_tile_type
 
                 offset += rclk_words
-                localutil.add_tile_bits(
-                    next_tile, database[next_tile], baseaddr, offset,
-                    int_frames, int_words)
+                localutil.add_tile_bits(next_tile, database[next_tile],
+                                        baseaddr, offset, int_frames,
+                                        int_words)
 
             tile_name = next_tile
             tile = database[tile_name]
@@ -209,8 +211,8 @@
 
         while True:
             prev_tile = tile
-            tile = tiles_by_grid[(
-                database[tile]['grid_x'], database[tile]['grid_y'] + 1)]
+            tile = tiles_by_grid[(database[tile]['grid_x'],
+                                  database[tile]['grid_y'] + 1)]
             if '_SING' in database[tile]['type']:
                 break
 
@@ -220,8 +222,8 @@
         bits = database[prev_tile]['bits']['CLB_IO_CLK']
 
         while True:
-            tile = tiles_by_grid[(
-                database[tile]['grid_x'], database[tile]['grid_y'] - 1)]
+            tile = tiles_by_grid[(database[tile]['grid_x'],
+                                  database[tile]['grid_y'] - 1)]
             seen_iobs.add(tile)
 
             if '_SING' in database[tile]['type']:
@@ -279,8 +281,8 @@
 
         while True:
             prev_tile = tile
-            tile = tiles_by_grid[(
-                database[tile]['grid_x'], database[tile]['grid_y'] + 1)]
+            tile = tiles_by_grid[(database[tile]['grid_x'],
+                                  database[tile]['grid_y'] + 1)]
             if '_SING' in database[tile]['type']:
                 break
 
@@ -290,8 +292,8 @@
         bits = database[prev_tile]['bits']['CLB_IO_CLK']
 
         while True:
-            tile = tiles_by_grid[(
-                database[tile]['grid_x'], database[tile]['grid_y'] - 1)]
+            tile = tiles_by_grid[(database[tile]['grid_x'],
+                                  database[tile]['grid_y'] - 1)]
             seen_iois.add(tile)
 
             if '_SING' in database[tile]['type']:
@@ -348,12 +350,11 @@
         assert False, "Unsupported architecture"
 
     for tile in tiles:
-        prev_tile = tiles_by_grid[(
-            database[tile]['grid_x'], database[tile]['grid_y'] - 1)]
+        prev_tile = tiles_by_grid[(database[tile]['grid_x'],
+                                   database[tile]['grid_y'] - 1)]
         while database[prev_tile]["type"] != database[tile]["type"]:
-            prev_tile = tiles_by_grid[(
-                database[prev_tile]['grid_x'],
-                database[prev_tile]['grid_y'] - 1)]
+            prev_tile = tiles_by_grid[(database[prev_tile]['grid_x'],
+                                       database[prev_tile]['grid_y'] - 1)]
         bits = database[prev_tile]['bits']['CLB_IO_CLK']
         database[tile]['bits']['CLB_IO_CLK'] = copy.deepcopy(bits)
         database[tile]['bits']['CLB_IO_CLK']['words'] = 4
diff --git a/fuzzers/002-tilegrid/util.py b/fuzzers/002-tilegrid/util.py
index 728fa6f..1d9b336 100644
--- a/fuzzers/002-tilegrid/util.py
+++ b/fuzzers/002-tilegrid/util.py
@@ -20,8 +20,13 @@
     return int_frames, int_words
 
 
-def add_tile_bits(
-        tile_name, tile_db, baseaddr, offset, frames, words, verbose=False):
+def add_tile_bits(tile_name,
+                  tile_db,
+                  baseaddr,
+                  offset,
+                  frames,
+                  words,
+                  verbose=False):
     '''
     Record data structure geometry for the given tile baseaddr
     For most tiles there is only one baseaddr, but some like BRAM have multiple
@@ -33,11 +38,11 @@
 
     assert offset <= 93 * 2, (tile_name, offset)
     # Few rare cases at X=0 for double width tiles split in half => small negative offset
-    assert offset >= 0 or "IOB" in tile_name, (
-        tile_name, hex(baseaddr), offset)
+    assert offset >= 0 or "IOB" in tile_name, (tile_name, hex(baseaddr),
+                                               offset)
     assert 1 <= words <= 93 * 2, words
-    assert offset + words <= 93 * 2, (
-        tile_name, offset + words, offset, words, block_type)
+    assert offset + words <= 93 * 2, (tile_name, offset + words, offset, words,
+                                      block_type)
 
     baseaddr_str = '0x%08X' % baseaddr
     block = bits.get(block_type, None)
diff --git a/fuzzers/010-cle-lutinit/generate.tcl b/fuzzers/010-cle-lutinit/generate.tcl
index 4374037..378eaa8 100644
--- a/fuzzers/010-cle-lutinit/generate.tcl
+++ b/fuzzers/010-cle-lutinit/generate.tcl
@@ -81,4 +81,3 @@
 
 write_bitstream -force design_1.bit
 write_txtdata design_1.txt
-
diff --git a/fuzzers/010-cle-lutinit/top.py b/fuzzers/010-cle-lutinit/top.py
index 60c27c7..7c9707d 100644
--- a/fuzzers/010-cle-lutinit/top.py
+++ b/fuzzers/010-cle-lutinit/top.py
@@ -30,7 +30,7 @@
     # Therefore the generated netlist contains
     # A-B LUTs/FFs or C-D, E-F or G-H LUTs/FFs
     seedn = int(os.getenv("SEEDN")) % 4
-    bels = ['E','F','G','H','A','B','C','D']
+    bels = ['E', 'F', 'G', 'H', 'A', 'B', 'C', 'D']
     for (tile_name, site_name) in sites:
         bel = bels[seedn * 2 + random.randrange(2)]
         params = {}
@@ -39,9 +39,10 @@
         params['bel_lut6'] = bel + "6LUT"
         params['bel_ff'] = bel + "FF"
         sites_params.append(params)
-    print(util.render_template(os.path.join(os.getenv("FUZDIR"), "top.tpl"),{
-        "parameters" : sites_params
-        }))
+    print(
+        util.render_template(
+            os.path.join(os.getenv("FUZDIR"), "top.tpl"),
+            {"parameters": sites_params}))
     write_params(params)
 
 
diff --git a/fuzzers/run_fuzzer.py b/fuzzers/run_fuzzer.py
index fb6ee75..70159d4 100755
--- a/fuzzers/run_fuzzer.py
+++ b/fuzzers/run_fuzzer.py
@@ -287,9 +287,9 @@
     62.0
     """
     units = {
-        'Gi': pow(2,30),
-        'Mi': pow(2,20),
-        'Ki': pow(2,10),
+        'Gi': pow(2, 30),
+        'Mi': pow(2, 20),
+        'Ki': pow(2, 10),
         'G': 1e9,
         'M': 1e6,
         'K': 1e3,
@@ -466,8 +466,7 @@
     if os.path.exists(fuzzer_runok):
         last_modified = datetime.fromtimestamp(os.stat(fuzzer_runok).st_mtime)
 
-        log(
-            "Skipping as run.ok exists (updated @ {})",
+        log("Skipping as run.ok exists (updated @ {})",
             last_modified.isoformat())
 
         return 0
@@ -615,8 +614,7 @@
             'Fuzzer failed with exit code: {}'.format(retcode), )
 
         # Log the last 10,000 lines of stderr on a failure
-        log(
-            """\
+        log("""\
 Failed @ {time_end} with exit code: {retcode}
 --------------------------------------------------------------------------
 {error_log}
diff --git a/minitests/litex/linux/zcu104/src/VexRiscv_Linux.v b/minitests/litex/linux/zcu104/src/VexRiscv_Linux.v
index e79b01b..7ba16d2 100644
--- a/minitests/litex/linux/zcu104/src/VexRiscv_Linux.v
+++ b/minitests/litex/linux/zcu104/src/VexRiscv_Linux.v
@@ -3207,7 +3207,7 @@
     end
   end
 
-  InstructionCache IBusCachedPlugin_cache ( 
+  InstructionCache IBusCachedPlugin_cache (
     .io_flush(_zz_239_),
     .io_cpu_prefetch_isValid(_zz_240_),
     .io_cpu_prefetch_haltIt(IBusCachedPlugin_cache_io_cpu_prefetch_haltIt),
@@ -3253,9 +3253,9 @@
     .io_mem_rsp_payload_data(iBus_rsp_payload_data),
     .io_mem_rsp_payload_error(iBus_rsp_payload_error),
     .clk(clk),
-    .reset(reset) 
+    .reset(reset)
   );
-  DataCache dataCache_1_ ( 
+  DataCache dataCache_1_ (
     .io_cpu_execute_isValid(_zz_248_),
     .io_cpu_execute_address(_zz_249_),
     .io_cpu_execute_args_wr(_zz_250_),
@@ -3308,7 +3308,7 @@
     .io_mem_rsp_payload_data(dBus_rsp_payload_data),
     .io_mem_rsp_payload_error(dBus_rsp_payload_error),
     .clk(clk),
-    .reset(reset) 
+    .reset(reset)
   );
   always @(*) begin
     case(_zz_497_)
diff --git a/minitests/litex/linux/zcu104/src/runme.py b/minitests/litex/linux/zcu104/src/runme.py
index c5ce4d5..7623c24 100755
--- a/minitests/litex/linux/zcu104/src/runme.py
+++ b/minitests/litex/linux/zcu104/src/runme.py
@@ -13,22 +13,33 @@
     f.write('write_checkpoint -force design.dcp')
 
 files = [
-    {'name': os.path.realpath('top.v'), 'file_type': 'verilogSource'},
-    {'name': os.path.realpath('VexRiscv_Linux.v'), 'file_type': 'verilogSource'},
-    {'name': os.path.realpath('top.xdc'), 'file_type': 'xdc'},
+    {
+        'name': os.path.realpath('top.v'),
+        'file_type': 'verilogSource'
+    },
+    {
+        'name': os.path.realpath('VexRiscv_Linux.v'),
+        'file_type': 'verilogSource'
+    },
+    {
+        'name': os.path.realpath('top.xdc'),
+        'file_type': 'xdc'
+    },
 ]
 
 tool = 'vivado'
 
 edam = {
-  'files' : files,
-  'name'  : 'design',
-  'toplevel': 'top',
-  'tool_options' : {'vivado' : {
-    'part' : os.environ['URAY_PART'],
-    'post_imp' : post_imp_file,
-    'synth' : synth_tool
-    }}
+    'files': files,
+    'name': 'design',
+    'toplevel': 'top',
+    'tool_options': {
+        'vivado': {
+            'part': os.environ['URAY_PART'],
+            'post_imp': post_imp_file,
+            'synth': synth_tool
+        }
+    }
 }
 
 backend = edalize.get_edatool(tool)(edam=edam, work_root=work_root)
diff --git a/minitests/litex/zephyr/zcu104/src/VexRiscv_Full.v b/minitests/litex/zephyr/zcu104/src/VexRiscv_Full.v
index a89d5cf..92abdef 100644
--- a/minitests/litex/zephyr/zcu104/src/VexRiscv_Full.v
+++ b/minitests/litex/zephyr/zcu104/src/VexRiscv_Full.v
@@ -2575,7 +2575,7 @@
     end
   end
 
-  InstructionCache IBusCachedPlugin_cache ( 
+  InstructionCache IBusCachedPlugin_cache (
     .io_flush(_zz_221_),
     .io_cpu_prefetch_isValid(_zz_222_),
     .io_cpu_prefetch_haltIt(IBusCachedPlugin_cache_io_cpu_prefetch_haltIt),
@@ -2621,9 +2621,9 @@
     .io_mem_rsp_payload_data(iBus_rsp_payload_data),
     .io_mem_rsp_payload_error(iBus_rsp_payload_error),
     .clk(clk),
-    .reset(reset) 
+    .reset(reset)
   );
-  DataCache dataCache_1_ ( 
+  DataCache dataCache_1_ (
     .io_cpu_execute_isValid(_zz_230_),
     .io_cpu_execute_address(_zz_231_),
     .io_cpu_execute_args_wr(execute_MEMORY_WR),
@@ -2671,7 +2671,7 @@
     .io_mem_rsp_payload_data(dBus_rsp_payload_data),
     .io_mem_rsp_payload_error(dBus_rsp_payload_error),
     .clk(clk),
-    .reset(reset) 
+    .reset(reset)
   );
   always @(*) begin
     case(_zz_375_)
diff --git a/minitests/litex/zephyr/zcu104/src/runme.py b/minitests/litex/zephyr/zcu104/src/runme.py
index b4c89fe..9d79a65 100755
--- a/minitests/litex/zephyr/zcu104/src/runme.py
+++ b/minitests/litex/zephyr/zcu104/src/runme.py
@@ -13,22 +13,33 @@
     f.write('write_checkpoint -force design.dcp')
 
 files = [
-    {'name': os.path.realpath('top.v'), 'file_type': 'verilogSource'},
-    {'name': os.path.realpath('VexRiscv_Full.v'), 'file_type': 'verilogSource'},
-    {'name': os.path.realpath('top.xdc'), 'file_type': 'xdc'},
+    {
+        'name': os.path.realpath('top.v'),
+        'file_type': 'verilogSource'
+    },
+    {
+        'name': os.path.realpath('VexRiscv_Full.v'),
+        'file_type': 'verilogSource'
+    },
+    {
+        'name': os.path.realpath('top.xdc'),
+        'file_type': 'xdc'
+    },
 ]
 
 tool = 'vivado'
 
 edam = {
-  'files' : files,
-  'name'  : 'design',
-  'toplevel': 'top',
-  'tool_options' : {'vivado' : {
-    'part' : os.environ['URAY_PART'],
-    'post_imp' : post_imp_file,
-    'synth' : synth_tool
-    }}
+    'files': files,
+    'name': 'design',
+    'toplevel': 'top',
+    'tool_options': {
+        'vivado': {
+            'part': os.environ['URAY_PART'],
+            'post_imp': post_imp_file,
+            'synth': synth_tool
+        }
+    }
 }
 
 backend = edalize.get_edatool(tool)(edam=edam, work_root=work_root)
diff --git a/minitests/opentitan/src.vivado/lowrisc_ibex_ibex_core_0.1/rtl/ibex_prefetch_buffer.sv b/minitests/opentitan/src.vivado/lowrisc_ibex_ibex_core_0.1/rtl/ibex_prefetch_buffer.sv
index ebd6024..046704c 100644
--- a/minitests/opentitan/src.vivado/lowrisc_ibex_ibex_core_0.1/rtl/ibex_prefetch_buffer.sv
+++ b/minitests/opentitan/src.vivado/lowrisc_ibex_ibex_core_0.1/rtl/ibex_prefetch_buffer.sv
@@ -157,7 +157,7 @@
   // Update on a branch or as soon as a request is issued
   assign fetch_addr_en = branch_i | (valid_new_req & ~valid_req_q);
 
-  assign fetch_addr_d = (branch_i ? addr_i : 
+  assign fetch_addr_d = (branch_i ? addr_i :
                                     {fetch_addr_q[31:2], 2'b00}) +
                         // Current address + 4
                         {{29{1'b0}},(valid_new_req & ~valid_req_q),2'b00};
diff --git a/minitests/opentitan/src.vivado/lowrisc_ip_xbar_main_0.1/xbar_main.sv b/minitests/opentitan/src.vivado/lowrisc_ip_xbar_main_0.1/xbar_main.sv
index b091744..22a9478 100644
--- a/minitests/opentitan/src.vivado/lowrisc_ip_xbar_main_0.1/xbar_main.sv
+++ b/minitests/opentitan/src.vivado/lowrisc_ip_xbar_main_0.1/xbar_main.sv
@@ -375,13 +375,13 @@
     dev_sel_s1n_15 = 3'd4;
     if ((tl_s1n_15_us_h2d.a_address & ~(ADDR_MASK_ROM)) == ADDR_SPACE_ROM) begin
       dev_sel_s1n_15 = 3'd0;
-    
+
     end else if ((tl_s1n_15_us_h2d.a_address & ~(ADDR_MASK_DEBUG_MEM)) == ADDR_SPACE_DEBUG_MEM) begin
       dev_sel_s1n_15 = 3'd1;
-    
+
     end else if ((tl_s1n_15_us_h2d.a_address & ~(ADDR_MASK_RAM_MAIN)) == ADDR_SPACE_RAM_MAIN) begin
       dev_sel_s1n_15 = 3'd2;
-    
+
     end else if ((tl_s1n_15_us_h2d.a_address & ~(ADDR_MASK_EFLASH)) == ADDR_SPACE_EFLASH) begin
       dev_sel_s1n_15 = 3'd3;
     end
@@ -392,16 +392,16 @@
     dev_sel_s1n_20 = 4'd12;
     if ((tl_s1n_20_us_h2d.a_address & ~(ADDR_MASK_ROM)) == ADDR_SPACE_ROM) begin
       dev_sel_s1n_20 = 4'd0;
-    
+
     end else if ((tl_s1n_20_us_h2d.a_address & ~(ADDR_MASK_DEBUG_MEM)) == ADDR_SPACE_DEBUG_MEM) begin
       dev_sel_s1n_20 = 4'd1;
-    
+
     end else if ((tl_s1n_20_us_h2d.a_address & ~(ADDR_MASK_RAM_MAIN)) == ADDR_SPACE_RAM_MAIN) begin
       dev_sel_s1n_20 = 4'd2;
-    
+
     end else if ((tl_s1n_20_us_h2d.a_address & ~(ADDR_MASK_EFLASH)) == ADDR_SPACE_EFLASH) begin
       dev_sel_s1n_20 = 4'd3;
-    
+
     end else if (
       ((tl_s1n_20_us_h2d.a_address <= (ADDR_MASK_PERI[0] + ADDR_SPACE_PERI[0])) &&
        (tl_s1n_20_us_h2d.a_address >= ADDR_SPACE_PERI[0])) ||
@@ -411,25 +411,25 @@
        (tl_s1n_20_us_h2d.a_address >= ADDR_SPACE_PERI[2]))
     ) begin
       dev_sel_s1n_20 = 4'd4;
-    
+
     end else if ((tl_s1n_20_us_h2d.a_address & ~(ADDR_MASK_FLASH_CTRL)) == ADDR_SPACE_FLASH_CTRL) begin
       dev_sel_s1n_20 = 4'd5;
-    
+
     end else if ((tl_s1n_20_us_h2d.a_address & ~(ADDR_MASK_AES)) == ADDR_SPACE_AES) begin
       dev_sel_s1n_20 = 4'd6;
-    
+
     end else if ((tl_s1n_20_us_h2d.a_address & ~(ADDR_MASK_HMAC)) == ADDR_SPACE_HMAC) begin
       dev_sel_s1n_20 = 4'd7;
-    
+
     end else if ((tl_s1n_20_us_h2d.a_address & ~(ADDR_MASK_RV_PLIC)) == ADDR_SPACE_RV_PLIC) begin
       dev_sel_s1n_20 = 4'd8;
-    
+
     end else if ((tl_s1n_20_us_h2d.a_address & ~(ADDR_MASK_PINMUX)) == ADDR_SPACE_PINMUX) begin
       dev_sel_s1n_20 = 4'd9;
-    
+
     end else if ((tl_s1n_20_us_h2d.a_address & ~(ADDR_MASK_ALERT_HANDLER)) == ADDR_SPACE_ALERT_HANDLER) begin
       dev_sel_s1n_20 = 4'd10;
-    
+
     end else if ((tl_s1n_20_us_h2d.a_address & ~(ADDR_MASK_NMI_GEN)) == ADDR_SPACE_NMI_GEN) begin
       dev_sel_s1n_20 = 4'd11;
     end
@@ -440,13 +440,13 @@
     dev_sel_s1n_30 = 4'd11;
     if ((tl_s1n_30_us_h2d.a_address & ~(ADDR_MASK_ROM)) == ADDR_SPACE_ROM) begin
       dev_sel_s1n_30 = 4'd0;
-    
+
     end else if ((tl_s1n_30_us_h2d.a_address & ~(ADDR_MASK_RAM_MAIN)) == ADDR_SPACE_RAM_MAIN) begin
       dev_sel_s1n_30 = 4'd1;
-    
+
     end else if ((tl_s1n_30_us_h2d.a_address & ~(ADDR_MASK_EFLASH)) == ADDR_SPACE_EFLASH) begin
       dev_sel_s1n_30 = 4'd2;
-    
+
     end else if (
       ((tl_s1n_30_us_h2d.a_address <= (ADDR_MASK_PERI[0] + ADDR_SPACE_PERI[0])) &&
        (tl_s1n_30_us_h2d.a_address >= ADDR_SPACE_PERI[0])) ||
@@ -456,25 +456,25 @@
        (tl_s1n_30_us_h2d.a_address >= ADDR_SPACE_PERI[2]))
     ) begin
       dev_sel_s1n_30 = 4'd3;
-    
+
     end else if ((tl_s1n_30_us_h2d.a_address & ~(ADDR_MASK_FLASH_CTRL)) == ADDR_SPACE_FLASH_CTRL) begin
       dev_sel_s1n_30 = 4'd4;
-    
+
     end else if ((tl_s1n_30_us_h2d.a_address & ~(ADDR_MASK_AES)) == ADDR_SPACE_AES) begin
       dev_sel_s1n_30 = 4'd5;
-    
+
     end else if ((tl_s1n_30_us_h2d.a_address & ~(ADDR_MASK_HMAC)) == ADDR_SPACE_HMAC) begin
       dev_sel_s1n_30 = 4'd6;
-    
+
     end else if ((tl_s1n_30_us_h2d.a_address & ~(ADDR_MASK_RV_PLIC)) == ADDR_SPACE_RV_PLIC) begin
       dev_sel_s1n_30 = 4'd7;
-    
+
     end else if ((tl_s1n_30_us_h2d.a_address & ~(ADDR_MASK_PINMUX)) == ADDR_SPACE_PINMUX) begin
       dev_sel_s1n_30 = 4'd8;
-    
+
     end else if ((tl_s1n_30_us_h2d.a_address & ~(ADDR_MASK_ALERT_HANDLER)) == ADDR_SPACE_ALERT_HANDLER) begin
       dev_sel_s1n_30 = 4'd9;
-    
+
     end else if ((tl_s1n_30_us_h2d.a_address & ~(ADDR_MASK_NMI_GEN)) == ADDR_SPACE_NMI_GEN) begin
       dev_sel_s1n_30 = 4'd10;
     end
diff --git a/minitests/opentitan/src.vivado/lowrisc_ip_xbar_peri_0.1/xbar_peri.sv b/minitests/opentitan/src.vivado/lowrisc_ip_xbar_peri_0.1/xbar_peri.sv
index d1775af..0b153ff 100644
--- a/minitests/opentitan/src.vivado/lowrisc_ip_xbar_peri_0.1/xbar_peri.sv
+++ b/minitests/opentitan/src.vivado/lowrisc_ip_xbar_peri_0.1/xbar_peri.sv
@@ -80,16 +80,16 @@
     dev_sel_s1n_6 = 3'd5;
     if ((tl_s1n_6_us_h2d.a_address & ~(ADDR_MASK_UART)) == ADDR_SPACE_UART) begin
       dev_sel_s1n_6 = 3'd0;
-    
+
     end else if ((tl_s1n_6_us_h2d.a_address & ~(ADDR_MASK_GPIO)) == ADDR_SPACE_GPIO) begin
       dev_sel_s1n_6 = 3'd1;
-    
+
     end else if ((tl_s1n_6_us_h2d.a_address & ~(ADDR_MASK_SPI_DEVICE)) == ADDR_SPACE_SPI_DEVICE) begin
       dev_sel_s1n_6 = 3'd2;
-    
+
     end else if ((tl_s1n_6_us_h2d.a_address & ~(ADDR_MASK_RV_TIMER)) == ADDR_SPACE_RV_TIMER) begin
       dev_sel_s1n_6 = 3'd3;
-    
+
     end else if ((tl_s1n_6_us_h2d.a_address & ~(ADDR_MASK_USBDEV)) == ADDR_SPACE_USBDEV) begin
       dev_sel_s1n_6 = 3'd4;
     end
diff --git a/minitests/opentitan/src.vivado/lowrisc_systems_top_earlgrey_0.1/rtl/autogen/top_earlgrey.sv b/minitests/opentitan/src.vivado/lowrisc_systems_top_earlgrey_0.1/rtl/autogen/top_earlgrey.sv
index 1bec4b5..01dab84 100644
--- a/minitests/opentitan/src.vivado/lowrisc_systems_top_earlgrey_0.1/rtl/autogen/top_earlgrey.sv
+++ b/minitests/opentitan/src.vivado/lowrisc_systems_top_earlgrey_0.1/rtl/autogen/top_earlgrey.sv
@@ -217,7 +217,7 @@
   logic intr_usbdev_connected;
 
 
-  
+
   logic [0:0] irq_plic;
   logic [0:0] msip;
   logic [6:0] irq_id[1];
@@ -593,8 +593,8 @@
       .intr_hmac_done_o (intr_hmac_hmac_done),
       .intr_fifo_full_o (intr_hmac_fifo_full),
       .intr_hmac_err_o  (intr_hmac_hmac_err),
-      
-      // [0]: msg_push_sha_disabled 
+
+      // [0]: msg_push_sha_disabled
       .alert_tx_o  ( alert_tx[0:0] ),
       .alert_rx_i  ( alert_rx[0:0] ),
 
diff --git a/minitests/opentitan/src.vivado/runme.py b/minitests/opentitan/src.vivado/runme.py
index 0db0600..5a01ffa 100755
--- a/minitests/opentitan/src.vivado/runme.py
+++ b/minitests/opentitan/src.vivado/runme.py
@@ -195,38 +195,64 @@
 with open(post_imp_file, 'w') as f:
     f.write('write_checkpoint -force design.dcp')
 
-files = [
-    {'name': os.path.realpath('lowrisc_systems_top_earlgrey_zcu104_0.1/data/pins_zcu104.xdc'), 'file_type': 'xdc'},
-    {'name': os.path.realpath('lowrisc_prim_assert_0.1/rtl/prim_assert.sv'), 'file_type': 'systemVerilogSource', 'is_include_file': 'true'}
-]
+files = [{
+    'name':
+    os.path.realpath(
+        'lowrisc_systems_top_earlgrey_zcu104_0.1/data/pins_zcu104.xdc'),
+    'file_type':
+    'xdc'
+},
+         {
+             'name':
+             os.path.realpath('lowrisc_prim_assert_0.1/rtl/prim_assert.sv'),
+             'file_type':
+             'systemVerilogSource',
+             'is_include_file':
+             'true'
+         }]
 
 parameters = {
-    'ROM_INIT_FILE': {'datatype': 'str', 'paramtype': 'vlogdefine'},
-    'PRIM_DEFAULT_IMPL': {'datatype': 'str', 'paramtype': 'vlogdefine'},
+    'ROM_INIT_FILE': {
+        'datatype': 'str',
+        'paramtype': 'vlogdefine'
+    },
+    'PRIM_DEFAULT_IMPL': {
+        'datatype': 'str',
+        'paramtype': 'vlogdefine'
+    },
 }
 
 for src in srcs:
-    files.append({'name': os.path.realpath(src), 'file_type': 'systemVerilogSource'})
+    files.append({
+        'name': os.path.realpath(src),
+        'file_type': 'systemVerilogSource'
+    })
 
 tool = 'vivado'
 
 incdirs = [os.path.realpath('lowrisc_prim_assert_0.1/rtl')]
 
 edam = {
-  'files' : files,
-  'name'  : 'design',
-  'toplevel': 'top_earlgrey_zcu104',
-  'parameters': parameters,
-  'tool_options' : {'vivado' : {
-    'part' : os.environ['URAY_PART'],
-    'post_imp' : post_imp_file,
-    'synth' : synth_tool
-    }}
+    'files': files,
+    'name': 'design',
+    'toplevel': 'top_earlgrey_zcu104',
+    'parameters': parameters,
+    'tool_options': {
+        'vivado': {
+            'part': os.environ['URAY_PART'],
+            'post_imp': post_imp_file,
+            'synth': synth_tool
+        }
+    }
 }
 
 backend = edalize.get_edatool(tool)(edam=edam, work_root=work_root)
 
-args = ['--ROM_INIT_FILE={}'.format(os.path.realpath('boot_rom_fpga_nexysvideo.vmem')), '--PRIM_DEFAULT_IMPL=prim_pkg::ImplXilinx']
+args = [
+    '--ROM_INIT_FILE={}'.format(
+        os.path.realpath('boot_rom_fpga_nexysvideo.vmem')),
+    '--PRIM_DEFAULT_IMPL=prim_pkg::ImplXilinx'
+]
 
 backend.configure(args)
 backend.build()
diff --git a/minitests/opentitan/src.yosys/runme.py b/minitests/opentitan/src.yosys/runme.py
index 48dbf43..a849db1 100755
--- a/minitests/opentitan/src.yosys/runme.py
+++ b/minitests/opentitan/src.yosys/runme.py
@@ -15,12 +15,16 @@
 with open(post_imp_file, 'w') as f:
     f.write('write_checkpoint -force design.dcp')
 
-files = [
-    {'name': os.path.realpath('../src.vivado/lowrisc_systems_top_earlgrey_zcu104_0.1/data/pins_zcu104.xdc'), 'file_type': 'xdc'}
-]
+files = [{
+    'name':
+    os.path.realpath(
+        '../src.vivado/lowrisc_systems_top_earlgrey_zcu104_0.1/data/pins_zcu104.xdc'
+    ),
+    'file_type':
+    'xdc'
+}]
 
-parameters = {
-}
+parameters = {}
 
 for src in srcs:
     files.append({'name': os.path.realpath(src), 'file_type': 'verilogSource'})
@@ -30,15 +34,17 @@
 incdirs = {}
 
 edam = {
-  'files' : files,
-  'name'  : 'design',
-  'toplevel': 'top_earlgrey_zcu104',
-  'parameters': parameters,
-  'tool_options' : {'vivado' : {
-    'part' : os.environ['URAY_PART'],
-    'post_imp' : post_imp_file,
-    'synth' : synth_tool
-    }}
+    'files': files,
+    'name': 'design',
+    'toplevel': 'top_earlgrey_zcu104',
+    'parameters': parameters,
+    'tool_options': {
+        'vivado': {
+            'part': os.environ['URAY_PART'],
+            'post_imp': post_imp_file,
+            'synth': synth_tool
+        }
+    }
 }
 
 backend = edalize.get_edatool(tool)(edam=edam, work_root=work_root)
diff --git a/minitests/util/runme.py b/minitests/util/runme.py
index 59bb24b..6f8cd63 100644
--- a/minitests/util/runme.py
+++ b/minitests/util/runme.py
@@ -6,8 +6,8 @@
 pins = {
     'clk': os.environ['URAY_PIN_00'],
     'stb': os.environ['URAY_PIN_01'],
-    'di':  os.environ['URAY_PIN_02'],
-    'do':  os.environ['URAY_PIN_03'],
+    'di': os.environ['URAY_PIN_02'],
+    'do': os.environ['URAY_PIN_03'],
 }
 
 xdc_file = os.path.realpath(os.path.join(work_root, 'top.xdc'))
@@ -21,35 +21,47 @@
 with open(xdc_file, 'w') as f:
     f.write('set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets *]\n')
     for key, val in pins.items():
-        f.write('set_property PACKAGE_PIN {} [get_ports {}]\n'.format(val, key))
-        f.write('set_property IOSTANDARD LVCMOS33 [get_ports {}]\n'.format(key))
+        f.write('set_property PACKAGE_PIN {} [get_ports {}]\n'.format(
+            val, key))
+        f.write(
+            'set_property IOSTANDARD LVCMOS33 [get_ports {}]\n'.format(key))
 
 with open(pre_imp_file, 'w') as f:
     f.write('create_pblock roi\n')
     f.write('add_cells_to_pblock [get_pblocks roi] [get_cells roi]\n')
-    f.write('resize_pblock [get_pblocks roi] -add "{}"\n'.format(os.environ['URAY_ROI']))
-    f.write('set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design]\n')
+    f.write('resize_pblock [get_pblocks roi] -add "{}"\n'.format(
+        os.environ['URAY_ROI']))
+    f.write(
+        'set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design]\n')
 
 with open(post_imp_file, 'w') as f:
     f.write('write_checkpoint -force design.dcp')
 
 files = [
-    {'name': os.path.realpath('top.v'), 'file_type': 'verilogSource'},
-    {'name': xdc_file, 'file_type': 'xdc'},
+    {
+        'name': os.path.realpath('top.v'),
+        'file_type': 'verilogSource'
+    },
+    {
+        'name': xdc_file,
+        'file_type': 'xdc'
+    },
 ]
 
 tool = 'vivado'
 
 edam = {
-  'files' : files,
-  'name'  : 'design',
-  'toplevel': 'top',
-  'tool_options' : {'vivado' : {
-    'part' : os.environ['URAY_PART'],
-    'pre_imp' : pre_imp_file,
-    'post_imp' : post_imp_file,
-    'synth' : synth_tool
-    }}
+    'files': files,
+    'name': 'design',
+    'toplevel': 'top',
+    'tool_options': {
+        'vivado': {
+            'part': os.environ['URAY_PART'],
+            'pre_imp': pre_imp_file,
+            'post_imp': post_imp_file,
+            'synth': synth_tool
+        }
+    }
 }
 
 backend = edalize.get_edatool(tool)(edam=edam, work_root=work_root)
diff --git a/spec/bram18.py b/spec/bram18.py
index bdb537b..e819f83 100644
--- a/spec/bram18.py
+++ b/spec/bram18.py
@@ -16,68 +16,96 @@
 import sys
 import math
 
-print("module top(input clk, clkb, rst, ena, enb, cea, ceb, input [13:0] ra, wa, input [3:0] we, input [17:0] wdata, input [10:0] sel, output [35:0] rdata);")
+print(
+    "module top(input clk, clkb, rst, ena, enb, cea, ceb, input [13:0] ra, wa, input [3:0] we, input [17:0] wdata, input [10:0] sel, output [35:0] rdata);"
+)
 N = 600
 print("    wire [35:0] int_d[0:%d-1];" % N)
-print("    assign rdata = sel[0] ? int_d[sel[10:1]][35:18] : int_d[sel[10:1]][17:0];")
+print(
+    "    assign rdata = sel[0] ? int_d[sel[10:1]][35:18] : int_d[sel[10:1]][17:0];"
+)
 for i in range(N):
-	write_width_b = np.random.choice([0, 1, 2, 4, 9, 18, 36])
-	read_width_a = np.random.choice([0, 1, 2, 4, 9, 18, 36], p=[0.05, 0.1, 0.1, 0.1, 0.1, 0.45, 0.1])
-	write_width_a = 0 if (write_width_b == 36 or read_width_a == 36) else np.random.choice([0, 1, 2, 4, 9, 18])
-	read_width_b = 0 if (read_width_a == 36 or write_width_b == 36) else np.random.choice([0, 1, 2, 4, 9, 18], p=[0.05, 0.1, 0.1, 0.1, 0.1, 0.55])
+    write_width_b = np.random.choice([0, 1, 2, 4, 9, 18, 36])
+    read_width_a = np.random.choice([0, 1, 2, 4, 9, 18, 36],
+                                    p=[0.05, 0.1, 0.1, 0.1, 0.1, 0.45, 0.1])
+    write_width_a = 0 if (write_width_b == 36
+                          or read_width_a == 36) else np.random.choice(
+                              [0, 1, 2, 4, 9, 18])
+    read_width_b = 0 if (
+        read_width_a == 36 or write_width_b == 36) else np.random.choice(
+            [0, 1, 2, 4, 9, 18], p=[0.05, 0.1, 0.1, 0.1, 0.1, 0.55])
 
-	cd = np.random.choice(["INDEPENDENT", "COMMON"])
+    cd = np.random.choice(["INDEPENDENT", "COMMON"])
 
-	print("    RAMB18E2 #(")
-	print("        .CLOCK_DOMAINS(\"%s\")," % cd)
-	print("        .READ_WIDTH_A(%d)," % read_width_a)
-	print("        .READ_WIDTH_B(%d)," % read_width_b)
-	print("        .WRITE_WIDTH_A(%d)," % write_width_a)
-	print("        .WRITE_WIDTH_B(%d)," % write_width_b)
-	print("        .WRITE_MODE_A(\"%s\")," % np.random.choice(["NO_CHANGE", "READ_FIRST", "WRITE_FIRST"]))
-	print("        .WRITE_MODE_B(\"%s\")," % np.random.choice(["NO_CHANGE", "READ_FIRST", "WRITE_FIRST"]))
-	print("        .CASCADE_ORDER_A(\"%s\")," % np.random.choice(["NONE", "FIRST", "MIDDLE", "LAST"]))
-	print("        .CASCADE_ORDER_B(\"%s\")," % np.random.choice(["NONE", "FIRST", "MIDDLE", "LAST"]))
-	print("        .DOA_REG(%d)," % (0 if (write_width_b == 36 or read_width_a == 36) else np.random.randint(2)))
-	print("        .DOB_REG(%d),"% (0 if (write_width_b == 36 or read_width_a == 36) else np.random.randint(2)))
-	print("        .ENADDRENA(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
-	print("        .ENADDRENB(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
-	print("        .RDADDRCHANGEA(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
-	print("        .RDADDRCHANGEB(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
-	print("        .RSTREG_PRIORITY_A(\"%s\")," % np.random.choice(["RSTREG", "REGCE"]))
-	print("        .RSTREG_PRIORITY_B(\"%s\")," % np.random.choice(["RSTREG", "REGCE"]))
-	print("        .SLEEP_ASYNC(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
-	for pin in ("CLKARDCLK", "CLKBWRCLK", "ENARDEN", "ENBWREN", "RSTRAMARSTRAM", "RSTRAMB", "RSTREGARSTREG", "RSTREGB"):
-		print("        .IS_%s_INVERTED(%d)," % (pin, np.random.randint(2)))
-	print("        .INIT_A(18'd%d)," % np.random.randint(2**18))
-	print("        .INIT_B(18'd%d)," % np.random.randint(2**18))
-	print("        .SRVAL_A(18'd%d)," % np.random.randint(2**18))
-	print("        .SRVAL_B(18'd%d)" % np.random.randint(2**18))
-	print("   ) ram%d (" % i)
-	print("        .DINADIN(wdata[15:0]),")
-	print("        .DINPADINP(wdata[17:16]),")
-	print("        .DOUTADOUT(int_d[%d][15:0])," % i)
-	print("        .DOUTPADOUTP(int_d[%d][17:16])," % i)
-	print("        .ADDRARDADDR(ra),")
-	print("        .CLKARDCLK(clk),")
-	print("        .ADDRENA(ena),")
-	print("        .ENARDEN(ena),")
-	print("        .REGCEAREGCE(cea),")
-	print("        .RSTRAMARSTRAM(rst),")
-	print("        .RSTREGARSTREG(rst),")
-	print("        .WEA(%s)," % ("2'b00" if write_width_a == 0 else "we[1:0]"))
-	print("        .DINBDIN(wdata[15:0]),")
-	print("        .DINPBDINP(wdata[17:16]),")
-	print("        .DOUTBDOUT(int_d[%d][33:18])," % i)
-	print("        .DOUTPBDOUTP(int_d[%d][35:34])," % i)
-	print("        .ADDRBWRADDR(wa),")
-	print("        .CLKBWRCLK(%s)," % ("clkb" if cd == "INDEPENDENT" else "clk"))
-	print("        .ENBWREN(enb),")
-	print("        .ADDRENB(enb),")
-	print("        .REGCEB(ceb),")
-	print("        .RSTRAMB(rst),")
-	print("        .RSTREGB(rst),")
-	print("        .WEBWE(%s)" % ("2'b00" if write_width_b == 0 else ("we[3:0]" if write_width_b == 36 else "we[3:2]")))
-	print("   );")
-	print()
-print("endmodule")
\ No newline at end of file
+    print("    RAMB18E2 #(")
+    print("        .CLOCK_DOMAINS(\"%s\")," % cd)
+    print("        .READ_WIDTH_A(%d)," % read_width_a)
+    print("        .READ_WIDTH_B(%d)," % read_width_b)
+    print("        .WRITE_WIDTH_A(%d)," % write_width_a)
+    print("        .WRITE_WIDTH_B(%d)," % write_width_b)
+    print("        .WRITE_MODE_A(\"%s\")," % np.random.choice(
+        ["NO_CHANGE", "READ_FIRST", "WRITE_FIRST"]))
+    print("        .WRITE_MODE_B(\"%s\")," % np.random.choice(
+        ["NO_CHANGE", "READ_FIRST", "WRITE_FIRST"]))
+    print("        .CASCADE_ORDER_A(\"%s\")," % np.random.choice(
+        ["NONE", "FIRST", "MIDDLE", "LAST"]))
+    print("        .CASCADE_ORDER_B(\"%s\")," % np.random.choice(
+        ["NONE", "FIRST", "MIDDLE", "LAST"]))
+    print(
+        "        .DOA_REG(%d)," % (0 if
+                                   (write_width_b == 36 or read_width_a == 36)
+                                   else np.random.randint(2)))
+    print(
+        "        .DOB_REG(%d)," % (0 if
+                                   (write_width_b == 36 or read_width_a == 36)
+                                   else np.random.randint(2)))
+    print("        .ENADDRENA(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
+    print("        .ENADDRENB(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
+    print("        .RDADDRCHANGEA(\"%s\")," % np.random.choice(
+        ["FALSE", "TRUE"]))
+    print("        .RDADDRCHANGEB(\"%s\")," % np.random.choice(
+        ["FALSE", "TRUE"]))
+    print("        .RSTREG_PRIORITY_A(\"%s\")," % np.random.choice(
+        ["RSTREG", "REGCE"]))
+    print("        .RSTREG_PRIORITY_B(\"%s\")," % np.random.choice(
+        ["RSTREG", "REGCE"]))
+    print(
+        "        .SLEEP_ASYNC(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
+    for pin in ("CLKARDCLK", "CLKBWRCLK", "ENARDEN", "ENBWREN",
+                "RSTRAMARSTRAM", "RSTRAMB", "RSTREGARSTREG", "RSTREGB"):
+        print("        .IS_%s_INVERTED(%d)," % (pin, np.random.randint(2)))
+    print("        .INIT_A(18'd%d)," % np.random.randint(2**18))
+    print("        .INIT_B(18'd%d)," % np.random.randint(2**18))
+    print("        .SRVAL_A(18'd%d)," % np.random.randint(2**18))
+    print("        .SRVAL_B(18'd%d)" % np.random.randint(2**18))
+    print("   ) ram%d (" % i)
+    print("        .DINADIN(wdata[15:0]),")
+    print("        .DINPADINP(wdata[17:16]),")
+    print("        .DOUTADOUT(int_d[%d][15:0])," % i)
+    print("        .DOUTPADOUTP(int_d[%d][17:16])," % i)
+    print("        .ADDRARDADDR(ra),")
+    print("        .CLKARDCLK(clk),")
+    print("        .ADDRENA(ena),")
+    print("        .ENARDEN(ena),")
+    print("        .REGCEAREGCE(cea),")
+    print("        .RSTRAMARSTRAM(rst),")
+    print("        .RSTREGARSTREG(rst),")
+    print("        .WEA(%s)," % ("2'b00" if write_width_a == 0 else "we[1:0]"))
+    print("        .DINBDIN(wdata[15:0]),")
+    print("        .DINPBDINP(wdata[17:16]),")
+    print("        .DOUTBDOUT(int_d[%d][33:18])," % i)
+    print("        .DOUTPBDOUTP(int_d[%d][35:34])," % i)
+    print("        .ADDRBWRADDR(wa),")
+    print(
+        "        .CLKBWRCLK(%s)," % ("clkb" if cd == "INDEPENDENT" else "clk"))
+    print("        .ENBWREN(enb),")
+    print("        .ADDRENB(enb),")
+    print("        .REGCEB(ceb),")
+    print("        .RSTRAMB(rst),")
+    print("        .RSTREGB(rst),")
+    print("        .WEBWE(%s)" %
+          ("2'b00" if write_width_b == 0 else
+           ("we[3:0]" if write_width_b == 36 else "we[3:2]")))
+    print("   );")
+    print()
+print("endmodule")
diff --git a/spec/bram18_2.py b/spec/bram18_2.py
index 4e7763e..6caaa40 100644
--- a/spec/bram18_2.py
+++ b/spec/bram18_2.py
@@ -16,74 +16,104 @@
 import sys
 import math
 
-print("module top(input clk, clkb, rst, ena, enb, cea, ceb, input [13:0] ra, wa, input [3:0] we, input [17:0] wdata, input [10:0] sel, output [35:0] rdata);")
+print(
+    "module top(input clk, clkb, rst, ena, enb, cea, ceb, input [13:0] ra, wa, input [3:0] we, input [17:0] wdata, input [10:0] sel, output [35:0] rdata);"
+)
 N = 200
 print("    wire [35:0] int_d[0:%d-1];" % N)
-print("    assign rdata = sel[0] ? int_d[sel[10:1]][35:18] : int_d[sel[10:1]][17:0];")
+print(
+    "    assign rdata = sel[0] ? int_d[sel[10:1]][35:18] : int_d[sel[10:1]][17:0];"
+)
 for i in range(N):
-	write_width_b = np.random.choice([0, 1, 2, 4, 9, 18, 36])
-	read_width_a = np.random.choice([0, 1, 2, 4, 9, 18, 36], p=[0.05, 0.1, 0.1, 0.1, 0.1, 0.45, 0.1])
-	write_width_a = 0 if (write_width_b == 36 or read_width_a == 36) else np.random.choice([0, 1, 2, 4, 9, 18])
-	read_width_b = 0 if (read_width_a == 36 or write_width_b == 36) else np.random.choice([0, 1, 2, 4, 9, 18], p=[0.05, 0.1, 0.1, 0.1, 0.1, 0.55])
+    write_width_b = np.random.choice([0, 1, 2, 4, 9, 18, 36])
+    read_width_a = np.random.choice([0, 1, 2, 4, 9, 18, 36],
+                                    p=[0.05, 0.1, 0.1, 0.1, 0.1, 0.45, 0.1])
+    write_width_a = 0 if (write_width_b == 36
+                          or read_width_a == 36) else np.random.choice(
+                              [0, 1, 2, 4, 9, 18])
+    read_width_b = 0 if (
+        read_width_a == 36 or write_width_b == 36) else np.random.choice(
+            [0, 1, 2, 4, 9, 18], p=[0.05, 0.1, 0.1, 0.1, 0.1, 0.55])
 
-	cd = np.random.choice(["INDEPENDENT", "COMMON"])
+    cd = np.random.choice(["INDEPENDENT", "COMMON"])
 
-	print("    (* keep, dont_touch *) RAMB18E2 #(")
-	print("        .CLOCK_DOMAINS(\"%s\")," % cd)
-	print("        .READ_WIDTH_A(%d)," % read_width_a)
-	print("        .READ_WIDTH_B(%d)," % read_width_b)
-	print("        .WRITE_WIDTH_A(%d)," % write_width_a)
-	print("        .WRITE_WIDTH_B(%d)," % write_width_b)
-	print("        .WRITE_MODE_A(\"%s\")," % np.random.choice(["NO_CHANGE", "READ_FIRST", "WRITE_FIRST"]))
-	print("        .WRITE_MODE_B(\"%s\")," % np.random.choice(["NO_CHANGE", "READ_FIRST", "WRITE_FIRST"]))
-	print("        .CASCADE_ORDER_A(\"%s\")," % np.random.choice(["NONE", "FIRST", "MIDDLE", "LAST"]))
-	print("        .CASCADE_ORDER_B(\"%s\")," % np.random.choice(["NONE", "FIRST", "MIDDLE", "LAST"]))
-	print("        .DOA_REG(%d)," % (0 if (write_width_b == 36 or read_width_a == 36) else np.random.randint(2)))
-	print("        .DOB_REG(%d),"% (0 if (write_width_b == 36 or read_width_a == 36) else np.random.randint(2)))
-	print("        .ENADDRENA(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
-	print("        .ENADDRENB(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
-	print("        .RDADDRCHANGEA(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
-	print("        .RDADDRCHANGEB(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
-	print("        .RSTREG_PRIORITY_A(\"%s\")," % np.random.choice(["RSTREG", "REGCE"]))
-	print("        .RSTREG_PRIORITY_B(\"%s\")," % np.random.choice(["RSTREG", "REGCE"]))
-	print("        .SLEEP_ASYNC(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
-	for pin in ("CLKARDCLK", "CLKBWRCLK", "ENARDEN", "ENBWREN", "RSTRAMARSTRAM", "RSTRAMB", "RSTREGARSTREG", "RSTREGB"):
-		print("        .IS_%s_INVERTED(%d)," % (pin, np.random.randint(2)))
-	print("        .INIT_A(18'd%d)," % np.random.randint(2**18))
-	print("        .INIT_B(18'd%d)," % np.random.randint(2**18))
-	print("        .SRVAL_A(18'd%d)," % np.random.randint(2**18))
-	print("        .SRVAL_B(18'd%d)" % np.random.randint(2**18))
-	print("   ) ram%d (" % i)
-	print("        .DINADIN(wdata[15:0]),")
-	print("        .DINPADINP(wdata[17:16]),")
-	douta_len = np.random.randint(0, 19)
-	if douta_len > 0:	
-		print("        .DOUTADOUT(int_d[%d][%d:0])," % (i, min(15, douta_len - 1)))
-	if douta_len > 16:
-		print("        .DOUTPADOUTP(int_d[%d][%d:16])," % (i, douta_len - 1))
-	print("        .ADDRARDADDR(ra),")
-	print("        .CLKARDCLK(clk),")
-	print("        .ADDRENA(ena),")
-	print("        .ENARDEN(ena),")
-	print("        .REGCEAREGCE(cea),")
-	print("        .RSTRAMARSTRAM(rst),")
-	print("        .RSTREGARSTREG(rst),")
-	print("        .WEA(%s)," % ("2'b00" if write_width_a == 0 else "we[1:0]"))
-	print("        .DINBDIN(wdata[15:0]),")
-	print("        .DINPBDINP(wdata[17:16]),")
-	doutb_len = np.random.randint(0, 19)
-	if doutb_len > 0:
-		print("        .DOUTBDOUT(int_d[%d][%d:18])," % (i, min(33, 17 + doutb_len)))
-	if doutb_len > 16:
-		print("        .DOUTPBDOUTP(int_d[%d][%d:34])," % (i, 17 + doutb_len))
-	print("        .ADDRBWRADDR(wa),")
-	print("        .CLKBWRCLK(%s)," % ("clkb" if cd == "INDEPENDENT" else "clk"))
-	print("        .ENBWREN(enb),")
-	print("        .ADDRENB(enb),")
-	print("        .REGCEB(ceb),")
-	print("        .RSTRAMB(rst),")
-	print("        .RSTREGB(rst),")
-	print("        .WEBWE(%s)" % ("2'b00" if write_width_b == 0 else ("we[3:0]" if write_width_b == 36 else "we[3:2]")))
-	print("   );")
-	print()
-print("endmodule")
\ No newline at end of file
+    print("    (* keep, dont_touch *) RAMB18E2 #(")
+    print("        .CLOCK_DOMAINS(\"%s\")," % cd)
+    print("        .READ_WIDTH_A(%d)," % read_width_a)
+    print("        .READ_WIDTH_B(%d)," % read_width_b)
+    print("        .WRITE_WIDTH_A(%d)," % write_width_a)
+    print("        .WRITE_WIDTH_B(%d)," % write_width_b)
+    print("        .WRITE_MODE_A(\"%s\")," % np.random.choice(
+        ["NO_CHANGE", "READ_FIRST", "WRITE_FIRST"]))
+    print("        .WRITE_MODE_B(\"%s\")," % np.random.choice(
+        ["NO_CHANGE", "READ_FIRST", "WRITE_FIRST"]))
+    print("        .CASCADE_ORDER_A(\"%s\")," % np.random.choice(
+        ["NONE", "FIRST", "MIDDLE", "LAST"]))
+    print("        .CASCADE_ORDER_B(\"%s\")," % np.random.choice(
+        ["NONE", "FIRST", "MIDDLE", "LAST"]))
+    print(
+        "        .DOA_REG(%d)," % (0 if
+                                   (write_width_b == 36 or read_width_a == 36)
+                                   else np.random.randint(2)))
+    print(
+        "        .DOB_REG(%d)," % (0 if
+                                   (write_width_b == 36 or read_width_a == 36)
+                                   else np.random.randint(2)))
+    print("        .ENADDRENA(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
+    print("        .ENADDRENB(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
+    print("        .RDADDRCHANGEA(\"%s\")," % np.random.choice(
+        ["FALSE", "TRUE"]))
+    print("        .RDADDRCHANGEB(\"%s\")," % np.random.choice(
+        ["FALSE", "TRUE"]))
+    print("        .RSTREG_PRIORITY_A(\"%s\")," % np.random.choice(
+        ["RSTREG", "REGCE"]))
+    print("        .RSTREG_PRIORITY_B(\"%s\")," % np.random.choice(
+        ["RSTREG", "REGCE"]))
+    print(
+        "        .SLEEP_ASYNC(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
+    for pin in ("CLKARDCLK", "CLKBWRCLK", "ENARDEN", "ENBWREN",
+                "RSTRAMARSTRAM", "RSTRAMB", "RSTREGARSTREG", "RSTREGB"):
+        print("        .IS_%s_INVERTED(%d)," % (pin, np.random.randint(2)))
+    print("        .INIT_A(18'd%d)," % np.random.randint(2**18))
+    print("        .INIT_B(18'd%d)," % np.random.randint(2**18))
+    print("        .SRVAL_A(18'd%d)," % np.random.randint(2**18))
+    print("        .SRVAL_B(18'd%d)" % np.random.randint(2**18))
+    print("   ) ram%d (" % i)
+    print("        .DINADIN(wdata[15:0]),")
+    print("        .DINPADINP(wdata[17:16]),")
+    douta_len = np.random.randint(0, 19)
+    if douta_len > 0:
+        print("        .DOUTADOUT(int_d[%d][%d:0])," %
+              (i, min(15, douta_len - 1)))
+    if douta_len > 16:
+        print("        .DOUTPADOUTP(int_d[%d][%d:16])," % (i, douta_len - 1))
+    print("        .ADDRARDADDR(ra),")
+    print("        .CLKARDCLK(clk),")
+    print("        .ADDRENA(ena),")
+    print("        .ENARDEN(ena),")
+    print("        .REGCEAREGCE(cea),")
+    print("        .RSTRAMARSTRAM(rst),")
+    print("        .RSTREGARSTREG(rst),")
+    print("        .WEA(%s)," % ("2'b00" if write_width_a == 0 else "we[1:0]"))
+    print("        .DINBDIN(wdata[15:0]),")
+    print("        .DINPBDINP(wdata[17:16]),")
+    doutb_len = np.random.randint(0, 19)
+    if doutb_len > 0:
+        print("        .DOUTBDOUT(int_d[%d][%d:18])," %
+              (i, min(33, 17 + doutb_len)))
+    if doutb_len > 16:
+        print("        .DOUTPBDOUTP(int_d[%d][%d:34])," % (i, 17 + doutb_len))
+    print("        .ADDRBWRADDR(wa),")
+    print(
+        "        .CLKBWRCLK(%s)," % ("clkb" if cd == "INDEPENDENT" else "clk"))
+    print("        .ENBWREN(enb),")
+    print("        .ADDRENB(enb),")
+    print("        .REGCEB(ceb),")
+    print("        .RSTRAMB(rst),")
+    print("        .RSTREGB(rst),")
+    print("        .WEBWE(%s)" %
+          ("2'b00" if write_width_b == 0 else
+           ("we[3:0]" if write_width_b == 36 else "we[3:2]")))
+    print("   );")
+    print()
+print("endmodule")
diff --git a/spec/bram18_3.py b/spec/bram18_3.py
index 8c26653..df37860 100644
--- a/spec/bram18_3.py
+++ b/spec/bram18_3.py
@@ -16,74 +16,106 @@
 import sys
 import math
 
-print("module top(input clk, clkb, rst, ena, enb, cea, ceb, input [13:0] ra, wa, input [3:0] we, input [17:0] wdata, input [10:0] sel, output [35:0] rdata);")
+print(
+    "module top(input clk, clkb, rst, ena, enb, cea, ceb, input [13:0] ra, wa, input [3:0] we, input [17:0] wdata, input [10:0] sel, output [35:0] rdata);"
+)
 N = 500
 print("    wire [35:0] int_d[0:%d-1];" % N)
-print("    assign rdata = sel[0] ? int_d[sel[10:1]][35:18] : int_d[sel[10:1]][17:0];")
+print(
+    "    assign rdata = sel[0] ? int_d[sel[10:1]][35:18] : int_d[sel[10:1]][17:0];"
+)
 for i in range(N):
-	write_width_b = np.random.choice([0, 1, 2, 4, 9, 18, 36])
-	read_width_a = np.random.choice([0, 1, 2, 4, 9, 18, 36], p=[0.05, 0.1, 0.1, 0.1, 0.1, 0.45, 0.1])
-	write_width_a = 0 if (write_width_b == 36 or read_width_a == 36) else np.random.choice([0, 1, 2, 4, 9, 18])
-	read_width_b = 0 if (read_width_a == 36 or write_width_b == 36) else np.random.choice([0, 1, 2, 4, 9, 18], p=[0.05, 0.1, 0.1, 0.1, 0.1, 0.55])
+    write_width_b = np.random.choice([0, 1, 2, 4, 9, 18, 36])
+    read_width_a = np.random.choice([0, 1, 2, 4, 9, 18, 36],
+                                    p=[0.05, 0.1, 0.1, 0.1, 0.1, 0.45, 0.1])
+    write_width_a = 0 if (write_width_b == 36
+                          or read_width_a == 36) else np.random.choice(
+                              [0, 1, 2, 4, 9, 18])
+    read_width_b = 0 if (
+        read_width_a == 36 or write_width_b == 36) else np.random.choice(
+            [0, 1, 2, 4, 9, 18], p=[0.05, 0.1, 0.1, 0.1, 0.1, 0.55])
 
-	cd = np.random.choice(["INDEPENDENT", "COMMON"])
+    cd = np.random.choice(["INDEPENDENT", "COMMON"])
 
-	print("    (* keep, dont_touch *) RAMB18E2 #(")
-	print("        .CLOCK_DOMAINS(\"%s\")," % cd)
-	print("        .READ_WIDTH_A(%d)," % read_width_a)
-	print("        .READ_WIDTH_B(%d)," % read_width_b)
-	print("        .WRITE_WIDTH_A(%d)," % write_width_a)
-	print("        .WRITE_WIDTH_B(%d)," % write_width_b)
-	print("        .WRITE_MODE_A(\"%s\")," % np.random.choice(["NO_CHANGE", "READ_FIRST", "WRITE_FIRST"]))
-	print("        .WRITE_MODE_B(\"%s\")," % np.random.choice(["NO_CHANGE", "READ_FIRST", "WRITE_FIRST"]))
-	print("        .CASCADE_ORDER_A(\"%s\")," % np.random.choice(["NONE", "FIRST", "MIDDLE", "LAST"]))
-	print("        .CASCADE_ORDER_B(\"%s\")," % np.random.choice(["NONE", "FIRST", "MIDDLE", "LAST"]))
-	print("        .DOA_REG(%d)," % (0 if (write_width_b == 36 or read_width_a == 36) else np.random.randint(2)))
-	print("        .DOB_REG(%d),"% (0 if (write_width_b == 36 or read_width_a == 36) else np.random.randint(2)))
-	print("        .ENADDRENA(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
-	print("        .ENADDRENB(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
-	print("        .RDADDRCHANGEA(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
-	print("        .RDADDRCHANGEB(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
-	print("        .RSTREG_PRIORITY_A(\"%s\")," % np.random.choice(["RSTREG", "REGCE"]))
-	print("        .RSTREG_PRIORITY_B(\"%s\")," % np.random.choice(["RSTREG", "REGCE"]))
-	print("        .SLEEP_ASYNC(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
-	for pin in ("CLKARDCLK", "CLKBWRCLK", "ENARDEN", "ENBWREN", "RSTRAMARSTRAM", "RSTRAMB", "RSTREGARSTREG", "RSTREGB"):
-		print("        .IS_%s_INVERTED(%d)," % (pin, np.random.randint(2)))
-	print("        .INIT_A(18'd%d)," % np.random.randint(2**18))
-	print("        .INIT_B(18'd%d)," % np.random.randint(2**18))
-	print("        .SRVAL_A(18'd%d)," % np.random.randint(2**18))
-	print("        .SRVAL_B(18'd%d)" % np.random.randint(2**18))
-	print("   ) ram%d (" % i)
-	print("        .DINADIN(wdata[15:0]),")
-	print("        .DINPADINP(wdata[17:16]),")
-	douta_bit = np.random.randint(-1, 19)
-	if douta_bit >= 0 and douta_bit < 16:	
-		print("        .DOUTADOUT({int_d[%d][0]%s})," % (i, ", {%d{1'bx}}" % douta_bit if douta_bit > 0 else ""))
-	if douta_bit >= 16:
-		print("        .DOUTPADOUTP({int_d[%d][16]%s})," % (i, ", {%d{1'bx}}" % (douta_bit - 16) if douta_bit > 16 else ""))
-	print("        .ADDRARDADDR(ra),")
-	print("        .CLKARDCLK(clk),")
-	print("        .ADDRENA(ena),")
-	print("        .ENARDEN(ena),")
-	print("        .REGCEAREGCE(cea),")
-	print("        .RSTRAMARSTRAM(rst),")
-	print("        .RSTREGARSTREG(rst),")
-	print("        .WEA(%s)," % ("2'b00" if write_width_a == 0 else "we[1:0]"))
-	print("        .DINBDIN(wdata[15:0]),")
-	print("        .DINPBDINP(wdata[17:16]),")
-	doutb_bit = np.random.randint(-1, 19)
-	if doutb_bit >= 0 and doutb_bit < 16:	
-		print("        .DOUTBDOUT({int_d[%d][18]%s})," % (i, ", {%d{1'bx}}" % doutb_bit if doutb_bit > 0 else ""))
-	if doutb_bit >= 16:
-		print("        .DOUTPBDOUTP({int_d[%d][34]%s})," % (i, ", {%d{1'bx}}" % (doutb_bit - 16) if doutb_bit > 16 else ""))
-	print("        .ADDRBWRADDR(wa),")
-	print("        .CLKBWRCLK(%s)," % ("clkb" if cd == "INDEPENDENT" else "clk"))
-	print("        .ENBWREN(enb),")
-	print("        .ADDRENB(enb),")
-	print("        .REGCEB(ceb),")
-	print("        .RSTRAMB(rst),")
-	print("        .RSTREGB(rst),")
-	print("        .WEBWE(%s)" % ("2'b00" if write_width_b == 0 else ("we[3:0]" if write_width_b == 36 else "we[3:2]")))
-	print("   );")
-	print()
-print("endmodule")
\ No newline at end of file
+    print("    (* keep, dont_touch *) RAMB18E2 #(")
+    print("        .CLOCK_DOMAINS(\"%s\")," % cd)
+    print("        .READ_WIDTH_A(%d)," % read_width_a)
+    print("        .READ_WIDTH_B(%d)," % read_width_b)
+    print("        .WRITE_WIDTH_A(%d)," % write_width_a)
+    print("        .WRITE_WIDTH_B(%d)," % write_width_b)
+    print("        .WRITE_MODE_A(\"%s\")," % np.random.choice(
+        ["NO_CHANGE", "READ_FIRST", "WRITE_FIRST"]))
+    print("        .WRITE_MODE_B(\"%s\")," % np.random.choice(
+        ["NO_CHANGE", "READ_FIRST", "WRITE_FIRST"]))
+    print("        .CASCADE_ORDER_A(\"%s\")," % np.random.choice(
+        ["NONE", "FIRST", "MIDDLE", "LAST"]))
+    print("        .CASCADE_ORDER_B(\"%s\")," % np.random.choice(
+        ["NONE", "FIRST", "MIDDLE", "LAST"]))
+    print(
+        "        .DOA_REG(%d)," % (0 if
+                                   (write_width_b == 36 or read_width_a == 36)
+                                   else np.random.randint(2)))
+    print(
+        "        .DOB_REG(%d)," % (0 if
+                                   (write_width_b == 36 or read_width_a == 36)
+                                   else np.random.randint(2)))
+    print("        .ENADDRENA(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
+    print("        .ENADDRENB(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
+    print("        .RDADDRCHANGEA(\"%s\")," % np.random.choice(
+        ["FALSE", "TRUE"]))
+    print("        .RDADDRCHANGEB(\"%s\")," % np.random.choice(
+        ["FALSE", "TRUE"]))
+    print("        .RSTREG_PRIORITY_A(\"%s\")," % np.random.choice(
+        ["RSTREG", "REGCE"]))
+    print("        .RSTREG_PRIORITY_B(\"%s\")," % np.random.choice(
+        ["RSTREG", "REGCE"]))
+    print(
+        "        .SLEEP_ASYNC(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
+    for pin in ("CLKARDCLK", "CLKBWRCLK", "ENARDEN", "ENBWREN",
+                "RSTRAMARSTRAM", "RSTRAMB", "RSTREGARSTREG", "RSTREGB"):
+        print("        .IS_%s_INVERTED(%d)," % (pin, np.random.randint(2)))
+    print("        .INIT_A(18'd%d)," % np.random.randint(2**18))
+    print("        .INIT_B(18'd%d)," % np.random.randint(2**18))
+    print("        .SRVAL_A(18'd%d)," % np.random.randint(2**18))
+    print("        .SRVAL_B(18'd%d)" % np.random.randint(2**18))
+    print("   ) ram%d (" % i)
+    print("        .DINADIN(wdata[15:0]),")
+    print("        .DINPADINP(wdata[17:16]),")
+    douta_bit = np.random.randint(-1, 19)
+    if douta_bit >= 0 and douta_bit < 16:
+        print("        .DOUTADOUT({int_d[%d][0]%s})," %
+              (i, ", {%d{1'bx}}" % douta_bit if douta_bit > 0 else ""))
+    if douta_bit >= 16:
+        print("        .DOUTPADOUTP({int_d[%d][16]%s})," %
+              (i, ", {%d{1'bx}}" % (douta_bit - 16) if douta_bit > 16 else ""))
+    print("        .ADDRARDADDR(ra),")
+    print("        .CLKARDCLK(clk),")
+    print("        .ADDRENA(ena),")
+    print("        .ENARDEN(ena),")
+    print("        .REGCEAREGCE(cea),")
+    print("        .RSTRAMARSTRAM(rst),")
+    print("        .RSTREGARSTREG(rst),")
+    print("        .WEA(%s)," % ("2'b00" if write_width_a == 0 else "we[1:0]"))
+    print("        .DINBDIN(wdata[15:0]),")
+    print("        .DINPBDINP(wdata[17:16]),")
+    doutb_bit = np.random.randint(-1, 19)
+    if doutb_bit >= 0 and doutb_bit < 16:
+        print("        .DOUTBDOUT({int_d[%d][18]%s})," %
+              (i, ", {%d{1'bx}}" % doutb_bit if doutb_bit > 0 else ""))
+    if doutb_bit >= 16:
+        print("        .DOUTPBDOUTP({int_d[%d][34]%s})," %
+              (i, ", {%d{1'bx}}" % (doutb_bit - 16) if doutb_bit > 16 else ""))
+    print("        .ADDRBWRADDR(wa),")
+    print(
+        "        .CLKBWRCLK(%s)," % ("clkb" if cd == "INDEPENDENT" else "clk"))
+    print("        .ENBWREN(enb),")
+    print("        .ADDRENB(enb),")
+    print("        .REGCEB(ceb),")
+    print("        .RSTRAMB(rst),")
+    print("        .RSTREGB(rst),")
+    print("        .WEBWE(%s)" %
+          ("2'b00" if write_width_b == 0 else
+           ("we[3:0]" if write_width_b == 36 else "we[3:2]")))
+    print("   );")
+    print()
+print("endmodule")
diff --git a/spec/bram36.py b/spec/bram36.py
index 6e6ed40..6211d20 100644
--- a/spec/bram36.py
+++ b/spec/bram36.py
@@ -16,70 +16,93 @@
 import sys
 import math
 
-print("module top(input clk, clkb, rst, ena, enb, cea, ceb, input [14:0] ra, wa, input [7:0] we, input [17:0] wdata, input [10:0] sel, output [35:0] rdata);")
+print(
+    "module top(input clk, clkb, rst, ena, enb, cea, ceb, input [14:0] ra, wa, input [7:0] we, input [17:0] wdata, input [10:0] sel, output [35:0] rdata);"
+)
 N = 300
 print("    wire [71:0] int_d[0:%d-1];" % N)
 print("    assign rdata = int_d[sel[10:2]][18 * sel[1:0] +: 18];")
 for i in range(N):
-	read_width_a = np.random.choice([0, 1, 2, 4, 9, 18, 36], p=[0.05, 0.1, 0.1, 0.1, 0.1, 0.1, 0.45])
-	write_width_a = np.random.choice([0, 1, 2, 4, 9, 18, 36])
-	read_width_b = np.random.choice([0, 1, 2, 4, 9, 18, 36], p=[0.05, 0.1, 0.1, 0.1, 0.1, 0.1, 0.45])
-	write_width_b = np.random.choice([0, 1, 2, 4, 9, 18, 36])
-	cd = np.random.choice(["INDEPENDENT", "COMMON"])
+    read_width_a = np.random.choice([0, 1, 2, 4, 9, 18, 36],
+                                    p=[0.05, 0.1, 0.1, 0.1, 0.1, 0.1, 0.45])
+    write_width_a = np.random.choice([0, 1, 2, 4, 9, 18, 36])
+    read_width_b = np.random.choice([0, 1, 2, 4, 9, 18, 36],
+                                    p=[0.05, 0.1, 0.1, 0.1, 0.1, 0.1, 0.45])
+    write_width_b = np.random.choice([0, 1, 2, 4, 9, 18, 36])
+    cd = np.random.choice(["INDEPENDENT", "COMMON"])
 
-	print("    RAMB36E2 #(")
-	print("        .CLOCK_DOMAINS(\"%s\")," % cd)
-	print("        .READ_WIDTH_A(%d)," % read_width_a)
-	print("        .READ_WIDTH_B(%d)," % read_width_b)
-	print("        .WRITE_WIDTH_A(%d)," % write_width_a)
-	print("        .WRITE_WIDTH_B(%d)," % write_width_b)
-	print("        .WRITE_MODE_A(\"%s\")," % np.random.choice(["NO_CHANGE", "READ_FIRST", "WRITE_FIRST"]))
-	print("        .WRITE_MODE_B(\"%s\")," % np.random.choice(["NO_CHANGE", "READ_FIRST", "WRITE_FIRST"]))
-	print("        .CASCADE_ORDER_A(\"%s\")," % np.random.choice(["NONE", "FIRST", "MIDDLE", "LAST"]))
-	print("        .CASCADE_ORDER_B(\"%s\")," % np.random.choice(["NONE", "FIRST", "MIDDLE", "LAST"]))
-	print("        .DOA_REG(%d)," % np.random.randint(2))
-	print("        .DOB_REG(%d),"% np.random.randint(2))
-	print("        .ENADDRENA(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
-	print("        .ENADDRENB(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
-	print("        .EN_ECC_PIPE(\"%s\")," % np.random.choice(["FALSE", "TRUE"], p=[0.9, 0.1]))
-	print("        .EN_ECC_READ(\"%s\")," % np.random.choice(["FALSE", "TRUE"], p=[0.9, 0.1]))
-	print("        .EN_ECC_WRITE(\"%s\")," % np.random.choice(["FALSE", "TRUE"], p=[0.9, 0.1]))
-	print("        .RDADDRCHANGEA(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
-	print("        .RDADDRCHANGEB(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
-	print("        .SLEEP_ASYNC(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
-	print("        .RSTREG_PRIORITY_A(\"%s\")," % np.random.choice(["RSTREG", "REGCE"]))
-	print("        .RSTREG_PRIORITY_B(\"%s\")," % np.random.choice(["RSTREG", "REGCE"]))
-	for pin in ("CLKARDCLK", "CLKBWRCLK", "ENARDEN", "ENBWREN", "RSTRAMARSTRAM", "RSTRAMB", "RSTREGARSTREG", "RSTREGB"):
-		print("        .IS_%s_INVERTED(%d)," % (pin, np.random.randint(2)))
-	print("        .INIT_A({18'd%d, 18'd%d})," % (np.random.randint(2**18), np.random.randint(2**18)))
-	print("        .INIT_B({18'd%d, 18'd%d})," % (np.random.randint(2**18), np.random.randint(2**18)))
-	print("        .SRVAL_A({18'd%d, 18'd%d})," % (np.random.randint(2**18), np.random.randint(2**18)))
-	print("        .SRVAL_B({18'd%d, 18'd%d})" % (np.random.randint(2**18), np.random.randint(2**18)))
-	print("   ) ram%d (" % i)
-	print("        .DINADIN({wdata[15:0], wdata[15:0]}),")
-	print("        .DINPADINP({wdata[17:16], wdata[17:16]}),")
-	print("        .DOUTADOUT({int_d[%d][31:0]})," % i)
-	print("        .DOUTPADOUTP({int_d[%d][35:32]})," % i)
-	print("        .ADDRARDADDR(ra),")
-	print("        .CLKARDCLK(clk),")
-	print("        .ADDRENA(ena),")
-	print("        .ENARDEN(ena),")
-	print("        .REGCEAREGCE(cea),")
-	print("        .RSTRAMARSTRAM(rst),")
-	print("        .RSTREGARSTREG(rst),")
-	print("        .WEA(%s)," % ("4'b00" if write_width_a == 0 else "we[3:0]"))
-	print("        .DINBDIN({wdata[15:0], wdata[15:0]}),")
-	print("        .DINPBDINP({wdata[17:16], wdata[17:16]}),")
-	print("        .DOUTBDOUT(int_d[%d][67:36])," % i)
-	print("        .DOUTPBDOUTP(int_d[%d][71:68])," % i)
-	print("        .ADDRBWRADDR(wa),")
-	print("        .CLKBWRCLK(%s)," % ("clkb" if cd == "INDEPENDENT" else "clk"))
-	print("        .ENBWREN(enb),")
-	print("        .ADDRENB(enb),")
-	print("        .REGCEB(ceb),")
-	print("        .RSTRAMB(rst),")
-	print("        .RSTREGB(rst),")
-	print("        .WEBWE(%s)" % ("4'b00" if write_width_b == 0 else "we[7:4]"))
-	print("   );")
-	print()
-print("endmodule")
\ No newline at end of file
+    print("    RAMB36E2 #(")
+    print("        .CLOCK_DOMAINS(\"%s\")," % cd)
+    print("        .READ_WIDTH_A(%d)," % read_width_a)
+    print("        .READ_WIDTH_B(%d)," % read_width_b)
+    print("        .WRITE_WIDTH_A(%d)," % write_width_a)
+    print("        .WRITE_WIDTH_B(%d)," % write_width_b)
+    print("        .WRITE_MODE_A(\"%s\")," % np.random.choice(
+        ["NO_CHANGE", "READ_FIRST", "WRITE_FIRST"]))
+    print("        .WRITE_MODE_B(\"%s\")," % np.random.choice(
+        ["NO_CHANGE", "READ_FIRST", "WRITE_FIRST"]))
+    print("        .CASCADE_ORDER_A(\"%s\")," % np.random.choice(
+        ["NONE", "FIRST", "MIDDLE", "LAST"]))
+    print("        .CASCADE_ORDER_B(\"%s\")," % np.random.choice(
+        ["NONE", "FIRST", "MIDDLE", "LAST"]))
+    print("        .DOA_REG(%d)," % np.random.randint(2))
+    print("        .DOB_REG(%d)," % np.random.randint(2))
+    print("        .ENADDRENA(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
+    print("        .ENADDRENB(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
+    print("        .EN_ECC_PIPE(\"%s\")," % np.random.choice(["FALSE", "TRUE"],
+                                                             p=[0.9, 0.1]))
+    print("        .EN_ECC_READ(\"%s\")," % np.random.choice(["FALSE", "TRUE"],
+                                                             p=[0.9, 0.1]))
+    print("        .EN_ECC_WRITE(\"%s\")," % np.random.choice(
+        ["FALSE", "TRUE"], p=[0.9, 0.1]))
+    print("        .RDADDRCHANGEA(\"%s\")," % np.random.choice(
+        ["FALSE", "TRUE"]))
+    print("        .RDADDRCHANGEB(\"%s\")," % np.random.choice(
+        ["FALSE", "TRUE"]))
+    print(
+        "        .SLEEP_ASYNC(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
+    print("        .RSTREG_PRIORITY_A(\"%s\")," % np.random.choice(
+        ["RSTREG", "REGCE"]))
+    print("        .RSTREG_PRIORITY_B(\"%s\")," % np.random.choice(
+        ["RSTREG", "REGCE"]))
+    for pin in ("CLKARDCLK", "CLKBWRCLK", "ENARDEN", "ENBWREN",
+                "RSTRAMARSTRAM", "RSTRAMB", "RSTREGARSTREG", "RSTREGB"):
+        print("        .IS_%s_INVERTED(%d)," % (pin, np.random.randint(2)))
+    print("        .INIT_A({18'd%d, 18'd%d})," % (np.random.randint(2**18),
+                                                  np.random.randint(2**18)))
+    print("        .INIT_B({18'd%d, 18'd%d})," % (np.random.randint(2**18),
+                                                  np.random.randint(2**18)))
+    print("        .SRVAL_A({18'd%d, 18'd%d})," % (np.random.randint(2**18),
+                                                   np.random.randint(2**18)))
+    print("        .SRVAL_B({18'd%d, 18'd%d})" % (np.random.randint(2**18),
+                                                  np.random.randint(2**18)))
+    print("   ) ram%d (" % i)
+    print("        .DINADIN({wdata[15:0], wdata[15:0]}),")
+    print("        .DINPADINP({wdata[17:16], wdata[17:16]}),")
+    print("        .DOUTADOUT({int_d[%d][31:0]})," % i)
+    print("        .DOUTPADOUTP({int_d[%d][35:32]})," % i)
+    print("        .ADDRARDADDR(ra),")
+    print("        .CLKARDCLK(clk),")
+    print("        .ADDRENA(ena),")
+    print("        .ENARDEN(ena),")
+    print("        .REGCEAREGCE(cea),")
+    print("        .RSTRAMARSTRAM(rst),")
+    print("        .RSTREGARSTREG(rst),")
+    print("        .WEA(%s)," % ("4'b00" if write_width_a == 0 else "we[3:0]"))
+    print("        .DINBDIN({wdata[15:0], wdata[15:0]}),")
+    print("        .DINPBDINP({wdata[17:16], wdata[17:16]}),")
+    print("        .DOUTBDOUT(int_d[%d][67:36])," % i)
+    print("        .DOUTPBDOUTP(int_d[%d][71:68])," % i)
+    print("        .ADDRBWRADDR(wa),")
+    print(
+        "        .CLKBWRCLK(%s)," % ("clkb" if cd == "INDEPENDENT" else "clk"))
+    print("        .ENBWREN(enb),")
+    print("        .ADDRENB(enb),")
+    print("        .REGCEB(ceb),")
+    print("        .RSTRAMB(rst),")
+    print("        .RSTREGB(rst),")
+    print(
+        "        .WEBWE(%s)" % ("4'b00" if write_width_b == 0 else "we[7:4]"))
+    print("   );")
+    print()
+print("endmodule")
diff --git a/spec/bram36_sdp.py b/spec/bram36_sdp.py
index def70ef..7a675a9 100644
--- a/spec/bram36_sdp.py
+++ b/spec/bram36_sdp.py
@@ -16,70 +16,104 @@
 import sys
 import math
 
-print("module top(input clk, clkb, rst, ena, enb, cea, ceb, input [14:0] ra, wa, input [7:0] we, input [17:0] wdata, input [10:0] sel, output [35:0] rdata);")
+print(
+    "module top(input clk, clkb, rst, ena, enb, cea, ceb, input [14:0] ra, wa, input [7:0] we, input [17:0] wdata, input [10:0] sel, output [35:0] rdata);"
+)
 N = 300
 print("    wire [71:0] int_d[0:%d-1];" % N)
 print("    assign rdata = int_d[sel[10:2]][18 * sel[1:0] +: 18];")
 for i in range(N):
-	write_width_b = np.random.choice([0, 1, 2, 4, 9, 18, 36, 72])
-	read_width_a = np.random.choice([0, 1, 2, 4, 9, 18, 36, 72], p=[0.05, 0.1, 0.1, 0.1, 0.05, 0.05, 0.45, 0.1])
-	write_width_a = 0 if (write_width_b == 72 or read_width_a == 72) else np.random.choice([0, 1, 2, 4, 9, 18, 36])
-	read_width_b = 0 if (write_width_b == 72 or read_width_a == 72) else np.random.choice([0, 1, 2, 4, 9, 18, 36], p=[0.05, 0.1, 0.1, 0.1, 0.1, 0.1, 0.45])
-	cd = np.random.choice(["INDEPENDENT", "COMMON"])
+    write_width_b = np.random.choice([0, 1, 2, 4, 9, 18, 36, 72])
+    read_width_a = np.random.choice(
+        [0, 1, 2, 4, 9, 18, 36, 72],
+        p=[0.05, 0.1, 0.1, 0.1, 0.05, 0.05, 0.45, 0.1])
+    write_width_a = 0 if (write_width_b == 72
+                          or read_width_a == 72) else np.random.choice(
+                              [0, 1, 2, 4, 9, 18, 36])
+    read_width_b = 0 if (
+        write_width_b == 72 or read_width_a == 72) else np.random.choice(
+            [0, 1, 2, 4, 9, 18, 36], p=[0.05, 0.1, 0.1, 0.1, 0.1, 0.1, 0.45])
+    cd = np.random.choice(["INDEPENDENT", "COMMON"])
 
-	print("    RAMB36E2 #(")
-	print("        .CLOCK_DOMAINS(\"%s\")," % cd)
-	print("        .READ_WIDTH_A(%d)," % read_width_a)
-	print("        .READ_WIDTH_B(%d)," % read_width_b)
-	print("        .WRITE_WIDTH_A(%d)," % write_width_a)
-	print("        .WRITE_WIDTH_B(%d)," % write_width_b)
-	print("        .WRITE_MODE_A(\"%s\")," % np.random.choice(["NO_CHANGE", "READ_FIRST", "WRITE_FIRST"]))
-	print("        .WRITE_MODE_B(\"%s\")," % np.random.choice(["NO_CHANGE", "READ_FIRST", "WRITE_FIRST"]))
-	print("        .CASCADE_ORDER_A(\"%s\")," % np.random.choice(["NONE", "FIRST", "MIDDLE", "LAST"]))
-	print("        .CASCADE_ORDER_B(\"%s\")," % np.random.choice(["NONE", "FIRST", "MIDDLE", "LAST"]))
-	print("        .DOA_REG(%d)," % (0 if (write_width_b == 72 or read_width_a == 72) else np.random.randint(2)))
-	print("        .DOB_REG(%d)," % (0 if (write_width_b == 72 or read_width_a == 72) else np.random.randint(2)))
-	print("        .ENADDRENA(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
-	print("        .ENADDRENB(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
-	print("        .EN_ECC_PIPE(\"%s\")," % np.random.choice(["FALSE", "TRUE"], p=[0.9, 0.1]))
-	print("        .EN_ECC_READ(\"%s\")," % np.random.choice(["FALSE", "TRUE"], p=[0.9, 0.1]))
-	print("        .EN_ECC_WRITE(\"%s\")," % np.random.choice(["FALSE", "TRUE"], p=[0.9, 0.1]))
-	print("        .RDADDRCHANGEA(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
-	print("        .RDADDRCHANGEB(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
-	print("        .SLEEP_ASYNC(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
-	print("        .RSTREG_PRIORITY_A(\"%s\")," % np.random.choice(["RSTREG", "REGCE"]))
-	print("        .RSTREG_PRIORITY_B(\"%s\")," % np.random.choice(["RSTREG", "REGCE"]))
-	for pin in ("CLKARDCLK", "CLKBWRCLK", "ENARDEN", "ENBWREN", "RSTRAMARSTRAM", "RSTRAMB", "RSTREGARSTREG", "RSTREGB"):
-		print("        .IS_%s_INVERTED(%d)," % (pin, np.random.randint(2)))
-	print("        .INIT_A({18'd%d, 18'd%d})," % (np.random.randint(2**18), np.random.randint(2**18)))
-	print("        .INIT_B({18'd%d, 18'd%d})," % (np.random.randint(2**18), np.random.randint(2**18)))
-	print("        .SRVAL_A({18'd%d, 18'd%d})," % (np.random.randint(2**18), np.random.randint(2**18)))
-	print("        .SRVAL_B({18'd%d, 18'd%d})" % (np.random.randint(2**18), np.random.randint(2**18)))
-	print("   ) ram%d (" % i)
-	print("        .DINADIN({wdata[15:0], wdata[15:0]}),")
-	print("        .DINPADINP({wdata[17:16], wdata[17:16]}),")
-	print("        .DOUTADOUT({int_d[%d][31:0]})," % i)
-	print("        .DOUTPADOUTP({int_d[%d][35:32]})," % i)
-	print("        .ADDRARDADDR(ra),")
-	print("        .CLKARDCLK(clk),")
-	print("        .ADDRENA(ena),")
-	print("        .ENARDEN(ena),")
-	print("        .REGCEAREGCE(cea),")
-	print("        .RSTRAMARSTRAM(rst),")
-	print("        .RSTREGARSTREG(rst),")
-	print("        .WEA(%s)," % ("4'b00" if write_width_a == 0 else "we[3:0]"))
-	print("        .DINBDIN({wdata[15:0], wdata[15:0]}),")
-	print("        .DINPBDINP({wdata[17:16], wdata[17:16]}),")
-	print("        .DOUTBDOUT(int_d[%d][67:36])," % i)
-	print("        .DOUTPBDOUTP(int_d[%d][71:68])," % i)
-	print("        .ADDRBWRADDR(wa),")
-	print("        .CLKBWRCLK(%s)," % ("clkb" if cd == "INDEPENDENT" else "clk"))
-	print("        .ENBWREN(enb),")
-	print("        .ADDRENB(enb),")
-	print("        .REGCEB(ceb),")
-	print("        .RSTRAMB(rst),")
-	print("        .RSTREGB(rst),")
-	print("        .WEBWE(%s)" % ("4'b00" if write_width_b == 0 else ("we[7:0]" if write_width_b == 72 else "we[7:4]")))
-	print("   );")
-	print()
-print("endmodule")
\ No newline at end of file
+    print("    RAMB36E2 #(")
+    print("        .CLOCK_DOMAINS(\"%s\")," % cd)
+    print("        .READ_WIDTH_A(%d)," % read_width_a)
+    print("        .READ_WIDTH_B(%d)," % read_width_b)
+    print("        .WRITE_WIDTH_A(%d)," % write_width_a)
+    print("        .WRITE_WIDTH_B(%d)," % write_width_b)
+    print("        .WRITE_MODE_A(\"%s\")," % np.random.choice(
+        ["NO_CHANGE", "READ_FIRST", "WRITE_FIRST"]))
+    print("        .WRITE_MODE_B(\"%s\")," % np.random.choice(
+        ["NO_CHANGE", "READ_FIRST", "WRITE_FIRST"]))
+    print("        .CASCADE_ORDER_A(\"%s\")," % np.random.choice(
+        ["NONE", "FIRST", "MIDDLE", "LAST"]))
+    print("        .CASCADE_ORDER_B(\"%s\")," % np.random.choice(
+        ["NONE", "FIRST", "MIDDLE", "LAST"]))
+    print(
+        "        .DOA_REG(%d)," % (0 if
+                                   (write_width_b == 72 or read_width_a == 72)
+                                   else np.random.randint(2)))
+    print(
+        "        .DOB_REG(%d)," % (0 if
+                                   (write_width_b == 72 or read_width_a == 72)
+                                   else np.random.randint(2)))
+    print("        .ENADDRENA(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
+    print("        .ENADDRENB(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
+    print("        .EN_ECC_PIPE(\"%s\")," % np.random.choice(["FALSE", "TRUE"],
+                                                             p=[0.9, 0.1]))
+    print("        .EN_ECC_READ(\"%s\")," % np.random.choice(["FALSE", "TRUE"],
+                                                             p=[0.9, 0.1]))
+    print("        .EN_ECC_WRITE(\"%s\")," % np.random.choice(
+        ["FALSE", "TRUE"], p=[0.9, 0.1]))
+    print("        .RDADDRCHANGEA(\"%s\")," % np.random.choice(
+        ["FALSE", "TRUE"]))
+    print("        .RDADDRCHANGEB(\"%s\")," % np.random.choice(
+        ["FALSE", "TRUE"]))
+    print(
+        "        .SLEEP_ASYNC(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
+    print("        .RSTREG_PRIORITY_A(\"%s\")," % np.random.choice(
+        ["RSTREG", "REGCE"]))
+    print("        .RSTREG_PRIORITY_B(\"%s\")," % np.random.choice(
+        ["RSTREG", "REGCE"]))
+    for pin in ("CLKARDCLK", "CLKBWRCLK", "ENARDEN", "ENBWREN",
+                "RSTRAMARSTRAM", "RSTRAMB", "RSTREGARSTREG", "RSTREGB"):
+        print("        .IS_%s_INVERTED(%d)," % (pin, np.random.randint(2)))
+    print("        .INIT_A({18'd%d, 18'd%d})," % (np.random.randint(2**18),
+                                                  np.random.randint(2**18)))
+    print("        .INIT_B({18'd%d, 18'd%d})," % (np.random.randint(2**18),
+                                                  np.random.randint(2**18)))
+    print("        .SRVAL_A({18'd%d, 18'd%d})," % (np.random.randint(2**18),
+                                                   np.random.randint(2**18)))
+    print("        .SRVAL_B({18'd%d, 18'd%d})" % (np.random.randint(2**18),
+                                                  np.random.randint(2**18)))
+    print("   ) ram%d (" % i)
+    print("        .DINADIN({wdata[15:0], wdata[15:0]}),")
+    print("        .DINPADINP({wdata[17:16], wdata[17:16]}),")
+    print("        .DOUTADOUT({int_d[%d][31:0]})," % i)
+    print("        .DOUTPADOUTP({int_d[%d][35:32]})," % i)
+    print("        .ADDRARDADDR(ra),")
+    print("        .CLKARDCLK(clk),")
+    print("        .ADDRENA(ena),")
+    print("        .ENARDEN(ena),")
+    print("        .REGCEAREGCE(cea),")
+    print("        .RSTRAMARSTRAM(rst),")
+    print("        .RSTREGARSTREG(rst),")
+    print("        .WEA(%s)," % ("4'b00" if write_width_a == 0 else "we[3:0]"))
+    print("        .DINBDIN({wdata[15:0], wdata[15:0]}),")
+    print("        .DINPBDINP({wdata[17:16], wdata[17:16]}),")
+    print("        .DOUTBDOUT(int_d[%d][67:36])," % i)
+    print("        .DOUTPBDOUTP(int_d[%d][71:68])," % i)
+    print("        .ADDRBWRADDR(wa),")
+    print(
+        "        .CLKBWRCLK(%s)," % ("clkb" if cd == "INDEPENDENT" else "clk"))
+    print("        .ENBWREN(enb),")
+    print("        .ADDRENB(enb),")
+    print("        .REGCEB(ceb),")
+    print("        .RSTRAMB(rst),")
+    print("        .RSTREGB(rst),")
+    print("        .WEBWE(%s)" %
+          ("4'b00" if write_width_b == 0 else
+           ("we[7:0]" if write_width_b == 72 else "we[7:4]")))
+    print("   );")
+    print()
+print("endmodule")
diff --git a/spec/bram36_sdp_2.py b/spec/bram36_sdp_2.py
index b415899..0e8b252 100644
--- a/spec/bram36_sdp_2.py
+++ b/spec/bram36_sdp_2.py
@@ -16,76 +16,114 @@
 import sys
 import math
 
-print("module top(input clk, clkb, rst, ena, enb, cea, ceb, input [14:0] ra, wa, input [7:0] we, input [17:0] wdata, input [10:0] sel, output [35:0] rdata);")
+print(
+    "module top(input clk, clkb, rst, ena, enb, cea, ceb, input [14:0] ra, wa, input [7:0] we, input [17:0] wdata, input [10:0] sel, output [35:0] rdata);"
+)
 N = 300
 print("    wire [71:0] int_d[0:%d-1];" % N)
 print("    assign rdata = int_d[sel[10:2]][18 * sel[1:0] +: 18];")
 for i in range(N):
-	write_width_b = np.random.choice([0, 1, 2, 4, 9, 18, 36, 72])
-	read_width_a = np.random.choice([0, 1, 2, 4, 9, 18, 36, 72], p=[0.05, 0.1, 0.1, 0.1, 0.05, 0.05, 0.45, 0.1])
-	write_width_a = 0 if (write_width_b == 72 or read_width_a == 72) else np.random.choice([0, 1, 2, 4, 9, 18, 36])
-	read_width_b = 0 if (write_width_b == 72 or read_width_a == 72) else np.random.choice([0, 1, 2, 4, 9, 18, 36], p=[0.05, 0.1, 0.1, 0.1, 0.1, 0.1, 0.45])
-	cd = np.random.choice(["INDEPENDENT", "COMMON"])
+    write_width_b = np.random.choice([0, 1, 2, 4, 9, 18, 36, 72])
+    read_width_a = np.random.choice(
+        [0, 1, 2, 4, 9, 18, 36, 72],
+        p=[0.05, 0.1, 0.1, 0.1, 0.05, 0.05, 0.45, 0.1])
+    write_width_a = 0 if (write_width_b == 72
+                          or read_width_a == 72) else np.random.choice(
+                              [0, 1, 2, 4, 9, 18, 36])
+    read_width_b = 0 if (
+        write_width_b == 72 or read_width_a == 72) else np.random.choice(
+            [0, 1, 2, 4, 9, 18, 36], p=[0.05, 0.1, 0.1, 0.1, 0.1, 0.1, 0.45])
+    cd = np.random.choice(["INDEPENDENT", "COMMON"])
 
-	print("    RAMB36E2 #(")
-	print("        .CLOCK_DOMAINS(\"%s\")," % cd)
-	print("        .READ_WIDTH_A(%d)," % read_width_a)
-	print("        .READ_WIDTH_B(%d)," % read_width_b)
-	print("        .WRITE_WIDTH_A(%d)," % write_width_a)
-	print("        .WRITE_WIDTH_B(%d)," % write_width_b)
-	print("        .WRITE_MODE_A(\"%s\")," % np.random.choice(["NO_CHANGE", "READ_FIRST", "WRITE_FIRST"]))
-	print("        .WRITE_MODE_B(\"%s\")," % np.random.choice(["NO_CHANGE", "READ_FIRST", "WRITE_FIRST"]))
-	print("        .CASCADE_ORDER_A(\"%s\")," % np.random.choice(["NONE", "FIRST", "MIDDLE", "LAST"]))
-	print("        .CASCADE_ORDER_B(\"%s\")," % np.random.choice(["NONE", "FIRST", "MIDDLE", "LAST"]))
-	print("        .DOA_REG(%d)," % (0 if (write_width_b == 72 or read_width_a == 72) else np.random.randint(2)))
-	print("        .DOB_REG(%d)," % (0 if (write_width_b == 72 or read_width_a == 72) else np.random.randint(2)))
-	print("        .ENADDRENA(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
-	print("        .ENADDRENB(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
-	print("        .EN_ECC_PIPE(\"%s\")," % np.random.choice(["FALSE", "TRUE"], p=[0.9, 0.1]))
-	print("        .EN_ECC_READ(\"%s\")," % np.random.choice(["FALSE", "TRUE"], p=[0.9, 0.1]))
-	print("        .EN_ECC_WRITE(\"%s\")," % np.random.choice(["FALSE", "TRUE"], p=[0.9, 0.1]))
-	print("        .RDADDRCHANGEA(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
-	print("        .RDADDRCHANGEB(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
-	print("        .SLEEP_ASYNC(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
-	print("        .RSTREG_PRIORITY_A(\"%s\")," % np.random.choice(["RSTREG", "REGCE"]))
-	print("        .RSTREG_PRIORITY_B(\"%s\")," % np.random.choice(["RSTREG", "REGCE"]))
-	for pin in ("CLKARDCLK", "CLKBWRCLK", "ENARDEN", "ENBWREN", "RSTRAMARSTRAM", "RSTRAMB", "RSTREGARSTREG", "RSTREGB"):
-		print("        .IS_%s_INVERTED(%d)," % (pin, np.random.randint(2)))
-	print("        .INIT_A({18'd%d, 18'd%d})," % (np.random.randint(2**18), np.random.randint(2**18)))
-	print("        .INIT_B({18'd%d, 18'd%d})," % (np.random.randint(2**18), np.random.randint(2**18)))
-	print("        .SRVAL_A({18'd%d, 18'd%d})," % (np.random.randint(2**18), np.random.randint(2**18)))
-	print("        .SRVAL_B({18'd%d, 18'd%d})" % (np.random.randint(2**18), np.random.randint(2**18)))
-	print("   ) ram%d (" % i)
-	print("        .DINADIN({wdata[15:0], wdata[15:0]}),")
-	print("        .DINPADINP({wdata[17:16], wdata[17:16]}),")
-	douta_bit = np.random.randint(-1, 37)
-	if douta_bit >= 0 and douta_bit < 32:	
-		print("        .DOUTADOUT({int_d[%d][0]%s})," % (i, ", {%d{1'bx}}" % douta_bit if douta_bit > 0 else ""))
-	if douta_bit >= 32:
-		print("        .DOUTPADOUTP({int_d[%d][32]%s})," % (i, ", {%d{1'bx}}" % (douta_bit - 32) if douta_bit > 32 else ""))
-	print("        .ADDRARDADDR(ra),")
-	print("        .CLKARDCLK(clk),")
-	print("        .ADDRENA(ena),")
-	print("        .ENARDEN(ena),")
-	print("        .REGCEAREGCE(cea),")
-	print("        .RSTRAMARSTRAM(rst),")
-	print("        .RSTREGARSTREG(rst),")
-	print("        .WEA(%s)," % ("4'b00" if write_width_a == 0 else "we[3:0]"))
-	print("        .DINBDIN({wdata[15:0], wdata[15:0]}),")
-	print("        .DINPBDINP({wdata[17:16], wdata[17:16]}),")
-	doutb_bit = np.random.randint(-1, 37)
-	if doutb_bit >= 0 and doutb_bit < 32:	
-		print("        .DOUTBDOUT({int_d[%d][36]%s})," % (i, ", {%d{1'bx}}" % doutb_bit if doutb_bit > 0 else ""))
-	if doutb_bit >= 32:
-		print("        .DOUTPBDOUTP({int_d[%d][68]%s})," % (i, ", {%d{1'bx}}" % (doutb_bit - 32) if doutb_bit > 32 else ""))
-	print("        .ADDRBWRADDR(wa),")
-	print("        .CLKBWRCLK(%s)," % ("clkb" if cd == "INDEPENDENT" else "clk"))
-	print("        .ENBWREN(enb),")
-	print("        .ADDRENB(enb),")
-	print("        .REGCEB(ceb),")
-	print("        .RSTRAMB(rst),")
-	print("        .RSTREGB(rst),")
-	print("        .WEBWE(%s)" % ("4'b00" if write_width_b == 0 else ("we[7:0]" if write_width_b == 72 else "we[7:4]")))
-	print("   );")
-	print()
-print("endmodule")
\ No newline at end of file
+    print("    RAMB36E2 #(")
+    print("        .CLOCK_DOMAINS(\"%s\")," % cd)
+    print("        .READ_WIDTH_A(%d)," % read_width_a)
+    print("        .READ_WIDTH_B(%d)," % read_width_b)
+    print("        .WRITE_WIDTH_A(%d)," % write_width_a)
+    print("        .WRITE_WIDTH_B(%d)," % write_width_b)
+    print("        .WRITE_MODE_A(\"%s\")," % np.random.choice(
+        ["NO_CHANGE", "READ_FIRST", "WRITE_FIRST"]))
+    print("        .WRITE_MODE_B(\"%s\")," % np.random.choice(
+        ["NO_CHANGE", "READ_FIRST", "WRITE_FIRST"]))
+    print("        .CASCADE_ORDER_A(\"%s\")," % np.random.choice(
+        ["NONE", "FIRST", "MIDDLE", "LAST"]))
+    print("        .CASCADE_ORDER_B(\"%s\")," % np.random.choice(
+        ["NONE", "FIRST", "MIDDLE", "LAST"]))
+    print(
+        "        .DOA_REG(%d)," % (0 if
+                                   (write_width_b == 72 or read_width_a == 72)
+                                   else np.random.randint(2)))
+    print(
+        "        .DOB_REG(%d)," % (0 if
+                                   (write_width_b == 72 or read_width_a == 72)
+                                   else np.random.randint(2)))
+    print("        .ENADDRENA(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
+    print("        .ENADDRENB(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
+    print("        .EN_ECC_PIPE(\"%s\")," % np.random.choice(["FALSE", "TRUE"],
+                                                             p=[0.9, 0.1]))
+    print("        .EN_ECC_READ(\"%s\")," % np.random.choice(["FALSE", "TRUE"],
+                                                             p=[0.9, 0.1]))
+    print("        .EN_ECC_WRITE(\"%s\")," % np.random.choice(
+        ["FALSE", "TRUE"], p=[0.9, 0.1]))
+    print("        .RDADDRCHANGEA(\"%s\")," % np.random.choice(
+        ["FALSE", "TRUE"]))
+    print("        .RDADDRCHANGEB(\"%s\")," % np.random.choice(
+        ["FALSE", "TRUE"]))
+    print(
+        "        .SLEEP_ASYNC(\"%s\")," % np.random.choice(["FALSE", "TRUE"]))
+    print("        .RSTREG_PRIORITY_A(\"%s\")," % np.random.choice(
+        ["RSTREG", "REGCE"]))
+    print("        .RSTREG_PRIORITY_B(\"%s\")," % np.random.choice(
+        ["RSTREG", "REGCE"]))
+    for pin in ("CLKARDCLK", "CLKBWRCLK", "ENARDEN", "ENBWREN",
+                "RSTRAMARSTRAM", "RSTRAMB", "RSTREGARSTREG", "RSTREGB"):
+        print("        .IS_%s_INVERTED(%d)," % (pin, np.random.randint(2)))
+    print("        .INIT_A({18'd%d, 18'd%d})," % (np.random.randint(2**18),
+                                                  np.random.randint(2**18)))
+    print("        .INIT_B({18'd%d, 18'd%d})," % (np.random.randint(2**18),
+                                                  np.random.randint(2**18)))
+    print("        .SRVAL_A({18'd%d, 18'd%d})," % (np.random.randint(2**18),
+                                                   np.random.randint(2**18)))
+    print("        .SRVAL_B({18'd%d, 18'd%d})" % (np.random.randint(2**18),
+                                                  np.random.randint(2**18)))
+    print("   ) ram%d (" % i)
+    print("        .DINADIN({wdata[15:0], wdata[15:0]}),")
+    print("        .DINPADINP({wdata[17:16], wdata[17:16]}),")
+    douta_bit = np.random.randint(-1, 37)
+    if douta_bit >= 0 and douta_bit < 32:
+        print("        .DOUTADOUT({int_d[%d][0]%s})," %
+              (i, ", {%d{1'bx}}" % douta_bit if douta_bit > 0 else ""))
+    if douta_bit >= 32:
+        print("        .DOUTPADOUTP({int_d[%d][32]%s})," %
+              (i, ", {%d{1'bx}}" % (douta_bit - 32) if douta_bit > 32 else ""))
+    print("        .ADDRARDADDR(ra),")
+    print("        .CLKARDCLK(clk),")
+    print("        .ADDRENA(ena),")
+    print("        .ENARDEN(ena),")
+    print("        .REGCEAREGCE(cea),")
+    print("        .RSTRAMARSTRAM(rst),")
+    print("        .RSTREGARSTREG(rst),")
+    print("        .WEA(%s)," % ("4'b00" if write_width_a == 0 else "we[3:0]"))
+    print("        .DINBDIN({wdata[15:0], wdata[15:0]}),")
+    print("        .DINPBDINP({wdata[17:16], wdata[17:16]}),")
+    doutb_bit = np.random.randint(-1, 37)
+    if doutb_bit >= 0 and doutb_bit < 32:
+        print("        .DOUTBDOUT({int_d[%d][36]%s})," %
+              (i, ", {%d{1'bx}}" % doutb_bit if doutb_bit > 0 else ""))
+    if doutb_bit >= 32:
+        print("        .DOUTPBDOUTP({int_d[%d][68]%s})," %
+              (i, ", {%d{1'bx}}" % (doutb_bit - 32) if doutb_bit > 32 else ""))
+    print("        .ADDRBWRADDR(wa),")
+    print(
+        "        .CLKBWRCLK(%s)," % ("clkb" if cd == "INDEPENDENT" else "clk"))
+    print("        .ENBWREN(enb),")
+    print("        .ADDRENB(enb),")
+    print("        .REGCEB(ceb),")
+    print("        .RSTRAMB(rst),")
+    print("        .RSTREGB(rst),")
+    print("        .WEBWE(%s)" %
+          ("4'b00" if write_width_b == 0 else
+           ("we[7:0]" if write_width_b == 72 else "we[7:4]")))
+    print("   );")
+    print()
+print("endmodule")
diff --git a/spec/dsp.py b/spec/dsp.py
index d550444..e56c8b0 100644
--- a/spec/dsp.py
+++ b/spec/dsp.py
@@ -20,133 +20,228 @@
 
 root = sys.argv[2]
 
+
 def random_vector(size):
-	return "{%s}" % ", ".join(["d[%d]" % np.random.randint(40) for k in range(size)])
+    return "{%s}" % ", ".join(
+        ["d[%d]" % np.random.randint(40) for k in range(size)])
+
 
 for x in range(X):
 
-
-	with open(root + "/dsp1/dsp%d.v" % x, "w") as f:
-		print("module top(input [7:0] clk, cen, rst, input [39:0] d, input [7:0] sel, output [63:0] q);", file=f)
-		print("    wire [8:0] r = {1'b0, rst}, e = {1'b1, cen};", file=f)
-		print("    wire [63:0] int_q[0:%d];" % (N-1), file=f)
-		print("    assign q = int_q[sel];", file=f)
-		for i in range(N):
-			use_preadd = np.random.choice([False, True])
-			bmultsel = (np.random.choice(["AD", "B"]) if use_preadd else "B")
-			amultsel = (np.random.choice(["AD", "A"]) if use_preadd and bmultsel == "AD" else ("AD" if use_preadd else "A"))
-			use_patdet = np.random.choice([False, True])
-			print("    DSP48E2 #(", file=f)
-			print("        .ADREG(%d)," % (np.random.randint(2) if use_preadd else 0), file=f)
-			print("        .ALUMODEREG(%d)," % np.random.randint(2), file=f)
-			print("        .AMULTSEL(\"%s\")," % amultsel, file=f)
-			print("        .AREG(%d)," % np.random.randint(3), file=f)
-			print("        .AUTORESET_PATDET(\"%s\")," % np.random.choice(["NO_RESET", "RESET_MATCH", "RESET_NOT_MATCH"]), file=f)
-			print("        .AUTORESET_PRIORITY(\"%s\")," % np.random.choice(["RESET", "CEP"]), file=f)
-			print("        .A_INPUT(\"DIRECT\"),", file=f)
-			print("        .BMULTSEL(\"%s\")," % bmultsel,file=f)
-			print("        .BREG(%d)," % np.random.randint(3), file=f)
-			print("        .B_INPUT(\"DIRECT\"),", file=f)
-			print("        .CARRYINREG(%d)," % np.random.randint(2), file=f)
-			print("        .CARRYINSELREG(%d)," % np.random.randint(2), file=f)
-			print("        .CREG(%d)," % np.random.randint(2), file=f)
-			print("        .DREG(%d)," % np.random.randint(2), file=f)
-			print("        .INMODEREG(%d)," % np.random.randint(2), file=f)
-			print("        .IS_ALUMODE_INVERTED(%d)," % np.random.randint(16), file=f)
-			print("        .IS_CARRYIN_INVERTED(%d)," % np.random.randint(2), file=f)
-			print("        .IS_CLK_INVERTED(%d)," % np.random.randint(2), file=f)
-			print("        .IS_INMODE_INVERTED(%d)," % np.random.randint(32), file=f)
-			print("        .IS_OPMODE_INVERTED(%d)," % np.random.randint(512), file=f)
-			print("        .IS_RSTALLCARRYIN_INVERTED(%d)," % np.random.randint(2), file=f)
-			print("        .IS_RSTALUMODE_INVERTED(%d)," % np.random.randint(2), file=f)
-			print("        .IS_RSTA_INVERTED(%d)," % np.random.randint(2), file=f)
-			print("        .IS_RSTB_INVERTED(%d)," % np.random.randint(2), file=f)
-			print("        .IS_RSTCTRL_INVERTED(%d)," % np.random.randint(2), file=f)
-			print("        .IS_RSTC_INVERTED(%d)," % np.random.randint(2), file=f)
-			print("        .IS_RSTD_INVERTED(%d)," % np.random.randint(2), file=f)
-			print("        .IS_RSTINMODE_INVERTED(%d)," % np.random.randint(2), file=f)
-			print("        .IS_RSTM_INVERTED(%d)," % np.random.randint(2), file=f)
-			print("        .IS_RSTP_INVERTED(%d)," % np.random.randint(2), file=f)
-			print("        .MASK({24'd%d, 24'd%d})," % (np.random.randint(2**24), np.random.randint(2**24)), file=f)
-			print("        .MREG(%d)," % np.random.randint(2), file=f)
-			print("        .OPMODEREG(%d)," % np.random.randint(2), file=f)
-			print("        .PATTERN({24'd%d, 24'd%d})," % (np.random.randint(2**24), np.random.randint(2**24)), file=f)
-			print("        .PREADDINSEL(\"%s\")," % np.random.choice(["A", "B"]), file=f)
-			print("        .PREG(%d)," % np.random.randint(2), file=f)
-			print("        .RND({24'd%d, 24'd%d})," % (np.random.randint(2**24), np.random.randint(2**24)), file=f)
-			print("        .SEL_MASK(\"%s\")," % np.random.choice(["MASK", "C", "ROUNDING_MODE1", "ROUNDING_MODE2"]), file=f)
-			print("        .SEL_PATTERN(\"%s\")," % np.random.choice(["PATTERN", "C"]), file=f)
-			print("        .USE_PATTERN_DETECT(\"%s\")," % ("PATDET" if use_patdet else "NO_PATDET"), file=f)
-			print("        .USE_SIMD(\"%s\")," %  np.random.choice(["ONE48", "TWO24", "FOUR12"]), file=f)
-			print("        .USE_WIDEXOR(\"%s\")," %  np.random.choice(["TRUE", "FALSE"]), file=f)
-			print("        .XORSIMD(\"%s\")" %  np.random.choice(["XOR12", "XOR24_48_96"]), file=f)
-			print("    ) dsp_%d (" % i, file=f)
-			print("        .A(%s)," % random_vector(30), file=f)
-			print("        .ALUMODE(%s)," % random_vector(4), file=f)
-			print("        .B(%s)," % random_vector(18), file=f)
-			print("        .C(%s)," % random_vector(48), file=f)
-			print("        .CARRYIN(%s)," % random_vector(1), file=f)
-			print("        .CEA1(e[%d])," % np.random.randint(9), file=f)
-			print("        .CEA2(e[%d])," % np.random.randint(9), file=f)
-			print("        .CEAD(e[%d])," % np.random.randint(9), file=f)
-			print("        .CEALUMODE(e[%d])," % np.random.randint(9), file=f)
-			print("        .CEC(e[%d])," % np.random.randint(9), file=f)
-			print("        .CECARRYIN(e[%d])," % np.random.randint(9), file=f)
-			print("        .CECTRL(e[%d])," % np.random.randint(9), file=f)
-			print("        .CED(e[%d])," % np.random.randint(9), file=f)
-			print("        .CEINMODE(e[%d])," % np.random.randint(9), file=f)
-			print("        .CEM(e[%d])," % np.random.randint(9), file=f)
-			print("        .CEP(e[%d])," % np.random.randint(9), file=f)
-			print("        .CLK(clk[%d])," % np.random.randint(8), file=f)
-			print("        .D(%s)," % random_vector(27), file=f)
-			print("        .INMODE(%s)," % random_vector(5), file=f)
-			print("        .OPMODE(%s)," % random_vector(9), file=f)
-			print("        .RSTA(r[%d])," % np.random.randint(9), file=f)
-			print("        .RSTALLCARRYIN(r[%d])," % np.random.randint(9), file=f)
-			print("        .RSTALUMODE(r[%d])," % np.random.randint(9), file=f)
-			print("        .RSTB(r[%d])," % np.random.randint(9), file=f)
-			print("        .RSTC(r[%d])," % np.random.randint(9), file=f)
-			print("        .RSTCTRL(r[%d])," % np.random.randint(9), file=f)
-			print("        .RSTD(r[%d])," % np.random.randint(9), file=f)
-			print("        .RSTINMODE(r[%d])," % np.random.randint(9), file=f)
-			print("        .RSTM(r[%d])," % np.random.randint(9), file=f)
-			print("        .RSTP(r[%d])," % np.random.randint(9), file=f)
-			print("        .P(int_q[%d][47:0])," % i, file=f)
-			print("        .CARRYOUT(int_q[%d][51:48])," % i, file=f)
-			print("        .XOROUT(int_q[%d][59:52])," % i, file=f)
-			print("        .PATTERNDETECT(int_q[%d][60])," % i, file=f)
-			print("        .PATTERNBDETECT(int_q[%d][61])," % i, file=f)
-			print("        .OVERFLOW(int_q[%d][62])," % i, file=f)
-			print("        .UNDERFLOW(int_q[%d][63])" % i, file=f)
-			print("    );", file=f)
-			print("", file=f)
-		print("endmodule", file=f)
-	with open(root + "/dsp1/dsp%d.tcl" % x, "w") as f:
-		print("add_files %s" % (root + ("/dsp1/dsp%d.v" % x)), file=f)
-		print("synth_design -top top -part xczu7ev-ffvc1156-2-e", file=f)
-		print("opt_design", file=f)
-		print("place_design", file=f)
-		print("route_design", file=f)
-		print("set_property SEVERITY {Warning} [get_drc_checks NSTD-1]", file=f)
-		print("set_property SEVERITY {Warning} [get_drc_checks UCIO-1]", file=f)
-		print("set_property SEVERITY {Warning} [get_drc_checks AVAL-*]", file=f)
-		print("set_property SEVERITY {Warning} [get_drc_checks REQP-*]", file=f)
-		print("set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design]", file=f)
-		print("write_checkpoint -force %s/specimen_bram/dsp%d.dcp" % (root, x), file=f)
-		print("write_edif -force %s/specimen_bram/dsp%d.edf" % (root, x), file=f)
-		print("write_bitstream -force %s/specimen_bram/dsp%d.bit" % (root, x), file=f)
+    with open(root + "/dsp1/dsp%d.v" % x, "w") as f:
+        print(
+            "module top(input [7:0] clk, cen, rst, input [39:0] d, input [7:0] sel, output [63:0] q);",
+            file=f)
+        print("    wire [8:0] r = {1'b0, rst}, e = {1'b1, cen};", file=f)
+        print("    wire [63:0] int_q[0:%d];" % (N - 1), file=f)
+        print("    assign q = int_q[sel];", file=f)
+        for i in range(N):
+            use_preadd = np.random.choice([False, True])
+            bmultsel = (np.random.choice(["AD", "B"]) if use_preadd else "B")
+            amultsel = (np.random.choice(["AD", "A"])
+                        if use_preadd and bmultsel == "AD" else
+                        ("AD" if use_preadd else "A"))
+            use_patdet = np.random.choice([False, True])
+            print("    DSP48E2 #(", file=f)
+            print(
+                "        .ADREG(%d)," %
+                (np.random.randint(2) if use_preadd else 0),
+                file=f)
+            print("        .ALUMODEREG(%d)," % np.random.randint(2), file=f)
+            print("        .AMULTSEL(\"%s\")," % amultsel, file=f)
+            print("        .AREG(%d)," % np.random.randint(3), file=f)
+            print(
+                "        .AUTORESET_PATDET(\"%s\")," % np.random.choice(
+                    ["NO_RESET", "RESET_MATCH", "RESET_NOT_MATCH"]),
+                file=f)
+            print(
+                "        .AUTORESET_PRIORITY(\"%s\")," % np.random.choice(
+                    ["RESET", "CEP"]),
+                file=f)
+            print("        .A_INPUT(\"DIRECT\"),", file=f)
+            print("        .BMULTSEL(\"%s\")," % bmultsel, file=f)
+            print("        .BREG(%d)," % np.random.randint(3), file=f)
+            print("        .B_INPUT(\"DIRECT\"),", file=f)
+            print("        .CARRYINREG(%d)," % np.random.randint(2), file=f)
+            print("        .CARRYINSELREG(%d)," % np.random.randint(2), file=f)
+            print("        .CREG(%d)," % np.random.randint(2), file=f)
+            print("        .DREG(%d)," % np.random.randint(2), file=f)
+            print("        .INMODEREG(%d)," % np.random.randint(2), file=f)
+            print(
+                "        .IS_ALUMODE_INVERTED(%d)," % np.random.randint(16),
+                file=f)
+            print(
+                "        .IS_CARRYIN_INVERTED(%d)," % np.random.randint(2),
+                file=f)
+            print(
+                "        .IS_CLK_INVERTED(%d)," % np.random.randint(2), file=f)
+            print(
+                "        .IS_INMODE_INVERTED(%d)," % np.random.randint(32),
+                file=f)
+            print(
+                "        .IS_OPMODE_INVERTED(%d)," % np.random.randint(512),
+                file=f)
+            print(
+                "        .IS_RSTALLCARRYIN_INVERTED(%d)," %
+                np.random.randint(2),
+                file=f)
+            print(
+                "        .IS_RSTALUMODE_INVERTED(%d)," % np.random.randint(2),
+                file=f)
+            print(
+                "        .IS_RSTA_INVERTED(%d)," % np.random.randint(2),
+                file=f)
+            print(
+                "        .IS_RSTB_INVERTED(%d)," % np.random.randint(2),
+                file=f)
+            print(
+                "        .IS_RSTCTRL_INVERTED(%d)," % np.random.randint(2),
+                file=f)
+            print(
+                "        .IS_RSTC_INVERTED(%d)," % np.random.randint(2),
+                file=f)
+            print(
+                "        .IS_RSTD_INVERTED(%d)," % np.random.randint(2),
+                file=f)
+            print(
+                "        .IS_RSTINMODE_INVERTED(%d)," % np.random.randint(2),
+                file=f)
+            print(
+                "        .IS_RSTM_INVERTED(%d)," % np.random.randint(2),
+                file=f)
+            print(
+                "        .IS_RSTP_INVERTED(%d)," % np.random.randint(2),
+                file=f)
+            print(
+                "        .MASK({24'd%d, 24'd%d})," % (np.random.randint(
+                    2**24), np.random.randint(2**24)),
+                file=f)
+            print("        .MREG(%d)," % np.random.randint(2), file=f)
+            print("        .OPMODEREG(%d)," % np.random.randint(2), file=f)
+            print(
+                "        .PATTERN({24'd%d, 24'd%d})," % (np.random.randint(
+                    2**24), np.random.randint(2**24)),
+                file=f)
+            print(
+                "        .PREADDINSEL(\"%s\")," % np.random.choice(["A", "B"]),
+                file=f)
+            print("        .PREG(%d)," % np.random.randint(2), file=f)
+            print(
+                "        .RND({24'd%d, 24'd%d})," % (np.random.randint(2**24),
+                                                     np.random.randint(2**24)),
+                file=f)
+            print(
+                "        .SEL_MASK(\"%s\")," % np.random.choice(
+                    ["MASK", "C", "ROUNDING_MODE1", "ROUNDING_MODE2"]),
+                file=f)
+            print(
+                "        .SEL_PATTERN(\"%s\")," % np.random.choice(
+                    ["PATTERN", "C"]),
+                file=f)
+            print(
+                "        .USE_PATTERN_DETECT(\"%s\")," %
+                ("PATDET" if use_patdet else "NO_PATDET"),
+                file=f)
+            print(
+                "        .USE_SIMD(\"%s\")," % np.random.choice(
+                    ["ONE48", "TWO24", "FOUR12"]),
+                file=f)
+            print(
+                "        .USE_WIDEXOR(\"%s\")," % np.random.choice(
+                    ["TRUE", "FALSE"]),
+                file=f)
+            print(
+                "        .XORSIMD(\"%s\")" % np.random.choice(
+                    ["XOR12", "XOR24_48_96"]),
+                file=f)
+            print("    ) dsp_%d (" % i, file=f)
+            print("        .A(%s)," % random_vector(30), file=f)
+            print("        .ALUMODE(%s)," % random_vector(4), file=f)
+            print("        .B(%s)," % random_vector(18), file=f)
+            print("        .C(%s)," % random_vector(48), file=f)
+            print("        .CARRYIN(%s)," % random_vector(1), file=f)
+            print("        .CEA1(e[%d])," % np.random.randint(9), file=f)
+            print("        .CEA2(e[%d])," % np.random.randint(9), file=f)
+            print("        .CEAD(e[%d])," % np.random.randint(9), file=f)
+            print("        .CEALUMODE(e[%d])," % np.random.randint(9), file=f)
+            print("        .CEC(e[%d])," % np.random.randint(9), file=f)
+            print("        .CECARRYIN(e[%d])," % np.random.randint(9), file=f)
+            print("        .CECTRL(e[%d])," % np.random.randint(9), file=f)
+            print("        .CED(e[%d])," % np.random.randint(9), file=f)
+            print("        .CEINMODE(e[%d])," % np.random.randint(9), file=f)
+            print("        .CEM(e[%d])," % np.random.randint(9), file=f)
+            print("        .CEP(e[%d])," % np.random.randint(9), file=f)
+            print("        .CLK(clk[%d])," % np.random.randint(8), file=f)
+            print("        .D(%s)," % random_vector(27), file=f)
+            print("        .INMODE(%s)," % random_vector(5), file=f)
+            print("        .OPMODE(%s)," % random_vector(9), file=f)
+            print("        .RSTA(r[%d])," % np.random.randint(9), file=f)
+            print(
+                "        .RSTALLCARRYIN(r[%d])," % np.random.randint(9),
+                file=f)
+            print("        .RSTALUMODE(r[%d])," % np.random.randint(9), file=f)
+            print("        .RSTB(r[%d])," % np.random.randint(9), file=f)
+            print("        .RSTC(r[%d])," % np.random.randint(9), file=f)
+            print("        .RSTCTRL(r[%d])," % np.random.randint(9), file=f)
+            print("        .RSTD(r[%d])," % np.random.randint(9), file=f)
+            print("        .RSTINMODE(r[%d])," % np.random.randint(9), file=f)
+            print("        .RSTM(r[%d])," % np.random.randint(9), file=f)
+            print("        .RSTP(r[%d])," % np.random.randint(9), file=f)
+            print("        .P(int_q[%d][47:0])," % i, file=f)
+            print("        .CARRYOUT(int_q[%d][51:48])," % i, file=f)
+            print("        .XOROUT(int_q[%d][59:52])," % i, file=f)
+            print("        .PATTERNDETECT(int_q[%d][60])," % i, file=f)
+            print("        .PATTERNBDETECT(int_q[%d][61])," % i, file=f)
+            print("        .OVERFLOW(int_q[%d][62])," % i, file=f)
+            print("        .UNDERFLOW(int_q[%d][63])" % i, file=f)
+            print("    );", file=f)
+            print("", file=f)
+        print("endmodule", file=f)
+    with open(root + "/dsp1/dsp%d.tcl" % x, "w") as f:
+        print("add_files %s" % (root + ("/dsp1/dsp%d.v" % x)), file=f)
+        print("synth_design -top top -part xczu7ev-ffvc1156-2-e", file=f)
+        print("opt_design", file=f)
+        print("place_design", file=f)
+        print("route_design", file=f)
+        print(
+            "set_property SEVERITY {Warning} [get_drc_checks NSTD-1]", file=f)
+        print(
+            "set_property SEVERITY {Warning} [get_drc_checks UCIO-1]", file=f)
+        print(
+            "set_property SEVERITY {Warning} [get_drc_checks AVAL-*]", file=f)
+        print(
+            "set_property SEVERITY {Warning} [get_drc_checks REQP-*]", file=f)
+        print(
+            "set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design]",
+            file=f)
+        print(
+            "write_checkpoint -force %s/specimen_bram/dsp%d.dcp" % (root, x),
+            file=f)
+        print(
+            "write_edif -force %s/specimen_bram/dsp%d.edf" % (root, x), file=f)
+        print(
+            "write_bitstream -force %s/specimen_bram/dsp%d.bit" % (root, x),
+            file=f)
 with open(root + "/dsp1/run.sh", "w") as f:
-	print("#/usr/bin/env bash", file=f)
-	#print("set -ex", file=f)
-	for x in range(X):
-		print("vivado -mode batch -nolog -nojournal -source dsp%d.tcl" % x, file=f)
-		print("if [ $? -eq 0 ]; then", file=f)
-		print("    ../../ultra/tools/dump_bitstream %s/specimen_bram/dsp%d.bit %s/frames.txt > %s/specimen_bram/dsp%d.dump" % (root, x, root, root, x), file=f)
-		print("    python3 ../../ultra/tools/bits_to_tiles.py %s/tile.json %s/specimen_bram/dsp%d.dump > %s/specimen_bram/dsp%d.tbits" % (root, root, x, root, x), file=f)
-		print("else", file=f)
-		print("   rm %s/specimen_bram/dsp%d.dump" % (root, x), file=f)
-		print("   rm %s/specimen_bram/dsp%d.tbits" % (root, x), file=f)
-		print("   rm %s/specimen_bram/dsp%d.dcp" % (root, x), file=f)
-		print("   rm %s/specimen_bram/dsp%d.bit" % (root, x), file=f)
-		print("   rm %s/specimen_bram/dsp%d.features" % (root, x), file=f)
-		print("fi", file=f)
\ No newline at end of file
+    print("#/usr/bin/env bash", file=f)
+    #print("set -ex", file=f)
+    for x in range(X):
+        print(
+            "vivado -mode batch -nolog -nojournal -source dsp%d.tcl" % x,
+            file=f)
+        print("if [ $? -eq 0 ]; then", file=f)
+        print(
+            "    ../../ultra/tools/dump_bitstream %s/specimen_bram/dsp%d.bit %s/frames.txt > %s/specimen_bram/dsp%d.dump"
+            % (root, x, root, root, x),
+            file=f)
+        print(
+            "    python3 ../../ultra/tools/bits_to_tiles.py %s/tile.json %s/specimen_bram/dsp%d.dump > %s/specimen_bram/dsp%d.tbits"
+            % (root, root, x, root, x),
+            file=f)
+        print("else", file=f)
+        print("   rm %s/specimen_bram/dsp%d.dump" % (root, x), file=f)
+        print("   rm %s/specimen_bram/dsp%d.tbits" % (root, x), file=f)
+        print("   rm %s/specimen_bram/dsp%d.dcp" % (root, x), file=f)
+        print("   rm %s/specimen_bram/dsp%d.bit" % (root, x), file=f)
+        print("   rm %s/specimen_bram/dsp%d.features" % (root, x), file=f)
+        print("fi", file=f)
diff --git a/spec/dsp_2.py b/spec/dsp_2.py
index 2392de2..b0b914b 100644
--- a/spec/dsp_2.py
+++ b/spec/dsp_2.py
@@ -20,141 +20,246 @@
 
 root = sys.argv[2]
 
+
 def random_vector(size):
-	return "{%s}" % ", ".join(["d[%d]" % np.random.randint(12) for k in range(size)])
+    return "{%s}" % ", ".join(
+        ["d[%d]" % np.random.randint(12) for k in range(size)])
+
 
 for x in range(X):
 
-
-	with open(root + "/dsp2/dsp_b%d.v" % x, "w") as f:
-		print("module top(input [7:0] clk, cen, rst, input [11:0] d, input [7:0] sel, output [63:0] q);", file=f)
-		print("    wire [8:0] r = {1'b0, rst}, e = {1'b1, cen};", file=f)
-		print("    wire [63:0] int_q[0:%d];" % (N-1), file=f)
-		print("    assign q = int_q[sel];", file=f)
-		for i in range(N):
-			use_preadd = np.random.choice([False, True])
-			bmultsel = (np.random.choice(["AD", "B"]) if use_preadd else "B")
-			amultsel = (np.random.choice(["AD", "A"]) if use_preadd and bmultsel == "AD" else ("AD" if use_preadd else "A"))
-			use_patdet = np.random.choice([False, True])
-			print("    (* keep, dont_touch *) DSP48E2 #(", file=f)
-			print("        .ADREG(%d)," % (np.random.randint(2) if use_preadd else 0), file=f)
-			print("        .ALUMODEREG(%d)," % np.random.randint(2), file=f)
-			print("        .AMULTSEL(\"%s\")," % amultsel, file=f)
-			print("        .AREG(%d)," % np.random.randint(3), file=f)
-			print("        .AUTORESET_PATDET(\"%s\")," % np.random.choice(["NO_RESET", "RESET_MATCH", "RESET_NOT_MATCH"]), file=f)
-			print("        .AUTORESET_PRIORITY(\"%s\")," % np.random.choice(["RESET", "CEP"]), file=f)
-			print("        .A_INPUT(\"DIRECT\"),", file=f)
-			print("        .BMULTSEL(\"%s\")," % bmultsel,file=f)
-			print("        .BREG(%d)," % np.random.randint(3), file=f)
-			print("        .B_INPUT(\"DIRECT\"),", file=f)
-			print("        .CARRYINREG(%d)," % np.random.randint(2), file=f)
-			print("        .CARRYINSELREG(%d)," % np.random.randint(2), file=f)
-			print("        .CREG(%d)," % np.random.randint(2), file=f)
-			print("        .DREG(%d)," % np.random.randint(2), file=f)
-			print("        .INMODEREG(%d)," % np.random.randint(2), file=f)
-			print("        .IS_ALUMODE_INVERTED(%d)," % np.random.randint(16), file=f)
-			print("        .IS_CARRYIN_INVERTED(%d)," % np.random.randint(2), file=f)
-			print("        .IS_CLK_INVERTED(%d)," % np.random.randint(2), file=f)
-			print("        .IS_INMODE_INVERTED(%d)," % np.random.randint(32), file=f)
-			print("        .IS_OPMODE_INVERTED(%d)," % np.random.randint(512), file=f)
-			print("        .IS_RSTALLCARRYIN_INVERTED(%d)," % np.random.randint(2), file=f)
-			print("        .IS_RSTALUMODE_INVERTED(%d)," % np.random.randint(2), file=f)
-			print("        .IS_RSTA_INVERTED(%d)," % np.random.randint(2), file=f)
-			print("        .IS_RSTB_INVERTED(%d)," % np.random.randint(2), file=f)
-			print("        .IS_RSTCTRL_INVERTED(%d)," % np.random.randint(2), file=f)
-			print("        .IS_RSTC_INVERTED(%d)," % np.random.randint(2), file=f)
-			print("        .IS_RSTD_INVERTED(%d)," % np.random.randint(2), file=f)
-			print("        .IS_RSTINMODE_INVERTED(%d)," % np.random.randint(2), file=f)
-			print("        .IS_RSTM_INVERTED(%d)," % np.random.randint(2), file=f)
-			print("        .IS_RSTP_INVERTED(%d)," % np.random.randint(2), file=f)
-			print("        .MASK({24'd%d, 24'd%d})," % (np.random.randint(2**24), np.random.randint(2**24)), file=f)
-			print("        .MREG(%d)," % np.random.randint(2), file=f)
-			print("        .OPMODEREG(%d)," % np.random.randint(2), file=f)
-			print("        .PATTERN({24'd%d, 24'd%d})," % (np.random.randint(2**24), np.random.randint(2**24)), file=f)
-			print("        .PREADDINSEL(\"%s\")," % np.random.choice(["A", "B"]), file=f)
-			print("        .PREG(%d)," % np.random.randint(2), file=f)
-			print("        .RND({24'd%d, 24'd%d})," % (np.random.randint(2**24), np.random.randint(2**24)), file=f)
-			print("        .SEL_MASK(\"%s\")," % np.random.choice(["MASK", "C", "ROUNDING_MODE1", "ROUNDING_MODE2"]), file=f)
-			print("        .SEL_PATTERN(\"%s\")," % np.random.choice(["PATTERN", "C"]), file=f)
-			print("        .USE_PATTERN_DETECT(\"%s\")," % ("PATDET" if use_patdet else "NO_PATDET"), file=f)
-			print("        .USE_SIMD(\"%s\")," %  np.random.choice(["ONE48", "TWO24", "FOUR12"]), file=f)
-			print("        .USE_WIDEXOR(\"%s\")," %  np.random.choice(["TRUE", "FALSE"]), file=f)
-			print("        .XORSIMD(\"%s\")" %  np.random.choice(["XOR12", "XOR24_48_96"]), file=f)
-			print("    ) dsp_%d (" % i, file=f)
-			print("        .A(%s)," % random_vector(30), file=f)
-			print("        .ALUMODE(%s)," % random_vector(4), file=f)
-			print("        .B(%s)," % random_vector(18), file=f)
-			#print("        .C(%s)," % random_vector(48), file=f)
-			print("        .CARRYIN(%s)," % random_vector(1), file=f)
-			print("        .CEA1(e[%d])," % np.random.randint(9), file=f)
-			print("        .CEA2(e[%d])," % np.random.randint(9), file=f)
-			print("        .CEAD(e[%d])," % np.random.randint(9), file=f)
-			print("        .CEALUMODE(e[%d])," % np.random.randint(9), file=f)
-			print("        .CEC(e[%d])," % np.random.randint(9), file=f)
-			print("        .CECARRYIN(e[%d])," % np.random.randint(9), file=f)
-			print("        .CECTRL(e[%d])," % np.random.randint(9), file=f)
-			print("        .CED(e[%d])," % np.random.randint(9), file=f)
-			print("        .CEINMODE(e[%d])," % np.random.randint(9), file=f)
-			print("        .CEM(e[%d])," % np.random.randint(9), file=f)
-			print("        .CEP(e[%d])," % np.random.randint(9), file=f)
-			#print("        .D(%s)," % random_vector(27), file=f)
-			print("        .INMODE(%s)," % random_vector(5), file=f)
-			print("        .OPMODE(%s)," % random_vector(9), file=f)
-			print("        .RSTA(r[%d])," % np.random.randint(9), file=f)
-			print("        .RSTALLCARRYIN(r[%d])," % np.random.randint(9), file=f)
-			print("        .RSTALUMODE(r[%d])," % np.random.randint(9), file=f)
-			print("        .RSTB(r[%d])," % np.random.randint(9), file=f)
-			print("        .RSTC(r[%d])," % np.random.randint(9), file=f)
-			print("        .RSTCTRL(r[%d])," % np.random.randint(9), file=f)
-			print("        .RSTD(r[%d])," % np.random.randint(9), file=f)
-			print("        .RSTINMODE(r[%d])," % np.random.randint(9), file=f)
-			print("        .RSTM(r[%d])," % np.random.randint(9), file=f)
-			print("        .RSTP(r[%d])," % np.random.randint(9), file=f)
-			o_bit = np.random.randint(-1, 64)
-			if o_bit >= 0 and o_bit < 48:
-				print("        .P({int_q[%d][0]%s})," % (i, ", {%d{1'bx}}" % o_bit if o_bit > 0 else ""), file=f)
-			if o_bit >= 48 and o_bit < 52:
-				print("        .CARRYOUT({int_q[%d][48]%s})," % (i, ", {%d{1'bx}}" % (o_bit-48) if o_bit > 48 else ""), file=f)
-			if o_bit >= 52 and o_bit < 60:
-				print("        .XOROUT({int_q[%d][52]%s})," % (i, ", {%d{1'bx}}" % (o_bit-52) if o_bit > 52 else ""), file=f)
-			if o_bit == 60:
-				print("        .PATTERNDETECT(int_q[%d][60])," % i, file=f)
-			if o_bit == 61:
-				print("        .PATTERNBDETECT(int_q[%d][61])," % i, file=f)
-			if o_bit == 62:
-				print("        .OVERFLOW(int_q[%d][62])," % i, file=f)
-			if o_bit == 63:
-				print("        .UNDERFLOW(int_q[%d][63])," % i, file=f)
-			print("        .CLK(clk[%d])" % np.random.randint(8), file=f)
-			print("    );", file=f)
-			print("", file=f)
-		print("endmodule", file=f)
-	with open(root + "/dsp2/dsp_b%d.tcl" % x, "w") as f:
-		print("add_files %s" % (root + ("/dsp2/dsp_b%d.v" % x)), file=f)
-		print("synth_design -top top -part xczu7ev-ffvc1156-2-e", file=f)
-		print("opt_design", file=f)
-		print("place_design", file=f)
-		print("route_design", file=f)
-		print("set_property SEVERITY {Warning} [get_drc_checks NSTD-1]", file=f)
-		print("set_property SEVERITY {Warning} [get_drc_checks UCIO-1]", file=f)
-		print("set_property SEVERITY {Warning} [get_drc_checks AVAL-*]", file=f)
-		print("set_property SEVERITY {Warning} [get_drc_checks REQP-*]", file=f)
-		print("set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design]", file=f)
-		print("write_checkpoint -force %s/specimen_bram/dsp_b%d.dcp" % (root, x), file=f)
-		print("write_edif -force %s/specimen_bram/dsp_b%d.edf" % (root, x), file=f)
-		print("write_bitstream -force %s/specimen_bram/dsp_b%d.bit" % (root, x), file=f)
+    with open(root + "/dsp2/dsp_b%d.v" % x, "w") as f:
+        print(
+            "module top(input [7:0] clk, cen, rst, input [11:0] d, input [7:0] sel, output [63:0] q);",
+            file=f)
+        print("    wire [8:0] r = {1'b0, rst}, e = {1'b1, cen};", file=f)
+        print("    wire [63:0] int_q[0:%d];" % (N - 1), file=f)
+        print("    assign q = int_q[sel];", file=f)
+        for i in range(N):
+            use_preadd = np.random.choice([False, True])
+            bmultsel = (np.random.choice(["AD", "B"]) if use_preadd else "B")
+            amultsel = (np.random.choice(["AD", "A"])
+                        if use_preadd and bmultsel == "AD" else
+                        ("AD" if use_preadd else "A"))
+            use_patdet = np.random.choice([False, True])
+            print("    (* keep, dont_touch *) DSP48E2 #(", file=f)
+            print(
+                "        .ADREG(%d)," %
+                (np.random.randint(2) if use_preadd else 0),
+                file=f)
+            print("        .ALUMODEREG(%d)," % np.random.randint(2), file=f)
+            print("        .AMULTSEL(\"%s\")," % amultsel, file=f)
+            print("        .AREG(%d)," % np.random.randint(3), file=f)
+            print(
+                "        .AUTORESET_PATDET(\"%s\")," % np.random.choice(
+                    ["NO_RESET", "RESET_MATCH", "RESET_NOT_MATCH"]),
+                file=f)
+            print(
+                "        .AUTORESET_PRIORITY(\"%s\")," % np.random.choice(
+                    ["RESET", "CEP"]),
+                file=f)
+            print("        .A_INPUT(\"DIRECT\"),", file=f)
+            print("        .BMULTSEL(\"%s\")," % bmultsel, file=f)
+            print("        .BREG(%d)," % np.random.randint(3), file=f)
+            print("        .B_INPUT(\"DIRECT\"),", file=f)
+            print("        .CARRYINREG(%d)," % np.random.randint(2), file=f)
+            print("        .CARRYINSELREG(%d)," % np.random.randint(2), file=f)
+            print("        .CREG(%d)," % np.random.randint(2), file=f)
+            print("        .DREG(%d)," % np.random.randint(2), file=f)
+            print("        .INMODEREG(%d)," % np.random.randint(2), file=f)
+            print(
+                "        .IS_ALUMODE_INVERTED(%d)," % np.random.randint(16),
+                file=f)
+            print(
+                "        .IS_CARRYIN_INVERTED(%d)," % np.random.randint(2),
+                file=f)
+            print(
+                "        .IS_CLK_INVERTED(%d)," % np.random.randint(2), file=f)
+            print(
+                "        .IS_INMODE_INVERTED(%d)," % np.random.randint(32),
+                file=f)
+            print(
+                "        .IS_OPMODE_INVERTED(%d)," % np.random.randint(512),
+                file=f)
+            print(
+                "        .IS_RSTALLCARRYIN_INVERTED(%d)," %
+                np.random.randint(2),
+                file=f)
+            print(
+                "        .IS_RSTALUMODE_INVERTED(%d)," % np.random.randint(2),
+                file=f)
+            print(
+                "        .IS_RSTA_INVERTED(%d)," % np.random.randint(2),
+                file=f)
+            print(
+                "        .IS_RSTB_INVERTED(%d)," % np.random.randint(2),
+                file=f)
+            print(
+                "        .IS_RSTCTRL_INVERTED(%d)," % np.random.randint(2),
+                file=f)
+            print(
+                "        .IS_RSTC_INVERTED(%d)," % np.random.randint(2),
+                file=f)
+            print(
+                "        .IS_RSTD_INVERTED(%d)," % np.random.randint(2),
+                file=f)
+            print(
+                "        .IS_RSTINMODE_INVERTED(%d)," % np.random.randint(2),
+                file=f)
+            print(
+                "        .IS_RSTM_INVERTED(%d)," % np.random.randint(2),
+                file=f)
+            print(
+                "        .IS_RSTP_INVERTED(%d)," % np.random.randint(2),
+                file=f)
+            print(
+                "        .MASK({24'd%d, 24'd%d})," % (np.random.randint(
+                    2**24), np.random.randint(2**24)),
+                file=f)
+            print("        .MREG(%d)," % np.random.randint(2), file=f)
+            print("        .OPMODEREG(%d)," % np.random.randint(2), file=f)
+            print(
+                "        .PATTERN({24'd%d, 24'd%d})," % (np.random.randint(
+                    2**24), np.random.randint(2**24)),
+                file=f)
+            print(
+                "        .PREADDINSEL(\"%s\")," % np.random.choice(["A", "B"]),
+                file=f)
+            print("        .PREG(%d)," % np.random.randint(2), file=f)
+            print(
+                "        .RND({24'd%d, 24'd%d})," % (np.random.randint(2**24),
+                                                     np.random.randint(2**24)),
+                file=f)
+            print(
+                "        .SEL_MASK(\"%s\")," % np.random.choice(
+                    ["MASK", "C", "ROUNDING_MODE1", "ROUNDING_MODE2"]),
+                file=f)
+            print(
+                "        .SEL_PATTERN(\"%s\")," % np.random.choice(
+                    ["PATTERN", "C"]),
+                file=f)
+            print(
+                "        .USE_PATTERN_DETECT(\"%s\")," %
+                ("PATDET" if use_patdet else "NO_PATDET"),
+                file=f)
+            print(
+                "        .USE_SIMD(\"%s\")," % np.random.choice(
+                    ["ONE48", "TWO24", "FOUR12"]),
+                file=f)
+            print(
+                "        .USE_WIDEXOR(\"%s\")," % np.random.choice(
+                    ["TRUE", "FALSE"]),
+                file=f)
+            print(
+                "        .XORSIMD(\"%s\")" % np.random.choice(
+                    ["XOR12", "XOR24_48_96"]),
+                file=f)
+            print("    ) dsp_%d (" % i, file=f)
+            print("        .A(%s)," % random_vector(30), file=f)
+            print("        .ALUMODE(%s)," % random_vector(4), file=f)
+            print("        .B(%s)," % random_vector(18), file=f)
+            #print("        .C(%s)," % random_vector(48), file=f)
+            print("        .CARRYIN(%s)," % random_vector(1), file=f)
+            print("        .CEA1(e[%d])," % np.random.randint(9), file=f)
+            print("        .CEA2(e[%d])," % np.random.randint(9), file=f)
+            print("        .CEAD(e[%d])," % np.random.randint(9), file=f)
+            print("        .CEALUMODE(e[%d])," % np.random.randint(9), file=f)
+            print("        .CEC(e[%d])," % np.random.randint(9), file=f)
+            print("        .CECARRYIN(e[%d])," % np.random.randint(9), file=f)
+            print("        .CECTRL(e[%d])," % np.random.randint(9), file=f)
+            print("        .CED(e[%d])," % np.random.randint(9), file=f)
+            print("        .CEINMODE(e[%d])," % np.random.randint(9), file=f)
+            print("        .CEM(e[%d])," % np.random.randint(9), file=f)
+            print("        .CEP(e[%d])," % np.random.randint(9), file=f)
+            #print("        .D(%s)," % random_vector(27), file=f)
+            print("        .INMODE(%s)," % random_vector(5), file=f)
+            print("        .OPMODE(%s)," % random_vector(9), file=f)
+            print("        .RSTA(r[%d])," % np.random.randint(9), file=f)
+            print(
+                "        .RSTALLCARRYIN(r[%d])," % np.random.randint(9),
+                file=f)
+            print("        .RSTALUMODE(r[%d])," % np.random.randint(9), file=f)
+            print("        .RSTB(r[%d])," % np.random.randint(9), file=f)
+            print("        .RSTC(r[%d])," % np.random.randint(9), file=f)
+            print("        .RSTCTRL(r[%d])," % np.random.randint(9), file=f)
+            print("        .RSTD(r[%d])," % np.random.randint(9), file=f)
+            print("        .RSTINMODE(r[%d])," % np.random.randint(9), file=f)
+            print("        .RSTM(r[%d])," % np.random.randint(9), file=f)
+            print("        .RSTP(r[%d])," % np.random.randint(9), file=f)
+            o_bit = np.random.randint(-1, 64)
+            if o_bit >= 0 and o_bit < 48:
+                print(
+                    "        .P({int_q[%d][0]%s})," %
+                    (i, ", {%d{1'bx}}" % o_bit if o_bit > 0 else ""),
+                    file=f)
+            if o_bit >= 48 and o_bit < 52:
+                print(
+                    "        .CARRYOUT({int_q[%d][48]%s})," %
+                    (i, ", {%d{1'bx}}" % (o_bit - 48) if o_bit > 48 else ""),
+                    file=f)
+            if o_bit >= 52 and o_bit < 60:
+                print(
+                    "        .XOROUT({int_q[%d][52]%s})," %
+                    (i, ", {%d{1'bx}}" % (o_bit - 52) if o_bit > 52 else ""),
+                    file=f)
+            if o_bit == 60:
+                print("        .PATTERNDETECT(int_q[%d][60])," % i, file=f)
+            if o_bit == 61:
+                print("        .PATTERNBDETECT(int_q[%d][61])," % i, file=f)
+            if o_bit == 62:
+                print("        .OVERFLOW(int_q[%d][62])," % i, file=f)
+            if o_bit == 63:
+                print("        .UNDERFLOW(int_q[%d][63])," % i, file=f)
+            print("        .CLK(clk[%d])" % np.random.randint(8), file=f)
+            print("    );", file=f)
+            print("", file=f)
+        print("endmodule", file=f)
+    with open(root + "/dsp2/dsp_b%d.tcl" % x, "w") as f:
+        print("add_files %s" % (root + ("/dsp2/dsp_b%d.v" % x)), file=f)
+        print("synth_design -top top -part xczu7ev-ffvc1156-2-e", file=f)
+        print("opt_design", file=f)
+        print("place_design", file=f)
+        print("route_design", file=f)
+        print(
+            "set_property SEVERITY {Warning} [get_drc_checks NSTD-1]", file=f)
+        print(
+            "set_property SEVERITY {Warning} [get_drc_checks UCIO-1]", file=f)
+        print(
+            "set_property SEVERITY {Warning} [get_drc_checks AVAL-*]", file=f)
+        print(
+            "set_property SEVERITY {Warning} [get_drc_checks REQP-*]", file=f)
+        print(
+            "set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design]",
+            file=f)
+        print(
+            "write_checkpoint -force %s/specimen_bram/dsp_b%d.dcp" % (root, x),
+            file=f)
+        print(
+            "write_edif -force %s/specimen_bram/dsp_b%d.edf" % (root, x),
+            file=f)
+        print(
+            "write_bitstream -force %s/specimen_bram/dsp_b%d.bit" % (root, x),
+            file=f)
 with open(root + "/dsp2/run.sh", "w") as f:
-	print("#/usr/bin/env bash", file=f)
-	#print("set -ex", file=f)
-	for x in range(X):
-		print("vivado -mode batch -nolog -nojournal -source dsp_b%d.tcl" % x, file=f)
-		print("if [ $? -eq 0 ]; then", file=f)
-		print("    ../../ultra/tools/dump_bitstream %s/specimen_bram/dsp_b%d.bit %s/frames.txt > %s/specimen_bram/dsp_b%d.dump" % (root, x, root, root, x), file=f)
-		print("    python3 ../../ultra/tools/bits_to_tiles.py %s/tile.json %s/specimen_bram/dsp_b%d.dump > %s/specimen_bram/dsp_b%d.tbits" % (root, root, x, root, x), file=f)
-		print("else", file=f)
-		print("   rm %s/specimen_bram/dsp_b%d.dump" % (root, x), file=f)
-		print("   rm %s/specimen_bram/dsp_b%d.tbits" % (root, x), file=f)
-		print("   rm %s/specimen_bram/dsp_b%d.dcp" % (root, x), file=f)
-		print("   rm %s/specimen_bram/dsp_b%d.bit" % (root, x), file=f)
-		print("   rm %s/specimen_bram/dsp_b%d.features" % (root, x), file=f)
-		print("fi", file=f)
\ No newline at end of file
+    print("#/usr/bin/env bash", file=f)
+    #print("set -ex", file=f)
+    for x in range(X):
+        print(
+            "vivado -mode batch -nolog -nojournal -source dsp_b%d.tcl" % x,
+            file=f)
+        print("if [ $? -eq 0 ]; then", file=f)
+        print(
+            "    ../../ultra/tools/dump_bitstream %s/specimen_bram/dsp_b%d.bit %s/frames.txt > %s/specimen_bram/dsp_b%d.dump"
+            % (root, x, root, root, x),
+            file=f)
+        print(
+            "    python3 ../../ultra/tools/bits_to_tiles.py %s/tile.json %s/specimen_bram/dsp_b%d.dump > %s/specimen_bram/dsp_b%d.tbits"
+            % (root, root, x, root, x),
+            file=f)
+        print("else", file=f)
+        print("   rm %s/specimen_bram/dsp_b%d.dump" % (root, x), file=f)
+        print("   rm %s/specimen_bram/dsp_b%d.tbits" % (root, x), file=f)
+        print("   rm %s/specimen_bram/dsp_b%d.dcp" % (root, x), file=f)
+        print("   rm %s/specimen_bram/dsp_b%d.bit" % (root, x), file=f)
+        print("   rm %s/specimen_bram/dsp_b%d.features" % (root, x), file=f)
+        print("fi", file=f)
diff --git a/spec/flipflops.py b/spec/flipflops.py
index f9ca1dd..c1f762d 100644
--- a/spec/flipflops.py
+++ b/spec/flipflops.py
@@ -23,42 +23,49 @@
 
 slices = []
 with open(sys.argv[1], "r") as tf:
-	for line in tf:
-		sl = line.strip().split(",")
-		if len(sl) < 4:
-			continue
-		for site in sl[4:]:
-			if "SLICEM" in site or "SLICEL" in site:
-				slices.append(site.split(":")[0])
+    for line in tf:
+        sl = line.strip().split(",")
+        if len(sl) < 4:
+            continue
+        for site in sl[4:]:
+            if "SLICEM" in site or "SLICEL" in site:
+                slices.append(site.split(":")[0])
 for i in range(6, N):
-	fftype, srsig = np.random.choice(["FDPE,PRE", "FDCE,CLR", "FDSE,S", "FDRE,R"]).split(",")
-	sl = slices.pop()
-	if np.random.ranf() < 0.5:
-		data = "int_d[%d]" % i
-	else:
-		lutsize = np.random.randint(2, 10)
-		if lutsize > 6:
-			lutsize = 6
-		print ("    wire lut_q_%d;" % i)
+    fftype, srsig = np.random.choice(
+        ["FDPE,PRE", "FDCE,CLR", "FDSE,S", "FDRE,R"]).split(",")
+    sl = slices.pop()
+    if np.random.ranf() < 0.5:
+        data = "int_d[%d]" % i
+    else:
+        lutsize = np.random.randint(2, 10)
+        if lutsize > 6:
+            lutsize = 6
+        print("    wire lut_q_%d;" % i)
 
-		print("     (* BEL=\"%s%dLUT\" *) (* LOC=\"%s\" *) LUT%d #(" % (np.random.choice(list("ABCDEFGH")), np.random.randint(6 if lutsize == 6 else 5, 7), sl, lutsize))
-		print("         .INIT(%d'h%016x)" % (2 ** lutsize, np.random.randint(1, (2 ** ((2 ** lutsize) - 1) - 1))))
-		print("     ) lut_%d (" % i)
-		for j in range(lutsize):
-			print("         .I%d(int_d[%d])," % (j, i - j))
-		print("         .O(lut_q_%d)" % i)
-		print("     );")
-		data = "lut_q_%d" % i
+        print("     (* BEL=\"%s%dLUT\" *) (* LOC=\"%s\" *) LUT%d #(" %
+              (np.random.choice(list("ABCDEFGH")),
+               np.random.randint(6 if lutsize == 6 else 5, 7), sl, lutsize))
+        print("         .INIT(%d'h%016x)" %
+              (2**lutsize, np.random.randint(1, (2**((2**lutsize) - 1) - 1))))
+        print("     ) lut_%d (" % i)
+        for j in range(lutsize):
+            print("         .I%d(int_d[%d])," % (j, i - j))
+        print("         .O(lut_q_%d)" % i)
+        print("     );")
+        data = "lut_q_%d" % i
 
-	print("    (* BEL=\"%sFF%s\" *) (* LOC=\"%s\" *) %s #(" % (np.random.choice(list("ABCDEFGH")), np.random.choice(["", "2"]),  sl, fftype))
-	print("          .IS_C_INVERTED(%s)," % np.random.choice(["0", "1"]))
-	print("          .IS_%s_INVERTED(%s)," % (srsig, np.random.choice(["0", "1"])))
-	print("          .INIT(%s)" % np.random.choice(["1'b0", "1'b1"]))
-	print("     ) ff_%d (" % i)
-	print("          .C(clk[%d])," % np.random.randint(0, 16))
-	print("          .CE(cen[%d])," % np.random.randint(0, 16))
-	print("          .%s(rst[%d])," % (srsig, np.random.randint(0, 16)))
-	print("          .D(%s)," % (data))
-	print("          .Q(int_d[%d])" % (i + 1))
-	print("     );")
+    print(
+        "    (* BEL=\"%sFF%s\" *) (* LOC=\"%s\" *) %s #(" % (np.random.choice(
+            list("ABCDEFGH")), np.random.choice(["", "2"]), sl, fftype))
+    print("          .IS_C_INVERTED(%s)," % np.random.choice(["0", "1"]))
+    print("          .IS_%s_INVERTED(%s)," % (srsig,
+                                              np.random.choice(["0", "1"])))
+    print("          .INIT(%s)" % np.random.choice(["1'b0", "1'b1"]))
+    print("     ) ff_%d (" % i)
+    print("          .C(clk[%d])," % np.random.randint(0, 16))
+    print("          .CE(cen[%d])," % np.random.randint(0, 16))
+    print("          .%s(rst[%d])," % (srsig, np.random.randint(0, 16)))
+    print("          .D(%s)," % (data))
+    print("          .Q(int_d[%d])" % (i + 1))
+    print("     );")
 print("endmodule")
diff --git a/spec/gclk.py b/spec/gclk.py
index e723fbe..40f9abb 100644
--- a/spec/gclk.py
+++ b/spec/gclk.py
@@ -17,13 +17,13 @@
 
 bufgces = []
 with open(sys.argv[1], "r") as tf:
-	for line in tf:
-		sl = line.strip().split(",")
-		if len(sl) < 4:
-			continue
-		for site in sl[4:]:
-			if ("BUFGCE" in site) and "HDIO" not in site and "DIV" not in site:
-				bufgces.append((site.split(":")[0], sl[2]))
+    for line in tf:
+        sl = line.strip().split(",")
+        if len(sl) < 4:
+            continue
+        for site in sl[4:]:
+            if ("BUFGCE" in site) and "HDIO" not in site and "DIV" not in site:
+                bufgces.append((site.split(":")[0], sl[2]))
 
 np.random.shuffle(bufgces)
 
@@ -33,12 +33,17 @@
 print("    assign r[0] = i;")
 print("    assign o = r[%d];" % N)
 for i in range(N):
-	bg, tile = bufgces[i]
-	print("(* LOC=\"%s\" *)" % bg)
-	if "BUFGCTRL" in bg:
-		print("    BUFGCTRL bufg_%d (.I0(r[%d]), .I1(r[%d]), .S0(1'b1), .S1(1'b0), .CE0(1'b1), .O(r[%d]));" % (i, i, i, i+1))
-	elif "DIV" in bg:
-		print("    BUFGCE_DIV #(.BUFGCE_DIVIDE(3)) bufg_%d (.I(r[%d]), .CLR(0), .CE(1'b1), .O(r[%d]));" % (i, i, i + 1))
-	else:
-		print("    BUFGCE bufg_%d (.I(r[%d]), .CE(1'b1), .O(r[%d]));" % (i, i, i+1))
-print("endmodule")
\ No newline at end of file
+    bg, tile = bufgces[i]
+    print("(* LOC=\"%s\" *)" % bg)
+    if "BUFGCTRL" in bg:
+        print(
+            "    BUFGCTRL bufg_%d (.I0(r[%d]), .I1(r[%d]), .S0(1'b1), .S1(1'b0), .CE0(1'b1), .O(r[%d]));"
+            % (i, i, i, i + 1))
+    elif "DIV" in bg:
+        print(
+            "    BUFGCE_DIV #(.BUFGCE_DIVIDE(3)) bufg_%d (.I(r[%d]), .CLR(0), .CE(1'b1), .O(r[%d]));"
+            % (i, i, i + 1))
+    else:
+        print("    BUFGCE bufg_%d (.I(r[%d]), .CE(1'b1), .O(r[%d]));" %
+              (i, i, i + 1))
+print("endmodule")
diff --git a/spec/gclk_2.py b/spec/gclk_2.py
index 0cfb058..20ad4fe 100644
--- a/spec/gclk_2.py
+++ b/spec/gclk_2.py
@@ -17,126 +17,177 @@
 
 bufgces_by_tile = {}
 with open(sys.argv[1], "r") as tf:
-	for line in tf:
-		sl = line.strip().split(",")
-		if len(sl) < 4:
-			continue
-		for site in sl[4:]:
-			if ("BUFGCE" in site or "BUFGCTRL" in site) and "HDIO" not in site:
-				if sl[2] not in bufgces_by_tile:
-					bufgces_by_tile[sl[2]] = []
-				bufgces_by_tile[sl[2]].append(site.split(":"))
+    for line in tf:
+        sl = line.strip().split(",")
+        if len(sl) < 4:
+            continue
+        for site in sl[4:]:
+            if ("BUFGCE" in site or "BUFGCTRL" in site) and "HDIO" not in site:
+                if sl[2] not in bufgces_by_tile:
+                    bufgces_by_tile[sl[2]] = []
+                bufgces_by_tile[sl[2]].append(site.split(":"))
 
 X = 64
 
 root = sys.argv[2]
 
 for x in range(X):
-	buffers = []
+    buffers = []
 
-	tiles = list(sorted(bufgces_by_tile.keys()))
-	np.random.shuffle(tiles)
+    tiles = list(sorted(bufgces_by_tile.keys()))
+    np.random.shuffle(tiles)
 
-	for tile in tiles:
-		shuffled_bufs = list(bufgces_by_tile[tile])
-		np.random.shuffle(shuffled_bufs)
-		target_type = np.random.choice(["BUFGCE", "BUFGCE_DIV", "BUFGCTRL"] if len(buffers) > 0 else ["BUFGCE", "BUFGCE_DIV"])
-		tile_buffers = np.random.randint(8)
-		found_buffers = 0
-		for buf, buftype in shuffled_bufs:
-			if found_buffers >= tile_buffers:
-				break
-			if buftype != target_type:
-				continue
-			buffers.append((buf, buftype))
-			print("%s %s" % (tile, buf))
-			found_buffers += 1
-	print()
-	def random_inversion(pins):
-		return ", ".join([".IS_%s_INVERTED(%d)" % (p, np.random.randint(2)) for p in pins])
+    for tile in tiles:
+        shuffled_bufs = list(bufgces_by_tile[tile])
+        np.random.shuffle(shuffled_bufs)
+        target_type = np.random.choice(
+            ["BUFGCE", "BUFGCE_DIV", "BUFGCTRL"]
+            if len(buffers) > 0 else ["BUFGCE", "BUFGCE_DIV"])
+        tile_buffers = np.random.randint(8)
+        found_buffers = 0
+        for buf, buftype in shuffled_bufs:
+            if found_buffers >= tile_buffers:
+                break
+            if buftype != target_type:
+                continue
+            buffers.append((buf, buftype))
+            print("%s %s" % (tile, buf))
+            found_buffers += 1
+    print()
 
-	def random_control(pins):
-		return ", ".join([".%s(aux[%d])" % (p, np.random.randint(10)) for p in pins])
+    def random_inversion(pins):
+        return ", ".join(
+            [".IS_%s_INVERTED(%d)" % (p, np.random.randint(2)) for p in pins])
 
-	with open(root + "/clkroute3/gclk%d.v" % x, "w") as f:
-		print("module top(input i, input [9:0] aux, d, output o, q);", file=f)
-		N = len(buffers)
-		print("    wire [%d:0] r;" % N, file=f)
-		print("    assign r[0] = i;", file=f)
-		print("    assign o = r[%d];" % N, file=f)
-		print("    wire [%d:0] r2;" % (2*N), file=f)
-		print("    assign r2[0] = d;", file=f)
-		print("    assign q = r2[%d];" % (2*N), file=f)
-		for i in range(N):
-			bg, buftype = buffers[i]
-			print("(* LOC=\"%s\" *)" % bg, file=f)
-			if "BUFGCTRL" in buftype:
-				print("    BUFGCTRL #(", file=f)
-				print("        %s," % random_inversion(["I0", "I1", "S0", "S1", "CE0", "CE1", "IGNORE0", "IGNORE1"]), file=f)
-				print("        .INIT_OUT(%d), .PRESELECT_I0(\"%s\"), .PRESELECT_I1(\"%s\")" %
-						(np.random.randint(2), np.random.choice(["TRUE", "FALSE"]), np.random.choice(["TRUE", "FALSE"])), file=f)
-				print("    ) bufgctrl_%d (" % i, file=f)
-				print("        .I0(r[%d]), .I1(r[%d]), " % (i, np.random.randint(i+1)), file=f)
-				print("        %s," % random_control(["S0", "S1", "CE0", "CE1", "IGNORE0", "IGNORE1"]), file=f)
-				print("        .O(r[%d])" % (i+1), file=f)
-				print("    );", file=f)
-			elif "DIV" in buftype:
-				print("    BUFGCE_DIV #(", file=f)
-				print("        .BUFGCE_DIVIDE(%d)," % np.random.randint(1, 9), file=f)
-				print("        %s" % random_inversion(["I", "CE", "CLR"]), file=f)
-				print("    ) bufgce_div_%d (" % i, file=f)
-				print("        .I(r[%d])," % i, file=f)
-				print("        %s," % random_control(["CE", "CLR"]), file=f)
-				print("        .O(r[%d])" % (i+1), file=f)
-				print("    );", file=f)
-			else:
-				print("    BUFGCE #(", file=f)
-				print("        .CE_TYPE(\"%s\")," % np.random.choice(["SYNC", "ASYNC"]), file=f)
-				print("        %s" % random_inversion(["I", "CE"]), file=f)
-				print("    ) bufgce_div_%d (" % i, file=f)
-				print("        .I(r[%d])," % i, file=f)
-				print("        %s," % random_control(["CE"]), file=f)
-				print("        .O(r[%d])" % (i+1), file=f)
-				print("    );", file=f)
+    def random_control(pins):
+        return ", ".join(
+            [".%s(aux[%d])" % (p, np.random.randint(10)) for p in pins])
 
-			if np.random.randint(2) == 1:
-				print("FDCE ff_%d(.C(r[%d]), .CE(1'b1), .CLR(1'b0), .D(r2[%d]), .Q(r2[%d]));" % (i, i, 2*i, 2*i+1), file=f)
-			else:
-				print("assign r2[%d] = r2[%d];" % (2*i+1, 2*i), file=f)
+    with open(root + "/clkroute3/gclk%d.v" % x, "w") as f:
+        print("module top(input i, input [9:0] aux, d, output o, q);", file=f)
+        N = len(buffers)
+        print("    wire [%d:0] r;" % N, file=f)
+        print("    assign r[0] = i;", file=f)
+        print("    assign o = r[%d];" % N, file=f)
+        print("    wire [%d:0] r2;" % (2 * N), file=f)
+        print("    assign r2[0] = d;", file=f)
+        print("    assign q = r2[%d];" % (2 * N), file=f)
+        for i in range(N):
+            bg, buftype = buffers[i]
+            print("(* LOC=\"%s\" *)" % bg, file=f)
+            if "BUFGCTRL" in buftype:
+                print("    BUFGCTRL #(", file=f)
+                print(
+                    "        %s," % random_inversion([
+                        "I0", "I1", "S0", "S1", "CE0", "CE1", "IGNORE0",
+                        "IGNORE1"
+                    ]),
+                    file=f)
+                print(
+                    "        .INIT_OUT(%d), .PRESELECT_I0(\"%s\"), .PRESELECT_I1(\"%s\")"
+                    % (np.random.randint(2), np.random.choice([
+                        "TRUE", "FALSE"
+                    ]), np.random.choice(["TRUE", "FALSE"])),
+                    file=f)
+                print("    ) bufgctrl_%d (" % i, file=f)
+                print(
+                    "        .I0(r[%d]), .I1(r[%d]), " %
+                    (i, np.random.randint(i + 1)),
+                    file=f)
+                print(
+                    "        %s," % random_control(
+                        ["S0", "S1", "CE0", "CE1", "IGNORE0", "IGNORE1"]),
+                    file=f)
+                print("        .O(r[%d])" % (i + 1), file=f)
+                print("    );", file=f)
+            elif "DIV" in buftype:
+                print("    BUFGCE_DIV #(", file=f)
+                print(
+                    "        .BUFGCE_DIVIDE(%d)," % np.random.randint(1, 9),
+                    file=f)
+                print(
+                    "        %s" % random_inversion(["I", "CE", "CLR"]),
+                    file=f)
+                print("    ) bufgce_div_%d (" % i, file=f)
+                print("        .I(r[%d])," % i, file=f)
+                print("        %s," % random_control(["CE", "CLR"]), file=f)
+                print("        .O(r[%d])" % (i + 1), file=f)
+                print("    );", file=f)
+            else:
+                print("    BUFGCE #(", file=f)
+                print(
+                    "        .CE_TYPE(\"%s\")," % np.random.choice(
+                        ["SYNC", "ASYNC"]),
+                    file=f)
+                print("        %s" % random_inversion(["I", "CE"]), file=f)
+                print("    ) bufgce_div_%d (" % i, file=f)
+                print("        .I(r[%d])," % i, file=f)
+                print("        %s," % random_control(["CE"]), file=f)
+                print("        .O(r[%d])" % (i + 1), file=f)
+                print("    );", file=f)
 
-			if np.random.randint(2) == 1:
-				print("SRLC32E srl_%d(.CLK(r[%d]), .CE(1'b1), .A(aux[4:0]), .D(r2[%d]), .Q(r2[%d]));" % (i, i, 2*i+1, 2*i+2), file=f)
-			else:
-				print("assign r2[%d] = r2[%d];" % (2*i+2, 2*i+1), file=f)
+            if np.random.randint(2) == 1:
+                print(
+                    "FDCE ff_%d(.C(r[%d]), .CE(1'b1), .CLR(1'b0), .D(r2[%d]), .Q(r2[%d]));"
+                    % (i, i, 2 * i, 2 * i + 1),
+                    file=f)
+            else:
+                print("assign r2[%d] = r2[%d];" % (2 * i + 1, 2 * i), file=f)
 
-			print("", file=f)
-		print("endmodule", file=f)
-	with open(root + "/clkroute3/gclk%d.tcl" % x, "w") as f:
-		print("add_files %s" % (root + ("/clkroute3/gclk%d.v" % x)), file=f)
-		#print("read_xdc %s" % (root + ("/clkroute3/gclk%d.xdc" % x)), file=f)
-		print("synth_design -top top -part xczu7ev-ffvc1156-2-e", file=f)
-		print("set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets]", file=f)
-		print("opt_design", file=f)
-		print("place_design", file=f)
-		print("route_design", file=f)
-		print("set_property SEVERITY {Warning} [get_drc_checks NSTD-1]", file=f)
-		print("set_property SEVERITY {Warning} [get_drc_checks UCIO-1]", file=f)
-		print("set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design]", file=f)
-		print("write_checkpoint -force %s/specimen_clk/gclk%d.dcp" % (root, x), file=f)
-		print("write_edif -force %s/specimen_clk/gclk%d.edf" % (root, x), file=f)
-		print("write_bitstream -force %s/specimen_clk/gclk%d.bit" % (root, x), file=f)
+            if np.random.randint(2) == 1:
+                print(
+                    "SRLC32E srl_%d(.CLK(r[%d]), .CE(1'b1), .A(aux[4:0]), .D(r2[%d]), .Q(r2[%d]));"
+                    % (i, i, 2 * i + 1, 2 * i + 2),
+                    file=f)
+            else:
+                print(
+                    "assign r2[%d] = r2[%d];" % (2 * i + 2, 2 * i + 1), file=f)
+
+            print("", file=f)
+        print("endmodule", file=f)
+    with open(root + "/clkroute3/gclk%d.tcl" % x, "w") as f:
+        print("add_files %s" % (root + ("/clkroute3/gclk%d.v" % x)), file=f)
+        #print("read_xdc %s" % (root + ("/clkroute3/gclk%d.xdc" % x)), file=f)
+        print("synth_design -top top -part xczu7ev-ffvc1156-2-e", file=f)
+        print("set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets]", file=f)
+        print("opt_design", file=f)
+        print("place_design", file=f)
+        print("route_design", file=f)
+        print(
+            "set_property SEVERITY {Warning} [get_drc_checks NSTD-1]", file=f)
+        print(
+            "set_property SEVERITY {Warning} [get_drc_checks UCIO-1]", file=f)
+        print(
+            "set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design]",
+            file=f)
+        print(
+            "write_checkpoint -force %s/specimen_clk/gclk%d.dcp" % (root, x),
+            file=f)
+        print(
+            "write_edif -force %s/specimen_clk/gclk%d.edf" % (root, x), file=f)
+        print(
+            "write_bitstream -force %s/specimen_clk/gclk%d.bit" % (root, x),
+            file=f)
 with open(root + "/clkroute3/run.sh", "w") as f:
-	print("#/usr/bin/env bash", file=f)
-	#print("set -ex", file=f)
-	for x in range(X):
-		print("vivado -mode batch -nolog -nojournal -source gclk%d.tcl" % x, file=f)
-		print("if [ $? -eq 0 ]; then", file=f)
-		print("    ../../ultra/tools/dump_bitstream %s/specimen_clk/gclk%d.bit %s/frames.txt > %s/specimen_clk/gclk%d.dump" % (root, x, root, root, x), file=f)
-		print("    python3 ../../ultra/tools/bits_to_tiles.py %s/tile.json %s/specimen_clk/gclk%d.dump > %s/specimen_clk/gclk%d.tbits" % (root, root, x, root, x), file=f)
-		print("else", file=f)
-		print("   rm %s/specimen_clk/gclk%d.dump" % (root, x), file=f)
-		print("   rm %s/specimen_clk/gclk%d.tbits" % (root, x), file=f)
-		print("   rm %s/specimen_clk/gclk%d.dcp" % (root, x), file=f)
-		print("   rm %s/specimen_clk/gclk%d.bit" % (root, x), file=f)
-		print("   rm %s/specimen_clk/gclk%d.features" % (root, x), file=f)
-		print("fi", file=f)
\ No newline at end of file
+    print("#/usr/bin/env bash", file=f)
+    #print("set -ex", file=f)
+    for x in range(X):
+        print(
+            "vivado -mode batch -nolog -nojournal -source gclk%d.tcl" % x,
+            file=f)
+        print("if [ $? -eq 0 ]; then", file=f)
+        print(
+            "    ../../ultra/tools/dump_bitstream %s/specimen_clk/gclk%d.bit %s/frames.txt > %s/specimen_clk/gclk%d.dump"
+            % (root, x, root, root, x),
+            file=f)
+        print(
+            "    python3 ../../ultra/tools/bits_to_tiles.py %s/tile.json %s/specimen_clk/gclk%d.dump > %s/specimen_clk/gclk%d.tbits"
+            % (root, root, x, root, x),
+            file=f)
+        print("else", file=f)
+        print("   rm %s/specimen_clk/gclk%d.dump" % (root, x), file=f)
+        print("   rm %s/specimen_clk/gclk%d.tbits" % (root, x), file=f)
+        print("   rm %s/specimen_clk/gclk%d.dcp" % (root, x), file=f)
+        print("   rm %s/specimen_clk/gclk%d.bit" % (root, x), file=f)
+        print("   rm %s/specimen_clk/gclk%d.features" % (root, x), file=f)
+        print("fi", file=f)
diff --git a/spec/gclk_3.py b/spec/gclk_3.py
index dfc290a..e17c40b 100644
--- a/spec/gclk_3.py
+++ b/spec/gclk_3.py
@@ -20,162 +20,193 @@
 rclk_int_l = []
 slices_by_tile = {}
 with open(sys.argv[1], "r") as tf:
-	for line in tf:
-		sl = line.strip().split(",")
-		if len(sl) < 4:
-			continue
-		tiles_by_xy[int(sl[0]), int(sl[1])] = sl[2]
-		if sl[2].startswith("RCLK_INT_L"):
-			rclk_int_l.append((int(sl[0]), int(sl[1]), sl[2]))
-		for site in sl[4:]:
-			if ("BUFGCE" in site or "BUFGCTRL" in site) and "HDIO" not in site:
-				if sl[2] not in bufgces_by_tile:
-					bufgces_by_tile[sl[2]] = []
-				bufgces_by_tile[sl[2]].append(site.split(":"))
-			elif "SLICE_" in site:
-				slices_by_tile[int(sl[0]), int(sl[1])] = site.split(":")[0]
+    for line in tf:
+        sl = line.strip().split(",")
+        if len(sl) < 4:
+            continue
+        tiles_by_xy[int(sl[0]), int(sl[1])] = sl[2]
+        if sl[2].startswith("RCLK_INT_L"):
+            rclk_int_l.append((int(sl[0]), int(sl[1]), sl[2]))
+        for site in sl[4:]:
+            if ("BUFGCE" in site or "BUFGCTRL" in site) and "HDIO" not in site:
+                if sl[2] not in bufgces_by_tile:
+                    bufgces_by_tile[sl[2]] = []
+                bufgces_by_tile[sl[2]].append(site.split(":"))
+            elif "SLICE_" in site:
+                slices_by_tile[int(sl[0]), int(sl[1])] = site.split(":")[0]
 
 halfcolumn_slices_by_row = {}
 for x, y, rclk in rclk_int_l:
-	hc_up = []
-	hc_down = []
-	if y not in halfcolumn_slices_by_row:
-		halfcolumn_slices_by_row[y] = []
-	for yplus in range(y+1, y+31):
-		if (x, yplus) not in tiles_by_xy:
-			continue
-		if not tiles_by_xy[x, yplus].startswith("INT_"):
-			break
-		slice_x = x + np.random.choice([+1, -1])
-		if (slice_x, yplus) not in slices_by_tile:
-			continue
-		hc_up.append(slices_by_tile[slice_x, yplus])
-	for yminus in range(y-1, y-31, -1):
-		if (x, yminus) not in tiles_by_xy:
-			continue
-		if not tiles_by_xy[x, yminus].startswith("INT_"):
-			break
-		slice_x = x + np.random.choice([+1, -1])
-		if (slice_x, yminus) not in slices_by_tile:
-			continue
-		hc_down.append(slices_by_tile[slice_x, yminus])
-	halfcolumn_slices_by_row[y].append(hc_up)
-	halfcolumn_slices_by_row[y].append(hc_down)
+    hc_up = []
+    hc_down = []
+    if y not in halfcolumn_slices_by_row:
+        halfcolumn_slices_by_row[y] = []
+    for yplus in range(y + 1, y + 31):
+        if (x, yplus) not in tiles_by_xy:
+            continue
+        if not tiles_by_xy[x, yplus].startswith("INT_"):
+            break
+        slice_x = x + np.random.choice([+1, -1])
+        if (slice_x, yplus) not in slices_by_tile:
+            continue
+        hc_up.append(slices_by_tile[slice_x, yplus])
+    for yminus in range(y - 1, y - 31, -1):
+        if (x, yminus) not in tiles_by_xy:
+            continue
+        if not tiles_by_xy[x, yminus].startswith("INT_"):
+            break
+        slice_x = x + np.random.choice([+1, -1])
+        if (slice_x, yminus) not in slices_by_tile:
+            continue
+        hc_down.append(slices_by_tile[slice_x, yminus])
+    halfcolumn_slices_by_row[y].append(hc_up)
+    halfcolumn_slices_by_row[y].append(hc_down)
 
 X = 32
 
 root = sys.argv[2]
 
 for x in range(X):
-	buffers = []
+    buffers = []
 
-	tiles = list(sorted(bufgces_by_tile.keys()))
-	np.random.shuffle(tiles)
+    tiles = list(sorted(bufgces_by_tile.keys()))
+    np.random.shuffle(tiles)
 
-	for tile in tiles:
-		shuffled_bufs = list(bufgces_by_tile[tile])
-		np.random.shuffle(shuffled_bufs)
-		target_type = np.random.choice(["BUFGCE", "BUFGCE_DIV", "BUFGCTRL"] if len(buffers) > 0 else ["BUFGCE", "BUFGCE_DIV"])
-		tile_buffers = np.random.randint(6)
-		found_buffers = 0
-		for buf, buftype in shuffled_bufs:
-			if found_buffers >= tile_buffers:
-				break
-			if buftype != target_type:
-				continue
-			buffers.append((buf, buftype))
-			print("%s %s" % (tile, buf))
-			found_buffers += 1
-	
-	def random_inversion(pins):
-		return ", ".join([".IS_%s_INVERTED(%d)" % (p, np.random.randint(2)) for p in pins])
+    for tile in tiles:
+        shuffled_bufs = list(bufgces_by_tile[tile])
+        np.random.shuffle(shuffled_bufs)
+        target_type = np.random.choice(
+            ["BUFGCE", "BUFGCE_DIV", "BUFGCTRL"]
+            if len(buffers) > 0 else ["BUFGCE", "BUFGCE_DIV"])
+        tile_buffers = np.random.randint(6)
+        found_buffers = 0
+        for buf, buftype in shuffled_bufs:
+            if found_buffers >= tile_buffers:
+                break
+            if buftype != target_type:
+                continue
+            buffers.append((buf, buftype))
+            print("%s %s" % (tile, buf))
+            found_buffers += 1
 
-	def random_control(pins):
-		return ", ".join([".%s(aux[%d])" % (p, np.random.randint(10)) for p in pins])
+    def random_inversion(pins):
+        return ", ".join(
+            [".IS_%s_INVERTED(%d)" % (p, np.random.randint(2)) for p in pins])
 
-	with open(root + "/clkroute4/gclkb_%d.v" % x, "w") as f:
-		print("module top(input [23:0] i, input [9:0] aux, input d, output o, q);", file=f)
-		N = 24
-		print("    wire [71:0] r;", file=f)
-		# print("    assign r[0] = i;", file=f)
-		# print("    assign o = r[%d];" % N, file=f)
-		# for i in range(N):
-		# 	bg, buftype = buffers[i]
-		# 	#print("(* LOC=\"%s\" *)" % bg, file=f)
-		# 	if "BUFGCTRL" in buftype:
-		# 		print("    BUFGCTRL #(", file=f)
-		# 		print("        %s," % random_inversion(["I0", "I1", "S0", "S1", "CE0", "CE1", "IGNORE0", "IGNORE1"]), file=f)
-		# 		print("        .INIT_OUT(%d), .PRESELECT_I0(\"%s\"), .PRESELECT_I1(\"%s\")" %
-		# 				(np.random.randint(2), np.random.choice(["TRUE", "FALSE"]), np.random.choice(["TRUE", "FALSE"])), file=f)
-		# 		print("    ) bufgctrl_%d (" % i, file=f)
-		# 		print("        .I0(r[%d]), .I1(r[%d]), " % (i, np.random.randint(i+1)), file=f)
-		# 		print("        %s," % random_control(["S0", "S1", "CE0", "CE1", "IGNORE0", "IGNORE1"]), file=f)
-		# 		print("        .O(r[%d])" % (i+1), file=f)
-		# 		print("    );", file=f)
-		print("    assign r[23:0] = i;", file=f)
-		for i in range(12):
-			print("    BUFGCE_DIV #(", file=f)
-			print("        .BUFGCE_DIVIDE(%d)," % np.random.randint(1, 9), file=f)
-			print("        %s" % random_inversion(["I", "CE", "CLR"]), file=f)
-			print("    ) bufgce_div_%d (" % i, file=f)
-			print("        .I(i[%d])," % i, file=f)
-			print("        %s," % random_control(["CE", "CLR"]), file=f)
-			print("        .O(r[%d])" % (24+i), file=f)
-			print("    );", file=f)
-		for i in range(36):
-			print("    BUFGCE #(", file=f)
-			print("        .CE_TYPE(\"%s\")," % np.random.choice(["SYNC", "ASYNC"]), file=f)
-			print("        %s" % random_inversion(["I", "CE"]), file=f)
-			print("    ) bufgce_%d (" % i, file=f)
-			print("        .I(i[%d])," %  np.random.randint(24), file=f)
-			print("        %s," % random_control(["CE"]), file=f)
-			print("        .O(r[%d])" % (i+36), file=f)
-			print("    );", file=f)
+    def random_control(pins):
+        return ", ".join(
+            [".%s(aux[%d])" % (p, np.random.randint(10)) for p in pins])
 
-		R2=0
-		NS=16
-		ffs=""
-		for row, hcs in sorted(halfcolumn_slices_by_row.items()):
-			row_clks = np.random.randint(16, 25)
-			clks = [np.random.randint(72) for k in range(row_clks)]
-			halfs = [hcs[np.random.randint(len(hcs))] for k in range(NS)]
-			for h in halfs:
-				half_clks = np.random.randint(8, 17)
-				rclks = [np.random.choice(clks) for k in range(half_clks)]
-				for sl in h:
-					ffs += "(* LOC=\"%s\" *) FDCE ff_%d (.C(r[%d]), .CE(aux[%d]), .CLR(1'b0), .D(r2[%d]), .Q(r2[%d]));\n" % (sl, R2, np.random.choice(rclks), np.random.randint(10), R2, R2+1)
-					R2 += 1
-		print("    wire [%d:0] r2;" % R2, file=f)
-		print("    assign r2[0] = d;", file=f)
-		print("    assign q = r2[%d];" % R2, file=f)
-		print(ffs, file=f)
-		print("endmodule", file=f)
-	with open(root + "/clkroute4/gclkb_%d.tcl" % x, "w") as f:
-		print("add_files %s" % (root + ("/clkroute4/gclkb_%d.v" % x)), file=f)
-		#print("read_xdc %s" % (root + ("/clkroute4/gclkb_%d.xdc" % x)), file=f)
-		print("synth_design -top top -part xczu7ev-ffvc1156-2-e", file=f)
-		print("# set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets]", file=f)
-		print("opt_design", file=f)
-		print("place_design", file=f)
-		print("route_design", file=f)
-		print("set_property SEVERITY {Warning} [get_drc_checks NSTD-1]", file=f)
-		print("set_property SEVERITY {Warning} [get_drc_checks UCIO-1]", file=f)
-		print("set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design]", file=f)
-		print("write_checkpoint -force %s/specimen_clk/gclkb_%d.dcp" % (root, x), file=f)
-		print("write_edif -force %s/specimen_clk/gclkb_%d.edf" % (root, x), file=f)
-		print("write_bitstream -force %s/specimen_clk/gclkb_%d.bit" % (root, x), file=f)
+    with open(root + "/clkroute4/gclkb_%d.v" % x, "w") as f:
+        print(
+            "module top(input [23:0] i, input [9:0] aux, input d, output o, q);",
+            file=f)
+        N = 24
+        print("    wire [71:0] r;", file=f)
+        # print("    assign r[0] = i;", file=f)
+        # print("    assign o = r[%d];" % N, file=f)
+        # for i in range(N):
+        # 	bg, buftype = buffers[i]
+        # 	#print("(* LOC=\"%s\" *)" % bg, file=f)
+        # 	if "BUFGCTRL" in buftype:
+        # 		print("    BUFGCTRL #(", file=f)
+        # 		print("        %s," % random_inversion(["I0", "I1", "S0", "S1", "CE0", "CE1", "IGNORE0", "IGNORE1"]), file=f)
+        # 		print("        .INIT_OUT(%d), .PRESELECT_I0(\"%s\"), .PRESELECT_I1(\"%s\")" %
+        # 				(np.random.randint(2), np.random.choice(["TRUE", "FALSE"]), np.random.choice(["TRUE", "FALSE"])), file=f)
+        # 		print("    ) bufgctrl_%d (" % i, file=f)
+        # 		print("        .I0(r[%d]), .I1(r[%d]), " % (i, np.random.randint(i+1)), file=f)
+        # 		print("        %s," % random_control(["S0", "S1", "CE0", "CE1", "IGNORE0", "IGNORE1"]), file=f)
+        # 		print("        .O(r[%d])" % (i+1), file=f)
+        # 		print("    );", file=f)
+        print("    assign r[23:0] = i;", file=f)
+        for i in range(12):
+            print("    BUFGCE_DIV #(", file=f)
+            print(
+                "        .BUFGCE_DIVIDE(%d)," % np.random.randint(1, 9),
+                file=f)
+            print("        %s" % random_inversion(["I", "CE", "CLR"]), file=f)
+            print("    ) bufgce_div_%d (" % i, file=f)
+            print("        .I(i[%d])," % i, file=f)
+            print("        %s," % random_control(["CE", "CLR"]), file=f)
+            print("        .O(r[%d])" % (24 + i), file=f)
+            print("    );", file=f)
+        for i in range(36):
+            print("    BUFGCE #(", file=f)
+            print(
+                "        .CE_TYPE(\"%s\")," % np.random.choice(
+                    ["SYNC", "ASYNC"]),
+                file=f)
+            print("        %s" % random_inversion(["I", "CE"]), file=f)
+            print("    ) bufgce_%d (" % i, file=f)
+            print("        .I(i[%d])," % np.random.randint(24), file=f)
+            print("        %s," % random_control(["CE"]), file=f)
+            print("        .O(r[%d])" % (i + 36), file=f)
+            print("    );", file=f)
+
+        R2 = 0
+        NS = 16
+        ffs = ""
+        for row, hcs in sorted(halfcolumn_slices_by_row.items()):
+            row_clks = np.random.randint(16, 25)
+            clks = [np.random.randint(72) for k in range(row_clks)]
+            halfs = [hcs[np.random.randint(len(hcs))] for k in range(NS)]
+            for h in halfs:
+                half_clks = np.random.randint(8, 17)
+                rclks = [np.random.choice(clks) for k in range(half_clks)]
+                for sl in h:
+                    ffs += "(* LOC=\"%s\" *) FDCE ff_%d (.C(r[%d]), .CE(aux[%d]), .CLR(1'b0), .D(r2[%d]), .Q(r2[%d]));\n" % (
+                        sl, R2, np.random.choice(rclks), np.random.randint(10),
+                        R2, R2 + 1)
+                    R2 += 1
+        print("    wire [%d:0] r2;" % R2, file=f)
+        print("    assign r2[0] = d;", file=f)
+        print("    assign q = r2[%d];" % R2, file=f)
+        print(ffs, file=f)
+        print("endmodule", file=f)
+    with open(root + "/clkroute4/gclkb_%d.tcl" % x, "w") as f:
+        print("add_files %s" % (root + ("/clkroute4/gclkb_%d.v" % x)), file=f)
+        #print("read_xdc %s" % (root + ("/clkroute4/gclkb_%d.xdc" % x)), file=f)
+        print("synth_design -top top -part xczu7ev-ffvc1156-2-e", file=f)
+        print("# set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets]", file=f)
+        print("opt_design", file=f)
+        print("place_design", file=f)
+        print("route_design", file=f)
+        print(
+            "set_property SEVERITY {Warning} [get_drc_checks NSTD-1]", file=f)
+        print(
+            "set_property SEVERITY {Warning} [get_drc_checks UCIO-1]", file=f)
+        print(
+            "set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design]",
+            file=f)
+        print(
+            "write_checkpoint -force %s/specimen_clk/gclkb_%d.dcp" % (root, x),
+            file=f)
+        print(
+            "write_edif -force %s/specimen_clk/gclkb_%d.edf" % (root, x),
+            file=f)
+        print(
+            "write_bitstream -force %s/specimen_clk/gclkb_%d.bit" % (root, x),
+            file=f)
 with open(root + "/clkroute4/run.sh", "w") as f:
-	print("#/usr/bin/env bash", file=f)
-	#print("set -ex", file=f)
-	for x in range(X):
-		print("vivado -mode batch -nolog -nojournal -source gclkb_%d.tcl" % x, file=f)
-		print("if [ $? -eq 0 ]; then", file=f)
-		print("    ../../ultra/tools/dump_bitstream %s/specimen_clk/gclkb_%d.bit %s/frames.txt > %s/specimen_clk/gclkb_%d.dump" % (root, x, root, root, x), file=f)
-		print("    python3 ../../ultra/tools/bits_to_tiles.py %s/tile.json %s/specimen_clk/gclkb_%d.dump > %s/specimen_clk/gclkb_%d.tbits" % (root, root, x, root, x), file=f)
-		print("else", file=f)
-		print("   rm %s/specimen_clk/gclkb_%d.dump" % (root, x), file=f)
-		print("   rm %s/specimen_clk/gclkb_%d.tbits" % (root, x), file=f)
-		print("   rm %s/specimen_clk/gclkb_%d.dcp" % (root, x), file=f)
-		print("   rm %s/specimen_clk/gclkb_%d.bit" % (root, x), file=f)
-		print("   rm %s/specimen_clk/gclkb_%d.features" % (root, x), file=f)
-		print("fi", file=f)
\ No newline at end of file
+    print("#/usr/bin/env bash", file=f)
+    #print("set -ex", file=f)
+    for x in range(X):
+        print(
+            "vivado -mode batch -nolog -nojournal -source gclkb_%d.tcl" % x,
+            file=f)
+        print("if [ $? -eq 0 ]; then", file=f)
+        print(
+            "    ../../ultra/tools/dump_bitstream %s/specimen_clk/gclkb_%d.bit %s/frames.txt > %s/specimen_clk/gclkb_%d.dump"
+            % (root, x, root, root, x),
+            file=f)
+        print(
+            "    python3 ../../ultra/tools/bits_to_tiles.py %s/tile.json %s/specimen_clk/gclkb_%d.dump > %s/specimen_clk/gclkb_%d.tbits"
+            % (root, root, x, root, x),
+            file=f)
+        print("else", file=f)
+        print("   rm %s/specimen_clk/gclkb_%d.dump" % (root, x), file=f)
+        print("   rm %s/specimen_clk/gclkb_%d.tbits" % (root, x), file=f)
+        print("   rm %s/specimen_clk/gclkb_%d.dcp" % (root, x), file=f)
+        print("   rm %s/specimen_clk/gclkb_%d.bit" % (root, x), file=f)
+        print("   rm %s/specimen_clk/gclkb_%d.features" % (root, x), file=f)
+        print("fi", file=f)
diff --git a/spec/gclk_4.py b/spec/gclk_4.py
index 7f1f314..27811c3 100644
--- a/spec/gclk_4.py
+++ b/spec/gclk_4.py
@@ -20,169 +20,200 @@
 rclk_int_l = []
 slices_by_tile = {}
 with open(sys.argv[1], "r") as tf:
-	for line in tf:
-		sl = line.strip().split(",")
-		if len(sl) < 4:
-			continue
-		tiles_by_xy[int(sl[0]), int(sl[1])] = sl[2]
-		if sl[2].startswith("RCLK_INT_L"):
-			rclk_int_l.append((int(sl[0]), int(sl[1]), sl[2]))
-		for site in sl[4:]:
-			if ("BUFGCE" in site or "BUFGCTRL" in site) and "HDIO" not in site:
-				if sl[2] not in bufgces_by_tile:
-					bufgces_by_tile[sl[2]] = []
-				bufgces_by_tile[sl[2]].append(site.split(":"))
-			elif "SLICE_" in site:
-				slices_by_tile[int(sl[0]), int(sl[1])] = site.split(":")[0]
+    for line in tf:
+        sl = line.strip().split(",")
+        if len(sl) < 4:
+            continue
+        tiles_by_xy[int(sl[0]), int(sl[1])] = sl[2]
+        if sl[2].startswith("RCLK_INT_L"):
+            rclk_int_l.append((int(sl[0]), int(sl[1]), sl[2]))
+        for site in sl[4:]:
+            if ("BUFGCE" in site or "BUFGCTRL" in site) and "HDIO" not in site:
+                if sl[2] not in bufgces_by_tile:
+                    bufgces_by_tile[sl[2]] = []
+                bufgces_by_tile[sl[2]].append(site.split(":"))
+            elif "SLICE_" in site:
+                slices_by_tile[int(sl[0]), int(sl[1])] = site.split(":")[0]
 
 halfcolumn_slices_by_row = {}
 for x, y, rclk in rclk_int_l:
-	hc_up = []
-	hc_down = []
-	if y not in halfcolumn_slices_by_row:
-		halfcolumn_slices_by_row[y] = []
-	for yplus in range(y+1, y+31):
-		if (x, yplus) not in tiles_by_xy:
-			continue
-		if not tiles_by_xy[x, yplus].startswith("INT_"):
-			break
-		slice_x = x + np.random.choice([+1, -1])
-		if (slice_x, yplus) not in slices_by_tile:
-			continue
-		hc_up.append(slices_by_tile[slice_x, yplus])
-	for yminus in range(y-1, y-31, -1):
-		if (x, yminus) not in tiles_by_xy:
-			continue
-		if not tiles_by_xy[x, yminus].startswith("INT_"):
-			break
-		slice_x = x + np.random.choice([+1, -1])
-		if (slice_x, yminus) not in slices_by_tile:
-			continue
-		hc_down.append(slices_by_tile[slice_x, yminus])
-	halfcolumn_slices_by_row[y].append(hc_up)
-	halfcolumn_slices_by_row[y].append(hc_down)
+    hc_up = []
+    hc_down = []
+    if y not in halfcolumn_slices_by_row:
+        halfcolumn_slices_by_row[y] = []
+    for yplus in range(y + 1, y + 31):
+        if (x, yplus) not in tiles_by_xy:
+            continue
+        if not tiles_by_xy[x, yplus].startswith("INT_"):
+            break
+        slice_x = x + np.random.choice([+1, -1])
+        if (slice_x, yplus) not in slices_by_tile:
+            continue
+        hc_up.append(slices_by_tile[slice_x, yplus])
+    for yminus in range(y - 1, y - 31, -1):
+        if (x, yminus) not in tiles_by_xy:
+            continue
+        if not tiles_by_xy[x, yminus].startswith("INT_"):
+            break
+        slice_x = x + np.random.choice([+1, -1])
+        if (slice_x, yminus) not in slices_by_tile:
+            continue
+        hc_down.append(slices_by_tile[slice_x, yminus])
+    halfcolumn_slices_by_row[y].append(hc_up)
+    halfcolumn_slices_by_row[y].append(hc_down)
 
 X = 32
 
 root = sys.argv[2]
 
 for x in range(X):
-	buffers = []
+    buffers = []
 
-	tiles = list(sorted(bufgces_by_tile.keys()))
-	np.random.shuffle(tiles)
+    tiles = list(sorted(bufgces_by_tile.keys()))
+    np.random.shuffle(tiles)
 
-	for tile in tiles:
-		shuffled_bufs = list(bufgces_by_tile[tile])
-		np.random.shuffle(shuffled_bufs)
-		target_type = np.random.choice(["BUFGCE", "BUFGCE_DIV", "BUFGCTRL"] if len(buffers) > 0 else ["BUFGCE", "BUFGCE_DIV"])
-		tile_buffers = np.random.randint(6)
-		found_buffers = 0
-		for buf, buftype in shuffled_bufs:
-			if found_buffers >= tile_buffers:
-				break
-			if buftype != target_type:
-				continue
-			buffers.append((buf, buftype))
-			print("%s %s" % (tile, buf))
-			found_buffers += 1
-	
-	def random_inversion(pins):
-		return ", ".join([".IS_%s_INVERTED(%d)" % (p, np.random.randint(2)) for p in pins])
+    for tile in tiles:
+        shuffled_bufs = list(bufgces_by_tile[tile])
+        np.random.shuffle(shuffled_bufs)
+        target_type = np.random.choice(
+            ["BUFGCE", "BUFGCE_DIV", "BUFGCTRL"]
+            if len(buffers) > 0 else ["BUFGCE", "BUFGCE_DIV"])
+        tile_buffers = np.random.randint(6)
+        found_buffers = 0
+        for buf, buftype in shuffled_bufs:
+            if found_buffers >= tile_buffers:
+                break
+            if buftype != target_type:
+                continue
+            buffers.append((buf, buftype))
+            print("%s %s" % (tile, buf))
+            found_buffers += 1
 
-	def random_control(pins):
-		return ", ".join([".%s(aux[%d])" % (p, np.random.randint(10)) for p in pins])
+    def random_inversion(pins):
+        return ", ".join(
+            [".IS_%s_INVERTED(%d)" % (p, np.random.randint(2)) for p in pins])
 
-	with open(root + "/clkroute5/gclkc_%d.v" % x, "w") as f:
-		print("module top(input [23:0] i, input [9:0] aux, input d, output o, q);", file=f)
-		N = 24
-		print("    wire [71:0] r;", file=f)
-		# print("    assign r[0] = i;", file=f)
-		# print("    assign o = r[%d];" % N, file=f)
-		# for i in range(N):
-		# 	bg, buftype = buffers[i]
-		# 	#print("(* LOC=\"%s\" *)" % bg, file=f)
-		# 	if "BUFGCTRL" in buftype:
-		# 		print("    BUFGCTRL #(", file=f)
-		# 		print("        %s," % random_inversion(["I0", "I1", "S0", "S1", "CE0", "CE1", "IGNORE0", "IGNORE1"]), file=f)
-		# 		print("        .INIT_OUT(%d), .PRESELECT_I0(\"%s\"), .PRESELECT_I1(\"%s\")" %
-		# 				(np.random.randint(2), np.random.choice(["TRUE", "FALSE"]), np.random.choice(["TRUE", "FALSE"])), file=f)
-		# 		print("    ) bufgctrl_%d (" % i, file=f)
-		# 		print("        .I0(r[%d]), .I1(r[%d]), " % (i, np.random.randint(i+1)), file=f)
-		# 		print("        %s," % random_control(["S0", "S1", "CE0", "CE1", "IGNORE0", "IGNORE1"]), file=f)
-		# 		print("        .O(r[%d])" % (i+1), file=f)
-		# 		print("    );", file=f)
-		print("    assign r[23:0] = i;", file=f)
-		for i in range(12):
-			print("    BUFGCE_DIV #(", file=f)
-			print("        .BUFGCE_DIVIDE(%d)," % np.random.randint(1, 9), file=f)
-			print("        %s" % random_inversion(["I", "CE", "CLR"]), file=f)
-			print("    ) bufgce_div_%d (" % i, file=f)
-			print("        .I(i[%d])," % i, file=f)
-			print("        %s," % random_control(["CE", "CLR"]), file=f)
-			print("        .O(r[%d])" % (24+i), file=f)
-			print("    );", file=f)
-		for i in range(12):
-			print("    BUFGCE #(", file=f)
-			print("        .CE_TYPE(\"%s\")," % np.random.choice(["SYNC", "ASYNC"]), file=f)
-			print("        %s" % random_inversion(["I", "CE"]), file=f)
-			print("    ) bufgce_%d (" % i, file=f)
-			print("        .I(i[%d])," %  np.random.randint(24), file=f)
-			print("        %s," % random_control(["CE"]), file=f)
-			print("        .O(r[%d])" % (i+36), file=f)
-			print("    );", file=f)
+    def random_control(pins):
+        return ", ".join(
+            [".%s(aux[%d])" % (p, np.random.randint(10)) for p in pins])
 
-		R2=0
-		NS=64
-		ffs=""
-		for row, hcs in sorted(halfcolumn_slices_by_row.items()):
-			row_clks = np.random.randint(20, 25)
-			clks = [np.random.randint(48) for k in range(row_clks)]
-			hi = []
-			while len(hi) < NS:
-				next_i = np.random.randint(len(hcs))
-				while next_i in hi:
-					next_i = np.random.randint(len(hcs))
-				hi.append(next_i)
+    with open(root + "/clkroute5/gclkc_%d.v" % x, "w") as f:
+        print(
+            "module top(input [23:0] i, input [9:0] aux, input d, output o, q);",
+            file=f)
+        N = 24
+        print("    wire [71:0] r;", file=f)
+        # print("    assign r[0] = i;", file=f)
+        # print("    assign o = r[%d];" % N, file=f)
+        # for i in range(N):
+        # 	bg, buftype = buffers[i]
+        # 	#print("(* LOC=\"%s\" *)" % bg, file=f)
+        # 	if "BUFGCTRL" in buftype:
+        # 		print("    BUFGCTRL #(", file=f)
+        # 		print("        %s," % random_inversion(["I0", "I1", "S0", "S1", "CE0", "CE1", "IGNORE0", "IGNORE1"]), file=f)
+        # 		print("        .INIT_OUT(%d), .PRESELECT_I0(\"%s\"), .PRESELECT_I1(\"%s\")" %
+        # 				(np.random.randint(2), np.random.choice(["TRUE", "FALSE"]), np.random.choice(["TRUE", "FALSE"])), file=f)
+        # 		print("    ) bufgctrl_%d (" % i, file=f)
+        # 		print("        .I0(r[%d]), .I1(r[%d]), " % (i, np.random.randint(i+1)), file=f)
+        # 		print("        %s," % random_control(["S0", "S1", "CE0", "CE1", "IGNORE0", "IGNORE1"]), file=f)
+        # 		print("        .O(r[%d])" % (i+1), file=f)
+        # 		print("    );", file=f)
+        print("    assign r[23:0] = i;", file=f)
+        for i in range(12):
+            print("    BUFGCE_DIV #(", file=f)
+            print(
+                "        .BUFGCE_DIVIDE(%d)," % np.random.randint(1, 9),
+                file=f)
+            print("        %s" % random_inversion(["I", "CE", "CLR"]), file=f)
+            print("    ) bufgce_div_%d (" % i, file=f)
+            print("        .I(i[%d])," % i, file=f)
+            print("        %s," % random_control(["CE", "CLR"]), file=f)
+            print("        .O(r[%d])" % (24 + i), file=f)
+            print("    );", file=f)
+        for i in range(12):
+            print("    BUFGCE #(", file=f)
+            print(
+                "        .CE_TYPE(\"%s\")," % np.random.choice(
+                    ["SYNC", "ASYNC"]),
+                file=f)
+            print("        %s" % random_inversion(["I", "CE"]), file=f)
+            print("    ) bufgce_%d (" % i, file=f)
+            print("        .I(i[%d])," % np.random.randint(24), file=f)
+            print("        %s," % random_control(["CE"]), file=f)
+            print("        .O(r[%d])" % (i + 36), file=f)
+            print("    );", file=f)
 
-			halfs = [hcs[hi[k]] for k in range(NS)]
-			for h in halfs:
-				half_clks = np.random.randint(13, 17)
-				rclks = [np.random.choice(clks) for k in range(half_clks)]
-				for sl in h:
-					ffs += "(* LOC=\"%s\" *) FDCE ff_%d (.C(r[%d]), .CE(aux[%d]), .CLR(~aux[%d]), .D(r2[%d]), .Q(r2[%d]));\n" % (sl, R2, rclks[R2 % len(rclks)], np.random.randint(10), np.random.randint(10), R2, R2+1)
-					R2 += 1
-		print("    wire [%d:0] r2;" % R2, file=f)
-		print("    assign r2[0] = d;", file=f)
-		print("    assign q = r2[%d];" % R2, file=f)
-		print(ffs, file=f)
-		print("endmodule", file=f)
-	with open(root + "/clkroute5/gclkc_%d.tcl" % x, "w") as f:
-		print("add_files %s" % (root + ("/clkroute5/gclkc_%d.v" % x)), file=f)
-		#print("read_xdc %s" % (root + ("/clkroute5/gclkc_%d.xdc" % x)), file=f)
-		print("synth_design -top top -part xczu7ev-ffvc1156-2-e", file=f)
-		print("# set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets]", file=f)
-		print("opt_design", file=f)
-		print("place_design", file=f)
-		print("route_design", file=f)
-		print("set_property SEVERITY {Warning} [get_drc_checks NSTD-1]", file=f)
-		print("set_property SEVERITY {Warning} [get_drc_checks UCIO-1]", file=f)
-		print("set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design]", file=f)
-		print("write_checkpoint -force %s/specimen_clk/gclkc_%d.dcp" % (root, x), file=f)
-		print("write_edif -force %s/specimen_clk/gclkc_%d.edf" % (root, x), file=f)
-		print("write_bitstream -force %s/specimen_clk/gclkc_%d.bit" % (root, x), file=f)
+        R2 = 0
+        NS = 64
+        ffs = ""
+        for row, hcs in sorted(halfcolumn_slices_by_row.items()):
+            row_clks = np.random.randint(20, 25)
+            clks = [np.random.randint(48) for k in range(row_clks)]
+            hi = []
+            while len(hi) < NS:
+                next_i = np.random.randint(len(hcs))
+                while next_i in hi:
+                    next_i = np.random.randint(len(hcs))
+                hi.append(next_i)
+
+            halfs = [hcs[hi[k]] for k in range(NS)]
+            for h in halfs:
+                half_clks = np.random.randint(13, 17)
+                rclks = [np.random.choice(clks) for k in range(half_clks)]
+                for sl in h:
+                    ffs += "(* LOC=\"%s\" *) FDCE ff_%d (.C(r[%d]), .CE(aux[%d]), .CLR(~aux[%d]), .D(r2[%d]), .Q(r2[%d]));\n" % (
+                        sl, R2, rclks[R2 % len(rclks)], np.random.randint(10),
+                        np.random.randint(10), R2, R2 + 1)
+                    R2 += 1
+        print("    wire [%d:0] r2;" % R2, file=f)
+        print("    assign r2[0] = d;", file=f)
+        print("    assign q = r2[%d];" % R2, file=f)
+        print(ffs, file=f)
+        print("endmodule", file=f)
+    with open(root + "/clkroute5/gclkc_%d.tcl" % x, "w") as f:
+        print("add_files %s" % (root + ("/clkroute5/gclkc_%d.v" % x)), file=f)
+        #print("read_xdc %s" % (root + ("/clkroute5/gclkc_%d.xdc" % x)), file=f)
+        print("synth_design -top top -part xczu7ev-ffvc1156-2-e", file=f)
+        print("# set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets]", file=f)
+        print("opt_design", file=f)
+        print("place_design", file=f)
+        print("route_design", file=f)
+        print(
+            "set_property SEVERITY {Warning} [get_drc_checks NSTD-1]", file=f)
+        print(
+            "set_property SEVERITY {Warning} [get_drc_checks UCIO-1]", file=f)
+        print(
+            "set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design]",
+            file=f)
+        print(
+            "write_checkpoint -force %s/specimen_clk/gclkc_%d.dcp" % (root, x),
+            file=f)
+        print(
+            "write_edif -force %s/specimen_clk/gclkc_%d.edf" % (root, x),
+            file=f)
+        print(
+            "write_bitstream -force %s/specimen_clk/gclkc_%d.bit" % (root, x),
+            file=f)
 with open(root + "/clkroute5/run.sh", "w") as f:
-	print("#/usr/bin/env bash", file=f)
-	#print("set -ex", file=f)
-	for x in range(X):
-		print("vivado -mode batch -nolog -nojournal -source gclkc_%d.tcl" % x, file=f)
-		print("if [ $? -eq 0 ]; then", file=f)
-		print("    ../../ultra/tools/dump_bitstream %s/specimen_clk/gclkc_%d.bit %s/frames.txt > %s/specimen_clk/gclkc_%d.dump" % (root, x, root, root, x), file=f)
-		print("    python3 ../../ultra/tools/bits_to_tiles.py %s/tile.json %s/specimen_clk/gclkc_%d.dump > %s/specimen_clk/gclkc_%d.tbits" % (root, root, x, root, x), file=f)
-		print("else", file=f)
-		print("   rm %s/specimen_clk/gclkc_%d.dump" % (root, x), file=f)
-		print("   rm %s/specimen_clk/gclkc_%d.tbits" % (root, x), file=f)
-		print("   rm %s/specimen_clk/gclkc_%d.dcp" % (root, x), file=f)
-		print("   rm %s/specimen_clk/gclkc_%d.bit" % (root, x), file=f)
-		print("   rm %s/specimen_clk/gclkc_%d.features" % (root, x), file=f)
-		print("fi", file=f)
\ No newline at end of file
+    print("#/usr/bin/env bash", file=f)
+    #print("set -ex", file=f)
+    for x in range(X):
+        print(
+            "vivado -mode batch -nolog -nojournal -source gclkc_%d.tcl" % x,
+            file=f)
+        print("if [ $? -eq 0 ]; then", file=f)
+        print(
+            "    ../../ultra/tools/dump_bitstream %s/specimen_clk/gclkc_%d.bit %s/frames.txt > %s/specimen_clk/gclkc_%d.dump"
+            % (root, x, root, root, x),
+            file=f)
+        print(
+            "    python3 ../../ultra/tools/bits_to_tiles.py %s/tile.json %s/specimen_clk/gclkc_%d.dump > %s/specimen_clk/gclkc_%d.tbits"
+            % (root, root, x, root, x),
+            file=f)
+        print("else", file=f)
+        print("   rm %s/specimen_clk/gclkc_%d.dump" % (root, x), file=f)
+        print("   rm %s/specimen_clk/gclkc_%d.tbits" % (root, x), file=f)
+        print("   rm %s/specimen_clk/gclkc_%d.dcp" % (root, x), file=f)
+        print("   rm %s/specimen_clk/gclkc_%d.bit" % (root, x), file=f)
+        print("   rm %s/specimen_clk/gclkc_%d.features" % (root, x), file=f)
+        print("fi", file=f)
diff --git a/spec/memory.py b/spec/memory.py
index a8e3b36..5ed7209 100644
--- a/spec/memory.py
+++ b/spec/memory.py
@@ -16,100 +16,109 @@
 import sys
 import math
 
-print("module top(input [15:0] clk, cen, input [8:0] wa, input [7:0] ra, input [7:0] d, input [11:0] sel, output [3:0] q);")
+print(
+    "module top(input [15:0] clk, cen, input [8:0] wa, input [7:0] ra, input [7:0] d, input [11:0] sel, output [3:0] q);"
+)
 N = 4096
 print("    wire [3:0] int_d[0:%d-1];" % N)
 print("    assign q = int_d[sel];")
 
+
 def connect(sig, dst, len):
-	if sig is None:
-		return []
-	bit = 0
-	conns = []
-	for x in sig:
-		if type(x) is tuple:
-			name, width = x
-			conns.append(".%s(%s[%d +: %d])" % (name, dst, bit, width))
-			bit += width
-		else:
-			conns.append(".%s(%s[%d])" % (x, dst, bit))
-			bit += 1
-	return conns
+    if sig is None:
+        return []
+    bit = 0
+    conns = []
+    for x in sig:
+        if type(x) is tuple:
+            name, width = x
+            conns.append(".%s(%s[%d +: %d])" % (name, dst, bit, width))
+            bit += width
+        else:
+            conns.append(".%s(%s[%d])" % (x, dst, bit))
+            bit += 1
+    return conns
+
 
 for i in range(N):
-	ctype = np.random.choice(["SRL16E", "SRLC32E", "RAM32X1D", "RAM32X1S", "RAM64X1D", "RAM64X1S", "RAM128X1S", "RAM128X1D", "RAM256X1D", "RAM256X1S", "RAM512X1S"])
-	clockport = None
-	ceport = None
-	wraddr = None
-	rdaddr = None
-	wdata = None
-	rdata = None
-	init_len = None
-	if ctype in ("SRL16E", "SRLC32E"):
-		clockport = "CLK"
-		ceport = "CE"
-		wdata = ["D"]
-		rdata = ["Q"]
-		if ctype == "SRLC32E":
-			rdata.append("Q31")
-			rdaddr = [("A", 5)]
-			init_len = 32
-		else:
-			rdaddr = ["A0", "A1", "A2", "A3"]
-			init_len = 16
-	elif ctype in ("RAM32X1D", "RAM32X1S"):
-		clockport = "WCLK"
-		ceport = "WE"
-		wdata = ["D"]
-		wraddr = ["A0", "A1", "A2", "A3", "A4"]
-		init_len = 32
-		if ctype == "RAM32X1D":
-			rdaddr = ["DPRA0", "DPRA1", "DPRA2", "DPRA3", "DPRA4"]
-			rdata = ["SPO", "DPO"]
-		else:
-			rdata = ["O"]
-	elif ctype in ("RAM64X1D", "RAM64X1S"):
-		clockport = "WCLK"
-		ceport = "WE"
-		wdata = ["D"]
-		wraddr = ["A0", "A1", "A2", "A3", "A4", "A5"]
-		init_len = 64
-		if ctype == "RAM64X1D":
-			rdaddr = ["DPRA0", "DPRA1", "DPRA2", "DPRA3", "DPRA4", "DPRA5"]
-			rdata = ["SPO", "DPO"]
-		else:
-			rdata = ["O"]
-	elif ctype in ("RAM128X1S", "RAM128X1D", "RAM256X1D", "RAM256X1S", "RAM512X1S"):
-		init_len = int(ctype[3:6])
-		abits = math.log2(init_len)
-		clockport = "WCLK"
-		ceport = "WE"
-		wdata = ["D"]
-		if ctype == "RAM128X1S":
-			wraddr = ["A0", "A1", "A2", "A3", "A4", "A5", "A6"]
-		else:
-			wraddr = [("A", abits)]
-		if ctype[-1] == "D":
-			rdaddr = [("DPRA", abits)]
-			rdata = ["SPO", "DPO"]
-		else:
-			rdata = ["O"]
-	else:
-		assert False, ctype
-	conns = []
-	if clockport is not None:
-		conns.append(".%s(clk[%d])" % (clockport, np.random.randint(0, 16)))
-	if ceport is not None:
-		conns.append(".%s(cen[%d])" % (ceport, np.random.randint(0, 16)))
-	conns += connect(wraddr, "wa", 9)
-	conns += connect(rdaddr, "ra", 8)
-	conns += connect(wdata, "d", 8)
-	conns += connect(rdata, "int_d[%d]" % i, 4)
-	print("    %s #(" % ctype)
-	if init_len is not None:
-		initdata = np.random.randint(2, size=init_len)
-		print("        .INIT(%d'b%s)" % (init_len, "".join([str(_) for _ in initdata])))
-	print("    ) %s_%d (" % (ctype, i))
-	print("    %s" % ",\n    ".join(conns))
-	print("    );")
+    ctype = np.random.choice([
+        "SRL16E", "SRLC32E", "RAM32X1D", "RAM32X1S", "RAM64X1D", "RAM64X1S",
+        "RAM128X1S", "RAM128X1D", "RAM256X1D", "RAM256X1S", "RAM512X1S"
+    ])
+    clockport = None
+    ceport = None
+    wraddr = None
+    rdaddr = None
+    wdata = None
+    rdata = None
+    init_len = None
+    if ctype in ("SRL16E", "SRLC32E"):
+        clockport = "CLK"
+        ceport = "CE"
+        wdata = ["D"]
+        rdata = ["Q"]
+        if ctype == "SRLC32E":
+            rdata.append("Q31")
+            rdaddr = [("A", 5)]
+            init_len = 32
+        else:
+            rdaddr = ["A0", "A1", "A2", "A3"]
+            init_len = 16
+    elif ctype in ("RAM32X1D", "RAM32X1S"):
+        clockport = "WCLK"
+        ceport = "WE"
+        wdata = ["D"]
+        wraddr = ["A0", "A1", "A2", "A3", "A4"]
+        init_len = 32
+        if ctype == "RAM32X1D":
+            rdaddr = ["DPRA0", "DPRA1", "DPRA2", "DPRA3", "DPRA4"]
+            rdata = ["SPO", "DPO"]
+        else:
+            rdata = ["O"]
+    elif ctype in ("RAM64X1D", "RAM64X1S"):
+        clockport = "WCLK"
+        ceport = "WE"
+        wdata = ["D"]
+        wraddr = ["A0", "A1", "A2", "A3", "A4", "A5"]
+        init_len = 64
+        if ctype == "RAM64X1D":
+            rdaddr = ["DPRA0", "DPRA1", "DPRA2", "DPRA3", "DPRA4", "DPRA5"]
+            rdata = ["SPO", "DPO"]
+        else:
+            rdata = ["O"]
+    elif ctype in ("RAM128X1S", "RAM128X1D", "RAM256X1D", "RAM256X1S",
+                   "RAM512X1S"):
+        init_len = int(ctype[3:6])
+        abits = math.log2(init_len)
+        clockport = "WCLK"
+        ceport = "WE"
+        wdata = ["D"]
+        if ctype == "RAM128X1S":
+            wraddr = ["A0", "A1", "A2", "A3", "A4", "A5", "A6"]
+        else:
+            wraddr = [("A", abits)]
+        if ctype[-1] == "D":
+            rdaddr = [("DPRA", abits)]
+            rdata = ["SPO", "DPO"]
+        else:
+            rdata = ["O"]
+    else:
+        assert False, ctype
+    conns = []
+    if clockport is not None:
+        conns.append(".%s(clk[%d])" % (clockport, np.random.randint(0, 16)))
+    if ceport is not None:
+        conns.append(".%s(cen[%d])" % (ceport, np.random.randint(0, 16)))
+    conns += connect(wraddr, "wa", 9)
+    conns += connect(rdaddr, "ra", 8)
+    conns += connect(wdata, "d", 8)
+    conns += connect(rdata, "int_d[%d]" % i, 4)
+    print("    %s #(" % ctype)
+    if init_len is not None:
+        initdata = np.random.randint(2, size=init_len)
+        print("        .INIT(%d'b%s)" % (init_len, "".join(
+            [str(_) for _ in initdata])))
+    print("    ) %s_%d (" % (ctype, i))
+    print("    %s" % ",\n    ".join(conns))
+    print("    );")
 print("endmodule")
diff --git a/spec/rclk_int.py b/spec/rclk_int.py
index 816924c..1323bf0 100644
--- a/spec/rclk_int.py
+++ b/spec/rclk_int.py
@@ -19,13 +19,13 @@
 
 bufgces = []
 with open(sys.argv[1], "r") as tf:
-	for line in tf:
-		sl = line.strip().split(",")
-		if len(sl) < 4:
-			continue
-		for site in sl[4:]:
-			if "BUFGCE" in site and "HDIO" not in site:
-				bufgces.append(site.split(":")[0])
+    for line in tf:
+        sl = line.strip().split(",")
+        if len(sl) < 4:
+            continue
+        for site in sl[4:]:
+            if "BUFGCE" in site and "HDIO" not in site:
+                bufgces.append(site.split(":")[0])
 
 print("module layer_1(input [31:0] clk, input [71:0] cen, input d, output q);")
 print("    wire [%d:0] r;" % N)
@@ -33,11 +33,12 @@
 print("    assign q = r[%d];" % N)
 print()
 for i in range(N):
-	print("    FDCE ff_%d (.C(clk[%d]), .CLR(1'b0), .CE(cen[%d]), .D(r[%d]), .Q(r[%d]));" % (i, (i * 32) // N, np.random.randint(72), i, i+1))
-	print()
+    print(
+        "    FDCE ff_%d (.C(clk[%d]), .CLR(1'b0), .CE(cen[%d]), .D(r[%d]), .Q(r[%d]));"
+        % (i, (i * 32) // N, np.random.randint(72), i, i + 1))
+    print()
 print("endmodule")
 
-
 M = 16
 print("module top(input [15:0] clk, cen, input d, output q);")
 print("    wire [511:0] clk_int;")
@@ -46,29 +47,36 @@
 print("    assign cen_int[15:0] = cen;")
 print("    assign cen_int[71:64] = 8'hFF;")
 for i in range(16, 512):
-	a = np.random.randint(16)
-	b = None
-	while b is None or b == a:
-		b = np.random.randint(16)
-	c = None
-	while c is None or c == a or c == b:
-		c = np.random.randint(16)
-	bg = None
-	if len(bufgces) > 0:
-		bg = bufgces.pop()
-	if bg is not None and np.random.randint(3) > 0:
-		if "DIV" in bg:
-			print("    BUFGCE_DIV #(.BUFGCE_DIVIDE(3)) bufg_%d (.I(clk[%d] ^ clk[%d] ^ clk[%d]), .CLR(0), .CE(1'b1), .O(clk_int[%d]));" % (i, a, b, c, i))
-		else:
-			print("    BUFGCE bufg_%d (.I(clk[%d] ^ clk[%d] ^ clk[%d]), .CE(1'b1), .O(clk_int[%d]));" % (i, a, b, c, i))
-	else:
-		print("    assign clk_int[%d] = clk[%d] ^ clk[%d] ^ clk[%d];" % (i, a, b, c))
-	if i < 64:
-		print("    assign cen_int[%d] = cen[%d] ^ cen[%d];" % (i, a, b))
+    a = np.random.randint(16)
+    b = None
+    while b is None or b == a:
+        b = np.random.randint(16)
+    c = None
+    while c is None or c == a or c == b:
+        c = np.random.randint(16)
+    bg = None
+    if len(bufgces) > 0:
+        bg = bufgces.pop()
+    if bg is not None and np.random.randint(3) > 0:
+        if "DIV" in bg:
+            print(
+                "    BUFGCE_DIV #(.BUFGCE_DIVIDE(3)) bufg_%d (.I(clk[%d] ^ clk[%d] ^ clk[%d]), .CLR(0), .CE(1'b1), .O(clk_int[%d]));"
+                % (i, a, b, c, i))
+        else:
+            print(
+                "    BUFGCE bufg_%d (.I(clk[%d] ^ clk[%d] ^ clk[%d]), .CE(1'b1), .O(clk_int[%d]));"
+                % (i, a, b, c, i))
+    else:
+        print("    assign clk_int[%d] = clk[%d] ^ clk[%d] ^ clk[%d];" % (i, a,
+                                                                         b, c))
+    if i < 64:
+        print("    assign cen_int[%d] = cen[%d] ^ cen[%d];" % (i, a, b))
 print()
 print("    wire [%d:0] r;" % M)
 print("    assign r[0] = d;")
 print("    assign q = r[%d];" % M)
 for i in range(M):
-	print("    layer_1 submod_%d(.clk(clk_int[%d +: 32]), .cen(cen_int), .d(r[%d]), .q(r[%d]));" % (i, 32 * i, i, i+1))
+    print(
+        "    layer_1 submod_%d(.clk(clk_int[%d +: 32]), .cen(cen_int), .d(r[%d]), .q(r[%d]));"
+        % (i, 32 * i, i, i + 1))
 print("endmodule")
diff --git a/spec/rclk_int_2.py b/spec/rclk_int_2.py
index 059d99b..62c5938 100644
--- a/spec/rclk_int_2.py
+++ b/spec/rclk_int_2.py
@@ -18,15 +18,15 @@
 bufgces = []
 slices = []
 with open(sys.argv[1], "r") as tf:
-	for line in tf:
-		sl = line.strip().split(",")
-		if len(sl) < 4:
-			continue
-		for site in sl[4:]:
-			if "BUFGCE" in site and "HDIO" not in site:
-				bufgces.append(site.split(":")[0])
-			if "SLICEM" in site or "SLICEL" in site:
-				slices.append(site.split(":")[0])
+    for line in tf:
+        sl = line.strip().split(",")
+        if len(sl) < 4:
+            continue
+        for site in sl[4:]:
+            if "BUFGCE" in site and "HDIO" not in site:
+                bufgces.append(site.split(":")[0])
+            if "SLICEM" in site or "SLICEL" in site:
+                slices.append(site.split(":")[0])
 orig_bufgces = list(bufgces)
 np.random.shuffle(bufgces)
 np.random.shuffle(slices)
@@ -37,86 +37,128 @@
 bufg_prob = np.random.randint(15, 20)
 
 for x in range(X):
-	with open(root + "/clkroute/clkr%d.v" % x, "w") as f:
-		N = 256
-		M = 16
-		for m in range(M):
-			print("module layer_1_%d(input [31:0] clk, input [71:0] cen, input d, output q);" % m, file=f)
-			print("    wire [%d:0] r;" % N, file=f)
-			print("    assign r[0] = d;", file=f)
-			print("    assign q = r[%d];" % N, file=f)
-			print("", file=f)
-			for i in range(N):
-				if N == 0 and len(slices) > 0:
-					loc = slices.pop()
-					print("(* LOC=\"%s\" *)" % loc, file=f)
-				print("    FDCE ff_%d (.C(clk[%d]), .CLR(1'b0), .CE(cen[%d]), .D(r[%d]), .Q(r[%d]));" % (i, (i * 32) // N, np.random.randint(72), i, i+1), file=f)
-			print("endmodule", file=f)
+    with open(root + "/clkroute/clkr%d.v" % x, "w") as f:
+        N = 256
+        M = 16
+        for m in range(M):
+            print(
+                "module layer_1_%d(input [31:0] clk, input [71:0] cen, input d, output q);"
+                % m,
+                file=f)
+            print("    wire [%d:0] r;" % N, file=f)
+            print("    assign r[0] = d;", file=f)
+            print("    assign q = r[%d];" % N, file=f)
+            print("", file=f)
+            for i in range(N):
+                if N == 0 and len(slices) > 0:
+                    loc = slices.pop()
+                    print("(* LOC=\"%s\" *)" % loc, file=f)
+                print(
+                    "    FDCE ff_%d (.C(clk[%d]), .CLR(1'b0), .CE(cen[%d]), .D(r[%d]), .Q(r[%d]));"
+                    % (i, (i * 32) // N, np.random.randint(72), i, i + 1),
+                    file=f)
+            print("endmodule", file=f)
 
+        print("module top(input [39:0] clk, cen, input d, output q);", file=f)
+        num_inputs = np.random.randint(8, 40)
+        print("    wire [511:0] clk_int;", file=f)
+        print("    wire [71:0] cen_int;", file=f)
+        print("    assign clk_int[%d:0] = clk;" % (num_inputs - 1), file=f)
+        print("    assign cen_int[%d:0] = cen;" % (num_inputs - 1), file=f)
+        print("    assign cen_int[71:64] = 8'hFF;", file=f)
 
-		print("module top(input [39:0] clk, cen, input d, output q);", file=f)
-		num_inputs = np.random.randint(8, 40)
-		print("    wire [511:0] clk_int;", file=f)
-		print("    wire [71:0] cen_int;", file=f)
-		print("    assign clk_int[%d:0] = clk;" % (num_inputs - 1), file=f)
-		print("    assign cen_int[%d:0] = cen;" % (num_inputs - 1), file=f)
-		print("    assign cen_int[71:64] = 8'hFF;", file=f)
+        bufgces = list(orig_bufgces)
+        np.random.shuffle(bufgces)
 
-		bufgces = list(orig_bufgces)
-		np.random.shuffle(bufgces)
-
-		for i in range(num_inputs, 512):
-			a = np.random.randint(num_inputs)
-			b = None
-			while b is None or b == a:
-				b = np.random.randint(num_inputs)
-			c = None
-			while c is None or c == a or c == b:
-				c = np.random.randint(num_inputs)
-			bg = None
-			if len(bufgces) > 0:
-				bg = bufgces.pop()
-			if bg is not None and np.random.randint(20) >= bufg_prob or (bg is not None and "DIV" in bg and np.random.randint(19) >= bufg_prob):
-				if "DIV" in bg:
-					print("    BUFGCE_DIV #(.BUFGCE_DIVIDE(%d), .IS_I_INVERTED(%d), .IS_CE_INVERTED(%d), .IS_CLR_INVERTED(%d)) bufg_%d (.I(clk[%d] ^ clk[%d] ^ clk[%d]), .CLR(!cen[%d]), .CE(cen[%d]), .O(clk_int[%d]));" %
-						(np.random.randint(1, 9), np.random.randint(2), np.random.randint(2), np.random.randint(2), i, a, b, c, np.random.randint(40), np.random.randint(40), i), file=f)
-				else:
-					ctype = np.random.choice(["", "_1"])
-					params = " #(.IS_I_INVERTED(%d), .IS_CE_INVERTED(%d), .CE_TYPE(\"%s\")) " % (np.random.randint(2), np.random.randint(2), np.random.choice(["SYNC", "ASYNC", "HARD_SYNC"])) if ctype == "" else ""
-					print("    BUFGCE%s %s bufg_%d (.I(clk[%d] ^ clk[%d] ^ clk[%d]), .CE(cen[%d]), .O(clk_int[%d]));" %
-						(ctype, params, i, a, b, c, np.random.randint(40), i), file=f)
-			else:
-				print("    assign clk_int[%d] = clk[%d] ^ clk[%d] ^ clk[%d];" % (i, a, b, c), file=f)
-			if i < 64:
-				print("    assign cen_int[%d] = cen[%d] ^ cen[%d];" % (i, a, b), file=f)
-		print("", file=f)
-		print("    wire [%d:0] r;" % M, file=f)
-		print("    assign r[0] = d;", file=f)
-		print("    assign q = r[%d];" % M, file=f)
-		for i in range(M):
-			print("    layer_1_%d submod_%d(.clk(clk_int[%d +: 32]), .cen(cen_int), .d(r[%d]), .q(r[%d]));" % (i, i, 32 * i, i, i+1), file=f)
-		print("endmodule", file=f)
-	with open(root + "/clkroute/clkr%d.tcl" % x, "w") as f:
-		print("add_files %s" % (root + ("/clkroute/clkr%d.v" % x)), file=f)
-		print("synth_design -top top -part xczu7ev-ffvc1156-2-e", file=f)
-		print("opt_design", file=f)
-		print("place_design", file=f)
-		print("route_design", file=f)
-		print("set_property SEVERITY {Warning} [get_drc_checks NSTD-1]", file=f)
-		print("set_property SEVERITY {Warning} [get_drc_checks UCIO-1]", file=f)
-		print("set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design]", file=f)
-		print("write_checkpoint -force %s/specimen_clk/clkr%d.dcp" % (root, x), file=f)
-		print("write_edif -force %s/specimen_clk/clkr%d.edf" % (root, x), file=f)
-		print("write_bitstream -force %s/specimen_clk/clkr%d.bit" % (root, x), file=f)
+        for i in range(num_inputs, 512):
+            a = np.random.randint(num_inputs)
+            b = None
+            while b is None or b == a:
+                b = np.random.randint(num_inputs)
+            c = None
+            while c is None or c == a or c == b:
+                c = np.random.randint(num_inputs)
+            bg = None
+            if len(bufgces) > 0:
+                bg = bufgces.pop()
+            if bg is not None and np.random.randint(20) >= bufg_prob or (
+                    bg is not None and "DIV" in bg
+                    and np.random.randint(19) >= bufg_prob):
+                if "DIV" in bg:
+                    print(
+                        "    BUFGCE_DIV #(.BUFGCE_DIVIDE(%d), .IS_I_INVERTED(%d), .IS_CE_INVERTED(%d), .IS_CLR_INVERTED(%d)) bufg_%d (.I(clk[%d] ^ clk[%d] ^ clk[%d]), .CLR(!cen[%d]), .CE(cen[%d]), .O(clk_int[%d]));"
+                        % (np.random.randint(1, 9), np.random.randint(2),
+                           np.random.randint(2), np.random.randint(2), i, a, b,
+                           c, np.random.randint(40), np.random.randint(40), i),
+                        file=f)
+                else:
+                    ctype = np.random.choice(["", "_1"])
+                    params = " #(.IS_I_INVERTED(%d), .IS_CE_INVERTED(%d), .CE_TYPE(\"%s\")) " % (
+                        np.random.randint(2), np.random.randint(2),
+                        np.random.choice(["SYNC", "ASYNC", "HARD_SYNC"
+                                          ])) if ctype == "" else ""
+                    print(
+                        "    BUFGCE%s %s bufg_%d (.I(clk[%d] ^ clk[%d] ^ clk[%d]), .CE(cen[%d]), .O(clk_int[%d]));"
+                        % (ctype, params, i, a, b, c, np.random.randint(40),
+                           i),
+                        file=f)
+            else:
+                print(
+                    "    assign clk_int[%d] = clk[%d] ^ clk[%d] ^ clk[%d];" %
+                    (i, a, b, c),
+                    file=f)
+            if i < 64:
+                print(
+                    "    assign cen_int[%d] = cen[%d] ^ cen[%d];" % (i, a, b),
+                    file=f)
+        print("", file=f)
+        print("    wire [%d:0] r;" % M, file=f)
+        print("    assign r[0] = d;", file=f)
+        print("    assign q = r[%d];" % M, file=f)
+        for i in range(M):
+            print(
+                "    layer_1_%d submod_%d(.clk(clk_int[%d +: 32]), .cen(cen_int), .d(r[%d]), .q(r[%d]));"
+                % (i, i, 32 * i, i, i + 1),
+                file=f)
+        print("endmodule", file=f)
+    with open(root + "/clkroute/clkr%d.tcl" % x, "w") as f:
+        print("add_files %s" % (root + ("/clkroute/clkr%d.v" % x)), file=f)
+        print("synth_design -top top -part xczu7ev-ffvc1156-2-e", file=f)
+        print("opt_design", file=f)
+        print("place_design", file=f)
+        print("route_design", file=f)
+        print(
+            "set_property SEVERITY {Warning} [get_drc_checks NSTD-1]", file=f)
+        print(
+            "set_property SEVERITY {Warning} [get_drc_checks UCIO-1]", file=f)
+        print(
+            "set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design]",
+            file=f)
+        print(
+            "write_checkpoint -force %s/specimen_clk/clkr%d.dcp" % (root, x),
+            file=f)
+        print(
+            "write_edif -force %s/specimen_clk/clkr%d.edf" % (root, x), file=f)
+        print(
+            "write_bitstream -force %s/specimen_clk/clkr%d.bit" % (root, x),
+            file=f)
 with open(root + "/clkroute/run.sh", "w") as f:
-	print("#/usr/bin/env bash", file=f)
-	#print("set -ex", file=f)
-	for x in range(X):
-		print("vivado -mode batch -nolog -nojournal -source clkr%d.tcl" % x, file=f)
-		print("if [ $? -eq 0 ]; then", file=f)
-		print("    ../../ultra/tools/dump_bitstream %s/specimen_clk/clkr%d.bit %s/frames.txt > %s/specimen_clk/clkr%d.dump" % (root, x, root, root, x), file=f)
-		print("    python3 ../../ultra/tools/bits_to_tiles.py %s/tile.json %s/specimen_clk/clkr%d.dump > %s/specimen_clk/clkr%d.tbits" % (root, root, x, root, x), file=f)
-		print("else", file=f)
-		print("   rm %s/specimen_clk/clkr%d.dump" % (root, x), file=f)
-		print("   rm %s/specimen_clk/clkr%d.tbits" % (root, x), file=f)
-		print("fi", file=f)
\ No newline at end of file
+    print("#/usr/bin/env bash", file=f)
+    #print("set -ex", file=f)
+    for x in range(X):
+        print(
+            "vivado -mode batch -nolog -nojournal -source clkr%d.tcl" % x,
+            file=f)
+        print("if [ $? -eq 0 ]; then", file=f)
+        print(
+            "    ../../ultra/tools/dump_bitstream %s/specimen_clk/clkr%d.bit %s/frames.txt > %s/specimen_clk/clkr%d.dump"
+            % (root, x, root, root, x),
+            file=f)
+        print(
+            "    python3 ../../ultra/tools/bits_to_tiles.py %s/tile.json %s/specimen_clk/clkr%d.dump > %s/specimen_clk/clkr%d.tbits"
+            % (root, root, x, root, x),
+            file=f)
+        print("else", file=f)
+        print("   rm %s/specimen_clk/clkr%d.dump" % (root, x), file=f)
+        print("   rm %s/specimen_clk/clkr%d.tbits" % (root, x), file=f)
+        print("fi", file=f)
diff --git a/spec/rclk_int_3.py b/spec/rclk_int_3.py
index c057ded..bcc821d 100644
--- a/spec/rclk_int_3.py
+++ b/spec/rclk_int_3.py
@@ -18,15 +18,15 @@
 bufgces = []
 slices = []
 with open(sys.argv[1], "r") as tf:
-	for line in tf:
-		sl = line.strip().split(",")
-		if len(sl) < 4:
-			continue
-		for site in sl[4:]:
-			if "BUFGCE" in site and "HDIO" not in site:
-				bufgces.append(site.split(":")[0])
-			if "SLICEM" in site or "SLICEL" in site:
-				slices.append(site.split(":")[0])
+    for line in tf:
+        sl = line.strip().split(",")
+        if len(sl) < 4:
+            continue
+        for site in sl[4:]:
+            if "BUFGCE" in site and "HDIO" not in site:
+                bufgces.append(site.split(":")[0])
+            if "SLICEM" in site or "SLICEL" in site:
+                slices.append(site.split(":")[0])
 orig_bufgces = list(bufgces)
 np.random.shuffle(bufgces)
 np.random.shuffle(slices)
@@ -37,104 +37,162 @@
 bufg_prob = np.random.randint(15, 20)
 
 for x in range(X):
-	with open(root + "/clkroute2/clkrb%d.v" % x, "w") as f:
-		N = 256
-		M = np.random.randint(24)
-		for m in range(M):
-			print("module layer_1_%d(input [31:0] clk, input [71:0] cen, input d, output q);" % m, file=f)
-			print("    wire [%d:0] r;" % N, file=f)
-			print("    assign r[0] = d;", file=f)
-			print("    assign q = r[%d];" % N, file=f)
-			print("", file=f)
-			for i in range(N):
-				if N == 0 and len(slices) > 0:
-					loc = slices.pop()
-					print("(* LOC=\"%s\" *)" % loc, file=f)
-				if N != 0 and np.random.randint(16) == 0:
-					print("    wire srl_tmp_%d;" % i, file=f)
-					print("    SRLC32E srl_%d (.CLK(clk[%d]), .CE(cen[%d]), .A(5'b11111), .D(r[%d]), .Q(srl_tmp_%d));" % (i, (i * 32) // N, np.random.randint(72), i, i), file=f)
-					print("    FDCE ff_%d (.C(clk[%d]), .CLR(1'b0), .CE(cen[%d]), .D(srl_tmp_%d), .Q(r[%d]));" % (i, (i * 32) // N, np.random.randint(72), i, i+1), file=f)
-				else:
-					print("    FDCE ff_%d (.C(clk[%d]), .CLR(1'b0), .CE(cen[%d]), .D(r[%d]), .Q(r[%d]));" % (i, (i * 32) // N, np.random.randint(72), i, i+1), file=f)
-			print("endmodule", file=f)
+    with open(root + "/clkroute2/clkrb%d.v" % x, "w") as f:
+        N = 256
+        M = np.random.randint(24)
+        for m in range(M):
+            print(
+                "module layer_1_%d(input [31:0] clk, input [71:0] cen, input d, output q);"
+                % m,
+                file=f)
+            print("    wire [%d:0] r;" % N, file=f)
+            print("    assign r[0] = d;", file=f)
+            print("    assign q = r[%d];" % N, file=f)
+            print("", file=f)
+            for i in range(N):
+                if N == 0 and len(slices) > 0:
+                    loc = slices.pop()
+                    print("(* LOC=\"%s\" *)" % loc, file=f)
+                if N != 0 and np.random.randint(16) == 0:
+                    print("    wire srl_tmp_%d;" % i, file=f)
+                    print(
+                        "    SRLC32E srl_%d (.CLK(clk[%d]), .CE(cen[%d]), .A(5'b11111), .D(r[%d]), .Q(srl_tmp_%d));"
+                        % (i, (i * 32) // N, np.random.randint(72), i, i),
+                        file=f)
+                    print(
+                        "    FDCE ff_%d (.C(clk[%d]), .CLR(1'b0), .CE(cen[%d]), .D(srl_tmp_%d), .Q(r[%d]));"
+                        % (i, (i * 32) // N, np.random.randint(72), i, i + 1),
+                        file=f)
+                else:
+                    print(
+                        "    FDCE ff_%d (.C(clk[%d]), .CLR(1'b0), .CE(cen[%d]), .D(r[%d]), .Q(r[%d]));"
+                        % (i, (i * 32) // N, np.random.randint(72), i, i + 1),
+                        file=f)
+            print("endmodule", file=f)
 
+        print("module top(input [39:0] clk, cen, input d, output q);", file=f)
+        num_inputs = np.random.randint(8, 40)
+        print("    wire [511:0] clk_int;", file=f)
+        print("    wire [71:0] cen_int;", file=f)
+        print("    assign clk_int[%d:0] = clk;" % (num_inputs - 1), file=f)
+        print("    assign cen_int[%d:0] = cen;" % (num_inputs - 1), file=f)
+        print("    assign cen_int[71:64] = 8'hFF;", file=f)
 
-		print("module top(input [39:0] clk, cen, input d, output q);", file=f)
-		num_inputs = np.random.randint(8, 40)
-		print("    wire [511:0] clk_int;", file=f)
-		print("    wire [71:0] cen_int;", file=f)
-		print("    assign clk_int[%d:0] = clk;" % (num_inputs - 1), file=f)
-		print("    assign cen_int[%d:0] = cen;" % (num_inputs - 1), file=f)
-		print("    assign cen_int[71:64] = 8'hFF;", file=f)
+        bufgces = list(orig_bufgces)
+        np.random.shuffle(bufgces)
 
-		bufgces = list(orig_bufgces)
-		np.random.shuffle(bufgces)
+        for i in range(num_inputs, 512):
+            a = np.random.randint(num_inputs)
+            b = None
+            while b is None or b == a:
+                b = np.random.randint(num_inputs)
+            c = None
+            while c is None or c == a or c == b:
+                c = np.random.randint(num_inputs)
+            bg = None
+            if len(bufgces) > 0:
+                bg = bufgces.pop()
+            if bg is not None and np.random.randint(20) >= bufg_prob or (
+                    bg is not None and "DIV" in bg
+                    and np.random.randint(19) >= bufg_prob):
+                if "DIV" in bg:
+                    print(
+                        "    BUFGCE_DIV #(.BUFGCE_DIVIDE(%d), .IS_I_INVERTED(%d), .IS_CE_INVERTED(%d), .IS_CLR_INVERTED(%d)) bufg_%d (.I(clk[%d] ^ clk[%d] ^ clk[%d]), .CLR(!cen[%d]), .CE(cen[%d]), .O(clk_int[%d]));"
+                        % (np.random.randint(1, 9), np.random.randint(2),
+                           np.random.randint(2), np.random.randint(2), i, a, b,
+                           c, np.random.randint(40), np.random.randint(40), i),
+                        file=f)
+                else:
+                    ctype = np.random.choice(["", "_1"])
+                    params = " #(.IS_I_INVERTED(%d), .IS_CE_INVERTED(%d), .CE_TYPE(\"%s\")) " % (
+                        np.random.randint(2), np.random.randint(2),
+                        np.random.choice(["SYNC", "ASYNC"
+                                          ])) if ctype == "" else ""
+                    print(
+                        "    BUFGCE%s %s bufg_%d (.I(clk[%d] ^ clk[%d] ^ clk[%d]), .CE(cen[%d]), .O(clk_int[%d]));"
+                        % (ctype, params, i, a, b, c, np.random.randint(40),
+                           i),
+                        file=f)
+            else:
+                print(
+                    "    assign clk_int[%d] = clk[%d] ^ clk[%d] ^ clk[%d];" %
+                    (i, a, b, c),
+                    file=f)
+            if i < 64:
+                print(
+                    "    assign cen_int[%d] = cen[%d] ^ cen[%d];" % (i, a, b),
+                    file=f)
+        print("", file=f)
+        print("    wire [%d:0] r;" % M, file=f)
+        print("    assign r[0] = d;", file=f)
+        print("    assign q = r[%d];" % M, file=f)
+        for i in range(M):
+            print(
+                "    layer_1_%d submod_%d(.clk(clk_int[%d +: 32]), .cen(cen_int), .d(r[%d]), .q(r[%d]));"
+                % (i, i, 32 * i, i, i + 1),
+                file=f)
+        print("endmodule", file=f)
+    ccio = [
+        "G23", "F23", "G21", "F22", "F11", "H11", "G10", "H9", "G15", "F17",
+        "E15", "D15", "AH11", "AH12", "AJ9", "AJ10", "AG21", "AH22", "AJ21",
+        "AJ20", "AF18", "AH18", "AJ16", "AJ17"
+    ]
+    np.random.shuffle(ccio)
+    with open(root + "/clkroute2/clkrb%d.xdc" % x, "w") as f:
+        for i in range(num_inputs):
+            if i >= len(ccio):
+                break
+            print(
+                "set_property PACKAGE_PIN %s [get_ports {clk[%d]}]" % (ccio[i],
+                                                                       i),
+                file=f)
+            print(
+                "set_property IOSTANDARD LVCMOS18 [get_ports {clk[%d]}]" % (i),
+                file=f)
 
-		for i in range(num_inputs, 512):
-			a = np.random.randint(num_inputs)
-			b = None
-			while b is None or b == a:
-				b = np.random.randint(num_inputs)
-			c = None
-			while c is None or c == a or c == b:
-				c = np.random.randint(num_inputs)
-			bg = None
-			if len(bufgces) > 0:
-				bg = bufgces.pop()
-			if bg is not None and np.random.randint(20) >= bufg_prob or (bg is not None and "DIV" in bg and np.random.randint(19) >= bufg_prob):
-				if "DIV" in bg:
-					print("    BUFGCE_DIV #(.BUFGCE_DIVIDE(%d), .IS_I_INVERTED(%d), .IS_CE_INVERTED(%d), .IS_CLR_INVERTED(%d)) bufg_%d (.I(clk[%d] ^ clk[%d] ^ clk[%d]), .CLR(!cen[%d]), .CE(cen[%d]), .O(clk_int[%d]));" %
-						(np.random.randint(1, 9), np.random.randint(2), np.random.randint(2), np.random.randint(2), i, a, b, c, np.random.randint(40), np.random.randint(40), i), file=f)
-				else:
-					ctype = np.random.choice(["", "_1"])
-					params = " #(.IS_I_INVERTED(%d), .IS_CE_INVERTED(%d), .CE_TYPE(\"%s\")) " % (np.random.randint(2), np.random.randint(2), np.random.choice(["SYNC", "ASYNC"])) if ctype == "" else ""
-					print("    BUFGCE%s %s bufg_%d (.I(clk[%d] ^ clk[%d] ^ clk[%d]), .CE(cen[%d]), .O(clk_int[%d]));" %
-						(ctype, params, i, a, b, c, np.random.randint(40), i), file=f)
-			else:
-				print("    assign clk_int[%d] = clk[%d] ^ clk[%d] ^ clk[%d];" % (i, a, b, c), file=f)
-			if i < 64:
-				print("    assign cen_int[%d] = cen[%d] ^ cen[%d];" % (i, a, b), file=f)
-		print("", file=f)
-		print("    wire [%d:0] r;" % M, file=f)
-		print("    assign r[0] = d;", file=f)
-		print("    assign q = r[%d];" % M, file=f)
-		for i in range(M):
-			print("    layer_1_%d submod_%d(.clk(clk_int[%d +: 32]), .cen(cen_int), .d(r[%d]), .q(r[%d]));" % (i, i, 32 * i, i, i+1), file=f)
-		print("endmodule", file=f)
-	ccio = ["G23", "F23", "G21", "F22", "F11", "H11", "G10", "H9", "G15", "F17", "E15", "D15", "AH11", "AH12", "AJ9", "AJ10", "AG21", "AH22", "AJ21", "AJ20", "AF18", "AH18", "AJ16", "AJ17"]
-	np.random.shuffle(ccio)
-	with open(root + "/clkroute2/clkrb%d.xdc" % x, "w") as f:
-		for i in range(num_inputs):
-			if i >= len(ccio):
-				break
-			print("set_property PACKAGE_PIN %s [get_ports {clk[%d]}]" % (ccio[i], i), file=f)
-			print("set_property IOSTANDARD LVCMOS18 [get_ports {clk[%d]}]" % (i), file=f)
-
-	with open(root + "/clkroute2/clkrb%d.tcl" % x, "w") as f:
-		print("add_files %s" % (root + ("/clkroute2/clkrb%d.v" % x)), file=f)
-		print("read_xdc %s" % (root + ("/clkroute2/clkrb%d.xdc" % x)), file=f)
-		print("synth_design -top top -part xczu7ev-ffvc1156-2-e", file=f)
-		print("opt_design", file=f)
-		print("place_design", file=f)
-		print("route_design", file=f)
-		print("set_property SEVERITY {Warning} [get_drc_checks NSTD-1]", file=f)
-		print("set_property SEVERITY {Warning} [get_drc_checks UCIO-1]", file=f)
-		print("set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design]", file=f)
-		print("write_checkpoint -force %s/specimen_clk/clkrb%d.dcp" % (root, x), file=f)
-		print("write_edif -force %s/specimen_clk/clkrb%d.edf" % (root, x), file=f)
-		print("write_bitstream -force %s/specimen_clk/clkrb%d.bit" % (root, x), file=f)
+    with open(root + "/clkroute2/clkrb%d.tcl" % x, "w") as f:
+        print("add_files %s" % (root + ("/clkroute2/clkrb%d.v" % x)), file=f)
+        print("read_xdc %s" % (root + ("/clkroute2/clkrb%d.xdc" % x)), file=f)
+        print("synth_design -top top -part xczu7ev-ffvc1156-2-e", file=f)
+        print("opt_design", file=f)
+        print("place_design", file=f)
+        print("route_design", file=f)
+        print(
+            "set_property SEVERITY {Warning} [get_drc_checks NSTD-1]", file=f)
+        print(
+            "set_property SEVERITY {Warning} [get_drc_checks UCIO-1]", file=f)
+        print(
+            "set_property BITSTREAM.GENERAL.PERFRAMECRC YES [current_design]",
+            file=f)
+        print(
+            "write_checkpoint -force %s/specimen_clk/clkrb%d.dcp" % (root, x),
+            file=f)
+        print(
+            "write_edif -force %s/specimen_clk/clkrb%d.edf" % (root, x),
+            file=f)
+        print(
+            "write_bitstream -force %s/specimen_clk/clkrb%d.bit" % (root, x),
+            file=f)
 with open(root + "/clkroute2/run.sh", "w") as f:
-	print("#/usr/bin/env bash", file=f)
-	#print("set -ex", file=f)
-	for x in range(X):
-		print("vivado -mode batch -nolog -nojournal -source clkrb%d.tcl" % x, file=f)
-		print("if [ $? -eq 0 ]; then", file=f)
-		print("    ../../ultra/tools/dump_bitstream %s/specimen_clk/clkrb%d.bit %s/frames.txt > %s/specimen_clk/clkrb%d.dump" % (root, x, root, root, x), file=f)
-		print("    python3 ../../ultra/tools/bits_to_tiles.py %s/tile.json %s/specimen_clk/clkrb%d.dump > %s/specimen_clk/clkrb%d.tbits" % (root, root, x, root, x), file=f)
-		print("else", file=f)
-		print("   rm %s/specimen_clk/clkrb%d.dump" % (root, x), file=f)
-		print("   rm %s/specimen_clk/clkrb%d.tbits" % (root, x), file=f)
-		print("   rm %s/specimen_clk/clkrb%d.dcp" % (root, x), file=f)
-		print("   rm %s/specimen_clk/clkrb%d.bit" % (root, x), file=f)
-		print("   rm %s/specimen_clk/clkrb%d.features" % (root, x), file=f)
-		print("fi", file=f)
\ No newline at end of file
+    print("#/usr/bin/env bash", file=f)
+    #print("set -ex", file=f)
+    for x in range(X):
+        print(
+            "vivado -mode batch -nolog -nojournal -source clkrb%d.tcl" % x,
+            file=f)
+        print("if [ $? -eq 0 ]; then", file=f)
+        print(
+            "    ../../ultra/tools/dump_bitstream %s/specimen_clk/clkrb%d.bit %s/frames.txt > %s/specimen_clk/clkrb%d.dump"
+            % (root, x, root, root, x),
+            file=f)
+        print(
+            "    python3 ../../ultra/tools/bits_to_tiles.py %s/tile.json %s/specimen_clk/clkrb%d.dump > %s/specimen_clk/clkrb%d.tbits"
+            % (root, root, x, root, x),
+            file=f)
+        print("else", file=f)
+        print("   rm %s/specimen_clk/clkrb%d.dump" % (root, x), file=f)
+        print("   rm %s/specimen_clk/clkrb%d.tbits" % (root, x), file=f)
+        print("   rm %s/specimen_clk/clkrb%d.dcp" % (root, x), file=f)
+        print("   rm %s/specimen_clk/clkrb%d.bit" % (root, x), file=f)
+        print("   rm %s/specimen_clk/clkrb%d.features" % (root, x), file=f)
+        print("fi", file=f)
diff --git a/spec/slice.v b/spec/slice.v
index ce33903..bc294ce 100644
--- a/spec/slice.v
+++ b/spec/slice.v
@@ -171,7 +171,7 @@
 			"D5":    assign OUT = D5;
 			"CY":    assign OUT = CY;
 			"BYP":   assign OUT = BYP;
-		endcase		
+		endcase
 	endgenerate
 endmodule
 
@@ -192,7 +192,7 @@
 			"FDCE": (* LOC=LOC, BEL=BEL, keep, dont_touch *) FDCE #(.IS_C_INVERTED(CLKINV), .IS_CLR_INVERTED(SRINV), .INIT(INIT)) ff_i (.C(C), .CE(CE), .CLR(SR), .D(D), .Q(Q));
 			"FDSE": (* LOC=LOC, BEL=BEL, keep, dont_touch *) FDSE #(.IS_C_INVERTED(CLKINV), .IS_S_INVERTED(SRINV), .INIT(INIT)) ff_i (.C(C), .CE(CE), .S(SR), .D(D), .Q(Q));
 			"FDRE": (* LOC=LOC, BEL=BEL, keep, dont_touch *) FDRE #(.IS_C_INVERTED(CLKINV), .IS_R_INVERTED(SRINV), .INIT(INIT)) ff_i (.C(C), .CE(CE), .R(SR), .D(D), .Q(Q));
-			
+
 			"LDPE": (* LOC=LOC, BEL=BEL, keep, dont_touch *) LDPE #(.IS_G_INVERTED(CLKINV), .IS_PRE_INVERTED(SRINV), .INIT(INIT)) ff_i (.G(C), .GE(CE), .PRE(SR), .D(D), .Q(Q));
 			"LDCE": (* LOC=LOC, BEL=BEL, keep, dont_touch *) LDCE #(.IS_G_INVERTED(CLKINV), .IS_CLR_INVERTED(SRINV), .INIT(INIT)) ff_i (.G(C), .GE(CE), .CLR(SR), .D(D), .Q(Q));
 			"NONE": assign Q = INIT;
@@ -213,6 +213,6 @@
 			"D6":    assign OUT = D6;
 			"D5":    assign OUT = D5;
 			"CY":    assign OUT = CY;
-		endcase		
+		endcase
 	endgenerate
 endmodule
\ No newline at end of file
diff --git a/spec/slice_carry.py b/spec/slice_carry.py
index d095b75..6f6776a 100644
--- a/spec/slice_carry.py
+++ b/spec/slice_carry.py
@@ -21,91 +21,108 @@
 
 slices = []
 with open(sys.argv[1], "r") as tf:
-	for line in tf:
-		sl = line.strip().split(",")
-		if len(sl) < 4:
-			continue
-		for site in sl[4:]:
-			if "SLICEM" in site or "SLICEL" in site:
-				slices.append(site.split(":")[0])
+    for line in tf:
+        sl = line.strip().split(",")
+        if len(sl) < 4:
+            continue
+        for site in sl[4:]:
+            if "SLICEM" in site or "SLICEL" in site:
+                slices.append(site.split(":")[0])
 
 np.random.shuffle(slices)
 
 for i in range(N):
-	sl = slices.pop()
-	ffmode = np.random.randint(3, size=2)
-	clk = tuple(np.random.randint(16, size=2))
-	sr = tuple(["1'b1" if y >= 16 else "sr[%d]" % y for y in np.random.randint(25, size=2)])
-	ce = tuple(["1'b1" if y >= 16 else "ce[%d]" % y for y in np.random.randint(25, size=4)])
+    sl = slices.pop()
+    ffmode = np.random.randint(3, size=2)
+    clk = tuple(np.random.randint(16, size=2))
+    sr = tuple([
+        "1'b1" if y >= 16 else "sr[%d]" % y
+        for y in np.random.randint(25, size=2)
+    ])
+    ce = tuple([
+        "1'b1" if y >= 16 else "ce[%d]" % y
+        for y in np.random.randint(25, size=4)
+    ])
 
-	def random_fftype(mode):
-		if mode == 0:
-			return np.random.choice(["FDSE", "FDRE"])
-		elif mode == 1:
-			return np.random.choice(["FDPE", "FDCE"])
-		elif mode == 2:
-			return np.random.choice(["LDPE", "LDCE"])
+    def random_fftype(mode):
+        if mode == 0:
+            return np.random.choice(["FDSE", "FDRE"])
+        elif mode == 1:
+            return np.random.choice(["FDPE", "FDCE"])
+        elif mode == 2:
+            return np.random.choice(["LDPE", "LDCE"])
 
-	def random_bit():
-		return np.random.choice(D)
+    def random_bit():
+        return np.random.choice(D)
 
-	def random_data(width):
-		return "{%s}" % (", ".join([random_bit() for k in range(width)]))
+    def random_data(width):
+        return "{%s}" % (", ".join([random_bit() for k in range(width)]))
 
-	fftypes = [random_fftype(ffmode[j // 8]) for j in range(16)]
-	used_outroute = [np.random.choice(["FF", "FF2", "MUX"]) for k in range(8)]
-	for j in range(8):
-		if used_outroute[j] == "FF":
-			fftypes[2*j + 1] = "NONE"
-		elif used_outroute[j] == "FF2":
-			fftypes[2*j] = "NONE"		
-		else:
-			fftypes[2*j] = "NONE"
-			fftypes[2*j + 1] = "NONE"
-	cmode = np.random.choice(["NONE", "SINGLE_CY8", "DUAL_CY4"], p=[0.1, 0.7, 0.2])
+    fftypes = [random_fftype(ffmode[j // 8]) for j in range(16)]
+    used_outroute = [np.random.choice(["FF", "FF2", "MUX"]) for k in range(8)]
+    for j in range(8):
+        if used_outroute[j] == "FF":
+            fftypes[2 * j + 1] = "NONE"
+        elif used_outroute[j] == "FF2":
+            fftypes[2 * j] = "NONE"
+        else:
+            fftypes[2 * j] = "NONE"
+            fftypes[2 * j + 1] = "NONE"
+    cmode = np.random.choice(["NONE", "SINGLE_CY8", "DUAL_CY4"],
+                             p=[0.1, 0.7, 0.2])
 
-	print('   wire [31:0] d%d;' % i)
-	print('   ultra_slice_carry #(')
-	print('      .LOC("%s"),' % sl)
-	for lut in "ABCDEFGH":
-		print("      .%sLUT_INIT(64'b%s)," % (lut, "".join(str(_) for _ in np.random.randint(2, size=64))))
-	for j in range(16):
-		print('      .%sFF%s_TYPE("%s"),' % ("ABCDEFGH"[j//2], "2" if (j % 2) == 1 else "", fftypes[j]))
-	print("      .FF_INIT(16'b%s)," % "".join(str(_) for _ in np.random.randint(2, size=16)))
-	for j1 in "ABCDEFGH":
-		for j2 in ("1", "2"):
-			print('        .FFMUX%s%s("%s"),' % (j1, j2, np.random.choice(["XORIN", "CY"] if cmode != "NONE" else ["D6"])))
-	for j in range(8):
-		print('        .OUTMUX%s("%s"),' % ("ABCDEFGH"[j], ("D6" if used_outroute[j] != "MUX" else np.random.choice(["D6", "XORIN", "CY"] if cmode != "NONE" else ["D6"]))))
-	print("      .CLKINV(2'd%d)," % np.random.randint(4))
-	print("      .SRINV(2'd%d)," % np.random.randint(4))
-	print('      .CARRY_TYPE("%s"),' % cmode)
-	for j in range (8):
-		print('      .DI%dMUX("%s"),' % (j, np.random.choice(["DI", "X"])))
-	print('      .CIMUX("%s"),' % np.random.choice(["1", "0", "X"]))
-	print('      .CITOPMUX("%s")' % (np.random.choice(["1", "0", "X"]) if cmode == "DUAL_CY4" else "CI"))
-	print('   ) slice%d (' % i)
-	for j in range(1, 7):
-		print("      .A%d(%s)," % (j, random_data(8)))
-	print("      .I(%s)," % random_data(8))
-	print("      .X(%s)," % random_data(8))
-	print("      .CLK({clk[%d], clk[%d]})," % clk)
-	print("      .SR({%s, %s})," % sr)
-	print("      .CE({%s, %s, %s, %s})," % ce)
-	print("      .O(d%d[7:0])," % i)
-	print("      .Q(d%d[15:8])," % i)
-	print("      .Q2(d%d[23:16])," % i)
-	print("      .MUX(d%d[31:24])" % i)
-	print('   );')
-	print()
-	
-	D.clear()
-	for j in range(8):
-		D.append("d%d[%d]" % (i, j))
-		D.append("d%d[%d]" % (i, 24 + j))
-		if fftypes[2 * j] != "NONE":
-			D.append("d%d[%d]" % (i, 8 + j))
-		if fftypes[2 * j + 1] != "NONE":
-			D.append("d%d[%d]" % (i, 16 + j))
-print("    assign q = d%d;" % (N-1))
-print("endmodule")
\ No newline at end of file
+    print('   wire [31:0] d%d;' % i)
+    print('   ultra_slice_carry #(')
+    print('      .LOC("%s"),' % sl)
+    for lut in "ABCDEFGH":
+        print("      .%sLUT_INIT(64'b%s)," % (lut, "".join(
+            str(_) for _ in np.random.randint(2, size=64))))
+    for j in range(16):
+        print('      .%sFF%s_TYPE("%s"),' % ("ABCDEFGH" [j // 2], "2" if
+                                             (j % 2) == 1 else "", fftypes[j]))
+    print("      .FF_INIT(16'b%s)," % "".join(
+        str(_) for _ in np.random.randint(2, size=16)))
+    for j1 in "ABCDEFGH":
+        for j2 in ("1", "2"):
+            print('        .FFMUX%s%s("%s"),' %
+                  (j1, j2,
+                   np.random.choice(
+                       ["XORIN", "CY"] if cmode != "NONE" else ["D6"])))
+    for j in range(8):
+        print('        .OUTMUX%s("%s"),' %
+              ("ABCDEFGH" [j],
+               ("D6" if used_outroute[j] != "MUX" else np.random.choice(
+                   ["D6", "XORIN", "CY"] if cmode != "NONE" else ["D6"]))))
+    print("      .CLKINV(2'd%d)," % np.random.randint(4))
+    print("      .SRINV(2'd%d)," % np.random.randint(4))
+    print('      .CARRY_TYPE("%s"),' % cmode)
+    for j in range(8):
+        print('      .DI%dMUX("%s"),' % (j, np.random.choice(["DI", "X"])))
+    print('      .CIMUX("%s"),' % np.random.choice(["1", "0", "X"]))
+    print('      .CITOPMUX("%s")' %
+          (np.random.choice(["1", "0", "X"]) if cmode == "DUAL_CY4" else "CI"))
+    print('   ) slice%d (' % i)
+    for j in range(1, 7):
+        print("      .A%d(%s)," % (j, random_data(8)))
+    print("      .I(%s)," % random_data(8))
+    print("      .X(%s)," % random_data(8))
+    print("      .CLK({clk[%d], clk[%d]})," % clk)
+    print("      .SR({%s, %s})," % sr)
+    print("      .CE({%s, %s, %s, %s})," % ce)
+    print("      .O(d%d[7:0])," % i)
+    print("      .Q(d%d[15:8])," % i)
+    print("      .Q2(d%d[23:16])," % i)
+    print("      .MUX(d%d[31:24])" % i)
+    print('   );')
+    print()
+
+    D.clear()
+    for j in range(8):
+        D.append("d%d[%d]" % (i, j))
+        D.append("d%d[%d]" % (i, 24 + j))
+        if fftypes[2 * j] != "NONE":
+            D.append("d%d[%d]" % (i, 8 + j))
+        if fftypes[2 * j + 1] != "NONE":
+            D.append("d%d[%d]" % (i, 16 + j))
+print("    assign q = d%d;" % (N - 1))
+print("endmodule")
diff --git a/spec/slice_carry.v b/spec/slice_carry.v
index 4eaeaee..1ec5577 100644
--- a/spec/slice_carry.v
+++ b/spec/slice_carry.v
@@ -209,7 +209,7 @@
 			"D5":    assign OUT = D5;
 			"CY":    assign OUT = CY;
 			"BYP":   assign OUT = BYP;
-		endcase		
+		endcase
 	endgenerate
 endmodule
 
@@ -230,7 +230,7 @@
 			"FDCE": (* LOC=LOC, BEL=BEL, keep, dont_touch *) FDCE #(.IS_C_INVERTED(CLKINV), .IS_CLR_INVERTED(SRINV), .INIT(INIT)) ff_i (.C(C), .CE(CE), .CLR(SR), .D(D), .Q(Q));
 			"FDSE": (* LOC=LOC, BEL=BEL, keep, dont_touch *) FDSE #(.IS_C_INVERTED(CLKINV), .IS_S_INVERTED(SRINV), .INIT(INIT)) ff_i (.C(C), .CE(CE), .S(SR), .D(D), .Q(Q));
 			"FDRE": (* LOC=LOC, BEL=BEL, keep, dont_touch *) FDRE #(.IS_C_INVERTED(CLKINV), .IS_R_INVERTED(SRINV), .INIT(INIT)) ff_i (.C(C), .CE(CE), .R(SR), .D(D), .Q(Q));
-			
+
 			"LDPE": (* LOC=LOC, BEL=BEL, keep, dont_touch *) LDPE #(.IS_G_INVERTED(CLKINV), .IS_PRE_INVERTED(SRINV), .INIT(INIT)) ff_i (.G(C), .GE(CE), .PRE(SR), .D(D), .Q(Q));
 			"LDCE": (* LOC=LOC, BEL=BEL, keep, dont_touch *) LDCE #(.IS_G_INVERTED(CLKINV), .IS_CLR_INVERTED(SRINV), .INIT(INIT)) ff_i (.G(C), .GE(CE), .CLR(SR), .D(D), .Q(Q));
 			"NONE": assign Q = INIT;
@@ -251,7 +251,7 @@
 			"D6":    assign OUT = D6;
 			"D5":    assign OUT = D5;
 			"CY":    assign OUT = CY;
-		endcase		
+		endcase
 	endgenerate
 endmodule
 
@@ -265,7 +265,7 @@
 		case(SEL)
 			"DI": assign OUT = DI;
 			"X":  assign OUT = X;
-		endcase		
+		endcase
 	endgenerate
 endmodule
 
@@ -281,6 +281,6 @@
 			"0":  assign OUT = 1'b0;
 			"1":  assign OUT = 1'b1;
 			"X":  assign OUT = X;
-		endcase		
+		endcase
 	endgenerate
 endmodule
\ No newline at end of file
diff --git a/spec/slice_logic.py b/spec/slice_logic.py
index ce6f46d..e308ecf 100644
--- a/spec/slice_logic.py
+++ b/spec/slice_logic.py
@@ -21,75 +21,86 @@
 
 slices = []
 with open(sys.argv[1], "r") as tf:
-	for line in tf:
-		sl = line.strip().split(",")
-		if len(sl) < 4:
-			continue
-		for site in sl[4:]:
-			if "SLICEM" in site or "SLICEL" in site:
-				slices.append(site.split(":")[0])
+    for line in tf:
+        sl = line.strip().split(",")
+        if len(sl) < 4:
+            continue
+        for site in sl[4:]:
+            if "SLICEM" in site or "SLICEL" in site:
+                slices.append(site.split(":")[0])
 
 np.random.shuffle(slices)
 
 for i in range(N):
-	sl = slices.pop()
-	ffmode = np.random.randint(3, size=2)
-	clk = tuple(np.random.randint(16, size=2))
-	sr = tuple(["1'b1" if y >= 16 else "sr[%d]" % y for y in np.random.randint(25, size=2)])
-	ce = tuple(["1'b1" if y >= 16 else "ce[%d]" % y for y in np.random.randint(25, size=4)])
+    sl = slices.pop()
+    ffmode = np.random.randint(3, size=2)
+    clk = tuple(np.random.randint(16, size=2))
+    sr = tuple([
+        "1'b1" if y >= 16 else "sr[%d]" % y
+        for y in np.random.randint(25, size=2)
+    ])
+    ce = tuple([
+        "1'b1" if y >= 16 else "ce[%d]" % y
+        for y in np.random.randint(25, size=4)
+    ])
 
-	def random_fftype(mode):
-		if mode == 0:
-			return np.random.choice(["NONE", "FDSE", "FDRE"])
-		elif mode == 1:
-			return np.random.choice(["NONE", "FDPE", "FDCE"])
-		elif mode == 2:
-			return np.random.choice(["NONE", "LDPE", "LDCE"])
+    def random_fftype(mode):
+        if mode == 0:
+            return np.random.choice(["NONE", "FDSE", "FDRE"])
+        elif mode == 1:
+            return np.random.choice(["NONE", "FDPE", "FDCE"])
+        elif mode == 2:
+            return np.random.choice(["NONE", "LDPE", "LDCE"])
 
-	def random_bit():
-		return np.random.choice(D)
+    def random_bit():
+        return np.random.choice(D)
 
-	def random_data(width):
-		return "{%s}" % (", ".join([random_bit() for k in range(width)]))
+    def random_data(width):
+        return "{%s}" % (", ".join([random_bit() for k in range(width)]))
 
-	fftypes = [random_fftype(ffmode[j // 8]) for j in range(16)]
+    fftypes = [random_fftype(ffmode[j // 8]) for j in range(16)]
 
-	print('   wire [31:0] d%d;' % i)
-	print('   ultra_slice_logic #(')
-	print('      .LOC("%s"),' % sl)
-	for lut in "ABCDEFGH":
-		print("      .%sLUT_INIT(64'b%s)," % (lut, "".join(str(_) for _ in np.random.randint(2, size=64))))
-	for j in range(16):
-		print('      .%sFF%s_TYPE("%s"),' % ("ABCDEFGH"[j//2], "2" if (j % 2) == 1 else "", fftypes[j]))
-	print("      .FF_INIT(16'b%s)," % "".join(str(_) for _ in np.random.randint(2, size=16)))
-	for j1 in "ABCDEFGH":
-		for j2 in ("1", "2"):
-			print('        .FFMUX%s%s("%s"),' % (j1, j2, np.random.choice(["F7F8", "D6", "D5", "BYP"])))
-	for j in "ABCDEFGH":
-		print('        .OUTMUX%s("%s"),' % (j, np.random.choice(["F7F8", "D6", "D5"])))
-	print("      .CLKINV(2'd%d)," % np.random.randint(4))
-	print("      .SRINV(2'd%d)" % np.random.randint(4))
-	print('   ) slice%d (' % i)
-	for j in range(1, 7):
-		print("      .A%d(%s)," % (j, random_data(8)))
-	print("      .I(%s)," % random_data(8))
-	print("      .X(%s)," % random_data(8))
-	print("      .CLK({clk[%d], clk[%d]})," % clk)
-	print("      .SR({%s, %s})," % sr)
-	print("      .CE({%s, %s, %s, %s})," % ce)
-	print("      .O(d%d[7:0])," % i)
-	print("      .Q(d%d[15:8])," % i)
-	print("      .Q2(d%d[23:16])," % i)
-	print("      .MUX(d%d[31:24])" % i)
-	print('   );')
-	print()
-	D.clear()
-	for j in range(8):
-		D.append("d%d[%d]" % (i, j))
-		D.append("d%d[%d]" % (i, 24 + j))
-		if fftypes[2 * j] != "NONE":
-			D.append("d%d[%d]" % (i, 8 + j))
-		if fftypes[2 * j + 1] != "NONE":
-			D.append("d%d[%d]" % (i, 16 + j))
-print("    assign q = d%d;" % (N-1))
-print("endmodule")
\ No newline at end of file
+    print('   wire [31:0] d%d;' % i)
+    print('   ultra_slice_logic #(')
+    print('      .LOC("%s"),' % sl)
+    for lut in "ABCDEFGH":
+        print("      .%sLUT_INIT(64'b%s)," % (lut, "".join(
+            str(_) for _ in np.random.randint(2, size=64))))
+    for j in range(16):
+        print('      .%sFF%s_TYPE("%s"),' % ("ABCDEFGH" [j // 2], "2" if
+                                             (j % 2) == 1 else "", fftypes[j]))
+    print("      .FF_INIT(16'b%s)," % "".join(
+        str(_) for _ in np.random.randint(2, size=16)))
+    for j1 in "ABCDEFGH":
+        for j2 in ("1", "2"):
+            print('        .FFMUX%s%s("%s"),' %
+                  (j1, j2, np.random.choice(["F7F8", "D6", "D5", "BYP"])))
+    for j in "ABCDEFGH":
+        print('        .OUTMUX%s("%s"),' %
+              (j, np.random.choice(["F7F8", "D6", "D5"])))
+    print("      .CLKINV(2'd%d)," % np.random.randint(4))
+    print("      .SRINV(2'd%d)" % np.random.randint(4))
+    print('   ) slice%d (' % i)
+    for j in range(1, 7):
+        print("      .A%d(%s)," % (j, random_data(8)))
+    print("      .I(%s)," % random_data(8))
+    print("      .X(%s)," % random_data(8))
+    print("      .CLK({clk[%d], clk[%d]})," % clk)
+    print("      .SR({%s, %s})," % sr)
+    print("      .CE({%s, %s, %s, %s})," % ce)
+    print("      .O(d%d[7:0])," % i)
+    print("      .Q(d%d[15:8])," % i)
+    print("      .Q2(d%d[23:16])," % i)
+    print("      .MUX(d%d[31:24])" % i)
+    print('   );')
+    print()
+    D.clear()
+    for j in range(8):
+        D.append("d%d[%d]" % (i, j))
+        D.append("d%d[%d]" % (i, 24 + j))
+        if fftypes[2 * j] != "NONE":
+            D.append("d%d[%d]" % (i, 8 + j))
+        if fftypes[2 * j + 1] != "NONE":
+            D.append("d%d[%d]" % (i, 16 + j))
+print("    assign q = d%d;" % (N - 1))
+print("endmodule")
diff --git a/spec/slice_memory.py b/spec/slice_memory.py
index 06130cb..6e1dfd4 100644
--- a/spec/slice_memory.py
+++ b/spec/slice_memory.py
@@ -21,123 +21,135 @@
 
 slices = []
 with open(sys.argv[1], "r") as tf:
-	for line in tf:
-		sl = line.strip().split(",")
-		if len(sl) < 4:
-			continue
-		if "CLEM" not in sl[3]:
-			continue
-		for site in sl[4:]:
-			if "SLICEM" in site or "SLICEL" in site:
-				slices.append(site.split(":")[0])
+    for line in tf:
+        sl = line.strip().split(",")
+        if len(sl) < 4:
+            continue
+        if "CLEM" not in sl[3]:
+            continue
+        for site in sl[4:]:
+            if "SLICEM" in site or "SLICEL" in site:
+                slices.append(site.split(":")[0])
 
 np.random.shuffle(slices)
 
 for i in range(N):
-	sl = slices.pop()
-	ffmode = np.random.randint(3, size=2)
-	clk = tuple(np.random.randint(16, size=2))
-	wclk = None
-	while wclk is None or wclk in clk:
-		wclk = np.random.randint(16)
-	sr = tuple(["1'b1" if y >= 16 else "sr[%d]" % y for y in np.random.randint(25, size=2)])
-	ce = tuple(["1'b1" if y >= 16 else "ce[%d]" % y for y in np.random.randint(25, size=4)])
-	we = np.random.randint(16)
-	def random_fftype(mode):
-		if mode == 0:
-			return np.random.choice(["NONE", "FDSE", "FDRE"])
-		elif mode == 1:
-			return np.random.choice(["NONE", "FDPE", "FDCE"])
-		elif mode == 2:
-			return np.random.choice(["NONE", "LDPE", "LDCE"])
+    sl = slices.pop()
+    ffmode = np.random.randint(3, size=2)
+    clk = tuple(np.random.randint(16, size=2))
+    wclk = None
+    while wclk is None or wclk in clk:
+        wclk = np.random.randint(16)
+    sr = tuple([
+        "1'b1" if y >= 16 else "sr[%d]" % y
+        for y in np.random.randint(25, size=2)
+    ])
+    ce = tuple([
+        "1'b1" if y >= 16 else "ce[%d]" % y
+        for y in np.random.randint(25, size=4)
+    ])
+    we = np.random.randint(16)
 
-	def random_bit():
-		return np.random.choice(D)
+    def random_fftype(mode):
+        if mode == 0:
+            return np.random.choice(["NONE", "FDSE", "FDRE"])
+        elif mode == 1:
+            return np.random.choice(["NONE", "FDPE", "FDCE"])
+        elif mode == 2:
+            return np.random.choice(["NONE", "LDPE", "LDCE"])
 
-	def random_data(width):
-		return "{%s}" % (", ".join([random_bit() for k in range(width)]))
+    def random_bit():
+        return np.random.choice(D)
 
-	#fftypes = [random_fftype(ffmode[j // 8]) for j in range(16)]
-	fftypes = ["NONE" for j in range(16)]
+    def random_data(width):
+        return "{%s}" % (", ".join([random_bit() for k in range(width)]))
 
-	dimux = []
-	mode = []
-	ram_legal = True
-	for lut in "HGFEDCBA":
-		choices = ["LOGIC"]
-		if lut == "H":
-			choices += ["RAMD64", "RAMS64", "RAMD32", "SRL16", "SRL32"]
-		else:
-			if mode[0][0:3] != "RAM":
-				choices += ["SRL16", "SRL32"]
-			if ram_legal:
-				choices.append(mode[0])
-		p = [0.1]
-		for j in range(1, len(choices)):
-			p.append(0.9 / (len(choices) - 1))
-		if len(choices) == 1:
-			p[0] = 1
-		next_mode = np.random.choice(choices, p=p)
-		if len(mode) > 0 and mode[-1] == "SRL32" and next_mode == "SRL32":
-			dimux.append(np.random.choice(["DI", "SIN"], p=[0.2, 0.8]))
-		else:
-			dimux.append("DI")
-		if next_mode[0:3] != "RAM":
-			ram_legal = False
-		mode.append(next_mode)
+    #fftypes = [random_fftype(ffmode[j // 8]) for j in range(16)]
+    fftypes = ["NONE" for j in range(16)]
 
-	dimux = list(reversed(dimux))
-	mode = list(reversed(mode))
+    dimux = []
+    mode = []
+    ram_legal = True
+    for lut in "HGFEDCBA":
+        choices = ["LOGIC"]
+        if lut == "H":
+            choices += ["RAMD64", "RAMS64", "RAMD32", "SRL16", "SRL32"]
+        else:
+            if mode[0][0:3] != "RAM":
+                choices += ["SRL16", "SRL32"]
+            if ram_legal:
+                choices.append(mode[0])
+        p = [0.1]
+        for j in range(1, len(choices)):
+            p.append(0.9 / (len(choices) - 1))
+        if len(choices) == 1:
+            p[0] = 1
+        next_mode = np.random.choice(choices, p=p)
+        if len(mode) > 0 and mode[-1] == "SRL32" and next_mode == "SRL32":
+            dimux.append(np.random.choice(["DI", "SIN"], p=[0.2, 0.8]))
+        else:
+            dimux.append("DI")
+        if next_mode[0:3] != "RAM":
+            ram_legal = False
+        mode.append(next_mode)
 
-	print('   wire [31:0] d%d;' % i)
-	print('   ultra_slice_memory #(')
-	print('      .LOC("%s"),' % sl)
-	for j in range(8):
-		print('      .%s_MODE("%s"),' % ("ABCDEFGH"[j], mode[j]))
-	for lut in "ABCDEFGH":
-		print("      .%sLUT_INIT(64'b%s)," % (lut, "".join(str(_) for _ in np.random.randint(2, size=64))))
-	for j in range(16):
-		print('      .%sFF%s_TYPE("%s"),' % ("ABCDEFGH"[j//2], "2" if (j % 2) == 1 else "", fftypes[j]))
-	print("      .FF_INIT(16'b%s)," % "".join(str(_) for _ in np.random.randint(2, size=16)))
-	for j1 in "ABCDEFGH":
-		for j2 in ("1", "2"):
-			print('        .FFMUX%s%s("%s"),' % (j1, j2, np.random.choice(["F7F8", "D6", "D5"])))
-	for j in "ABCDEFGH":
-		print('        .OUTMUX%s("%s"),' % (j, np.random.choice(["F7F8", "D6", "D5"])))
-	for j in range(7):
-		print('      .DIMUX%s("%s"),' % ("ABCDEFG"[j], dimux[j]))
-	print("      .WCLKINV(1'd%d)," % np.random.randint(2))
+    dimux = list(reversed(dimux))
+    mode = list(reversed(mode))
 
-	waused = np.random.randint(4)
+    print('   wire [31:0] d%d;' % i)
+    print('   ultra_slice_memory #(')
+    print('      .LOC("%s"),' % sl)
+    for j in range(8):
+        print('      .%s_MODE("%s"),' % ("ABCDEFGH" [j], mode[j]))
+    for lut in "ABCDEFGH":
+        print("      .%sLUT_INIT(64'b%s)," % (lut, "".join(
+            str(_) for _ in np.random.randint(2, size=64))))
+    for j in range(16):
+        print('      .%sFF%s_TYPE("%s"),' % ("ABCDEFGH" [j // 2], "2" if
+                                             (j % 2) == 1 else "", fftypes[j]))
+    print("      .FF_INIT(16'b%s)," % "".join(
+        str(_) for _ in np.random.randint(2, size=16)))
+    for j1 in "ABCDEFGH":
+        for j2 in ("1", "2"):
+            print('        .FFMUX%s%s("%s"),' %
+                  (j1, j2, np.random.choice(["F7F8", "D6", "D5"])))
+    for j in "ABCDEFGH":
+        print('        .OUTMUX%s("%s"),' %
+              (j, np.random.choice(["F7F8", "D6", "D5"])))
+    for j in range(7):
+        print('      .DIMUX%s("%s"),' % ("ABCDEFG" [j], dimux[j]))
+    print("      .WCLKINV(1'd%d)," % np.random.randint(2))
 
-	print("      .WA6USED(1'd%d)," % (1 if waused > 0 else 0))
-	print("      .WA7USED(1'd%d)," % (1 if waused > 1 else 0))
-	print("      .WA8USED(1'd%d)," % (1 if waused > 2 else 0))
-	print("      .CLKINV(2'd%d)," % np.random.randint(4))
-	print("      .SRINV(2'd%d)" % np.random.randint(4))
-	print('   ) slice%d (' % i)
-	for j in range(1, 7):
-		print("      .A%d(%s)," % (j, random_data(8)))
-	print("      .I(%s)," % random_data(8))
-	print("      .X(%s)," % random_data(8))
-	print("      .CLK({clk[%d], clk[%d]})," % clk[0:2])
-	print("      .WCLK(clk[%d])," % wclk)
-	print("      .SR({%s, %s})," % sr)
-	print("      .CE({%s, %s, %s, %s})," % ce[0:4])
-	print("      .WE(ce[%d])," % we)
-	print("      .O(d%d[7:0])," % i)
-	print("      .Q(d%d[15:8])," % i)
-	print("      .Q2(d%d[23:16])," % i)
-	print("      .MUX(d%d[31:24])" % i)
-	print('   );')
-	print()
-	D.clear()
-	for j in range(8):
-		D.append("d%d[%d]" % (i, j))
-		D.append("d%d[%d]" % (i, 24 + j))
-		if fftypes[2 * j] != "NONE":
-			D.append("d%d[%d]" % (i, 8 + j))
-		if fftypes[2 * j + 1] != "NONE":
-			D.append("d%d[%d]" % (i, 16 + j))
-print("    assign q = d%d;" % (N-1))
-print("endmodule")
\ No newline at end of file
+    waused = np.random.randint(4)
+
+    print("      .WA6USED(1'd%d)," % (1 if waused > 0 else 0))
+    print("      .WA7USED(1'd%d)," % (1 if waused > 1 else 0))
+    print("      .WA8USED(1'd%d)," % (1 if waused > 2 else 0))
+    print("      .CLKINV(2'd%d)," % np.random.randint(4))
+    print("      .SRINV(2'd%d)" % np.random.randint(4))
+    print('   ) slice%d (' % i)
+    for j in range(1, 7):
+        print("      .A%d(%s)," % (j, random_data(8)))
+    print("      .I(%s)," % random_data(8))
+    print("      .X(%s)," % random_data(8))
+    print("      .CLK({clk[%d], clk[%d]})," % clk[0:2])
+    print("      .WCLK(clk[%d])," % wclk)
+    print("      .SR({%s, %s})," % sr)
+    print("      .CE({%s, %s, %s, %s})," % ce[0:4])
+    print("      .WE(ce[%d])," % we)
+    print("      .O(d%d[7:0])," % i)
+    print("      .Q(d%d[15:8])," % i)
+    print("      .Q2(d%d[23:16])," % i)
+    print("      .MUX(d%d[31:24])" % i)
+    print('   );')
+    print()
+    D.clear()
+    for j in range(8):
+        D.append("d%d[%d]" % (i, j))
+        D.append("d%d[%d]" % (i, 24 + j))
+        if fftypes[2 * j] != "NONE":
+            D.append("d%d[%d]" % (i, 8 + j))
+        if fftypes[2 * j + 1] != "NONE":
+            D.append("d%d[%d]" % (i, 16 + j))
+print("    assign q = d%d;" % (N - 1))
+print("endmodule")
diff --git a/spec/slice_memory.v b/spec/slice_memory.v
index efe2fe7..95e99b9 100644
--- a/spec/slice_memory.v
+++ b/spec/slice_memory.v
@@ -207,7 +207,7 @@
 			"D5":    assign OUT = D5;
 			"CY":    assign OUT = CY;
 			"BYP":   assign OUT = BYP;
-		endcase		
+		endcase
 	endgenerate
 endmodule
 
@@ -228,7 +228,7 @@
 			"FDCE": (* LOC=LOC, BEL=BEL, keep, dont_touch *) FDCE #(.IS_C_INVERTED(CLKINV), .IS_CLR_INVERTED(SRINV), .INIT(INIT)) ff_i (.C(C), .CE(CE), .CLR(SR), .D(D), .Q(Q));
 			"FDSE": (* LOC=LOC, BEL=BEL, keep, dont_touch *) FDSE #(.IS_C_INVERTED(CLKINV), .IS_S_INVERTED(SRINV), .INIT(INIT)) ff_i (.C(C), .CE(CE), .S(SR), .D(D), .Q(Q));
 			"FDRE": (* LOC=LOC, BEL=BEL, keep, dont_touch *) FDRE #(.IS_C_INVERTED(CLKINV), .IS_R_INVERTED(SRINV), .INIT(INIT)) ff_i (.C(C), .CE(CE), .R(SR), .D(D), .Q(Q));
-			
+
 			"LDPE": (* LOC=LOC, BEL=BEL, keep, dont_touch *) LDPE #(.IS_G_INVERTED(CLKINV), .IS_PRE_INVERTED(SRINV), .INIT(INIT)) ff_i (.G(C), .GE(CE), .PRE(SR), .D(D), .Q(Q));
 			"LDCE": (* LOC=LOC, BEL=BEL, keep, dont_touch *) LDCE #(.IS_G_INVERTED(CLKINV), .IS_CLR_INVERTED(SRINV), .INIT(INIT)) ff_i (.G(C), .GE(CE), .CLR(SR), .D(D), .Q(Q));
 			"NONE": assign Q = INIT;
@@ -249,7 +249,7 @@
 			"D6":    assign OUT = D6;
 			"D5":    assign OUT = D5;
 			"CY":    assign OUT = CY;
-		endcase		
+		endcase
 	endgenerate
 endmodule
 
@@ -263,7 +263,7 @@
 		case(SEL)
 			"DI": assign OUT = DI;
 			"SIN":  assign OUT = SIN;
-		endcase		
+		endcase
 	endgenerate
 endmodule
 
@@ -302,7 +302,7 @@
 					.CLK(CLK), .WE(CE),
 					.I(DI[0]), .O(DO[1])
 				);
-			
+
 			end else if (WA6USED) begin
 				(* BEL=BEL6, LOC=LOC, keep, dont_touch *) RAMD64E #(.INIT(INIT), .IS_CLK_INVERTED(CLKINV)) ram_i (
 					.RADR0(A[0]), .RADR1(A[1]), .RADR2(A[2]), .RADR3(A[3]), .RADR4(A[4]), .RADR5(A[5]),
@@ -324,7 +324,7 @@
 			if (WA6USED && WA7USED && WA8USED) begin
 				(* BEL=BEL6, LOC=LOC, keep, dont_touch *) RAMS64E1 #(.INIT(INIT), .IS_CLK_INVERTED(CLKINV)) ram_i (
 					.ADR0(WA[0]), .ADR1(WA[1]), .ADR2(WA[2]), .ADR3(WA[3]), .ADR4(WA[4]), .ADR5(WA[5]),
-					.WADR6(WA[6]), .WADR7(WA[7]), .WADR8(WA[8]), 
+					.WADR6(WA[6]), .WADR7(WA[7]), .WADR8(WA[8]),
 					.CLK(CLK), .WE(CE),
 					.I(DI[0]), .O(DO[1])
 				);
@@ -366,13 +366,13 @@
 		end else if (MODE == "RAMD32") begin
 			(* BEL=BEL6, LOC=LOC, keep, dont_touch *) RAMD32 #(.INIT(INIT[63:32]), .IS_CLK_INVERTED(CLKINV)) ram1_i (
 				.WADR0(WA[0]), .WADR1(WA[1]), .WADR2(WA[2]), .WADR3(WA[3]), .WADR4(WA[4]),
-				.RADR0(A[0]), .RADR1(A[1]), .RADR2(A[2]), .RADR3(A[3]), .RADR4(A[4]), 
+				.RADR0(A[0]), .RADR1(A[1]), .RADR2(A[2]), .RADR3(A[3]), .RADR4(A[4]),
 				.CLK(CLK), .WE(CE),
 				.I(DI[1]), .O(DO[1])
 			);
 			(* BEL=BEL5, LOC=LOC, keep, dont_touch *) RAMD32 #(.INIT(INIT[31:0]), .IS_CLK_INVERTED(CLKINV)) ram0_i (
 				.WADR0(WA[0]), .WADR1(WA[1]), .WADR2(WA[2]), .WADR3(WA[3]), .WADR4(WA[4]),
-				.RADR0(A[0]), .RADR1(A[1]), .RADR2(A[2]), .RADR3(A[3]), .RADR4(A[4]), 
+				.RADR0(A[0]), .RADR1(A[1]), .RADR2(A[2]), .RADR3(A[3]), .RADR4(A[4]),
 				.CLK(CLK), .WE(CE),
 				.I(DI[0]), .O(DO[0])
 			);
diff --git a/tools/assemble.cpp b/tools/assemble.cpp
index f86e494..7036aa0 100644
--- a/tools/assemble.cpp
+++ b/tools/assemble.cpp
@@ -85,7 +85,7 @@
 		// e.g. word 3, bit 9
 		// offset: 0b10100110010 - concatenate (3 + (255 - 92)) [frame offset] and 9/4 [nibble offset]
 		// becomes: 0x10100110010
-		// shifted by bit in nibble (9%4): 0x20200220020 
+		// shifted by bit in nibble (9%4): 0x20200220020
 		uint32_t offset =  (word + (255 - 92)) << 3  | nib;
 		uint64_t exp_offset = 0;
 		// Odd parity
@@ -237,7 +237,7 @@
 			// Duplicate last frame in a row, but empty??
 			for (int i = 0; i < 93; i++)
 				fdata[i] = 0;
-			bsw.write_short_packet(OP_WRITE, FDRI, fdata);				
+			bsw.write_short_packet(OP_WRITE, FDRI, fdata);
 			bsw.write_short_packet(OP_WRITE, FAR, {fr.first});
 			bsw.write_crc();
 			if (next_frame.count(fr.first)) {
@@ -310,7 +310,7 @@
 			continue;
 		dest_set.insert(addr);
 		frames[addr].clear();
-		frames[addr].resize(93*32, false); 
+		frames[addr].resize(93*32, false);
 	}
 }
 
@@ -320,7 +320,7 @@
 		if (addr == 0x07FC0000)
 			continue;
 		frames[addr].clear();
-		frames[addr].resize(93*32, false); 
+		frames[addr].resize(93*32, false);
 		if (last_frame != 0xFFFFFFFF)
 			next_frame[last_frame] = addr;
 		last_frame = addr;
diff --git a/tools/bits.py b/tools/bits.py
index e493cc4..4729a08 100644
--- a/tools/bits.py
+++ b/tools/bits.py
@@ -22,60 +22,62 @@
 frame_rc_height = {}
 
 with open(sys.argv[1], 'r') as f:
-	for line in f:
-		m = frame_line_re.match(line)
-		if not m:
-			continue
-		frame = int(m.group(1), 16)
-		bus = (frame >> 24) & 0x7
-		half = (frame >> 23) & 0x1
-		row = (frame >> 18) & 0x1F
-		col = (frame >> 8) & 0x3FF
-		minor = frame & 0xFF
-		if bus != 0 or half != 0:
-			continue
-		if (row, col) not in frame_rc_height:
-			frame_rc_height[(row, col, frame & ~0xFF)] = minor + 1
-		else:
-			frame_rc_height[(row, col, frame & ~0xFF)] = max(frame_rc_height[(row, col)], minor + 1)
+    for line in f:
+        m = frame_line_re.match(line)
+        if not m:
+            continue
+        frame = int(m.group(1), 16)
+        bus = (frame >> 24) & 0x7
+        half = (frame >> 23) & 0x1
+        row = (frame >> 18) & 0x1F
+        col = (frame >> 8) & 0x3FF
+        minor = frame & 0xFF
+        if bus != 0 or half != 0:
+            continue
+        if (row, col) not in frame_rc_height:
+            frame_rc_height[(row, col, frame & ~0xFF)] = minor + 1
+        else:
+            frame_rc_height[(row, col, frame & ~0xFF)] = max(
+                frame_rc_height[(row, col)], minor + 1)
 
 tiles_to_xy = {}
 with open(sys.argv[2], 'r') as tilef:
-	for line in tilef:
-		sl = line.strip().split(",")
-		if len(sl) < 4:
-			continue
-		x = int(sl[0])
-		y = int(sl[1])
-		name = sl[2]
-		tiles_to_xy[name] = (x, y)
+    for line in tilef:
+        sl = line.strip().split(",")
+        if len(sl) < 4:
+            continue
+        x = int(sl[0])
+        y = int(sl[1])
+        name = sl[2]
+        tiles_to_xy[name] = (x, y)
 
 with open(sys.argv[3]) as tb_f:
-	tbj = json.load(tb_f)
+    tbj = json.load(tb_f)
 
-frames_to_tiles = {} 
+frames_to_tiles = {}
 for tilename, tiledata in tbj.items():
-	tile_offset = 0
-	for chunk in tiledata:
-		frame, start, size = chunk
-		if frame not in frames_to_tiles:
-			frames_to_tiles[frame] = []
-		name = tilename.split(":")[0]
-		frames_to_tiles[frame].append((start, tiles_to_xy[name][1], tiles_to_xy[name][0], name))
-		tile_offset += size
+    tile_offset = 0
+    for chunk in tiledata:
+        frame, start, size = chunk
+        if frame not in frames_to_tiles:
+            frames_to_tiles[frame] = []
+        name = tilename.split(":")[0]
+        frames_to_tiles[frame].append((start, tiles_to_xy[name][1],
+                                       tiles_to_xy[name][0], name))
+        tile_offset += size
 
 for frame, tiles in frames_to_tiles.items():
-	tiles.sort()
+    tiles.sort()
 
 for rc, height in sorted(frame_rc_height.items()):
-	row, col, frame = rc
-	line = "%08x %6d %6d %6d" % (frame, row, col, height)
-	print(line)
-	frame = (row << 18) | (col << 8)
-	last_start = 0;
-	if frame in frames_to_tiles and len(frames_to_tiles[frame]) > 0:
-		for tile in frames_to_tiles[frame]:
-			start, ty, tx, tname = tile
-			print("                            %6d (%4d) %6d %6d %s" % (start, start - last_start, tx, ty, tname))
-			last_start = start
-
+    row, col, frame = rc
+    line = "%08x %6d %6d %6d" % (frame, row, col, height)
+    print(line)
+    frame = (row << 18) | (col << 8)
+    last_start = 0
+    if frame in frames_to_tiles and len(frames_to_tiles[frame]) > 0:
+        for tile in frames_to_tiles[frame]:
+            start, ty, tx, tname = tile
+            print("                            %6d (%4d) %6d %6d %s" %
+                  (start, start - last_start, tx, ty, tname))
+            last_start = start
diff --git a/tools/bits_to_tiles.py b/tools/bits_to_tiles.py
index 42a5928..858e880 100644
--- a/tools/bits_to_tiles.py
+++ b/tools/bits_to_tiles.py
@@ -17,45 +17,45 @@
 import json
 
 line_re = re.compile(r'F(0x[0-9A-Fa-f]+)W(\d+)B(\d+)')
-frames_to_tiles = {} # (start, size, tile, tile offset)
- 
+frames_to_tiles = {}  # (start, size, tile, tile offset)
+
 with open(sys.argv[1]) as tb_f:
-	tbj = json.load(tb_f)
+    tbj = json.load(tb_f)
 
 for tilename, tiledata in tbj.items():
-	tile_offset = 0
-	for chunk in tiledata:
-		frame, start, size = chunk
-		if frame not in frames_to_tiles:
-			frames_to_tiles[frame] = []
-		frames_to_tiles[frame].append((start, size, tilename, tile_offset))
-		tile_offset += size
+    tile_offset = 0
+    for chunk in tiledata:
+        frame, start, size = chunk
+        if frame not in frames_to_tiles:
+            frames_to_tiles[frame] = []
+        frames_to_tiles[frame].append((start, size, tilename, tile_offset))
+        tile_offset += size
 
 tile_bits = {}
 
 # Always write these tiles to avoid correlation issues
 # (distinguishing between all/no bits)
 for tilename, tiledata in tbj.items():
-	if "INT_INTF_L_IO" in tilename:
-		tile_bits[tilename] = set()
+    if "INT_INTF_L_IO" in tilename:
+        tile_bits[tilename] = set()
 
 with open(sys.argv[2]) as df:
-	for line in df:
-		m = line_re.match(line)
-		if not m:
-			continue
-		frame = int(m[1], 16)
-		if frame not in frames_to_tiles:
-			continue
-		framebit = int(m[2]) * 32 + int(m[3])
-		for fb in frames_to_tiles[frame]:
-			start, size, tile, toff = fb
-			if framebit >= start and framebit < (start + size):
-				if tile not in tile_bits:
-					tile_bits[tile] = set()
-				tile_bits[tile].add(toff + (framebit - start))
+    for line in df:
+        m = line_re.match(line)
+        if not m:
+            continue
+        frame = int(m[1], 16)
+        if frame not in frames_to_tiles:
+            continue
+        framebit = int(m[2]) * 32 + int(m[3])
+        for fb in frames_to_tiles[frame]:
+            start, size, tile, toff = fb
+            if framebit >= start and framebit < (start + size):
+                if tile not in tile_bits:
+                    tile_bits[tile] = set()
+                tile_bits[tile].add(toff + (framebit - start))
 
 for tile, bits in sorted(tile_bits.items()):
-	print(".tile %s" % tile)
-	for b in sorted(bits):
-		print(b)
+    print(".tile %s" % tile)
+    for b in sorted(bits):
+        print(b)
diff --git a/tools/columns.py b/tools/columns.py
index 826cc04..132349b 100644
--- a/tools/columns.py
+++ b/tools/columns.py
@@ -22,59 +22,60 @@
 frame_rc_height = {}
 
 with open(sys.argv[1], 'r') as f:
-	for line in f:
-		m = frame_line_re.match(line)
-		if not m:
-			continue
-		frame = int(m.group(1), 16)
-		bus = (frame >> 24) & 0x7
-		half = (frame >> 23) & 0x1
-		row = (frame >> 18) & 0x1F
-		col = (frame >> 8) & 0x3FF
-		minor = frame & 0xFF
-		if bus != 0 or half != 0:
-			continue
-		if (row, col) not in frame_rc_height:
-			frame_rc_height[(row, col)] = minor + 1
-		else:
-			frame_rc_height[(row, col)] = max(frame_rc_height[(row, col)], minor + 1)
+    for line in f:
+        m = frame_line_re.match(line)
+        if not m:
+            continue
+        frame = int(m.group(1), 16)
+        bus = (frame >> 24) & 0x7
+        half = (frame >> 23) & 0x1
+        row = (frame >> 18) & 0x1F
+        col = (frame >> 8) & 0x3FF
+        minor = frame & 0xFF
+        if bus != 0 or half != 0:
+            continue
+        if (row, col) not in frame_rc_height:
+            frame_rc_height[(row, col)] = minor + 1
+        else:
+            frame_rc_height[(row, col)] = max(frame_rc_height[(row, col)],
+                                              minor + 1)
 
 tiles_to_xy = {}
 with open(sys.argv[2], 'r') as tilef:
-	for line in tilef:
-		sl = line.strip().split(",")
-		if len(sl) < 4:
-			continue
-		x = int(sl[0])
-		y = int(sl[1])
-		name = sl[2]
-		tiles_to_xy[name] = (x, y)
+    for line in tilef:
+        sl = line.strip().split(",")
+        if len(sl) < 4:
+            continue
+        x = int(sl[0])
+        y = int(sl[1])
+        name = sl[2]
+        tiles_to_xy[name] = (x, y)
 
 with open(sys.argv[3]) as tb_f:
-	tbj = json.load(tb_f)
+    tbj = json.load(tb_f)
 
-frames_to_tiles = {} 
+frames_to_tiles = {}
 for tilename, tiledata in tbj.items():
-	tile_offset = 0
-	for chunk in tiledata:
-		frame, start, size = chunk
-		if frame not in frames_to_tiles:
-			frames_to_tiles[frame] = []
-		name = tilename.split(":")[0]
-		frames_to_tiles[frame].append((tiles_to_xy[name][1], tiles_to_xy[name][0], name))
-		tile_offset += size
+    tile_offset = 0
+    for chunk in tiledata:
+        frame, start, size = chunk
+        if frame not in frames_to_tiles:
+            frames_to_tiles[frame] = []
+        name = tilename.split(":")[0]
+        frames_to_tiles[frame].append((tiles_to_xy[name][1],
+                                       tiles_to_xy[name][0], name))
+        tile_offset += size
 
 for frame, tiles in frames_to_tiles.items():
-	tiles.sort()
+    tiles.sort()
 
 print("row    col    height tx     ty     tname")
 
 for rc, height in sorted(frame_rc_height.items()):
-	row, col = rc
-	line = "%6d %6d %6d" % (row, col, height)
-	frame = (row << 18) | (col << 8)
-	if frame in frames_to_tiles and len(frames_to_tiles[frame]) > 0:
-		ty, tx, tname = frames_to_tiles[frame][0]
-		line += " %6d %6d %s" % (tx, ty, tname)
-	print(line)
-
+    row, col = rc
+    line = "%6d %6d %6d" % (row, col, height)
+    frame = (row << 18) | (col << 8)
+    if frame in frames_to_tiles and len(frames_to_tiles[frame]) > 0:
+        ty, tx, tname = frames_to_tiles[frame][0]
+        line += " %6d %6d %s" % (tx, ty, tname)
+    print(line)
diff --git a/tools/common.h b/tools/common.h
index 481e842..21565a0 100644
--- a/tools/common.h
+++ b/tools/common.h
@@ -1,16 +1,16 @@
 #ifndef COMMON_H
 #define COMMON_H
 
-#include <stdint.h>
-#include <string>
-#include <vector>
-#include <iostream>
 #include <fstream>
-#include <stdexcept>
+#include <iostream>
 #include <map>
 #include <set>
-#include <unordered_map>
 #include <stdarg.h>
+#include <stdexcept>
+#include <stdint.h>
+#include <string>
+#include <unordered_map>
+#include <vector>
 constexpr uint32_t kCrc32CastagnoliPolynomial = 0x82F63B78;
 
 // From prjxray
@@ -21,191 +21,183 @@
 // frame data (32bit) pair and return the newly computed CRC value.
 
 inline uint32_t icap_crc(uint32_t addr, uint32_t data, uint32_t prev) {
-	constexpr int kAddressBitWidth = 5;
-	constexpr int kDataBitWidth = 32;
+  constexpr int kAddressBitWidth = 5;
+  constexpr int kDataBitWidth = 32;
 
-	uint64_t poly = static_cast<uint64_t>(kCrc32CastagnoliPolynomial) << 1;
-	uint64_t val = (static_cast<uint64_t>(addr) << 32) | data;
-	uint64_t crc = prev;
+  uint64_t poly = static_cast<uint64_t>(kCrc32CastagnoliPolynomial) << 1;
+  uint64_t val = (static_cast<uint64_t>(addr) << 32) | data;
+  uint64_t crc = prev;
 
-	for (int i = 0; i < kAddressBitWidth + kDataBitWidth; i++) {
-		if ((val & 1) != (crc & 1))
-			crc ^= poly;
+  for (int i = 0; i < kAddressBitWidth + kDataBitWidth; i++) {
+    if ((val & 1) != (crc & 1))
+      crc ^= poly;
 
-		val >>= 1;
-		crc >>= 1;
-	}
-	return crc;
+    val >>= 1;
+    crc >>= 1;
+  }
+  return crc;
 }
 
 // From Yosys
-inline std::string vstringf(const char *fmt, va_list ap)
-{
-	std::string string;
-	char *str = NULL;
+inline std::string vstringf(const char *fmt, va_list ap) {
+  std::string string;
+  char *str = NULL;
 
-#if defined(_WIN32 )|| defined(__CYGWIN__)
-	int sz = 64, rc;
-	while (1) {
-		va_list apc;
-		va_copy(apc, ap);
-		str = (char*)realloc(str, sz);
-		rc = vsnprintf(str, sz, fmt, apc);
-		va_end(apc);
-		if (rc >= 0 && rc < sz)
-			break;
-		sz *= 2;
-	}
+#if defined(_WIN32) || defined(__CYGWIN__)
+  int sz = 64, rc;
+  while (1) {
+    va_list apc;
+    va_copy(apc, ap);
+    str = (char *)realloc(str, sz);
+    rc = vsnprintf(str, sz, fmt, apc);
+    va_end(apc);
+    if (rc >= 0 && rc < sz)
+      break;
+    sz *= 2;
+  }
 #else
-	if (vasprintf(&str, fmt, ap) < 0)
-		str = NULL;
+  if (vasprintf(&str, fmt, ap) < 0)
+    str = NULL;
 #endif
 
-	if (str != NULL) {
-		string = str;
-		free(str);
-	}
+  if (str != NULL) {
+    string = str;
+    free(str);
+  }
 
-	return string;
+  return string;
 }
 
-inline std::string stringf(const char *fmt, ...)
-{
-	std::string string;
-	va_list ap;
+inline std::string stringf(const char *fmt, ...) {
+  std::string string;
+  va_list ap;
 
-	va_start(ap, fmt);
-	string = vstringf(fmt, ap);
-	va_end(ap);
+  va_start(ap, fmt);
+  string = vstringf(fmt, ap);
+  va_end(ap);
 
-	return string;
+  return string;
 }
 
 // Bitstream definitions
 
-enum BitstreamOp : uint8_t {
-	OP_NOP = 0,
-	OP_READ = 1,
-	OP_WRITE = 2
-};
+enum BitstreamOp : uint8_t { OP_NOP = 0, OP_READ = 1, OP_WRITE = 2 };
 
 // File and database convenience functions
 // Line-by-line reader, skipping over blank lines and comments
 struct LineReader {
-	LineReader(const std::string &filename) {
-		in.open(filename);
-		if (!in) {
-			throw std::runtime_error("failed to open " + filename);
-		}
-	}
-	std::ifstream in;
-	std::string linebuf;
-	bool at_sof = true;
+  LineReader(const std::string &filename) {
+    in.open(filename);
+    if (!in) {
+      throw std::runtime_error("failed to open " + filename);
+    }
+  }
+  std::ifstream in;
+  std::string linebuf;
+  bool at_sof = true;
 
-	struct iterator {
-		LineReader *parent = nullptr;
-		bool at_end = false;
-		inline bool operator!=(const iterator &other) const {
-			return at_end != other.at_end;
-		};
-		inline const std::string& operator*() const {
-			return parent->linebuf;
-		}
-		inline iterator &operator++() {
-			parent->next();
-			at_end = parent->linebuf.empty();
-			return *this;
-		}
-	};
+  struct iterator {
+    LineReader *parent = nullptr;
+    bool at_end = false;
+    inline bool operator!=(const iterator &other) const {
+      return at_end != other.at_end;
+    };
+    inline const std::string &operator*() const { return parent->linebuf; }
+    inline iterator &operator++() {
+      parent->next();
+      at_end = parent->linebuf.empty();
+      return *this;
+    }
+  };
 
-	void next() {
-		while (std::getline(in, linebuf)) {
-			auto cpos = linebuf.find('#');
-			if (cpos != std::string::npos)
-				linebuf = linebuf.substr(0, cpos);
-			if (linebuf.empty())
-				continue;
-			linebuf = linebuf.substr(linebuf.find_first_not_of(" \t"));
-			if (linebuf.empty())
-				continue;			
-			break;
-		}
-		at_sof = false;
-	}
+  void next() {
+    while (std::getline(in, linebuf)) {
+      auto cpos = linebuf.find('#');
+      if (cpos != std::string::npos)
+        linebuf = linebuf.substr(0, cpos);
+      if (linebuf.empty())
+        continue;
+      linebuf = linebuf.substr(linebuf.find_first_not_of(" \t"));
+      if (linebuf.empty())
+        continue;
+      break;
+    }
+    at_sof = false;
+  }
 
-	iterator begin() {
-		if (at_sof)
-			next();
-		return iterator{this, linebuf.empty()};
-	}
+  iterator begin() {
+    if (at_sof)
+      next();
+    return iterator{this, linebuf.empty()};
+  }
 
-	iterator end() {
-		return iterator{this, true};
-	}
+  iterator end() { return iterator{this, true}; }
 };
 
 struct TileInstance {
-	std::string name;
-	int type;
-	int x, y;
-	struct TileBitMapping {
-		int frame_offset;
-		int bit_offset;
-		int size;
-	};
-	std::vector<TileBitMapping> bits;
+  std::string name;
+  int type;
+  int x, y;
+  struct TileBitMapping {
+    int frame_offset;
+    int bit_offset;
+    int size;
+  };
+  std::vector<TileBitMapping> bits;
 };
 
 struct TileType {
-	std::string type;
-	bool loaded_db = false;
-	std::unordered_map<std::string, std::vector<int>> features;
+  std::string type;
+  bool loaded_db = false;
+  std::unordered_map<std::string, std::vector<int>> features;
 };
 
 struct ChipData {
 
-	std::string root;
-	void open(const std::string &root);
-	void load_frames();
-	void load_tiles();
-	void load_tiletype_database(int type);
+  std::string root;
+  void open(const std::string &root);
+  void load_frames();
+  void load_tiles();
+  void load_tiletype_database(int type);
 
-	std::unordered_map<std::string, TileInstance> tiles;
-	inline TileInstance &get_tile_by_name(const std::string &name) {
-		return tiles.at(name);
-	}
+  std::unordered_map<std::string, TileInstance> tiles;
+  inline TileInstance &get_tile_by_name(const std::string &name) {
+    return tiles.at(name);
+  }
 
-	std::vector<TileType> tiletypes;
-	std::unordered_map<std::string, int> tiletype_by_name;
-	TileType &get_tiletype_by_name(const std::string &name) {
-		return tiletypes.at(tiletype_by_name.at(name));
-	}
-	TileType &load_tile_database(const std::string &tile) {
-		int type = tiles.at(tile).type;
-		load_tiletype_database(type);
-		return tiletypes.at(type);
-	}
+  std::vector<TileType> tiletypes;
+  std::unordered_map<std::string, int> tiletype_by_name;
+  TileType &get_tiletype_by_name(const std::string &name) {
+    return tiletypes.at(tiletype_by_name.at(name));
+  }
+  TileType &load_tile_database(const std::string &tile) {
+    int type = tiles.at(tile).type;
+    load_tiletype_database(type);
+    return tiletypes.at(type);
+  }
 
-	std::set<uint32_t> all_frames;
-
+  std::set<uint32_t> all_frames;
 };
 
-inline void split_str(const std::string &s, std::vector<std::string> &dest, const std::string &delim = " ", bool skip_empty = true, int lim = -1) {
-	dest.clear();
-	std::string buf;
+inline void split_str(const std::string &s, std::vector<std::string> &dest,
+                      const std::string &delim = " ", bool skip_empty = true,
+                      int lim = -1) {
+  dest.clear();
+  std::string buf;
 
-	for (char c : s) {
-		if (delim.find(c) != std::string::npos && (lim == -1 || int(dest.size()) < lim)) {
-			if (!buf.empty() || !skip_empty)
-				dest.push_back(buf);
-			buf.clear();
-		} else {
-			buf += c;
-		}
-	}
+  for (char c : s) {
+    if (delim.find(c) != std::string::npos &&
+        (lim == -1 || int(dest.size()) < lim)) {
+      if (!buf.empty() || !skip_empty)
+        dest.push_back(buf);
+      buf.clear();
+    } else {
+      buf += c;
+    }
+  }
 
-	if (!buf.empty())
-		dest.push_back(buf);
+  if (!buf.empty())
+    dest.push_back(buf);
 }
 
 #endif
\ No newline at end of file
diff --git a/tools/dump_bitstream.cpp b/tools/dump_bitstream.cpp
index c1b3689..a4b7169 100644
--- a/tools/dump_bitstream.cpp
+++ b/tools/dump_bitstream.cpp
@@ -115,7 +115,7 @@
 		// e.g. word 3, bit 9
 		// offset: 0b10100110010 - concatenate (3 + (255 - 92)) [frame offset] and 9/4 [nibble offset]
 		// becomes: 0x10100110010
-		// shifted by bit in nibble (9%4): 0x20200220020 
+		// shifted by bit in nibble (9%4): 0x20200220020
 		uint32_t offset =  (word + (255 - 92)) << 3  | nib;
 		uint64_t exp_offset = 0;
 		// Odd parity
@@ -142,7 +142,7 @@
 					exp_checksum ^= get_ecc_value(word, i);
 				}
 				std::cout <<  stringf("F0x%08xW%03dB%02d", frame, word, i) << std::endl;
-			}			
+			}
 		++word;
 		if (word >= 93 && next_frame.count(frame)) {
 			// 4 parity bits for each bit in nibbles
@@ -273,6 +273,6 @@
 		std::cerr << "Failed to open input file" << std::endl;
 		return 2;
 	}
-	rd.data.insert(rd.data.begin(), std::istream_iterator<uint8_t>(file), std::istream_iterator<uint8_t>()); 
+	rd.data.insert(rd.data.begin(), std::istream_iterator<uint8_t>(file), std::istream_iterator<uint8_t>());
 	parse_bitstream(rd);
 }
\ No newline at end of file
diff --git a/tools/explain.cpp b/tools/explain.cpp
index acc1d07..0d42518 100644
--- a/tools/explain.cpp
+++ b/tools/explain.cpp
@@ -78,7 +78,7 @@
 // Currently have poor quality DBs for these tiles,
 // skip outputting them
 std::set<std::string> skip_tiles = {
-	"CLEL_L", "CLEM_R", "RCLK_INT_R", 
+	"CLEL_L", "CLEM_R", "RCLK_INT_R",
 };
 
 
diff --git a/tools/filter.py b/tools/filter.py
index 8776311..c29e1c4 100644
--- a/tools/filter.py
+++ b/tools/filter.py
@@ -17,14 +17,14 @@
 import json
 
 line_re = re.compile(r'F(0x[0-9A-Fa-f]+)W(\d+)B(\d+)')
-frames_to_tiles = {} # (start, size, tile, tile offset)
+frames_to_tiles = {}  # (start, size, tile, tile offset)
 
 active = False
 
 with open(sys.argv[1]) as f:
-	for line in f:
-		sl = line.strip()
-		if sl[0] == '.':
-			active = sys.argv[2] in sl
-		if active:
-			print(sl)
\ No newline at end of file
+    for line in f:
+        sl = line.strip()
+        if sl[0] == '.':
+            active = sys.argv[2] in sl
+        if active:
+            print(sl)
diff --git a/tools/frames.py b/tools/frames.py
index 8265cb3..ceb5bb3 100644
--- a/tools/frames.py
+++ b/tools/frames.py
@@ -20,18 +20,18 @@
 outlines = set()
 
 with open(sys.argv[1], 'r') as f:
-	for line in f:
-		m = line_re.match(line)
-		if not m:
-			continue
-		frame = int(m.group(1), 16)
-		bus = (frame >> 24) & 0x7
-		half = (frame >> 23) & 0x1
-		row = (frame >> 18) & 0x1F
-		col = (frame >> 8) & 0x3FF
-		minor = frame & 0xFF
-		outlines.add("F=%08x B=%d H=%d R=%03d C=%04d M=%03d"
-							% (frame, bus, half, row, col, minor))
+    for line in f:
+        m = line_re.match(line)
+        if not m:
+            continue
+        frame = int(m.group(1), 16)
+        bus = (frame >> 24) & 0x7
+        half = (frame >> 23) & 0x1
+        row = (frame >> 18) & 0x1F
+        col = (frame >> 8) & 0x3FF
+        minor = frame & 0xFF
+        outlines.add("F=%08x B=%d H=%d R=%03d C=%04d M=%03d" %
+                     (frame, bus, half, row, col, minor))
 
 for o in sorted(outlines):
-	print(o)
+    print(o)
diff --git a/tools/frames_2.py b/tools/frames_2.py
index 0fe5890..eb55fc5 100644
--- a/tools/frames_2.py
+++ b/tools/frames_2.py
@@ -20,18 +20,18 @@
 outlines = set()
 
 with open(sys.argv[1], 'r') as f:
-	for line in f:
-		m = line_re.match(line)
-		if not m:
-			continue
-		frame = int(m.group(1), 16)
-		bus = (frame >> 24) & 0x7
-		half = (frame >> 23) & 0x1
-		row = (frame >> 18) & 0x1F
-		col = (frame >> 8) & 0x3FF
-		minor = frame & 0xFF
-		outlines.add("F=%08x B=%d H=%d R=%03d C=%04d M=%03d"
-							% (frame, bus, half, row, col, minor))
+    for line in f:
+        m = line_re.match(line)
+        if not m:
+            continue
+        frame = int(m.group(1), 16)
+        bus = (frame >> 24) & 0x7
+        half = (frame >> 23) & 0x1
+        row = (frame >> 18) & 0x1F
+        col = (frame >> 8) & 0x3FF
+        minor = frame & 0xFF
+        outlines.add("F=%08x B=%d H=%d R=%03d C=%04d M=%03d" %
+                     (frame, bus, half, row, col, minor))
 
 for o in sorted(outlines):
-	print(o)
+    print(o)
diff --git a/tools/ll.py b/tools/ll.py
index f65beb9..853198a 100644
--- a/tools/ll.py
+++ b/tools/ll.py
@@ -15,24 +15,26 @@
 import re
 import sys
 
-line_re = re.compile(r'Bit\s+\d+\s+(0x[0-9A-Fa-f]+)\s+\d+\s+SLR\d\s+\d+\s+Block=([A-Za-z0-9_]+).*')
+line_re = re.compile(
+    r'Bit\s+\d+\s+(0x[0-9A-Fa-f]+)\s+\d+\s+SLR\d\s+\d+\s+Block=([A-Za-z0-9_]+).*'
+)
 
 outlines = set()
 
 with open(sys.argv[1], 'r') as f:
-	for line in f:
-		m = line_re.match(line)
-		if not m:
-			continue
-		frame = int(m.group(1), 16)
-		site = m.group(2)
-		bus = (frame >> 24) & 0x7
-		half = (frame >> 23) & 0x1
-		row = (frame >> 18) & 0x1F
-		col = (frame >> 8) & 0x3FF
-		minor = frame & 0xFF
-		outlines.add("F=%08x B=%d H=%d R=%03d C=%04d M=%03d %s"
-							% (frame, bus, half, row, col, minor, site))
+    for line in f:
+        m = line_re.match(line)
+        if not m:
+            continue
+        frame = int(m.group(1), 16)
+        site = m.group(2)
+        bus = (frame >> 24) & 0x7
+        half = (frame >> 23) & 0x1
+        row = (frame >> 18) & 0x1F
+        col = (frame >> 8) & 0x3FF
+        minor = frame & 0xFF
+        outlines.add("F=%08x B=%d H=%d R=%03d C=%04d M=%03d %s" %
+                     (frame, bus, half, row, col, minor, site))
 
 for o in sorted(outlines):
-	print(o)
+    print(o)
diff --git a/tools/oddtiles.py b/tools/oddtiles.py
index 82451cf..a34579f 100644
--- a/tools/oddtiles.py
+++ b/tools/oddtiles.py
@@ -17,42 +17,42 @@
 import json
 
 line_re = re.compile(r'F(0x[0-9A-Fa-f]+)W(\d+)B(\d+)')
-frames_to_tiles = {} # (start, size, tile, tile offset)
+frames_to_tiles = {}  # (start, size, tile, tile offset)
 
 with open(sys.argv[1]) as tb_f:
-	tbj = json.load(tb_f)
+    tbj = json.load(tb_f)
 
 for tilename, tiledata in tbj.items():
-	tile_offset = 0
-	for chunk in tiledata:
-		frame, start, size = chunk
-		if frame not in frames_to_tiles:
-			frames_to_tiles[frame] = []
-		frames_to_tiles[frame].append((start, size, tilename, tile_offset))
-		tile_offset += size
+    tile_offset = 0
+    for chunk in tiledata:
+        frame, start, size = chunk
+        if frame not in frames_to_tiles:
+            frames_to_tiles[frame] = []
+        frames_to_tiles[frame].append((start, size, tilename, tile_offset))
+        tile_offset += size
 
 tile_bits = {}
 
 with open(sys.argv[2]) as df:
-	for line in df:
-		m = line_re.match(line)
-		if not m:
-			continue
-		frame = int(m[1], 16)
-		if frame not in frames_to_tiles:
-			continue
-		framebit = int(m[2]) * 32 + int(m[3])
-		for fb in frames_to_tiles[frame]:
-			start, size, tile, toff = fb
-			if framebit > start and framebit < (start + size):
-				if tile not in tile_bits:
-					tile_bits[tile] = set()
-				tile_bits[tile].add(toff + (framebit - start))
+    for line in df:
+        m = line_re.match(line)
+        if not m:
+            continue
+        frame = int(m[1], 16)
+        if frame not in frames_to_tiles:
+            continue
+        framebit = int(m[2]) * 32 + int(m[3])
+        for fb in frames_to_tiles[frame]:
+            start, size, tile, toff = fb
+            if framebit > start and framebit < (start + size):
+                if tile not in tile_bits:
+                    tile_bits[tile] = set()
+                tile_bits[tile].add(toff + (framebit - start))
 
 for tile, bits in sorted(tile_bits.items()):
-	if "CLE" in tile:
-		if 152 not in bits:
-			print(tile)
-	if "INT" in tile:
-		if 3640 not in bits:
-			print(tile)
\ No newline at end of file
+    if "CLE" in tile:
+        if 152 not in bits:
+            print(tile)
+    if "INT" in tile:
+        if 3640 not in bits:
+            print(tile)
diff --git a/tools/roi.py b/tools/roi.py
index e1b217a..8676552 100644
--- a/tools/roi.py
+++ b/tools/roi.py
@@ -17,62 +17,45 @@
 import json
 # Usage: tilegrid.json
 with open(sys.argv[1]) as tb_f:
-	tbj = json.load(tb_f)
+    tbj = json.load(tb_f)
 tile_to_frames = {}
 frame_to_tiles = {}
 for tilename, tiledata in tbj.items():
-	tn = tilename.split(":")[0]
-	tile_offset = 0
-	tile_to_frames[tn] = []
-	for chunk in tiledata:
-		frame, start, size = chunk
-		tile_to_frames[tn].append(frame)
-		if frame not in frame_to_tiles:
-			frame_to_tiles[frame] = []
-		frame_to_tiles[frame].append(tn)
+    tn = tilename.split(":")[0]
+    tile_offset = 0
+    tile_to_frames[tn] = []
+    for chunk in tiledata:
+        frame, start, size = chunk
+        tile_to_frames[tn].append(frame)
+        if frame not in frame_to_tiles:
+            frame_to_tiles[frame] = []
+        frame_to_tiles[frame].append(tn)
 basis_tiles = [
-	"CLEM_X41Y120",
-	"INT_X41Y120",
-	"CLEL_R_X41Y120",
-	"BRAM_X42Y120",
-	"INT_INTF_L_X42Y120",
-	"INT_X42Y120",
-	"CLEL_R_X42Y120",
-	"CLEM_X43Y120",
-	"INT_X43Y120",
-	"INT_INTF_R_X43Y120",
-	"DSP_X43Y120",
-	"CLEM_X44Y120",
-	"INT_X44Y120",
-	"CLEL_R_X44Y120",
-	"CLEM_X45Y120",
-	"INT_X45Y120",
-	"INT_INTF_R_X45Y120",
-	"DSP_X45Y120",
-	"CLEM_X46Y120",
-	"INT_X46Y120",
-	"CLEL_R_X46Y120",
-	"INT_X47Y120",
-	"CLEL_R_X47Y120"
+    "CLEM_X41Y120", "INT_X41Y120", "CLEL_R_X41Y120", "BRAM_X42Y120",
+    "INT_INTF_L_X42Y120", "INT_X42Y120", "CLEL_R_X42Y120", "CLEM_X43Y120",
+    "INT_X43Y120", "INT_INTF_R_X43Y120", "DSP_X43Y120", "CLEM_X44Y120",
+    "INT_X44Y120", "CLEL_R_X44Y120", "CLEM_X45Y120", "INT_X45Y120",
+    "INT_INTF_R_X45Y120", "DSP_X45Y120", "CLEM_X46Y120", "INT_X46Y120",
+    "CLEL_R_X46Y120", "INT_X47Y120", "CLEL_R_X47Y120"
 ]
 
 roi_frames = set()
 
 for tile in basis_tiles:
-	if tile not in tile_to_frames:
-		continue
-	for frame in tile_to_frames[tile]:
-		roi_frames.add(frame)
+    if tile not in tile_to_frames:
+        continue
+    for frame in tile_to_frames[tile]:
+        roi_frames.add(frame)
 
 roi_tiles = set()
 for frame in roi_frames:
-	for tile in frame_to_tiles[frame]:
-		roi_tiles.add(tile)
+    for tile in frame_to_tiles[frame]:
+        roi_tiles.add(tile)
 
-with open(sys.argv[2], "w") as frames_f: 
-	for frame in sorted(roi_frames):
-		print("0x%08x" % frame, file=frames_f)
+with open(sys.argv[2], "w") as frames_f:
+    for frame in sorted(roi_frames):
+        print("0x%08x" % frame, file=frames_f)
 
 with open(sys.argv[3], "w") as tiles_f:
-	for tile in sorted(roi_tiles):
-		print("tile %s" % tile, file=tiles_f)
\ No newline at end of file
+    for tile in sorted(roi_tiles):
+        print("tile %s" % tile, file=tiles_f)
diff --git a/tools/stripdb.cpp b/tools/stripdb.cpp
index 01ff1ab..6991ee6 100644
--- a/tools/stripdb.cpp
+++ b/tools/stripdb.cpp
@@ -69,7 +69,7 @@
 	// Currently have poor quality DBs for these tiles,
 	// skip outputting them
 	std::set<std::string> skip_tiles = {
-		"CLEL_L", "CLEM_R", "RCLK_INT_R", 
+		"CLEL_L", "CLEM_R", "RCLK_INT_R",
 	};
 
 	for (const auto &entry : fs::directory_iterator(argv[1])) {
diff --git a/tools/tilebits.py b/tools/tilebits.py
index 57fbe2b..de472d9 100644
--- a/tools/tilebits.py
+++ b/tools/tilebits.py
@@ -18,134 +18,147 @@
 
 tiles = {}
 site_to_tile = {}
-tile_to_bits = {} # (frame, bit start, bit size)
+tile_to_bits = {}  # (frame, bit start, bit size)
 
 with open(sys.argv[1], 'r') as tilef:
-	for line in tilef:
-		sl = line.strip().split(",")
-		if len(sl) < 4:
-			continue
-		x = int(sl[0])
-		y = int(sl[1])
-		name = sl[2]
-		ttype = sl[3]
-		tiles[(x, y)] = (name + ":" + ttype, ttype, [])
-		for site in sl[4:]:
-			sitename, sitetype = site.split(":")
-			tiles[(x, y)][2].append((sitename, sitetype))
-			site_to_tile[sitename] = (x, y)
+    for line in tilef:
+        sl = line.strip().split(",")
+        if len(sl) < 4:
+            continue
+        x = int(sl[0])
+        y = int(sl[1])
+        name = sl[2]
+        ttype = sl[3]
+        tiles[(x, y)] = (name + ":" + ttype, ttype, [])
+        for site in sl[4:]:
+            sitename, sitetype = site.split(":")
+            tiles[(x, y)][2].append((sitename, sitetype))
+            site_to_tile[sitename] = (x, y)
 
-ll_line_re = re.compile(r'Bit\s+\d+\s+(0x[0-9A-Fa-f]+)\s+(\d+)\s+SLR\d\s+\d+\s+Block=([A-Za-z0-9_]+).*')
+ll_line_re = re.compile(
+    r'Bit\s+\d+\s+(0x[0-9A-Fa-f]+)\s+(\d+)\s+SLR\d\s+\d+\s+Block=([A-Za-z0-9_]+).*'
+)
 site_re = re.compile(r'SLICE_X(\d+)Y(\d+)')
 with open(sys.argv[2], 'r') as llf:
-	for line in llf:
-		m = ll_line_re.match(line)
-		if not m:
-			continue
-		frame = int(m.group(1), 16)
-		bit = int(m.group(2))
-		start_bit = bit - 2
-		site = m.group(3)
-		bus = (frame >> 24) & 0x7
-		half = (frame >> 23) & 0x1
-		row = (frame >> 18) & 0x1F
-		col = (frame >> 8) & 0x3FF
-		m = frame & 0xFF
+    for line in llf:
+        m = ll_line_re.match(line)
+        if not m:
+            continue
+        frame = int(m.group(1), 16)
+        bit = int(m.group(2))
+        start_bit = bit - 2
+        site = m.group(3)
+        bus = (frame >> 24) & 0x7
+        half = (frame >> 23) & 0x1
+        row = (frame >> 18) & 0x1F
+        col = (frame >> 8) & 0x3FF
+        m = frame & 0xFF
 
+        sm = site_re.match(site)
+        site_x = int(sm.group(1))
+        site_y = int(sm.group(2))
+        frame_upper = frame & ~0xFF
 
-		sm = site_re.match(site)
-		site_x = int(sm.group(1))
-		site_y = int(sm.group(2))
-		frame_upper = frame & ~0xFF
+        if site not in site_to_tile:
+            continue
+        tx, ty = site_to_tile[site]
+        tiledata = tiles[tx, ty]
+        tile_to_bits[tiledata[0]] = []
+        for m in range(16):
+            tile_to_bits[tiledata[0]].append((frame_upper | m, start_bit, 48))
 
+        def process_nonlogic(x, y, icol):
+            if (x, y) not in tiles:
+                return
+            itiledata = tiles[x, y]
+            if itiledata[1] == "INT":
+                if (x + 1, y) not in tiles:
+                    return
 
-		if site not in site_to_tile:
-			continue
-		tx, ty = site_to_tile[site]
-		tiledata = tiles[tx, ty]
-		tile_to_bits[tiledata[0]] = []
-		for m in range(16):
-			tile_to_bits[tiledata[0]].append((frame_upper | m, start_bit, 48))
+                int_frame_base = (frame_upper & ~0x3FFFF) | (icol << 8)
+                tile_to_bits[itiledata[0]] = []
+                for m in range(76):
+                    tile_to_bits[itiledata[0]].append((int_frame_base | m,
+                                                       start_bit, 48))
+                process_clock(x, y - 1, int_frame_base, start_bit + 48, 76)
+                process_cmt(x - 2, y, icol - 2)
+                process_int_intf(x - 1, y, icol - 1)
+            elif itiledata[1] == "BRAM":
+                bram_frame_base = (frame_upper & ~0x3FFFF) | (icol << 8)
+                tile_to_bits[itiledata[0]] = []
+                for m in range(6):
+                    tile_to_bits[itiledata[0]].append((bram_frame_base | m,
+                                                       start_bit, 5 * 48))
+                process_clock(x, y - 5, bram_frame_base, start_bit + 5 * 48, 6)
+            elif itiledata[1] == "DSP":
+                dsp_frame_base = (frame_upper & ~0x3FFFF) | (icol << 8)
+                tile_to_bits[itiledata[0]] = []
+                for m in range(8):
+                    tile_to_bits[itiledata[0]].append((dsp_frame_base | m,
+                                                       start_bit, 5 * 48))
+                process_clock(x, y - 5, dsp_frame_base, start_bit + 5 * 48, 8)
 
-		def process_nonlogic(x, y, icol):
-			if (x, y) not in tiles:
-				return
-			itiledata = tiles[x, y]
-			if itiledata[1] == "INT":
-				if (x + 1, y) not in tiles:
-					return
+                if (x - 1, y) in tiles and "INT_INTF" in tiles[x - 1, y][1]:
+                    process_clock(x - 1, y - 5, dsp_frame_base,
+                                  start_bit + 5 * 48, 8)
 
-				int_frame_base = (frame_upper & ~0x3FFFF) | (icol << 8)
-				tile_to_bits[itiledata[0]] = []
-				for m in range(76):
-					tile_to_bits[itiledata[0]].append((int_frame_base | m, start_bit, 48))
-				process_clock(x, y-1, int_frame_base, start_bit + 48, 76)
-				process_cmt(x-2, y, icol-2)
-				process_int_intf(x-1, y, icol-1)
-			elif itiledata[1] == "BRAM":
-				bram_frame_base = (frame_upper & ~0x3FFFF) | (icol << 8)
-				tile_to_bits[itiledata[0]] = []
-				for m in range(6):
-					tile_to_bits[itiledata[0]].append((bram_frame_base | m, start_bit, 5 * 48))
-				process_clock(x, y-5, bram_frame_base, start_bit + 5*48, 6)
-			elif itiledata[1] == "DSP":
-				dsp_frame_base = (frame_upper & ~0x3FFFF) | (icol << 8)
-				tile_to_bits[itiledata[0]] = []
-				for m in range(8):
-					tile_to_bits[itiledata[0]].append((dsp_frame_base | m, start_bit, 5 * 48))
-				process_clock(x, y-5, dsp_frame_base, start_bit + 5*48, 8)
+        def process_clock(cx, cy, frame_base, end_bit, height):
+            if (cx, cy) not in tiles:
+                return
+            if end_bit != (1392 + 48):
+                return
+            ctiledata = tiles[cx, cy]
+            if not ctiledata[1].startswith("RCLK"):
+                return
+            tile_to_bits[ctiledata[0]] = []
+            for m in range(height):
+                tile_to_bits[ctiledata[0]].append((frame_base | m,
+                                                   end_bit + 48, 48))
 
-				if (x - 1, y) in tiles and "INT_INTF" in tiles[x - 1, y][1]:
-					process_clock(x-1, y-5, dsp_frame_base, start_bit + 5*48, 8)
+        def process_cmt(x, y, icol):
+            if (x, y) not in tiles:
+                return
+            ctiledata = tiles[x, y]
+            if not ctiledata[1] in ("CMT_L", "CMT_RIGHT"):
+                return
+            cmt_frame_base = (frame_upper & ~0x3FFFF) | (icol << 8)
+            tile_to_bits[ctiledata[0]] = []
+            for m in range(12):
+                tile_to_bits[ctiledata[0]].append((cmt_frame_base | m,
+                                                   start_bit, 60 * 48))
 
-		def process_clock(cx, cy, frame_base, end_bit, height):
-			if (cx, cy) not in tiles:
-				return
-			if end_bit != (1392 + 48):
-				return
-			ctiledata = tiles[cx, cy]
-			if not ctiledata[1].startswith("RCLK"):
-				return
-			tile_to_bits[ctiledata[0]] = []
-			for m in range(height):
-				tile_to_bits[ctiledata[0]].append((frame_base | m, end_bit + 48, 48))
+        def process_int_intf(x, y, icol):
+            if (x, y) not in tiles:
+                return
+            itiledata = tiles[x, y]
+            if not itiledata[1] in ("INT_INTF_L_IO", "INT_INTF_R_IO"):
+                return
+            int_frame_base = (frame_upper & ~0x3FFFF) | (icol << 8)
+            tile_to_bits[itiledata[0]] = []
+            for m in range(4):
+                tile_to_bits[itiledata[0]].append((int_frame_base | m,
+                                                   start_bit, 48))
 
-		def process_cmt(x, y, icol):
-			if (x, y) not in tiles:
-				return
-			ctiledata = tiles[x, y]
-			if not ctiledata[1] in ("CMT_L", "CMT_RIGHT"):
-				return
-			cmt_frame_base = (frame_upper & ~0x3FFFF) | (icol << 8)
-			tile_to_bits[ctiledata[0]] = []
-			for m in range(12):
-				tile_to_bits[ctiledata[0]].append((cmt_frame_base | m, start_bit, 60 * 48))
-
-		def process_int_intf(x, y, icol):
-			if (x, y) not in tiles:
-				return
-			itiledata = tiles[x, y]
-			if not itiledata[1] in ("INT_INTF_L_IO", "INT_INTF_R_IO"):
-				return
-			int_frame_base = (frame_upper & ~0x3FFFF) | (icol << 8)
-			tile_to_bits[itiledata[0]] = []
-			for m in range(4):
-				tile_to_bits[itiledata[0]].append((int_frame_base | m, start_bit, 48))
-
-
-		process_nonlogic(tx-1, ty, col-1)
-		process_nonlogic(tx+1, ty, col+1)
-		process_clock(tx, ty-1, frame_upper, start_bit + 48, 16)
+        process_nonlogic(tx - 1, ty, col - 1)
+        process_nonlogic(tx + 1, ty, col + 1)
+        process_clock(tx, ty - 1, frame_upper, start_bit + 48, 16)
 # Original JSON
 with open(sys.argv[3], 'w') as tj:
-	tj.write(json.dumps(tile_to_bits, sort_keys=True, indent=4, separators=(',', ': ')))
-	tj.write("\n")
+    tj.write(
+        json.dumps(
+            tile_to_bits, sort_keys=True, indent=4, separators=(',', ': ')))
+    tj.write("\n")
 # New simplified text format
 with open(sys.argv[4], 'w') as tf:
-	for loc, tiledata in sorted(tiles.items()):
-		print(".tile %s %s %d %d" % (tiledata[0].split(":")[0], tiledata[1], loc[0], loc[1]), file=tf)
-		for site in tiledata[2]:
-			print("site %s %s" % site, file=tf)
-		if tiledata[0] in tile_to_bits:
-			for frame, offset, size in tile_to_bits[tiledata[0]]:
-				print("frame 0x%08x bits %d +: %d" % (frame, offset, size), file=tf)
\ No newline at end of file
+    for loc, tiledata in sorted(tiles.items()):
+        print(
+            ".tile %s %s %d %d" % (tiledata[0].split(":")[0], tiledata[1],
+                                   loc[0], loc[1]),
+            file=tf)
+        for site in tiledata[2]:
+            print("site %s %s" % site, file=tf)
+        if tiledata[0] in tile_to_bits:
+            for frame, offset, size in tile_to_bits[tiledata[0]]:
+                print(
+                    "frame 0x%08x bits %d +: %d" % (frame, offset, size),
+                    file=tf)
diff --git a/tools/tilegrid_report.py b/tools/tilegrid_report.py
index 9add2ca..52df26b 100755
--- a/tools/tilegrid_report.py
+++ b/tools/tilegrid_report.py
@@ -59,10 +59,9 @@
         if args.show_only_missing and have_bits == len(tiles):
             continue
 
-        print(
-            '{}: {}/{} ({:.2f} %)'.format(
-                tile_type, have_bits, len(tiles),
-                100. * float(have_bits) / len(tiles)))
+        print('{}: {}/{} ({:.2f} %)'.format(
+            tile_type, have_bits, len(tiles),
+            100. * float(have_bits) / len(tiles)))
 
         if args.verbose:
             tiles_with_missing_bits = []
@@ -75,10 +74,9 @@
                 print('{} is missing CLB_IO_CLK'.format(tile_name))
 
     print('')
-    print(
-        'Summary: {}/{} ({:.2f} %)'.format(
-            total_have_bits, total_tile_count,
-            100. * float(total_have_bits) / total_tile_count))
+    print('Summary: {}/{} ({:.2f} %)'.format(
+        total_have_bits, total_tile_count,
+        100. * float(total_have_bits) / total_tile_count))
 
 
 if __name__ == "__main__":
diff --git a/tools/update_tilebits_all.sh b/tools/update_tilebits_all.sh
index 0596c19..9cb1c78 100644
--- a/tools/update_tilebits_all.sh
+++ b/tools/update_tilebits_all.sh
@@ -14,5 +14,5 @@
 # limitations under the License.
 
 for x in $1/*.dump; do
-	python bits_to_tiles.py $2 $x > ${x%.*}.tbits 
+	python bits_to_tiles.py $2 $x > ${x%.*}.tbits
 done
diff --git a/utils/bit2fasm.py b/utils/bit2fasm.py
index bedb997..06e5b11 100755
--- a/utils/bit2fasm.py
+++ b/utils/bit2fasm.py
@@ -14,7 +14,12 @@
 import tempfile
 
 
-def bit_to_bits(bitread, part_yaml, arch, bit_file, bits_file, frame_range=None):
+def bit_to_bits(bitread,
+                part_yaml,
+                arch,
+                bit_file,
+                bits_file,
+                frame_range=None):
     """ Calls bitread to create bits (ASCII) from bit file (binary) """
     if frame_range:
         frame_range_arg = '-F {}'.format(frame_range)
@@ -85,7 +90,8 @@
         default=default_bitread)
     parser.add_argument(
         '--architecture',
-        help="Name of the device architecture family (e.g. UltraScale, Series7, etc.)",
+        help=
+        "Name of the device architecture family (e.g. UltraScale, Series7, etc.)",
         default="UltraScale")
     parser.add_argument(
         '--frame_range', help="Frame range to use with bitread.")
@@ -113,9 +119,8 @@
             frame_range=args.frame_range,
         )
 
-        bits_to_fasm(
-            args.db_root, args.part, bits_file.name, args.verbose,
-            args.canonical)
+        bits_to_fasm(args.db_root, args.part, bits_file.name, args.verbose,
+                     args.canonical)
 
 
 if __name__ == '__main__':
diff --git a/utils/bitstream.py b/utils/bitstream.py
index 832e46d..7f63f96 100644
--- a/utils/bitstream.py
+++ b/utils/bitstream.py
@@ -101,8 +101,8 @@
         for rowk, rowv in tbv["rows"].items():
             for busk, busv in rowv["configuration_buses"].items():
                 for colk, colv in busv["configuration_columns"].items():
-                    yield (
-                        busk, tbk, int(rowk), int(colk), colv["frame_count"])
+                    yield (busk, tbk, int(rowk), int(colk),
+                           colv["frame_count"])
 
 
 def addr_bits2word(block_type, top_bottom, cfg_row, cfg_col, minor_addr):
diff --git a/utils/bitstream_analyzer.py b/utils/bitstream_analyzer.py
index c2e4632..473bb6a 100755
--- a/utils/bitstream_analyzer.py
+++ b/utils/bitstream_analyzer.py
@@ -61,6 +61,7 @@
 
 opcodes = ("NOP", "READ", "WRITE", "UNKNOWN")
 
+
 class Bitstream:
     def __init__(self, file_name, verbose=False):
         self.frame_data = []
@@ -70,7 +71,7 @@
         with open(file_name, "rb") as f:
             word = f.read(4)
             while word:
-                self.words.append(int.from_bytes(word, byteorder = 'big'))
+                self.words.append(int.from_bytes(word, byteorder='big'))
                 word = f.read(4)
         pos, self.header = self.get_header()
         self.body = self.words[pos + 1:]
@@ -85,8 +86,8 @@
         payload_len = 0
         for word in self.body:
             if payload_len > 0:
-                payload_len = self.parse_reg(
-                    reg_addr, word, payload_len, verbose)
+                payload_len = self.parse_reg(reg_addr, word, payload_len,
+                                             verbose)
                 continue
             else:
                 packet_header = self.parse_packet_header(word)
@@ -99,9 +100,12 @@
                         print("\n\tNOP")
                     else:
                         print(
-                        "\n\tConfiguration Register Word: ", hex(word),
-                        'Type: {}, Op: {}, Addr: {} ({}), Words: {}'.format(
-                            type, opcodes[opcode], conf_regs[reg_addr] if reg_addr in conf_regs else "UNKNOWN", reg_addr, words))
+                            "\n\tConfiguration Register Word: ", hex(word),
+                            'Type: {}, Op: {}, Addr: {} ({}), Words: {}'.
+                            format(
+                                type, opcodes[opcode], conf_regs[reg_addr]
+                                if reg_addr in conf_regs else "UNKNOWN",
+                                reg_addr, words))
                 if opcode and reg_addr in conf_regs:
                     payload_len = words
                     if conf_regs[reg_addr] == "FDRI" and type == 1:
@@ -144,10 +148,11 @@
             self.parse_cor0(word, verbose)
         elif reg == "FDRI":
             # We are in progress of a FDRI operation
-            # Keep adding data words 
+            # Keep adding data words
             if self.fdri_in_progress:
                 if verbose:
-                    print("\t{:2d}. 0x{:08X}".format(self.fdri_write_len - payload_len, word))
+                    print("\t{:2d}. 0x{:08X}".format(
+                        self.fdri_write_len - payload_len, word))
                 self.frame_data.append(word)
                 if payload_len == 1:
                     self.fdri_in_progress = False
diff --git a/utils/connections.py b/utils/connections.py
index 334d2f4..8885ab2 100644
--- a/utils/connections.py
+++ b/utils/connections.py
@@ -35,8 +35,8 @@
                     (grid_deltas, tile_types[1], pairs[1]))
 
     def all_possible_connections_from(self, wire_in_grid):
-        tile_type = self.coord_to_tile_type[(
-            wire_in_grid.grid_x, wire_in_grid.grid_y)]
+        tile_type = self.coord_to_tile_type[(wire_in_grid.grid_x,
+                                             wire_in_grid.grid_y)]
 
         key = (tile_type, wire_in_grid.wire)
 
@@ -46,8 +46,8 @@
         for relative_coord, target_tile_type, target_wire in (
                 self.potential_connections[key]):
             rel_x, rel_y = relative_coord
-            target_coord = (
-                wire_in_grid.grid_x + rel_x, wire_in_grid.grid_y + rel_y)
+            target_coord = (wire_in_grid.grid_x + rel_x,
+                            wire_in_grid.grid_y + rel_y)
 
             if target_coord in self.coord_to_tile_type:
                 if self.coord_to_tile_type[target_coord] == target_tile_type:
diff --git a/utils/db.py b/utils/db.py
index 74d20d1..2ba0c1f 100644
--- a/utils/db.py
+++ b/utils/db.py
@@ -49,8 +49,8 @@
             if f.endswith('.json') and f.startswith('tile_type_'):
                 tile_type = f[len('tile_type_'):-len('.json')].lower()
 
-                segbits = os.path.join(
-                    self.db_root, 'segbits_{}.db'.format(tile_type))
+                segbits = os.path.join(self.db_root,
+                                       'segbits_{}.db'.format(tile_type))
                 if not os.path.isfile(segbits):
                     segbits = None
 
@@ -59,19 +59,19 @@
                 if not os.path.isfile(block_ram_segbits):
                     block_ram_segbits = None
 
-                ppips = os.path.join(
-                    self.db_root, 'ppips_{}.db'.format(tile_type))
+                ppips = os.path.join(self.db_root,
+                                     'ppips_{}.db'.format(tile_type))
                 if not os.path.isfile(ppips):
                     ppips = None
 
-                mask = os.path.join(
-                    self.db_root, 'mask_{}.db'.format(tile_type))
+                mask = os.path.join(self.db_root,
+                                    'mask_{}.db'.format(tile_type))
                 if not os.path.isfile(mask):
                     mask = None
 
                 tile_type_file = os.path.join(
-                    self.db_root, 'tile_type_{}.json'.format(
-                        tile_type.upper()))
+                    self.db_root,
+                    'tile_type_{}.json'.format(tile_type.upper()))
                 if not os.path.isfile(tile_type_file):
                     tile_type_file = None
 
@@ -88,8 +88,8 @@
 
                 self.site_types[site_type_name] = os.path.join(self.db_root, f)
 
-        required_features_path = os.path.join(
-            self.db_root, self.part, "required_features.fasm")
+        required_features_path = os.path.join(self.db_root, self.part,
+                                              "required_features.fasm")
         if os.path.isfile(required_features_path):
             with open(required_features_path, "r") as fp:
                 features = []
@@ -143,11 +143,10 @@
         self._read_tileconn()
         self._read_tile_types()
 
-        tile_wires = dict(
-            (tile_type, db['wires'])
-            for tile_type, db in self.tile_types.items())
-        return connections.Connections(
-            self.tilegrid, self.tileconn, tile_wires)
+        tile_wires = dict((tile_type, db['wires'])
+                          for tile_type, db in self.tile_types.items())
+        return connections.Connections(self.tilegrid, self.tileconn,
+                                       tile_wires)
 
     def get_site_types(self):
         return self.site_types.keys()
diff --git a/utils/fasm_assembler.py b/utils/fasm_assembler.py
index 1775a4e..8a3fba8 100644
--- a/utils/fasm_assembler.py
+++ b/utils/fasm_assembler.py
@@ -57,8 +57,8 @@
 
         for bits_info in self.grid.iter_all_frames():
             for coli in range(bits_info.bits.frames):
-                init_frame_at_address(
-                    frames, bits_info.bits.base_address + coli)
+                init_frame_at_address(frames,
+                                      bits_info.bits.base_address + coli)
 
         return frames
 
@@ -123,8 +123,8 @@
         any_bits = set()
 
         try:
-            for block_type, bit in segbits.feature_to_bits(gridinfo.bits, db_k,
-                                                           address):
+            for block_type, bit in segbits.feature_to_bits(
+                    gridinfo.bits, db_k, address):
                 any_bits.add(block_type)
                 update_segbit(bit)
         except KeyError:
diff --git a/utils/fasm_disassembler.py b/utils/fasm_disassembler.py
index 44415ef..337cffd 100644
--- a/utils/fasm_disassembler.py
+++ b/utils/fasm_disassembler.py
@@ -37,14 +37,13 @@
         self.segment_map = self.grid.get_segment_map()
         self.decode_warnings = set()
 
-    def find_features_in_tile(
-            self,
-            tile_name,
-            block_type,
-            bits,
-            solved_bitdata,
-            bitdata,
-            verbose=False):
+    def find_features_in_tile(self,
+                              tile_name,
+                              block_type,
+                              bits,
+                              solved_bitdata,
+                              bitdata,
+                              verbose=False):
         gridinfo = self.grid.gridinfo_at_tilename(tile_name)
 
         try:
@@ -75,8 +74,8 @@
             self.decode_warnings.add(gridinfo.tile_type)
             return
 
-        for ones_matched, feature in tile_segbits.match_bitdata(block_type,
-                                                                bits, bitdata):
+        for ones_matched, feature in tile_segbits.match_bitdata(
+                block_type, bits, bitdata):
             for frame, bit in ones_matched:
                 if frame not in solved_bitdata:
                     solved_bitdata[frame] = set()
@@ -117,8 +116,12 @@
                 tiles_checked.add((bits_info.tile, bits_info.block_type))
 
                 for fasm_line in self.find_features_in_tile(
-                        bits_info.tile, bits_info.block_type, bits_info.bits,
-                        solved_bitdata, bitdata, verbose=verbose):
+                        bits_info.tile,
+                        bits_info.block_type,
+                        bits_info.bits,
+                        solved_bitdata,
+                        bitdata,
+                        verbose=verbose):
                     if fasm_line not in emitted_features:
                         emitted_features.add(fasm_line)
                         yield fasm_line
@@ -151,9 +154,8 @@
                             'unknown_bit', '{:08x}_{}_{}'.format(
                                 frame, wordidx, bitidx)))
                     annotations.append(
-                        fasm.Annotation(
-                            'unknown_segment',
-                            '0x{:08x}'.format(aligned_frame)))
+                        fasm.Annotation('unknown_segment',
+                                        '0x{:08x}'.format(aligned_frame)))
                     annotations.append(
                         fasm.Annotation(
                             'unknown_segbit', '{:02d}_{:02d}'.format(
diff --git a/utils/grid_types.py b/utils/grid_types.py
index a27c3ac..22e732f 100644
--- a/utils/grid_types.py
+++ b/utils/grid_types.py
@@ -12,8 +12,8 @@
 
 GridLoc = namedtuple('GridLoc', 'grid_x grid_y')
 ClockRegion = namedtuple('ClockRegion', 'name x y')
-GridInfo = namedtuple(
-    'GridInfo', 'bits sites tile_type pin_functions clock_region')
+GridInfo = namedtuple('GridInfo',
+                      'bits sites tile_type pin_functions clock_region')
 BitAlias = namedtuple('BitAlias', 'tile_type start_offset sites')
 Bits = namedtuple('Bits', 'base_address frames offset words alias')
 BitsInfo = namedtuple('BitsInfo', 'block_type tile bits')
diff --git a/utils/lib.py b/utils/lib.py
index 8922e4e..94ada84 100644
--- a/utils/lib.py
+++ b/utils/lib.py
@@ -53,8 +53,8 @@
                 if set((wire, )) != raw_node_set:
                     error_nodes.append((node, tuple(raw_node_set), (wire, )))
             elif wire_nodes[wire] != raw_node_set:
-                error_nodes.append(
-                    (node, tuple(raw_node_set), tuple(wire_nodes[wire])))
+                error_nodes.append((node, tuple(raw_node_set),
+                                    tuple(wire_nodes[wire])))
 
 
 def check_errors(flat_error_nodes, ignored_wires):
diff --git a/utils/mergedb.py b/utils/mergedb.py
index 83544c2..6962599 100755
--- a/utils/mergedb.py
+++ b/utils/mergedb.py
@@ -62,8 +62,7 @@
     parser.add_argument('ins', nargs='+', help='Last takes precedence')
     args = parser.parse_args()
 
-    run(
-        args.ins,
+    run(args.ins,
         args.out,
         strict=int(os.getenv("MERGEDB_STRICT", "1")),
         track_origin=args.track_origin,
diff --git a/utils/segmaker.py b/utils/segmaker.py
index 67f4267..99b62ea 100644
--- a/utils/segmaker.py
+++ b/utils/segmaker.py
@@ -72,7 +72,12 @@
 
 
 class Segmaker:
-    def __init__(self, bitsfile, verbose=False, db_root=None, part=None, bits_per_word=32):
+    def __init__(self,
+                 bitsfile,
+                 verbose=False,
+                 db_root=None,
+                 part=None,
+                 bits_per_word=32):
         self.db_root = db_root
         if self.db_root is None:
             self.db_root = util.get_db_root()
@@ -148,19 +153,21 @@
                 line = line.split("_")
                 bit_frame = int(line[1], 16)
                 # Word indexes in the .bits file for US+/US assume 32-bits per word
-                bit_wordidx = int(line[2], 10) * (32 / self.bits_per_word) + int(line[3], 10) // self.bits_per_word
+                bit_wordidx = int(line[2],
+                                  10) * (32 / self.bits_per_word) + int(
+                                      line[3], 10) // self.bits_per_word
                 bit_bitidx = int(line[3], 10) % self.bits_per_word
                 # Bit ranges in the Frame Address Register Description differs between US+ and US devices
                 # For US the ranges are identical to 7-series, but US+ is shifted 1 bit left
                 # Refer to UG570 Table 9-21
-                base_frame = bit_frame & (~0xff if os.getenv("URAY_ARCH") in "UltraScalePlus" else ~0x7f)
+                base_frame = bit_frame & (~0xff if os.getenv("URAY_ARCH") in
+                                          "UltraScalePlus" else ~0x7f)
                 self.bits.setdefault(base_frame, dict()).setdefault(
-                    bit_wordidx, set()).add(
-                        (bit_frame, bit_wordidx, bit_bitidx))
+                    bit_wordidx, set()).add((bit_frame, bit_wordidx,
+                                             bit_bitidx))
         if self.verbose:
-            print(
-                'Loaded bits: %u bits in %u base frames' %
-                (recurse_sum(self.bits), len(self.bits)))
+            print('Loaded bits: %u bits in %u base frames' % (recurse_sum(
+                self.bits), len(self.bits)))
 
     def add_site_tag(self, site, name, value):
         '''
@@ -322,9 +329,8 @@
                     'ILOGIC': name_y0y1,
                     'OLOGIC': name_y0y1,
                 }.get(site_prefix, name_default)()
-                self.verbose and print(
-                    'site %s w/ %s prefix => tag %s' %
-                    (site, site_prefix, sitekey))
+                self.verbose and print('site %s w/ %s prefix => tag %s' %
+                                       (site, site_prefix, sitekey))
 
                 for name, value in self.site_tags[site].items():
                     self.verbose and print("Site %s: check tags" % site)
@@ -350,8 +356,8 @@
             -LIOI3 => IOI3
             '''
             tile_type_norm = re.sub("(_TOP|_BOT|LL|LM)?_[LR]$", "", tile_type)
-            tile_type_norm = re.sub(
-                "_TOP_[LR]_UPPER", "_UPPER", tile_type_norm)
+            tile_type_norm = re.sub("_TOP_[LR]_UPPER", "_UPPER",
+                                    tile_type_norm)
 
             if tile_type_norm in ['LIOB33', 'RIOB33']:
                 tile_type_norm = 'IOB33'
@@ -414,9 +420,9 @@
         assert self.segments_by_type, 'No data to write'
 
         if not allow_empty:
-            assert sum(
-                [len(segments) for segments in self.segments_by_type.values()
-                 ]) != 0, "Didn't  generate any segments"
+            assert sum([
+                len(segments) for segments in self.segments_by_type.values()
+            ]) != 0, "Didn't  generate any segments"
 
         for segtype in self.segments_by_type.keys():
             if suffix is not None:
diff --git a/utils/tile.py b/utils/tile.py
index 9b8e57f..3bf88cc 100644
--- a/utils/tile.py
+++ b/utils/tile.py
@@ -4,8 +4,8 @@
 from utils import lib
 from utils.timing import fast_slow_tuple_to_corners, RcElement
 
-TileDbs = namedtuple(
-    'TileDbs', 'segbits block_ram_segbits ppips mask tile_type')
+TileDbs = namedtuple('TileDbs',
+                     'segbits block_ram_segbits ppips mask tile_type')
 
 
 class OutPinTiming(namedtuple('OutPinTiming', 'delays drive_resistance')):
@@ -36,8 +36,9 @@
     pass
 
 
-class PipTiming(namedtuple('PipTiming',
-                           'delays drive_resistance internal_capacitance')):
+class PipTiming(
+        namedtuple('PipTiming',
+                   'delays drive_resistance internal_capacitance')):
     """ Timing for pips.
 
     Attributes
@@ -53,10 +54,11 @@
     pass
 
 
-class Pip(namedtuple(
-        'Pip',
-    ('name', 'net_to', 'net_from', 'can_invert', 'is_directional', 'is_pseudo',
-     'is_pass_transistor', 'timing', 'backward_timing'))):
+class Pip(
+        namedtuple(
+            'Pip',
+            ('name', 'net_to', 'net_from', 'can_invert', 'is_directional',
+             'is_pseudo', 'is_pass_transistor', 'timing', 'backward_timing'))):
     """ Pip information.
 
     Attributes
diff --git a/utils/tile_segbits.py b/utils/tile_segbits.py
index 39e6c0f..2c6e6f3 100644
--- a/utils/tile_segbits.py
+++ b/utils/tile_segbits.py
@@ -113,8 +113,8 @@
             match = True
             skip = False
             for query_bit in segbit:
-                if match_filter is not None and not match_filter(block_type,
-                                                                 query_bit):
+                if match_filter is not None and not match_filter(
+                        block_type, query_bit):
                     skip = True
                     break
 
@@ -167,5 +167,5 @@
 
         block_type, feature = self.feature_addresses[feature][address]
         for bit in self.segbits[block_type][feature]:
-            yield block_type, self.map_bit_to_frame(
-                block_type, bits_map[block_type], bit)
+            yield block_type, self.map_bit_to_frame(block_type,
+                                                    bits_map[block_type], bit)
diff --git a/utils/timing.py b/utils/timing.py
index 782d0e3..9fd9314 100644
--- a/utils/timing.py
+++ b/utils/timing.py
@@ -173,17 +173,18 @@
 
     fast_min, fast_max, slow_min, slow_max = map(float, arr)
 
-    return hashabledict(
-        {
-            PvtCorner.FAST: IntristicDelay(
-                min=fast_min,
-                max=fast_max,
-            ),
-            PvtCorner.SLOW: IntristicDelay(
-                min=slow_min,
-                max=slow_max,
-            ),
-        })
+    return hashabledict({
+        PvtCorner.FAST:
+        IntristicDelay(
+            min=fast_min,
+            max=fast_max,
+        ),
+        PvtCorner.SLOW:
+        IntristicDelay(
+            min=slow_min,
+            max=slow_max,
+        ),
+    })
 
 
 class TimingNode(object):
@@ -498,8 +499,8 @@
 
         assert self.sink_wire is not None
         self.sink_wire.propigate_delays(self.propigated_delays + [self], math)
-        self.rc_delay = math.multiply(
-            self.downstream_cap, self.drive_resistance)
+        self.rc_delay = math.multiply(self.downstream_cap,
+                                      self.drive_resistance)
 
     def get_intrinsic_delays(self):
         return self.delays
@@ -561,8 +562,8 @@
 
         assert self.sink_wire is not None
         self.sink_wire.propigate_delays(self.propigated_delays + [self], math)
-        self.rc_delay = math.multiply(
-            self.downstream_cap, self.drive_resistance)
+        self.rc_delay = math.multiply(self.downstream_cap,
+                                      self.drive_resistance)
 
     def get_intrinsic_delays(self):
         return self.delays
diff --git a/utils/util.py b/utils/util.py
index 50d4086..89e74e0 100644
--- a/utils/util.py
+++ b/utils/util.py
@@ -5,10 +5,12 @@
 from utils.roi import Roi
 from jinja2 import Environment, FileSystemLoader
 
-def get_jinja_template(tpl_file, directory = "./"):
+
+def get_jinja_template(tpl_file, directory="./"):
     env = Environment(loader=FileSystemLoader(searchpath=directory))
     return env.get_template(tpl_file)
 
+
 def render_template(tpl_path, variables=dict()):
     '''
     Render text for jinja template.
@@ -25,14 +27,15 @@
     template = get_jinja_template(file_name, directory if directory else "./")
     return template.render(variables)
 
+
 def get_db_root():
     # Used during tilegrid db bootstrap
     ret = os.getenv("URAY_DATABASE_ROOT", None)
     if ret:
         return ret
 
-    return "%s/%s" % (
-        os.getenv("URAY_DATABASE_DIR"), os.getenv("URAY_DATABASE"))
+    return "%s/%s" % (os.getenv("URAY_DATABASE_DIR"),
+                      os.getenv("URAY_DATABASE"))
 
 
 def get_part():
@@ -89,9 +92,8 @@
     '''Return (X1, X2), (Y1, Y2) from URAY_ROI, exclusive end (for xrange)'''
     # SLICE_X12Y100:SLICE_X27Y149
     # Note URAY_ROI_GRID_* is something else
-    m = re.match(
-        r'SLICE_X([0-9]*)Y([0-9]*):SLICE_X([0-9]*)Y([0-9]*)',
-        os.getenv('URAY_ROI'))
+    m = re.match(r'SLICE_X([0-9]*)Y([0-9]*):SLICE_X([0-9]*)Y([0-9]*)',
+                 os.getenv('URAY_ROI'))
     ms = [int(m.group(i + 1)) for i in range(4)]
     return ((ms[0], ms[2] + 1), (ms[1], ms[3] + 1))
 
diff --git a/utils/verilog.py b/utils/verilog.py
index de3895e..262237a 100644
--- a/utils/verilog.py
+++ b/utils/verilog.py
@@ -4,8 +4,7 @@
 
 
 def top_harness(DIN_N, DOUT_N, f=sys.stdout):
-    f.write(
-        '''
+    f.write('''
 module top(input clk, stb, di, output do);
     localparam integer DIN_N = %d;
     localparam integer DOUT_N = %d;
diff --git a/utils/xyaml.py b/utils/xyaml.py
index 08e9e35..6ec9f8b 100755
--- a/utils/xyaml.py
+++ b/utils/xyaml.py
@@ -26,8 +26,7 @@
 
 class XYamlTest(unittest.TestCase):
     def test(self):
-        s = io.StringIO(
-            """\
+        s = io.StringIO("""\
 !<xilinx/xc7series/part>
 idcode: 0x362d093
 global_clock_regions: