diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,14 @@
 # Changelog for the [`clash-systemverilog`](http://hackage.haskell.org/package/clash-systemverilog) package
 
+## 0.6.6 *March 11th 2016*
+* New features:
+  * Support `clash-lib` 0.6
+  * Generated structs are packed
+  * Elements of arrays are packed
+* Fixes bugs:
+  * Vivado fails to infer block ram [#127](https://github.com/clash-lang/clash-compiler/issues/127)
+    * Users must use the `-clash-hdlsyn Vivado` flag in order to generate Xilinx Vivado specific HDL for which Vivado can infer block RAM.
+
 ## 0.6.5 *January 29th 2016*
 * New features:
   * Support clash-lib-0.6.9
diff --git a/clash-systemverilog.cabal b/clash-systemverilog.cabal
--- a/clash-systemverilog.cabal
+++ b/clash-systemverilog.cabal
@@ -1,5 +1,5 @@
 Name:                 clash-systemverilog
-Version:              0.6.5
+Version:              0.6.6
 Synopsis:             CAES Language for Synchronous Hardware - SystemVerilog backend
 Description:
   CλaSH (pronounced ‘clash’) is a functional hardware description language that
@@ -98,7 +98,7 @@
                       ViewPatterns
 
   Build-depends:      base                    >= 4.6.0.1 && < 5,
-                      clash-lib               >= 0.6,
+                      clash-lib               >= 0.6.11,
                       clash-prelude           >= 0.10.1,
                       fgl                     >= 5.4.2.4,
                       lens                    >= 3.9.2,
diff --git a/primitives/CLaSH.Driver.TopWrapper.json b/primitives/CLaSH.Driver.TopWrapper.json
--- a/primitives/CLaSH.Driver.TopWrapper.json
+++ b/primitives/CLaSH.Driver.TopWrapper.json
@@ -2,8 +2,8 @@
     { "name"      : "CLaSH.TopWrapper.syncReset"
     , "templateD" :
 "// reset ~RESULT is asynchronously asserted, but synchronously de-asserted
-~SIGD[~SYM[0]][0];
-~SIGD[~SYM[1]][0];
+~SIGD[~GENSYM[r1][0]][0];
+~SIGD[~GENSYM[r2][1]][0];
 
 always_ff @(posedge ~CLKO or negedge ~ARG[0])
 if (~ ~ARG[0]) begin
diff --git a/primitives/CLaSH.Prelude.BlockRam.File.json b/primitives/CLaSH.Prelude.BlockRam.File.json
--- a/primitives/CLaSH.Prelude.BlockRam.File.json
+++ b/primitives/CLaSH.Prelude.BlockRam.File.json
@@ -12,21 +12,21 @@
                -> Signal' clk (BitVector m)"
     , "templateD" :
 "// blockRamFile begin
-~SIGDO[RAM_~SYM[0]] [0:~LIT[2]-1];
-~SIGD[dout_~SYM[1]][7];
+~SIGDO[~GENSYM[RAM][0]] [0:~LIT[2]-1];
+~SIGD[~GENSYM[dout][1]][7];
 
 initial begin
-  $readmemb(~FILE[~LIT[3]],RAM_~SYM[0]);
+  $readmemb(~FILE[~LIT[3]],~SYM[0]);
 end
 
-always @(posedge ~CLK[1]) begin : blockRamFile_~COMPNAME_~SYM[2]
+always @(posedge ~CLK[1]) begin : ~GENSYM[~COMPNAME_blockRamFile][2]
   if (~ARG[7]) begin
-    RAM_~SYM[0][~ARG[4]] <= ~ARG[7];
+    ~SYM[0][~ARG[4]] <= ~ARG[7];
   end
-  dout_~SYM[1] <= RAM_~SYM[0][~ARG[6]];
+  ~SYM[1] <= ~SYM[0][~ARG[6]];
 end
 
-assign ~RESULT = dout_~SYM[1];
+assign ~RESULT = ~SYM[1];
 // blockRamFile end"
     }
   }
diff --git a/primitives/CLaSH.Prelude.BlockRam.json b/primitives/CLaSH.Prelude.BlockRam.json
--- a/primitives/CLaSH.Prelude.BlockRam.json
+++ b/primitives/CLaSH.Prelude.BlockRam.json
@@ -11,30 +11,18 @@
            -> Signal' clk a"
     , "templateD" :
 "// blockRam begin
-typedef logic [~SIZE[~TYPO]-1:0] RAM_array_~SYM[4] [0:~LENGTH[~TYP[2]]-1];
-RAM_array_~SYM[4] RAM_~SYM[0];
-logic [~SIZE[~TYPO]-1:0] dout_~SYM[1];
-
-function RAM_array_~SYM[4] init_to_bv_~SYM[2];
-  input ~SIGD[value][2];
-  begin
-    for (int i_~SYM[3]=0; i_~SYM[3]<~LENGTH[~TYP[2]]; i_~SYM[3]=i_~SYM[3]+1)
-      init_to_bv_~SYM[2][i_~SYM[3]] = ~TOBV[value[ i_~SYM[3] ]][6];
-  end
-endfunction
-
+~SIGD[~GENSYM[RAM][0]][2];
+logic [~SIZE[~TYP[6]]-1:0] ~GENSYM[dout][1];
 initial begin
-  RAM_~SYM[0] = init_to_bv_~SYM[2](~LIT[2]);
+  ~SYM[0] = ~LIT[2];
 end
-
-always @(posedge ~CLK[1]) begin : blockRam_~COMPNAME_~SYM[3]
+always @(posedge ~CLK[1]) begin : ~GENSYM[~COMPNAME_blockRam][2]
   if (~ARG[5]) begin
-    RAM_~SYM[0][~ARG[3]] <= ~TOBV[~ARG[6]][6];
+    ~SYM[0][~ARG[3]] <= ~TOBV[~ARG[6]][~TYP[6]];
   end
-  dout_~SYM[1] <= RAM_~SYM[0][~ARG[4]];
+  ~SYM[1] <= ~SYM[0][~ARG[4]];
 end
-
-assign ~RESULT = ~FROMBV[dout_~SYM[1]][6];
+assign ~RESULT = ~FROMBV[~SYM[1]][~TYP[6]];
 // blockRam end"
     }
   }
diff --git a/primitives/CLaSH.Prelude.RAM.json b/primitives/CLaSH.Prelude.RAM.json
--- a/primitives/CLaSH.Prelude.RAM.json
+++ b/primitives/CLaSH.Prelude.RAM.json
@@ -11,15 +11,15 @@
            -> Signal' rclk a"
     , "templateD" :
 "// asyncRam begin
-~SIGD[RAM_~SYM[0]][6] [0:~LIT[2]-1];
+logic [~SIZE[~TYP[6]]-1:0] ~GENSYM[RAM][0] [0:~LIT[2]-1];
 
-always @(posedge ~CLK[0]) begin : Ram_~COMPNAME_~SYM[4]
+always @(posedge ~CLK[0]) begin : ~GENSYM[~COMPNAME_Ram][1]
   if (~ARG[5]) begin
-    RAM_~SYM[0][~ARG[3]] <= ~ARG[6];
+    ~SYM[0][~ARG[3]] <= ~TOBV[~ARG[6]][~TYP[6]];
   end
 end
 
-assign ~RESULT = RAM_~SYM[0][~ARG[4]];
+assign ~RESULT = ~FROMBV[~SYM[0][\\~ARG[4]\\]][~TYPO];
 // asyncRam end"
     }
   }
diff --git a/primitives/CLaSH.Prelude.ROM.File.json b/primitives/CLaSH.Prelude.ROM.File.json
--- a/primitives/CLaSH.Prelude.ROM.File.json
+++ b/primitives/CLaSH.Prelude.ROM.File.json
@@ -8,13 +8,13 @@
               -> BitVector m"
     , "templateD" :
 "// asyncRomFile begin
-~SIGDO[ROM_~SYM[0]] [0:~LIT[1]-1];
+~SIGDO[~GENSYM[ROM][0]] [0:~LIT[1]-1];
 
 initial begin
-  $readmemb(~FILE[~LIT[2]],ROM_~SYM[0]);
+  $readmemb(~FILE[~LIT[2]],~SYM[0]);
 end
 
-assign ~RESULT = ROM_~SYM[0][~ARG[3]];
+assign ~RESULT = ~SYM[0][~ARG[3]];
 // asyncRomFile end"
     }
   }
@@ -29,18 +29,18 @@
           -> Signal' clk (BitVector m)"
     , "templateD" :
 "// romFile begin
-~SIGDO[ROM_~SYM[0]] [0:~LIT[2]-1];
+~SIGDO[~GENSYM[ROM][0]] [0:~LIT[2]-1];
 
 initial begin
-  $readmemb(~FILE[~LIT[3]],ROM_~SYM[0]);
+  $readmemb(~FILE[~LIT[3]],~SYM[0]);
 end
 
-~SIGDO[dout_~SYM[1]];
-always @(posedge ~CLK[1]) begin : romFile_~COMPNAME_~SYM[2]
-  dout_~SYM[1] <= ROM_~SYM[0][~ARG[4]];
+~SIGDO[~GENSYM[dout][1]];
+always @(posedge ~CLK[1]) begin : ~GENSYM[~COMPNAME_romFile][2]
+  ~SYM[1] <= ~SYM[0][~ARG[4]];
 end
 
-assign ~RESULT = dout_~SYM[1];
+assign ~RESULT = ~SYM[1];
 // romFile end"
     }
   }
diff --git a/primitives/CLaSH.Prelude.ROM.json b/primitives/CLaSH.Prelude.ROM.json
--- a/primitives/CLaSH.Prelude.ROM.json
+++ b/primitives/CLaSH.Prelude.ROM.json
@@ -7,10 +7,10 @@
            -> a"
     , "templateD" :
 "// asyncRom begin
-~SIGD[ROM_~SYM[0]][1];
-assign ROM_SYM[0] = ~ARG[1];
+~SIGD[~GENSYM[ROM][0]][1];
+assign ~SYM[0] = ~ARG[1];
 
-assign ~RESULT = ROM_~SYM[0][~ARG[2]];
+assign ~RESULT = ~FROMBV[~SYM[0][\\~ARG[2]\\]][~TYPO];
 // asyncRom end"
     }
   }
@@ -24,15 +24,15 @@
       -> Signal' clk a"
     , "templateD" :
 "// rom begin
-~SIGD[ROM_~SYM[0]][2];
-assign ROM_~SYM[0] = ~ARG[2];
+~SIGD[~GENSYM[ROM][0]][2];
+assign ~SYM[0] = ~ARG[2];
 
-~SIGDO[dout_~SYM[1]];
-always @(posedge ~CLK[1]) begin : rom_~COMPNAME_~SYM[2]
-  dout_~SYM[1] <= ROM_~SYM[0][~ARG[3]];
+logic [~SIZE[~TYPO]-1:0] ~GENSYM[dout][1];
+always @(posedge ~CLK[1]) begin : ~GENSYM[~COMPNAME_rom][2]
+  ~SYM[1] <= ~SYM[0][~ARG[3]];
 end
 
-assign ~RESULT = dout_~SYM[1];
+assign ~RESULT = ~FROMBV[~SYM[1]][~TYPO];
 // rom end"
     }
   }
diff --git a/primitives/CLaSH.Prelude.Testbench.json b/primitives/CLaSH.Prelude.Testbench.json
--- a/primitives/CLaSH.Prelude.Testbench.json
+++ b/primitives/CLaSH.Prelude.Testbench.json
@@ -13,7 +13,7 @@
 // pragma translate_off
 always @(posedge ~CLK[2] or posedge ~RST[2]) begin
   if (~ARG[4] !== ~ARG[5]) begin
-    $display(\"@%0tns: %s, expected: %b, actual: %b\", $time, ~LIT[3], ~TYPM[5]_to_lv(~ARG[5]), ~TYPM[4]_to_lv(~ARG[4]));
+    $display(\"@%0tns: %s, expected: %b, actual: %b\", $time, ~LIT[3], ~TOBV[~ARG[5]][~TYP[5]], ~TOBV[~ARG[4]][~TYP[4]]);
     $stop;
   end
 end
diff --git a/primitives/CLaSH.Signal.Internal.json b/primitives/CLaSH.Signal.Internal.json
--- a/primitives/CLaSH.Signal.Internal.json
+++ b/primitives/CLaSH.Signal.Internal.json
@@ -7,9 +7,9 @@
            -> Signal' clk a"
     , "templateD" :
 "// register begin
-~SIGD[~SYM[0]][2];
+~SIGD[~GENSYM[dout][0]][2];
 
-always_ff @(posedge ~CLK[0] or negedge ~RST[0]) begin : register_~COMPNAME_~SYM[1]
+always_ff @(posedge ~CLK[0] or negedge ~RST[0]) begin : ~GENSYM[~COMPNAME_register][1]
   if (~ ~RST[0]) begin
     ~SYM[0] <= ~ARG[1];
   end else begin
@@ -31,9 +31,9 @@
         -> Signal' clk a"
     , "templateD" :
 "// regEn begin
-~SIGD[~SYM[0]][3];
+~SIGD[~GENSYM[dout][0]][3];
 
-always_ff @(posedge ~CLK[0] or negedge ~RST[0]) begin : regEn_~COMPNAME_~SYM[1]
+always_ff @(posedge ~CLK[0] or negedge ~RST[0]) begin : ~GENSYM[~COMPNAME_regEn][1]
   if (~ ~RST[0]) begin
     ~SYM[0] <= ~ARG[1];
   end else begin
diff --git a/primitives/CLaSH.Sized.Internal.BitVector.json b/primitives/CLaSH.Sized.Internal.BitVector.json
--- a/primitives/CLaSH.Sized.Internal.BitVector.json
+++ b/primitives/CLaSH.Sized.Internal.BitVector.json
@@ -55,10 +55,10 @@
         -> Bit"
     , "templateD" :
 "// indexBit begin
-~SIGD[vec_~SYM[0]][1];
-assign vec_~SYM[0] = ~ARG[1];
+~SIGD[~GENSYM[bv][0]][1];
+assign ~SYM[0] = ~ARG[1];
 
-assign ~RESULT = vec_~SYM[0][~ARG[2]];
+assign ~RESULT = ~SYM[0][~ARG[2]];
 // indexBit end"
     }
   }
@@ -72,16 +72,14 @@
              -> BitVector n"
     , "templateD" :
 "// replaceBit start
-~SIGD[vec_~SYM[0]][1];
-~SIGD[din_~SYM[1]][3];
-assign din_~SYM[1] = ~ARG[3];
+~SIGD[~GENSYM[bv][0]][1];
 
 always_comb begin
-  vec_~SYM[0] = ~ARG[1];
-  vec_~SYM[0][~ARG[2]] = din_~SYM[1];
+  ~SYM[0] = ~ARG[1];
+  ~SYM[0][~ARG[2]] = ~ARG[3];
 end
 
-assign ~RESULT = vec_~SYM[0];
+assign ~RESULT = ~SYM[0];
 // replaceBit end"
     }
   }
@@ -95,7 +93,7 @@
            -> BitVector (m + 1 + i)"
     , "templateD" :
 "// setSlice begin
-~SIGD[~SYM[0]][0];
+~SIGD[~GENSYM[bv][0]][0];
 
 always_comb begin
   ~SYM[0] = ~ARG[0];
@@ -115,7 +113,7 @@
         -> BitVector (m + 1 - n)"
     , "templateD" :
 "// slice begin
-~SIGD[~SYM[0]][0];
+~SIGD[~GENSYM[bv][0]][0];
 assign ~SYM[0] = ~ARG[0];
 assign ~RESULT = ~SYM[0][~LIT[1] : ~LIT[2]];
 // slice end"
@@ -129,11 +127,11 @@
         -> (BitVector m, BitVector n)"
     , "templateD" :
 "// split begin
-~SIGD[~SYM[0]][1];
+~SIGD[~GENSYM[bv][0]][1];
 assign ~SYM[0] = ~ARG[1];
-assign ~RESULT = '{ ~SYM[0][$high(~SYM[0]) : ~LIT[0]]
-                  , ~SYM[0][(~LIT[0]-1) : 0]
-                  };
+assign ~RESULT = { ~SYM[0][$high(~SYM[0]) : ~LIT[0]]
+                 , ~SYM[0][(~LIT[0]-1) : 0]
+                 };
 // split end"
     }
   }
@@ -145,7 +143,7 @@
       -> Bit"
     , "templateD" :
 "// msb begin~IF ~LIT[0] ~THEN
-~SIGD[~SYM[0]][1];
+~SIGD[~GENSYM[bv][0]][1];
 assign ~SYM[0] = ~ARG[1];
 assign ~RESULT = ~SYM[0][~LIT[0]-1];
 ~ELSE
@@ -160,7 +158,7 @@
       -> Bit"
     , "templateD" :
 "// lsb begin~IF ~SIZE[~TYP[0]] ~THEN
-~SIGD[~SYM[0]][0];
+~SIGD[~GENSYM[bv][0]][0];
 assign ~SYM[0] = ~ARG[0];
 assign ~RESULT = ~SYM[0][0];
 ~ELSE
@@ -323,7 +321,7 @@
     , "type"      : "rotateL# :: KnownNat n => BitVector n -> Int -> BitVector n"
     , "templateD" :
 "// rotateL begin
-logic [2*~LIT[0]-1:0] ~SYM[0];
+logic [2*~LIT[0]-1:0] ~GENSYM[bv][0];
 assign ~SYM[0] = {~ARG[1],~ARG[1]} << ~ARG[2];
 assign ~RESULT = ~SYM[0][2*~LIT[0]-1 : ~LIT[0]];
 // rotateL end"
@@ -334,7 +332,7 @@
     , "type"      : "rotateR# :: KnownNat n => BitVector n -> Int -> BitVector n"
     , "templateD" :
 "// rotateR begin
-logic [2*~LIT[0]-1:0] ~SYM[0];
+logic [2*~LIT[0]-1:0] ~GENSYM[bv][0];
 assign ~SYM[0] = {~ARG[1],~ARG[1]} >> ~ARG[2];
 assign ~RESULT = ~SYM[0][~LIT[0]-1 : 0];
 // rotateR end"
diff --git a/primitives/CLaSH.Sized.Internal.Signed.json b/primitives/CLaSH.Sized.Internal.Signed.json
--- a/primitives/CLaSH.Sized.Internal.Signed.json
+++ b/primitives/CLaSH.Sized.Internal.Signed.json
@@ -137,9 +137,9 @@
     , "type"      : "div# :: KnownNat n => Signed n -> Signed n -> Signed n"
     , "templateD" :
 "// divSigned begin
-~SIGD[~SYM[0]][1];
-~SIGD[~SYM[1]][1];
-~SIGD[~SYM[2]][2];
+~SIGD[~GENSYM[quot_res][0]][1];
+~SIGD[~GENSYM[dividend][1]][1];
+~SIGD[~GENSYM[divider][2]][2];
 
 // divide (rounds towards zero)
 assign ~SYM[0] = ~ARG[1] / ~ARG[2];
@@ -156,9 +156,9 @@
     , "type"      : "mod# :: Signed n -> Signed n -> Signed n"
     , "templateD" :
 "// modSigned begin
-~SIGD[~SYM[0]][0];
-~SIGD[~SYM[1]][0];
-~SIGD[~SYM[2]][1];
+~SIGD[~GENSYM[rem_res][0]][0];
+~SIGD[~GENSYM[dividend][1]][0];
+~SIGD[~GENSYM[divider][2]][1];
 
 // remainder
 assign ~SYM[0] = ~ARG[0] % ~ARG[1];
@@ -219,7 +219,7 @@
     , "type"      : "rotateL# :: KnownNat n => Signed n -> Int -> Signed n"
     , "templateD" :
 "// rotateL begin
-logic [2*~LIT[0]-1:0] ~SYM[0];
+logic [2*~LIT[0]-1:0] ~GENSYM[s][0];
 assign ~SYM[0] = {~ARG[1],~ARG[1]} << ~ARG[2];
 assign ~RESULT = $signed(~SYM[0][~LIT[1]-1 : 0]);
 // rotateL end"
@@ -230,7 +230,7 @@
     , "type"      : "rotateR# :: KnownNat n => Signed n -> Int -> Signed n"
     , "templateD" :
 "// rotateR begin
-logic [2*~LIT[0]-1:0] ~SYM[0];
+logic [2*~LIT[0]-1:0] ~GENSYM[s][0];
 assign ~SYM[0] = {~ARG[1],~ARG[1]} >> ~ARG[2];
 assign ~RESULT = $signed(~SYM[0][~LIT[1]-1 : 0]);
 // rotateR end"
@@ -245,7 +245,7 @@
 ~GENERATE
   if (~LIT[1] < ~LIT[0]) begin
     // truncate, sign preserving
-    ~SIGD[~SYM[0]][2];
+    ~SIGD[~GENSYM[s][0]][2];
     assign ~SYM[0] = ~ARG[2];
     assign ~RESULT = $signed({~SYM[0][~LIT[0]-1],~SYM[0][(~LIT[1]-2):0]});
   end else begin
diff --git a/primitives/CLaSH.Sized.Internal.Unsigned.json b/primitives/CLaSH.Sized.Internal.Unsigned.json
--- a/primitives/CLaSH.Sized.Internal.Unsigned.json
+++ b/primitives/CLaSH.Sized.Internal.Unsigned.json
@@ -171,7 +171,7 @@
     , "type"      : "rotateL# :: KnownNat n => Unsigned n -> Int -> Unsigned n"
     , "templateD" :
 "// rotateL begin
-logic [2*~LIT[0]-1:0] ~SYM[0];
+logic [2*~LIT[0]-1:0] ~GENSYM[u][0];
 assign ~SYM[0] = {~ARG[1],~ARG[1]} << ~ARG[2];
 assign ~RESULT = ~SYM[0][~LIT[1]-1 : 0];
 // rotateL end"
@@ -182,7 +182,7 @@
     , "type"      : "rotateR# :: KnownNat n => Unsigned n -> Int -> Unsigned n"
     , "templateD" :
 "// rotateR begin
-logic [2*~LIT[0]-1:0] ~SYM[0];
+logic [2*~LIT[0]-1:0] ~GENSYM[u][0];
 assign ~SYM[0] = {~ARG[1],~ARG[1]} >> ~ARG[2];
 assign ~RESULT = ~SYM[0][~LIT[1]-1 : 0];
 // rotateR end"
diff --git a/primitives/CLaSH.Sized.Vector.json b/primitives/CLaSH.Sized.Vector.json
--- a/primitives/CLaSH.Sized.Vector.json
+++ b/primitives/CLaSH.Sized.Vector.json
@@ -3,10 +3,10 @@
     , "type"      : "head :: Vec (n + 1) a -> a"
     , "templateD" :
 "// head begin
-~SIGD[~SYM[0]][0];
+~SIGD[~GENSYM[vec][0]][0];
 assign ~SYM[0] = ~ARG[0];
 
-assign ~RESULT = ~SYM[0][0];
+assign ~RESULT = ~FROMBV[~SYM[0][\\0\\]][~TYPO];
 // head end"
     }
   }
@@ -15,7 +15,7 @@
     , "type"      : "tail :: Vec (n + 1) a -> Vec n a"
     , "templateD" :
 "// tail begin
-~SIGD[~SYM[0]][0];
+~SIGD[~GENSYM[vec][0]][0];
 assign ~SYM[0] = ~ARG[0];
 
 assign ~RESULT = ~SYM[0][1 : $high(~SYM[0])];
@@ -27,10 +27,10 @@
     , "type"      : "Vec (n + 1) a -> a"
     , "templateD" :
 "// last begin
-~SIGD[~SYM[0]][0];
+~SIGD[~GENSYM[vec][0]][0];
 assign ~SYM[0] = ~ARG[0];
 
-assign ~RESULT = ~SYM[0][$high(~SYM[0])];
+assign ~RESULT = ~FROMBV[~SYM[0][\\$high(~SYM[0])\\]][~TYPO];
 // last end"
     }
   }
@@ -39,7 +39,7 @@
     , "type"      : "Vec (n + 1) a -> Vec n a"
     , "templateD" :
 "// init begin
-~SIGD[~SYM[0]][0];
+~SIGD[~GENSYM[vec][0]][0];
 assign ~SYM[0] = ~ARG[0];
 
 assign ~RESULT = ~SYM[0][0 : $high(~SYM[0]) - 1];
@@ -57,12 +57,12 @@
         -> Vec n a"
     , "templateD" :
 "// select begin
-~SIGD[~SYM[0]][4];
+~SIGD[~GENSYM[vec][0]][4];
 assign ~SYM[0] = ~ARG[4];
 
-genvar ~SYM[1];
+genvar ~GENSYM[n][1];
 ~GENERATE
-  for (~SYM[1]=0; ~SYM[1] < ~LIT[3]; ~SYM[1] = ~SYM[1] + 1) begin : select_~SYM[2]
+  for (~SYM[1]=0; ~SYM[1] < ~LIT[3]; ~SYM[1] = ~SYM[1] + 1) begin : ~GENSYM[select][2]
     assign ~RESULT[~SYM[1]] = ~SYM[0][~LIT[1] + (~LIT[2] * ~SYM[1])];
   end
 ~ENDGENERATE
@@ -72,25 +72,7 @@
 , { "BlackBox" :
     { "name"      : "CLaSH.Sized.Vector.++"
     , "type"      : "(++) :: Vec n a -> Vec m a -> Vec (n + m) a"
-    , "templateD" :
-"// (++) begin
-~SIGD[~SYM[0]][0];
-~SIGD[~SYM[1]][1];
-
-assign ~SYM[0] = ~ARG[0];
-assign ~SYM[1] = ~ARG[1];
-
-genvar ~SYM[2];
-~GENERATE
-  for (~SYM[2]=0; ~SYM[2] < $size(~RESULT); ~SYM[2] = ~SYM[2] + 1) begin : append_~SYM[3]
-    if (~SYM[2] < $size(~SYM[0])) begin
-      assign ~RESULT[~SYM[2]] = ~SYM[0][~SYM[2]];
-    end else begin
-      assign ~RESULT[~SYM[2]] = ~SYM[1][~SYM[2]-$size(~SYM[0])];
-    end
-  end
-~ENDGENERATE
-// (++) end"
+    , "templateE" : "~FROMBV[{~TOBV[~ARG[0]][~TYP[0]],~TOBV[~ARG[1]][~TYP[1]]}][~TYPO]"
     }
   }
 , { "BlackBox" :
@@ -98,13 +80,13 @@
     , "type"      : "concat :: Vec n (Vec m a) -> Vec (n * m) a"
     , "templateD" :
 "// concat begin
-~SIGD[~SYM[0]][0];
+~SIGD[~GENSYM[vec][0]][0];
 assign ~SYM[0] = ~ARG[0];
 
-genvar ~SYM[1];
+genvar ~GENSYM[n][1];
 ~GENERATE
-  for (~SYM[1]=0; ~SYM[1] < $size(~SYM[0]); ~SYM[1] = ~SYM[1] + 1) begin : concat_~SYM[2]
-    assign ~RESULT[(~SYM[1] * $size(~SYM[0][0])) : ((~SYM[1] * $size(~SYM[0][0])) + $high(~SYM[0][0]))] = ~SYM[0][~SYM[1]];
+  for (~SYM[1]=0; ~SYM[1] < $size(~SYM[0]); ~SYM[1] = ~SYM[1] + 1) begin : ~GENSYM[concat][2]
+    assign ~RESULT[~SYM[1]*~LENGTH[~TYPEL[~TYP[0]]] : ~SYM[1]*~LENGTH[~TYPEL[~TYP[0]]]+(~LENGTH[~TYPEL[~TYP[0]]]-1)] = ~FROMBV[~SYM[0][\\~SYM[1]\\]][~TYPEL[~TYP[0]]];
   end
 ~ENDGENERATE
 // concat end"
@@ -115,12 +97,12 @@
     , "type"      : "splitAt :: SNat m -> Vec (m + n) a -> (Vec m a, Vec n a)"
     , "templateD" :
 "// splitAt begin
-~SIGD[~SYM[0]][1];
-assign ~SYM[0] = ~ARG[1];
+logic [0:~LENGTH[~TYP[1]]-1] [0:~SIZE[~TYPEL[~TYP[1]]]-1] ~GENSYM[vec][0];
+assign ~SYM[0] = ~TOBV[~ARG[1]][~TYP[1]];
 
-assign ~RESULT = '{~SYM[0][$left(~RESULT.~TYPMO_sel0) : $right(~RESULT.~TYPMO_sel0)]
-                  ,~SYM[0][($left(~RESULT.~TYPMO_sel1) + $size(~RESULT.~TYPMO_sel0)) : ($right(~RESULT.~TYPMO_sel1) + $size(~RESULT.~TYPMO_sel0))]
-                  };
+assign ~RESULT = {~SYM[0][0:~LIT[0]-1]
+                 ,~SYM[0][~LIT[0]:~LENGTH[~TYP[1]]-1]
+                 };
 // splitAt end"
     }
   }
@@ -133,13 +115,13 @@
            -> Vec n (Vec m a)"
     , "templateD" :
 "// unconcat begin
-~SIGD[~SYM[0]][2];
+~SIGD[~GENSYM[vec][0]][2];
 assign ~SYM[0] = ~ARG[2];
 
-genvar ~SYM[1];
+genvar ~GENSYM[n][1];
 ~GENERATE
-  for (~SYM[1] = 0; ~SYM[1] < $size(~RESULT); ~SYM[1] = ~SYM[1] + 1) begin : unconcat_~SYM[2]
-    assign ~RESULT[~SYM[1]] = ~SYM[0][(~SYM[1] * ~LIT[1]) : ((~SYM[1] * ~LIT[1]) + ~LIT[1] - 1)];
+  for (~SYM[1] = 0; ~SYM[1] < $size(~RESULT); ~SYM[1] = ~SYM[1] + 1) begin : ~GENSYM[unconcat][2]
+    assign ~RESULT[~SYM[1]] = ~TOBV[~SYM[0][\\(~SYM[1] * ~LIT[1]) : ((~SYM[1] * ~LIT[1]) + ~LIT[1] - 1)\\]][~TYPEL[~TYPO]];
   end
 ~ENDGENERATE
 // unconcat end"
@@ -150,16 +132,20 @@
     , "type"      : "map :: (a -> b) -> Vec n a -> Vec n b"
     , "templateD" :
 "// map begin
-~SIGD[~SYM[0]][1];
+~SIGD[~GENSYM[vec][0]][1];
 assign ~SYM[0] = ~ARG[1];
 
-genvar ~SYM[1];
+genvar ~GENSYM[n][1];
 ~GENERATE
-  for (~SYM[1]=0; ~SYM[1] < $size(~RESULT); ~SYM[1] = ~SYM[1] + 1) begin : map_~SYM[2]
+  for (~SYM[1]=0; ~SYM[1] < $size(~RESULT); ~SYM[1] = ~SYM[1] + 1) begin : ~GENSYM[map][2]
+    ~TYPEL[~TYP[1]] ~GENSYM[map_in][3];
+    ~TYPEL[~TYPO] ~GENSYM[map_out][4];
+    assign ~SYM[3] = ~FROMBV[~SYM[0][\\~SYM[1]\\]][~TYPEL[~TYP[1]]];
     ~INST 0
-      ~OUTPUT <= ~RESULT[~SYM[1]]~ ~TYPEL[~TYPO]~
-      ~INPUT  <= ~SYM[0][~SYM[1]]~ ~TYPEL[~TYP[1]]~
+      ~OUTPUT <= ~SYM[4]~ ~TYPEL[~TYPO]~
+      ~INPUT  <= ~SYM[3]~ ~TYPEL[~TYP[1]]~
     ~INST
+    assign ~RESULT[~SYM[1]] = ~TOBV[~SYM[4]][~TYPEL[~TYPO]];
   end
 ~ENDGENERATE
 // map end"
@@ -170,19 +156,23 @@
     , "type"      : "imap :: KnownNat n => (Index n -> a -> b) -> Vec n a -> Vec n b"
     , "templateD" :
 "// imap begin
-~SIGD[~SYM[0]][2];
+~SIGD[~GENSYM[vec][0]][2];
 assign ~SYM[0] = ~ARG[2];
 
-genvar ~SYM[1];
+genvar ~GENSYM[n][1];
 ~GENERATE
-  for (~SYM[1]=0; ~SYM[1] < $size(~RESULT); ~SYM[1] = ~SYM[1] + 1) begin : map_~SYM[2]
-    logic [~SIZE[~INDEXTYPE[~LIT[0]]]-1:0] ~SYM[3];
+  for (~SYM[1]=0; ~SYM[1] < $size(~RESULT); ~SYM[1] = ~SYM[1] + 1) begin : ~GENSYM[imap][2]
+    ~INDEXTYPE[~LIT[0]] ~GENSYM[i][3];
     assign ~SYM[3] = ~SYM[1];
+    ~TYPEL[~TYP[2]] ~GENSYM[imap_in][4];
+    ~TYPEL[~TYPO] ~GENSYM[imap_out][5];
+    assign ~SYM[4] = ~FROMBV[~SYM[0][\\~SYM[1]\\]][~TYPEL[~TYP[2]]];
     ~INST 1
-      ~OUTPUT <= ~RESULT[~SYM[1]]~ ~TYPEL[~TYPO]~
+      ~OUTPUT <= ~SYM[5]~ ~TYPEL[~TYPO]~
       ~INPUT  <= ~SYM[3]~ ~INDEXTYPE[~LIT[0]]~
-      ~INPUT  <= ~SYM[0][~SYM[1]]~ ~TYPEL[~TYP[2]]~
+      ~INPUT  <= ~SYM[4]~ ~TYPEL[~TYP[2]]~
     ~INST
+    assign ~RESULT[~SYM[1]] = ~TOBV[~SYM[5]][~TYPEL[~TYPO]];
   end
 ~ENDGENERATE
 // imap end"
@@ -193,19 +183,25 @@
     , "type"      : "zipWith :: (a -> b -> c) -> Vec n a -> Vec n b -> Vec n c"
     , "templateD" :
 "// zipWith begin
-~SIGD[~SYM[0]][1];
-~SIGD[~SYM[1]][2];
+~SIGD[~GENSYM[vec1][0]][1];
+~SIGD[~GENSYM[vec2][1]][2];
 assign ~SYM[0] = ~ARG[1];
 assign ~SYM[1] = ~ARG[2];
 
-genvar ~SYM[2];
+genvar ~GENSYM[n][2];
 ~GENERATE
-  for (~SYM[2] = 0; ~SYM[2] < $size(~RESULT); ~SYM[2] = ~SYM[2] + 1) begin : zipWith_~SYM[2]
+  for (~SYM[2] = 0; ~SYM[2] < $size(~RESULT); ~SYM[2] = ~SYM[2] + 1) begin : ~GENSYM[zipWith][3]
+    ~TYPEL[~TYP[1]] ~GENSYM[zipWith_in1][4];
+    ~TYPEL[~TYP[2]] ~GENSYM[zipWith_in2][5];
+    ~TYPEL[~TYPO] ~GENSYM[zipWith_out][6];
+    assign ~SYM[4] = ~FROMBV[~SYM[0][\\~SYM[2]\\]][~TYPEL[~TYP[1]]];
+    assign ~SYM[5] = ~FROMBV[~SYM[1][\\~SYM[2]\\]][~TYPEL[~TYP[2]]];
     ~INST 0
-      ~OUTPUT <= ~RESULT[~SYM[2]]~ ~TYPEL[~TYPO]~
-      ~INPUT  <= ~SYM[0][~SYM[2]]~ ~TYPEL[~TYP[1]]~
-      ~INPUT  <= ~SYM[1][~SYM[2]]~ ~TYPEL[~TYP[2]]~
+      ~OUTPUT <= ~SYM[6]~ ~TYPEL[~TYPO]~
+      ~INPUT  <= ~SYM[4]~ ~TYPEL[~TYP[1]]~
+      ~INPUT  <= ~SYM[5]~ ~TYPEL[~TYP[2]]~
     ~INST
+    assign ~RESULT[~SYM[2]] = ~TOBV[~SYM[6]][~TYPEL[~TYPO]];
   end
 ~ENDGENERATE
 // zipWith end"
@@ -216,24 +212,26 @@
     , "type"      : "foldr :: (a -> b -> b) -> b -> Vec n a -> b"
     , "templateD" :
 "// foldr start~IF ~LENGTH[~TYP[2]] ~THEN
-~SIGDO[intermediate_~SYM[0]] [0:~LENGTH[~TYP[2]]];
-assign intermediate_~SYM[0][~LENGTH[~TYP[2]]] = ~ARG[1];
+~SIGDO[~GENSYM[intermediate][0]] [0:~LENGTH[~TYP[2]]];
+assign ~SYM[0][~LENGTH[~TYP[2]]] = ~ARG[1];
 
-~SIGD[xs_~SYM[2]][2];
-assign xs_~SYM[2] = ~ARG[2];
+~SIGD[~GENSYM[xs][2]][2];
+assign ~SYM[2] = ~ARG[2];
 
-genvar i_~SYM[3];
+genvar ~GENSYM[i][3];
 ~GENERATE
-for (i_~SYM[3]=0; i_~SYM[3] < ~LENGTH[~TYP[2]]; i_~SYM[3]=i_~SYM[3]+1) begin : foldr_loop
+for (~SYM[3]=0; ~SYM[3] < ~LENGTH[~TYP[2]]; ~SYM[3]=~SYM[3]+1) begin : ~GENSYM[foldr_loop][4]
+  ~TYPEL[~TYP[2]] ~GENSYM[foldr_in][5];
+  assign ~SYM[5] = ~FROMBV[~SYM[2][\\~SYM[3]\\]][~TYPEL[~TYP[2]]];
   ~INST 0
-    ~OUTPUT <= intermediate_~SYM[0][i_~SYM[3]]~ ~TYP[1]~
-    ~INPUT <= xs_~SYM[2][i_~SYM[3]]~ ~TYPEL[~TYP[2]]~
-    ~INPUT <= intermediate_~SYM[0][i_~SYM[3]+1]~ ~TYP[1]~
+    ~OUTPUT <= ~SYM[0][~SYM[3]]~ ~TYP[1]~
+    ~INPUT <= ~SYM[5]~ ~TYPEL[~TYP[2]]~
+    ~INPUT <= ~SYM[0][~SYM[3]+1]~ ~TYP[1]~
   ~INST
 end
 ~ENDGENERATE
 
-assign ~RESULT = intermediate_~SYM[0][0];
+assign ~RESULT = ~SYM[0][0];
 ~ELSE
 assign ~RESULT = ~ARG[1];
 ~FI// foldr end"
@@ -246,32 +244,32 @@
     , "templateD" :
 "// fold begin
 // put flat input array into the first half of the intermediate array
-~SIGDO[intermediate_~SYM[0]][0:(2*~LENGTH[~TYP[1]])-2];
-assign intermediate_~SYM[0][0:~LENGTH[~TYP[1]]-1] = ~ARG[1];
+~SIGDO[~GENSYM[intermediate][0]] [0:(2*~LENGTH[~TYP[1]])-2];
+assign ~SYM[0][0:~LENGTH[~TYP[1]]-1] = ~ARG[1];
 
 // calculate the depth of the tree
-localparam levels_~SYM[4] = $clog2(~LENGTH[~TYP[1]]);
+localparam ~GENSYM[levels][4] = $clog2(~LENGTH[~TYP[1]]);
 
 // given a level and a depth, calculate the corresponding index into the
 // intermediate array
-function integer depth2Index_~SYM[8];
+function integer ~GENSYM[depth2Index][8];
   input integer levels;
   input integer depth;
 
-  depth2Index_~SYM[8] = (2 ** levels) - (2 ** depth);
+  ~SYM[8] = (2 ** levels) - (2 ** depth);
 endfunction
 
 // Create the tree of instantiated components
-genvar d_~SYM[5];
-genvar i_~SYM[6];
+genvar ~GENSYM[d][5];
+genvar ~GENSYM[i][6];
 ~GENERATE
-if (levels_~SYM[4] != 0) begin : make_tree_~SYM[7]
-  for (d_~SYM[5] = (levels_~SYM[4] - 1); d_~SYM[5] >= 0; d_~SYM[5]=d_~SYM[5]-1) begin : tree_depth
-    for (i_~SYM[6] = 0; i_~SYM[6] < (2**d_~SYM[5]); i_~SYM[6] = i_~SYM[6]+1) begin : tree_depth_loop
+if (~SYM[4] != 0) begin : ~GENSYM[make_tree][7]
+  for (~SYM[5] = (~SYM[4] - 1); ~SYM[5] >= 0; ~SYM[5]=~SYM[5]-1) begin : tree_depth
+    for (~SYM[6] = 0; ~SYM[6] < (2**~SYM[5]); ~SYM[6] = ~SYM[6]+1) begin : tree_depth_loop
         ~INST 0
-          ~OUTPUT <= intermediate_~SYM[0][depth2Index_~SYM[8](levels_~SYM[4]+1,d_~SYM[5]+1)+i_~SYM[6]]~ ~TYPO~
-          ~INPUT  <= intermediate_~SYM[0][depth2Index_~SYM[8](levels_~SYM[4]+1,d_~SYM[5]+2)+(2*i_~SYM[6])]~ ~TYPO~
-          ~INPUT  <= intermediate_~SYM[0][depth2Index_~SYM[8](levels_~SYM[4]+1,d_~SYM[5]+2)+(2*i_~SYM[6])+1]~ ~TYPO~
+          ~OUTPUT <= ~SYM[0][~SYM[8](~SYM[4]+1,~SYM[5]+1)+~SYM[6]]~ ~TYPO~
+          ~INPUT  <= ~SYM[0][~SYM[8](~SYM[4]+1,~SYM[5]+2)+(2*~SYM[6])]~ ~TYPO~
+          ~INPUT  <= ~SYM[0][~SYM[8](~SYM[4]+1,~SYM[5]+2)+(2*~SYM[6])+1]~ ~TYPO~
         ~INST
     end
   end
@@ -279,7 +277,7 @@
 ~ENDGENERATE
 
 // The last element of the intermediate array holds the result
-assign ~RESULT = intermediate_~SYM[0][(2*~LENGTH[~TYP[1]])-2];
+assign ~RESULT = ~SYM[0][(2*~LENGTH[~TYP[1]])-2];
 // fold end"
     }
   }
@@ -288,10 +286,10 @@
     , "type"      : "index_integer :: KnownNat n => Vec n a -> Int -> a"
     , "templateD" :
 "// indexVec begin
-~SIGD[vec_~SYM[0]][1];
-assign vec_~SYM[0] = ~ARG[1];
+~SIGD[~GENSYM[vec][0]][1];
+assign ~SYM[0] = ~ARG[1];
 
-assign ~RESULT = vec_~SYM[0][~ARG[2]];
+assign ~RESULT = ~FROMBV[~SYM[0][\\~ARG[2]\\]][~TYPO];
 // indexVec end"
     }
   }
@@ -300,16 +298,14 @@
     , "type"      : "replace_int :: KnownNat n => Vec n a -> Int -> a -> Vec n a"
     , "templateD" :
 "// replaceVec start
-~SIGD[vec_~SYM[0]][1];
-~SIGD[din_~SYM[1]][3];
-assign din_~SYM[1] = ~ARG[3];
+~SIGD[~GENSYM[vec][0]][1];
 
 always_comb begin
-  vec_~SYM[0] = ~ARG[1];
-  vec_~SYM[0][~ARG[2]] = din_~SYM[1];
+  ~SYM[0] = ~ARG[1];
+  ~SYM[0][~ARG[2]] = ~TOBV[~ARG[3]][~TYP[3]];
 end
 
-assign ~RESULT = vec_~SYM[0];
+assign ~RESULT = ~SYM[0];
 // replaceVec end"
     }
   }
@@ -328,7 +324,7 @@
 , { "BlackBox" :
     { "name"      : "CLaSH.Sized.Vector.replicate"
     , "type"      : "replicate :: SNat n -> a -> Vec n a"
-    , "templateE" : "'{~LIT[0] {~ARG[1]}}"
+    , "templateE" : "'{~LIT[0] {~TOBV[~ARG[1]][~TYP[1]]}}"
     }
   }
 , { "BlackBox" :
@@ -336,15 +332,16 @@
     , "type"      : "transpose :: KnownNat n => Vec m (Vec n a) -> Vec n (Vec m a)"
     , "templateD" :
 "// transpose begin
-~SIGD[~SYM[0]][1];
+~SIGD[~GENSYM[matrix][0]][1];
 assign ~SYM[0] = ~ARG[1];
 
-genvar ~SYM[1];
-genvar ~SYM[2];
+genvar ~GENSYM[row_index][1];
+genvar ~GENSYM[col_index][2];
 ~GENERATE
-  for (~SYM[1] = 0; ~SYM[1] < $size(~SYM[0]); ~SYM[1] = ~SYM[1] + 1) begin : transpose_outer_~SYM[3]
-    for (~SYM[2] = 0; ~SYM[2] < $size(~RESULT); ~SYM[2] = ~SYM[2] + 1) begin : transpose_inner_~SYM[4]
-      assign ~RESULT[~SYM[2]][~SYM[1]] = ~SYM[0][~SYM[1]][~SYM[2]];
+  for (~SYM[1] = 0; ~SYM[1] < $size(~SYM[0]); ~SYM[1] = ~SYM[1] + 1) begin : ~GENSYM[transpose_outer][3]
+    for (~SYM[2] = 0; ~SYM[2] < $size(~RESULT); ~SYM[2] = ~SYM[2] + 1) begin : ~GENSYM[transpose_inner][4]~IF ~VIVADO ~THEN
+      assign ~RESULT[~SYM[2]][($size(~SYM[0])-~SYM[1])*~SIZE[~TYPEL[~TYPEL[~TYPO]]]-1 : ($size(~SYM[0])-~SYM[1]-1)*~SIZE[~TYPEL[~TYPEL[~TYPO]]]] = ~SYM[0][~SYM[1]][($size(~RESULT)-~SYM[2])*~SIZE[~TYPEL[~TYPEL[~TYPO]]]-1 : ($size(~RESULT)-~SYM[2]-1)*~SIZE[~TYPEL[~TYPEL[~TYPO]]]];~ELSE
+      assign ~RESULT[~SYM[2]][~SYM[1]] = ~SYM[0][~SYM[1]][~SYM[2]];~FI
     end
   end
 ~ENDGENERATE
@@ -356,12 +353,12 @@
     , "type"      : "reverse :: Vec n a -> Vec n a"
     , "templateD" :
 "// reverse begin
-~SIGD[~SYM[0]][0];
+~SIGD[~GENSYM[vec][0]][0];
 assign ~SYM[0] = ~ARG[0];
 
-genvar ~SYM[1];
+genvar ~GENSYM[n][1];
 ~GENERATE
-  for (~SYM[1] = 0; ~SYM[1] < $size(~SYM[0]); ~SYM[1] = ~SYM[1] + 1) begin : reverse_~SYM[2]
+  for (~SYM[1] = 0; ~SYM[1] < $size(~SYM[0]); ~SYM[1] = ~SYM[1] + 1) begin : ~GENSYM[reverse][2]
     assign ~RESULT[$high(~SYM[0]) - ~SYM[1]] = ~SYM[0][~SYM[1]];
   end
 ~ENDGENERATE
@@ -380,18 +377,7 @@
 "concatBitVector# :: KnownNat m           -- ARG[0]
                   => Vec n (BitVector m)  -- ARG[1]
                   -> BitVector (n * m)"
-    , "templateD" :
-"// concatBitVector begin
-~SIGD[~SYM[0]][1];
-assign ~SYM[0] = ~ARG[1];
-
-genvar ~SYM[1];
-~GENERATE
-  for (~SYM[1] = 0; ~SYM[1] < $size(~SYM[0]); ~SYM[1] = ~SYM[1] + 1) begin : concatBitVector_~SYM[2]
-    assign ~RESULT[((~SYM[1] * ~LIT[0]) + ~LIT[0] - 1) : (~SYM[1] * ~LIT[0])] = ~SYM[0][$high(~SYM[0]) - ~SYM[1]];
-  end
-~ENDGENERATE
-// concatBitVector end"
+    , "templateE" : "~TOBV[~ARG[1]][~TYP[1]]"
     }
   }
 , { "BlackBox" :
@@ -400,18 +386,7 @@
 "unconcatBitVector# :: (KnownNat n, KnownNat m) -- (ARG[0],ARG[1])
                     => BitVector (n * m)        -- ARG[2]
                     -> Vec n (BitVector m)"
-    , "templateD" :
-"// unconcatBitVector begin
-~SIGD[~SYM[0]][2];
-assign ~SYM[0] = ~ARG[2];
-
-genvar ~SYM[1];
-~GENERATE
-  for (~SYM[1] = 0; ~SYM[1] < $size(~RESULT); ~SYM[1] = ~SYM[1] + 1) begin : unconcatBitVector_~SYM[2]
-    assign ~RESULT[$high(~RESULT) - ~SYM[1]] = ~SYM[0][((~SYM[1] * ~LIT[1]) + ~LIT[1] - 1) : (~SYM[1] * ~LIT[1])];
-  end
-~ENDGENERATE
-// unconcatBitVector end"
+    , "templateE" : "~FROMBV[~ARG[2]][~TYPO]"
     }
   }
 , { "BlackBox" :
@@ -419,17 +394,17 @@
     , "type"      : "rotateLeftS :: KnownNat n => Vec n a -> SNat d -> Vec n a"
     , "templateD" :
 "// rotateLeftS begin
-~SIGD[~SYM[1]][1];
-localparam shift_amount_~SYM[2] = ~LIT[2] % ~LIT[0];
+~SIGD[~GENSYM[vec][1]][1];
+localparam ~GENSYM[shift_amount][2] = ~LIT[2] % ~LIT[0];
 
 assign ~SYM[1] = ~ARG[1];
 
 ~GENERATE
-if (shift_amount_~SYM[2] == 0) begin : no_shift_~SYM[3]
+if (~SYM[2] == 0) begin : ~GENSYM[no_shift][3]
   assign ~RESULT = ~SYM[1];
-end else begin : do_shift_~SYM[4]
-  assign ~RESULT[0:~LIT[0]-shift_amount_~SYM[2]-1] = ~SYM[1][shift_amount_~SYM[2]:~LIT[0]-1];
-  assign ~RESULT[shift_amount_~SYM[2]:~LIT[0]-1] = ~SYM[1][0 to shift_amount_~SYM[2]-1];
+end else begin : ~GENSYM[do_shift][4]
+  assign ~RESULT[0:~LIT[0]-~SYM[2]-1] = ~SYM[1][~SYM[2]:~LIT[0]-1];
+  assign ~RESULT[~SYM[2]:~LIT[0]-1] = ~SYM[1][0 to ~SYM[2]-1];
 end
 ~ENDGENERATE
 // rotateLeftS end"
@@ -440,17 +415,17 @@
     , "type"      : "rotateRightS :: KnownNat n => Vec n a -> SNat d -> Vec n a"
     , "templateD" :
 "// rotateRightS begin
-~SIGD[~SYM[1]][1];
-localparam shift_amount_~SYM[2] = ~LIT[2] % ~LIT[0];
+~SIGD[~GENSYM[vec][1]][1];
+localparam ~GENSYM[shift_amount][2] = ~LIT[2] % ~LIT[0];
 
 assign ~SYM[1] = ~ARG[1];
 
 ~GENERATE
-if (shift_amount_~SYM[2] == 0) begin : no_shift_~SYM[3]
+if (~SYM[2] == 0) begin : ~GENSYM[no_shift][3]
   assign ~RESULT = ~SYM[1];
-end else begin : do_shift_~SYM[4]
-  assign ~RESULT[0:shift_amount_~SYM[2]-1] = ~SYM[1][~LIT[0]-shift_amount_~SYM[2]:~LIT[0]-1];
-  assign ~RESULT[shift_amount_~SYM[2]:~LIT[0]-1] = ~SYM[1][0:~LIT[0]-shift_amount_~SYM[2]-1];
+end else begin : ~GENSYM[do_shift][4]
+  assign ~RESULT[0:~SYM[2]-1] = ~SYM[1][~LIT[0]-~SYM[2]:~LIT[0]-1];
+  assign ~RESULT[~SYM[2]:~LIT[0]-1] = ~SYM[1][0:~LIT[0]-~SYM[2]-1];
 end
 ~ENDGENERATE
 // rotateRightS end"
diff --git a/primitives/GHC.Base.json b/primitives/GHC.Base.json
--- a/primitives/GHC.Base.json
+++ b/primitives/GHC.Base.json
@@ -20,9 +20,9 @@
     , "type"      : "divInt :: Int -> Int -> Int"
     , "templateD" :
 "// divInt begin
-~SIGD[~SYM[0]][0];
-~SIGD[~SYM[1]][0];
-~SIGD[~SYM[2]][1];
+~SIGD[~GENSYM[quot_res][0]][0];
+~SIGD[~GENSYM[dividend][1]][0];
+~SIGD[~GENSYM[divider][2]][1];
 
 // divide (rounds towards zero)
 assign ~SYM[0] = ~ARG[0] / ~ARG[1];
@@ -39,9 +39,9 @@
     , "type"      : "modInt :: Int -> Int -> Int"
     , "templateD" :
 "// modInt begin
-~SIGD[~SYM[0]][0];
-~SIGD[~SYM[1]][0];
-~SIGD[~SYM[2]][1];
+~SIGD[~GENSYM[rem_res][0]][0];
+~SIGD[~GENSYM[dividend][1]][0];
+~SIGD[~GENSYM[divider][2]][1];
 
 // remainder
 assign ~SYM[0] = ~ARG[0] % ~ARG[1];
diff --git a/primitives/GHC.Classes.json b/primitives/GHC.Classes.json
--- a/primitives/GHC.Classes.json
+++ b/primitives/GHC.Classes.json
@@ -57,9 +57,9 @@
     , "type"      : "divInt# :: Int# -> Int# -> Int#"
     , "templateD" :
 "// divInt begin
-~SIGD[~SYM[0]][0];
-~SIGD[~SYM[1]][0];
-~SIGD[~SYM[2]][1];
+~SIGD[~GENSYM[quot_res][0]][0];
+~SIGD[~GENSYM[dividend][1]][0];
+~SIGD[~GENSYM[divider][2]][1];
 
 // divide (rounds towards zero)
 assign ~SYM[0] = ~ARG[0] / ~ARG[1];
@@ -76,9 +76,9 @@
     , "type"      : "modInt# :: Int# -> Int# -> Int#"
     , "templateD" :
 "// modInt begin
-~SIGD[~SYM[0]][0];
-~SIGD[~SYM[1]][0];
-~SIGD[~SYM[2]][1];
+~SIGD[~GENSYM[rem_res][0]][0];
+~SIGD[~GENSYM[dividend][1]][0];
+~SIGD[~GENSYM[divider][2]][1];
 
 // remainder
 assign ~SYM[0] = ~ARG[0] % ~ARG[1];
diff --git a/primitives/GHC.Integer.Type.json b/primitives/GHC.Integer.Type.json
--- a/primitives/GHC.Integer.Type.json
+++ b/primitives/GHC.Integer.Type.json
@@ -45,9 +45,9 @@
     , "type"      : "divInteger :: Integer -> Integer -> Integer"
     , "templateD" :
 "// divInteger begin
-~SIGD[~SYM[0]][0];
-~SIGD[~SYM[1]][0];
-~SIGD[~SYM[2]][1];
+~SIGD[~GENSYM[quot_res][0]][0];
+~SIGD[~GENSYM[dividend][1]][0];
+~SIGD[~GENSYM[divider][2]][1];
 
 // divide (rounds towards zero)
 assign ~SYM[0] = ~ARG[0] / ~ARG[1];
@@ -64,9 +64,9 @@
     , "type"      : "modInteger :: Integer -> Integer -> Integer"
     , "templateD" :
 "// modInteger begin
-~SIGD[~SYM[0]][0];
-~SIGD[~SYM[1]][0];
-~SIGD[~SYM[2]][1];
+~SIGD[~GENSYM[rem_res][0]][0];
+~SIGD[~GENSYM[dividend][1]][0];
+~SIGD[~GENSYM[divider][2]][1];
 
 // remainder
 assign ~SYM[0] = ~ARG[0] % ~ARG[1];
diff --git a/primitives/GHC.Prim.json b/primitives/GHC.Prim.json
--- a/primitives/GHC.Prim.json
+++ b/primitives/GHC.Prim.json
@@ -75,1768 +75,1669 @@
     , "type"      : "quotRemInt# :: Int# -> Int# -> (#Int#, Int##)"
     , "templateD" :
 "// quotRemInt begin
-~SIGD[~SYM[0]][0];
-~SIGD[~SYM[1]][0];
-assign ~SYM[0] = ~ARG[0] / ~ARG[1];
-assign ~SYM[1] = ~ARG[0] % ~ARG[1];
-
-assign ~RESULT = {~SYM[0],~SYM[1]};
-// quotRemInt end"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.andI#"
-    , "type"      : "andI# :: Int# -> Int# -> Int#"
-    , "templateE" : "~ARG[0] & ~ARG[1]"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.orI#"
-    , "type"      : "orI# :: Int# -> Int# -> Int#"
-    , "templateE" : "~ARG[0] | ~ARG[1]"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.xorI#"
-    , "type"      : "xorI# :: Int# -> Int# -> Int#"
-    , "templateE" : "~ARG[0] ^ ~ARG[1]"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.notI#"
-    , "type"      : "notI# :: Int# -> Int#"
-    , "templateE" : "~ ~ARG[0]"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.negateInt#"
-    , "type"      : "negateInt# :: Int# -> Int#"
-    , "templateE" : "-(~ARG[0])"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.>#"
-     , "type"     : "(>#) :: Int# -> Int# -> Int#"
-    , "templateE" : "(~ARG[0] > ~ARG[1]) ? ~SIZE[~TYPO]'sd1 : ~SIZE[~TYPO]'sd0"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.>=#"
-    , "type"      : "(>=#) :: Int# -> Int# -> Int#"
-    , "templateE" : "(~ARG[0] >= ~ARG[1]) ? ~SIZE[~TYPO]'sd1 : ~SIZE[~TYPO]'sd0"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.==#"
-    , "type"      : "(==) :: Int# -> Int# -> Int#"
-    , "templateE" : "(~ARG[0] == ~ARG[1]) ? ~SIZE[~TYPO]'sd1 : ~SIZE[~TYPO]'sd0"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim./=#"
-    , "type"      : "(/=#) :: Int# -> Int# -> Int#"
-    , "templateE" : "(~ARG[0] != ~ARG[1]) ? ~SIZE[~TYPO]'sd1 : ~SIZE[~TYPO]'sd0"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.<#"
-    , "type"      : "(<#) :: Int# -> Int# -> Int#"
-    , "templateE" : "(~ARG[0] < ~ARG[1]) ? ~SIZE[~TYPO]'sd1 : ~SIZE[~TYPO]'sd0"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.<=#"
-    , "type"      : "(<=#) :: Int# -> Int# -> Int#"
-    , "templateE" : "(~ARG[0] <= ~ARG[1]) ? ~SIZE[~TYPO]'sd1 : ~SIZE[~TYPO]'sd0"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.chr#"
-    , "type"      : "ord :: Int# -> Char#"
-    , "templateD" : "assign ~RESULT = $unsigned(~ARG[0]);"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.int2Word#"
-    , "type"      : "int2Word# :: Int# -> Word#"
-    , "templateE" : "$unsigned(~ARG[0])"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.uncheckedIShiftL#"
-    , "type"      : "uncheckedIShiftL# :: Int# -> Int# -> Int#"
-    , "templateE" : "~ARG[0] <<< ~ARG[1]"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.uncheckedIShiftRA#"
-    , "type"      : "uncheckedIShiftRA# :: Int# -> Int# -> Int#"
-    , "templateE" : "~ARG[0] >>> ~ARG[1]"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.uncheckedIShiftRL#"
-    , "type"      : "uncheckedIShiftRL# :: Int# -> Int# -> Int#"
-    , "templateE" : "~ARG[0] >> ~ARG[1]"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.plusWord#"
-    , "type"      : "plusWord# :: Word# -> Word# -> Word#"
-    , "templateE" : "~ARG[0] + ~ARG[1]"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.minusWord#"
-    , "type"      : "minusWord# :: Word# -> Word# -> Word#"
-    , "templateE" : "~ARG[0] - ~ARG[1]"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.timesWord#"
-    , "type"      : "timesWord# :: Word# -> Word# -> Word#"
-    , "templateE" : "~ARG[0] * ~ARG[1]"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.quotWord#"
-    , "type"      : "quotWord# :: Word# -> Word# -> Word#"
-    , "templateE" : "~ARG[0] / ~ARG[1]"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.remWord#"
-    , "type"      : "remWord# :: Word# -> Word# -> Word#"
-    , "templateE" : "~ARG[0] % ~ARG[1]"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.quotRemWord#"
-    , "type"      : "quotRemWord# :: Word# -> Word# -> (#Word#, Word##)"
-    , "templateD" :
-"// quotRemWord begin
-~SIGD[~SYM[0]][0];
-~SIGD[~SYM[1]][0];
-assign ~SYM[0] = ~ARG[0] / ~ARG[1];
-assign ~SYM[1] = ~ARG[0] % ~ARG[1];
-
-assign ~RESULT = {~SYM[0],~SYM[1]};
-// quotRemWord end"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.and#"
-    , "type"      : "and# :: Word# -> Word# -> Word#"
-    , "templateE" : "~ARG[0] & ~ARG[1]"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.or#"
-    , "type"      : "or# :: Word# -> Word# -> Word#"
-    , "templateE" : "~ARG[0] | ~ARG[1]"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.xor#"
-    , "type"      : "xor# :: Word# -> Word# -> Word#"
-    , "templateE" : "~ARG[0] ^ ~ARG[1]"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.not#"
-    , "type"      : "not# :: Word# -> Word#"
-    , "templateE" : "~ ~ARG[0]"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.uncheckedShiftL#"
-    , "type"      : "uncheckedShiftL# :: Word# -> Int# -> Word#"
-    , "templateE" : "~ARG[0] << ~ARG[1]"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.uncheckedIShiftL#"
-    , "type"      : "uncheckedShiftRL# :: Word# -> Int# -> Word#"
-    , "templateE" : "~ARG[0] >> ~ARG[1]"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.word2Int#"
-    , "type"      : "int2Word# :: Word# -> Int#"
-    , "templateE" : "$signed(~ARG[0])"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.gtWord#"
-     , "type"     : "gtWord# :: Word# -> Word# -> Int#"
-    , "templateE" : "(~ARG[0] > ~ARG[1]) ? ~SIZE[~TYPO]'sd1 : ~SIZE[~TYPO]'sd0"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.geWord#"
-    , "type"      : "geWord# :: Word# -> Word# -> Int#"
-    , "templateE" : "(~ARG[0] >= ~ARG[1]) ? ~SIZE[~TYPO]'sd1 : ~SIZE[~TYPO]'sd0"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.eqWord#"
-    , "type"      : "eqWord# :: Word# -> Word# -> Int#"
-    , "templateE" : "(~ARG[0] == ~ARG[1]) ? ~SIZE[~TYPO]'sd1 : ~SIZE[~TYPO]'sd0"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.neWord#"
-    , "type"      : "neWord# :: Word# -> Word# -> Int#"
-    , "templateE" : "(~ARG[0] != ~ARG[1]) ? ~SIZE[~TYPO]'sd1 : ~SIZE[~TYPO]'sd0"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.ltWord#"
-    , "type"      : "ltWord# :: Word# -> Word# -> Int#"
-    , "templateE" : "(~ARG[0] < ~ARG[1]) ? ~SIZE[~TYPO]'sd1 : ~SIZE[~TYPO]'sd0"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.leWord#"
-    , "type"      : "leWord# :: Word# -> Word# -> Int#"
-    , "templateE" : "(~ARG[0] <= ~ARG[1]) ? ~SIZE[~TYPO]'sd1 : ~SIZE[~TYPO]'sd0"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.popCnt8#"
-    , "type"      : "popCnt8# :: Word# -> Word#"
-    , "templateD" :
-"// popCnt8 begin
-localparam width_~SYM[0] = 8;
-
-// ceiling of log2
-function integer log2_~SYM[1];
-  input integer value;
-  begin
-    value = value-1;
-    for (log2_~SYM[1]=0; value>0; log2_~SYM[1]=log2_~SYM[1]+1)
-      value = value>>1;
-  end
-endfunction
-
-// depth of the tree
-localparam levels_~SYM[2] = log2_~SYM[1](width_~SYM[0]);
-
-wire [levels_~SYM[2]:0] intermediate_~SYM[3] [0:(2*width_~SYM[0])-2];
-
-// put input into the first half of the intermediate array
-genvar i_~SYM[4];
-~GENERATE
-for (i_~SYM[4] = 0; i_~SYM[4] < width_~SYM[0]; i_~SYM[4]=i_~SYM[4]+1) begin : array_~SYM[5]
-  assign intermediate_~SYM[3][i_~SYM[4]] = $unsigned(~ARG[0][i_~SYM[4]]);
-end
-~ENDGENERATE
-
-// given a level and a depth, calculate the corresponding index into the
-// intermediate array
-function integer depth2Index_~SYM[5];
-  input integer levels;
-  input integer depth;
-
-  depth2Index_~SYM[5] = (2 ** levels) - (2 ** depth);
-endfunction
-
-// Create the tree of instantiated components
-genvar d_~SYM[6];
-genvar i_~SYM[7];
-~GENERATE
-if (levels_~SYM[2] != 0) begin : make_tree_~SYM[8]
-  for (d_~SYM[6] = (levels_~SYM[2] - 1); d_~SYM[6] >= 0; d_~SYM[6]=d_~SYM[6]-1) begin : tree_depth
-    for (i_~SYM[7] = 0; i_~SYM[7] < (2**d_~SYM[6]); i_~SYM[7] = i_~SYM[7]+1) begin : tree_depth_loop
-      assign intermediate_~SYM[3][depth2Index_~SYM[5](levels_~SYM[2]+1,d_~SYM[6]+1)+i_~SYM[7]] =
-             intermediate_~SYM[3][depth2Index_~SYM[5](levels_~SYM[2]+1,d_~SYM[6]+2)+(2*i_~SYM[7])] +
-             intermediate_~SYM[3][depth2Index_~SYM[5](levels_~SYM[2]+1,d_~SYM[6]+2)+(2*i_~SYM[7])+1];
-    end
-  end
-end
-~ENDGENERATE
-
-// The last element of the intermediate array holds the result
-assign ~RESULT = $unsigned(intermediate_~SYM[3][(2*width_~SYM[0])-2]);
-// popCnt8 end"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.popCnt16#"
-    , "type"      : "popCnt16# :: Word# -> Word#"
-    , "templateD" :
-"// popCnt16 begin
-localparam width_~SYM[0] = 16;
-
-// ceiling of log2
-function integer log2_~SYM[1];
-  input integer value;
-  begin
-    value = value-1;
-    for (log2_~SYM[1]=0; value>0; log2_~SYM[1]=log2_~SYM[1]+1)
-      value = value>>1;
-  end
-endfunction
-
-// depth of the tree
-localparam levels_~SYM[2] = log2_~SYM[1](width_~SYM[0]);
-
-logic [levels_~SYM[2]:0] intermediate_~SYM[3] [0:(2*width_~SYM[0])-2];
-
-// put input into the first half of the intermediate array
-genvar i_~SYM[4];
-~GENERATE
-for (i_~SYM[4] = 0; i_~SYM[4] < width_~SYM[0]; i_~SYM[4]=i_~SYM[4]+1) begin : array_~SYM[5]
-  assign intermediate_~SYM[3][i_~SYM[4]] = $unsigned(~ARG[0][i_~SYM[4]]);
-end
-~ENDGENERATE
-
-// given a level and a depth, calculate the corresponding index into the
-// intermediate array
-function integer depth2Index_~SYM[5];
-  input integer levels;
-  input integer depth;
-
-  depth2Index_~SYM[5] = (2 ** levels) - (2 ** depth);
-endfunction
-
-// Create the tree of instantiated components
-genvar d_~SYM[6];
-genvar i_~SYM[7];
-~GENERATE
-if (levels_~SYM[2] != 0) begin : make_tree_~SYM[8]
-  for (d_~SYM[6] = (levels_~SYM[2] - 1); d_~SYM[6] >= 0; d_~SYM[6]=d_~SYM[6]-1) begin : tree_depth
-    for (i_~SYM[7] = 0; i_~SYM[7] < (2**d_~SYM[6]); i_~SYM[7] = i_~SYM[7]+1) begin : tree_depth_loop
-      assign intermediate_~SYM[3][depth2Index_~SYM[5](levels_~SYM[2]+1,d_~SYM[6]+1)+i_~SYM[7]] =
-             intermediate_~SYM[3][depth2Index_~SYM[5](levels_~SYM[2]+1,d_~SYM[6]+2)+(2*i_~SYM[7])] +
-             intermediate_~SYM[3][depth2Index_~SYM[5](levels_~SYM[2]+1,d_~SYM[6]+2)+(2*i_~SYM[7])+1];
-    end
-  end
-end
-~ENDGENERATE
-
-// The last element of the intermediate array holds the result
-assign ~RESULT = $unsigned(intermediate_~SYM[3][(2*width_~SYM[0])-2]);
-// popCnt16 end"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.popCnt32#"
-    , "type"      : "popCnt32# :: Word# -> Word#"
-    , "templateD" :
-"// popCnt32 begin
-localparam width_~SYM[0] = 32;
-
-// ceiling of log2
-function integer log2_~SYM[1];
-  input integer value;
-  begin
-    value = value-1;
-    for (log2_~SYM[1]=0; value>0; log2_~SYM[1]=log2_~SYM[1]+1)
-      value = value>>1;
-  end
-endfunction
-
-// depth of the tree
-localparam levels_~SYM[2] = log2_~SYM[1](width_~SYM[0]);
-
-logic [levels_~SYM[2]:0] intermediate_~SYM[3] [0:(2*width_~SYM[0])-2];
-
-// put input into the first half of the intermediate array
-genvar i_~SYM[4];
-~GENERATE
-for (i_~SYM[4] = 0; i_~SYM[4] < width_~SYM[0]; i_~SYM[4]=i_~SYM[4]+1) begin : array_~SYM[5]
-  assign intermediate_~SYM[3][i_~SYM[4]] = $unsigned(~ARG[0][i_~SYM[4]]);
-end
-~ENDGENERATE
-
-// given a level and a depth, calculate the corresponding index into the
-// intermediate array
-function integer depth2Index_~SYM[5];
-  input integer levels;
-  input integer depth;
-
-  depth2Index_~SYM[5] = (2 ** levels) - (2 ** depth);
-endfunction
-
-// Create the tree of instantiated components
-genvar d_~SYM[6];
-genvar i_~SYM[7];
-~GENERATE
-if (levels_~SYM[2] != 0) begin : make_tree_~SYM[8]
-  for (d_~SYM[6] = (levels_~SYM[2] - 1); d_~SYM[6] >= 0; d_~SYM[6]=d_~SYM[6]-1) begin : tree_depth
-    for (i_~SYM[7] = 0; i_~SYM[7] < (2**d_~SYM[6]); i_~SYM[7] = i_~SYM[7]+1) begin : tree_depth_loop
-      assign intermediate_~SYM[3][depth2Index_~SYM[5](levels_~SYM[2]+1,d_~SYM[6]+1)+i_~SYM[7]] =
-             intermediate_~SYM[3][depth2Index_~SYM[5](levels_~SYM[2]+1,d_~SYM[6]+2)+(2*i_~SYM[7])] +
-             intermediate_~SYM[3][depth2Index_~SYM[5](levels_~SYM[2]+1,d_~SYM[6]+2)+(2*i_~SYM[7])+1];
-    end
-  end
-end
-~ENDGENERATE
-
-// The last element of the intermediate array holds the result
-assign ~RESULT = $unsigned(intermediate_~SYM[3][(2*width_~SYM[0])-2]);
-// popCnt32 end"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.popCnt64#"
-    , "type"      : "popCnt64# :: Word# -> Word#"
-    , "templateD" :
-"// popCnt64 begin
-localparam width_~SYM[0] = 64;
-
-// ceiling of log2
-function integer log2_~SYM[1];
-  input integer value;
-  begin
-    value = value-1;
-    for (log2_~SYM[1]=0; value>0; log2_~SYM[1]=log2_~SYM[1]+1)
-      value = value>>1;
-  end
-endfunction
-
-// depth of the tree
-localparam levels_~SYM[2] = log2_~SYM[1](width_~SYM[0]);
-
-logic [levels_~SYM[2]:0] intermediate_~SYM[3] [0:(2*width_~SYM[0])-2];
-
-// put input into the first half of the intermediate array
-genvar i_~SYM[4];
-~GENERATE
-for (i_~SYM[4] = 0; i_~SYM[4] < width_~SYM[0]; i_~SYM[4]=i_~SYM[4]+1) begin : array_~SYM[5]
-  assign intermediate_~SYM[3][i_~SYM[4]] = $unsigned(~ARG[0][i_~SYM[4]]);
-end
-~ENDGENERATE
-
-// given a level and a depth, calculate the corresponding index into the
-// intermediate array
-function integer depth2Index_~SYM[5];
-  input integer levels;
-  input integer depth;
-
-  depth2Index_~SYM[5] = (2 ** levels) - (2 ** depth);
-endfunction
-
-// Create the tree of instantiated components
-genvar d_~SYM[6];
-genvar i_~SYM[7];
-~GENERATE
-if (levels_~SYM[2] != 0) begin : make_tree_~SYM[8]
-  for (d_~SYM[6] = (levels_~SYM[2] - 1); d_~SYM[6] >= 0; d_~SYM[6]=d_~SYM[6]-1) begin : tree_depth
-    for (i_~SYM[7] = 0; i_~SYM[7] < (2**d_~SYM[6]); i_~SYM[7] = i_~SYM[7]+1) begin : tree_depth_loop
-      assign intermediate_~SYM[3][depth2Index_~SYM[5](levels_~SYM[2]+1,d_~SYM[6]+1)+i_~SYM[7]] =
-             intermediate_~SYM[3][depth2Index_~SYM[5](levels_~SYM[2]+1,d_~SYM[6]+2)+(2*i_~SYM[7])] +
-             intermediate_~SYM[3][depth2Index_~SYM[5](levels_~SYM[2]+1,d_~SYM[6]+2)+(2*i_~SYM[7])+1];
-    end
-  end
-end
-~ENDGENERATE
-
-// The last element of the intermediate array holds the result
-assign ~RESULT = $unsigned(intermediate_~SYM[3][(2*width_~SYM[0])-2]);
-// popCnt64 end"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.popCnt#"
-    , "type"      : "popCnt8# :: Word# -> Word#"
-    , "templateD" :
-"// popCnt begin
-localparam width_~SYM[0] = ~SIZE[~TYPO];
-
-// ceiling of log2
-function integer log2_~SYM[1];
-  input integer value;
-  begin
-    value = value-1;
-    for (log2_~SYM[1]=0; value>0; log2_~SYM[1]=log2_~SYM[1]+1)
-      value = value>>1;
-  end
-endfunction
-
-// depth of the tree
-localparam levels_~SYM[2] = log2_~SYM[1](width_~SYM[0]);
-
-logic [levels_~SYM[2]:0] intermediate_~SYM[3] [0:(2*width_~SYM[0])-2];
-
-// put input into the first half of the intermediate array
-genvar i_~SYM[4];
-~GENERATE
-for (i_~SYM[4] = 0; i_~SYM[4] < width_~SYM[0]; i_~SYM[4]=i_~SYM[4]+1) begin : array_~SYM[5]
-  assign intermediate_~SYM[3][i_~SYM[4]] = $unsigned(~ARG[0][i_~SYM[4]]);
-end
-~ENDGENERATE
-
-// given a level and a depth, calculate the corresponding index into the
-// intermediate array
-function integer depth2Index_~SYM[5];
-  input integer levels;
-  input integer depth;
-
-  depth2Index_~SYM[5] = (2 ** levels) - (2 ** depth);
-endfunction
-
-// Create the tree of instantiated components
-genvar d_~SYM[6];
-genvar i_~SYM[7];
-~GENERATE
-if (levels_~SYM[2] != 0) begin : make_tree_~SYM[8]
-  for (d_~SYM[6] = (levels_~SYM[2] - 1); d_~SYM[6] >= 0; d_~SYM[6]=d_~SYM[6]-1) begin : tree_depth
-    for (i_~SYM[7] = 0; i_~SYM[7] < (2**d_~SYM[6]); i_~SYM[7] = i_~SYM[7]+1) begin : tree_depth_loop
-      assign intermediate_~SYM[3][depth2Index_~SYM[5](levels_~SYM[2]+1,d_~SYM[6]+1)+i_~SYM[7]] =
-             intermediate_~SYM[3][depth2Index_~SYM[5](levels_~SYM[2]+1,d_~SYM[6]+2)+(2*i_~SYM[7])] +
-             intermediate_~SYM[3][depth2Index_~SYM[5](levels_~SYM[2]+1,d_~SYM[6]+2)+(2*i_~SYM[7])+1];
-    end
-  end
-end
-~ENDGENERATE
-
-// The last element of the intermediate array holds the result
-assign ~RESULT = $unsigned(intermediate_~SYM[3][(2*width_~SYM[0])-2]);
-// popCnt end"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.clz8#"
-    , "type"      : "clz8 :: Word# -> Word#"
-    , "templateD" :
-"// clz8 begin
-~GENERATE
-if (1) begin
-function [1:0] enc;
-  input [1:0] a;
-  case (a)
-    2'b00:   enc = 2'b10;
-    2'b01:   enc = 2'b01;
-    2'b10:   enc = 2'b00;
-    default: enc = 2'b00;
-  endcase
-endfunction
-
-logic [0:7] v;
-assign v = ~ARG[0][7:0];
-
-logic [0:7] e;
-genvar i;
-~GENERATE
-for (i=0;i<4;i=i+1) begin : enc_stage
-  assign e[i*2:i*2+1] = enc(v[i*2:i*2+1]);
-end
-~ENDGENERATE
-
-logic [0:5] a;
-genvar i1;
-~GENERATE
-for (i1=0;i1<2;i1=i1+1) begin : mux_stage1
-  localparam n = 2;
-  logic [3:0] i;
-  assign i = e[i1*4:i1*4+3];
-  always @(*) begin
-    case (i[n-1+n])
-      1'b0    : a[i1*3:i1*3+2] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
-      default : a[i1*3:i1*3+2] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
-    endcase
-  end
-end
-~ENDGENERATE
-
-logic [0:3] res;
-~GENERATE
-if (1) begin
-localparam n = 3;
-logic [5:0] i;
-assign i = a[0:5];
-always @(*) begin
-  case (i[n-1+n])
-    1'b0    : res = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
-    default : res = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
-  endcase
-end
-end
-~ENDGENERATE
-
-assign ~RESULT = $unsigned(res);
-end
-~ENDGENERATE
-// clz8 end"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.clz16#"
-    , "type"      : "clz16 :: Word# -> Word#"
-    , "templateD" :
-"// clz16 begin
-~GENERATE
-if (1) begin
-function [1:0] enc;
-  input [1:0] a;
-  case (a)
-    2'b00:   enc = 2'b10;
-    2'b01:   enc = 2'b01;
-    2'b10:   enc = 2'b00;
-    default: enc = 2'b00;
-  endcase
-endfunction
-
-logic [0:15] v;
-assign v = ~ARG[0][15:0];
-
-logic [0:15] e;
-genvar i;
-~GENERATE
-for (i=0;i<8;i=i+1) begin : enc_stage
-  assign e[i*2:i*2+1] = enc(v[i*2:i*2+1]);
-end
-~ENDGENERATE
-
-reg [0:11] a;
-genvar i1;
-~GENERATE
-for (i1=0;i1<4;i1=i1+1) begin : mux_stage1
-  localparam n = 2;
-  logic [3:0] i;
-  assign i = e[i1*4:i1*4+3];
-  always @(*) begin
-    case (i[n-1+n])
-      1'b0    : a[i1*3:i1*3+2] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
-      default : a[i1*3:i1*3+2] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
-    endcase
-  end
-end
-~ENDGENERATE
-
-reg [0:7] b;
-genvar i2;
-~GENERATE
-for (i2=0;i2<2;i2=i2+1) begin : mux_stage2
-  localparam n = 3;
-  logic [5:0] i;
-  assign i = a[i2*6:i2*6+5];
-  always @(*) begin
-    case (i[n-1+n])
-      1'b0    : b[i2*4:i2*4+3] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
-      default : b[i2*4:i2*4+3] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
-    endcase
-  end
-end
-~ENDGENERATE
-
-reg [0:4] res;
-~GENERATE
-if (1) begin
-localparam n = 4;
-logic [7:0] i;
-assign i = b[0:7];
-always @(*) begin
-  case (i[n-1+n])
-    1'b0    : res = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
-    default : res = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
-  endcase
-end
-end
-~ENDGENERATE
-
-assign ~RESULT = $unsigned(res);
-end
-~ENDGENERATE
-// clz16 end"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.clz32#"
-    , "type"      : "clz32 :: Word# -> Word#"
-    , "templateD" :
-"// clz32 begin
-~GENERATE
-if (1) begin
-function [1:0] enc;
-  input [1:0] a;
-  case (a)
-    2'b00:   enc = 2'b10;
-    2'b01:   enc = 2'b01;
-    2'b10:   enc = 2'b00;
-    default: enc = 2'b00;
-  endcase
-endfunction
-
-logic [0:31] v;
-assign v = ~ARG[0][31:0];
-
-logic [0:31] e;
-genvar i;
-~GENERATE
-for (i=0;i<16;i=i+1) begin : enc_stage
-  assign e[i*2:i*2+1] = enc(v[i*2:i*2+1]);
-end
-~ENDGENERATE
-
-reg [0:23] a;
-genvar i1;
-~GENERATE
-for (i1=0;i1<8;i1=i1+1) begin : mux_stage1
-  localparam n = 2;
-  logic [3:0] i;
-  assign i = e[i1*4:i1*4+3];
-  always @(*) begin
-    case (i[n-1+n])
-      1'b0    : a[i1*3:i1*3+2] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
-      default : a[i1*3:i1*3+2] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
-    endcase
-  end
-end
-~ENDGENERATE
-
-reg [0:15] b;
-genvar i2;
-~GENERATE
-for (i2=0;i2<4;i2=i2+1) begin : mux_stage2
-  localparam n = 3;
-  logic [5:0] i;
-  assign i = a[i2*6:i2*6+5];
-  always @(*) begin
-    case (i[n-1+n])
-      1'b0    : b[i2*4:i2*4+3] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
-      default : b[i2*4:i2*4+3] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
-    endcase
-  end
-end
-~ENDGENERATE
-
-reg [0:9] c;
-genvar i3;
-~GENERATE
-for (i3=0;i3<2;i3=i3+1) begin : mux_stage3
-  localparam n = 4;
-  logic [7:0] i;
-  assign i = b[i3*8:i3*8+7];
-  always @(*) begin
-    case (i[n-1+n])
-      1'b0    : c[i3*5:i3*5+4] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
-      default : c[i3*5:i3*5+4] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
-    endcase
-  end
-end
-~ENDGENERATE
-
-reg [0:5] res;
-~GENERATE
-if (1) begin
-localparam n = 5;
-logic [9:0] i;
-assign i = c[0:9];
-always @(*) begin
-  case (i[n-1+n])
-    1'b0    : res = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
-    default : res = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
-  endcase
-end
-end
-~ENDGENERATE
-
-assign ~RESULT = $unsigned(res);
-end
-~ENDGENERATE
-// clz32 end"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.clz64#"
-    , "type"      : "clz64 :: Word# -> Word#"
-    , "templateD" :
-"// clz64 begin
-~GENERATE
-if (1) begin
-function [1:0] enc;
-  input [1:0] a;
-  case (a)
-    2'b00:   enc = 2'b10;
-    2'b01:   enc = 2'b01;
-    2'b10:   enc = 2'b00;
-    default: enc = 2'b00;
-  endcase
-endfunction
-
-logic [0:63] v;
-assign v = ~ARG[0][63:0];
-
-logic [0:63] e;
-genvar i;
-~GENERATE
-for (i=0;i<32;i=i+1) begin : enc_stage
-  assign e[i*2:i*2+1] = enc(v[i*2:i*2+1]);
-end
-~ENDGENERATE
-
-reg [0:47] a;
-genvar i1;
-~GENERATE
-for (i1=0;i1<16;i1=i1+1) begin : mux_stage1
-  localparam n = 2;
-  logic [3:0] i;
-  assign i = e[i1*4:i1*4+3];
-  always @(*) begin
-    case (i[n-1+n])
-      1'b0    : a[i1*3:i1*3+2] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
-      default : a[i1*3:i1*3+2] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
-    endcase
-  end
-end
-~ENDGENERATE
-
-reg [0:31] b;
-genvar i2;
-~GENERATE
-for (i2=0;i2<8;i2=i2+1) begin : mux_stage2
-  localparam n = 3;
-  logic [5:0] i;
-  assign i = a[i2*6:i2*6+5];
-  always @(*) begin
-    case (i[n-1+n])
-      1'b0    : b[i2*4:i2*4+3] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
-      default : b[i2*4:i2*4+3] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
-    endcase
-  end
-end
-~ENDGENERATE
-
-reg [0:19] c;
-genvar i3;
-~GENERATE
-for (i3=0;i3<4;i3=i3+1) begin : mux_stage3
-  localparam n = 4;
-  logic [7:0] i;
-  assign i = b[i3*8:i3*8+7];
-  always @(*) begin
-    case (i[n-1+n])
-      1'b0    : c[i3*5:i3*5+4] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
-      default : c[i3*5:i3*5+4] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
-    endcase
-  end
-end
-~ENDGENERATE
-
-reg [0:11] d;
-genvar i4;
-~GENERATE
-for (i4=0;i4<2;i4=i4+1) begin : mux_stage4
-  localparam n = 5;
-  logic [9:0] i;
-  assign i = c[i4*10:i4*10+9];
-  always @(*) begin
-    case (i[n-1+n])
-      1'b0    : d[i4*6:i4*6+5] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
-      default : d[i4*6:i4*6+5] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
-    endcase
-  end
-end
-~ENDGENERATE
-
-reg [0:6] res;
-~GENERATE
-if (1) begin
-localparam n = 6;
-logic [11:0] i;
-assign i = d[0:11];
-always @(*) begin
-  case (i[n-1+n])
-    1'b0    : res = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
-    default : res = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
-  endcase
-end
-end
-~ENDGENERATE
-
-assign ~RESULT = $unsigned(res);
-end
-~ENDGENERATE
-// clz64 end"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.clz#"
-    , "type"      : "clz :: Word# -> Word#"
-    , "templateD" :
-"// clz begin
-~GENERATE
-if (1) begin
-function [1:0] enc;
-  input [1:0] a;
-  case (a)
-    2'b00:   enc = 2'b10;
-    2'b01:   enc = 2'b01;
-    2'b10:   enc = 2'b00;
-    default: enc = 2'b00;
-  endcase
-endfunction
-~IF ~IW64 ~THEN
-logic [0:63] v;
-assign v = ~ARG[0][63:0];
-
-logic [0:63] e;
-genvar i;
-~GENERATE
-for (i=0;i<32;i=i+1) begin : enc_stage
-  assign e[i*2:i*2+1] = enc(v[i*2:i*2+1]);
-end
-~ENDGENERATE
-
-reg [0:47] a;
-genvar i1;
-~GENERATE
-for (i1=0;i1<16;i1=i1+1) begin : mux_stage1
-  localparam n = 2;
-  logic [3:0] i;
-  assign i = e[i1*4:i1*4+3];
-  always @(*) begin
-    case (i[n-1+n])
-      1'b0    : a[i1*3:i1*3+2] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
-      default : a[i1*3:i1*3+2] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
-    endcase
-  end
-end
-~ENDGENERATE
-
-reg [0:31] b;
-genvar i2;
-~GENERATE
-for (i2=0;i2<8;i2=i2+1) begin : mux_stage2
-  localparam n = 3;
-  logic [5:0] i;
-  assign i = a[i2*6:i2*6+5];
-  always @(*) begin
-    case (i[n-1+n])
-      1'b0    : b[i2*4:i2*4+3] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
-      default : b[i2*4:i2*4+3] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
-    endcase
-  end
-end
-~ENDGENERATE
-
-reg [0:19] c;
-genvar i3;
-~GENERATE
-for (i3=0;i3<4;i3=i3+1) begin : mux_stage3
-  localparam n = 4;
-  logic [7:0] i;
-  assign i = b[i3*8:i3*8+7];
-  always @(*) begin
-    case (i[n-1+n])
-      1'b0    : c[i3*5:i3*5+4] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
-      default : c[i3*5:i3*5+4] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
-    endcase
-  end
-end
-~ENDGENERATE
-
-reg [0:11] d;
-genvar i4;
-~GENERATE
-for (i4=0;i4<2;i4=i4+1) begin : mux_stage4
-  localparam n = 5;
-  logic [9:0] i;
-  assign i = c[i4*10:i4*10+9];
-  always @(*) begin
-    case (i[n-1+n])
-      1'b0    : d[i4*6:i4*6+5] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
-      default : d[i4*6:i4*6+5] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
-    endcase
-  end
-end
-~ENDGENERATE
-
-reg [0:6] res;
-~GENERATE
-if (1) begin
-localparam n = 6;
-logic [11:0] i;
-assign i = d[0:11];
-always @(*) begin
-  case (i[n-1+n])
-    1'b0    : res = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
-    default : res = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
-  endcase
-end
-end
-~ENDGENERATE
-~ELSE
-logic [0:31] v;
-assign v = ~ARG[0][31:0];
-
-logic [0:31] e;
-genvar i;
-~GENERATE
-for (i=0;i<16;i=i+1) begin : enc_stage
-  assign e[i*2:i*2+1] = enc(v[i*2:i*2+1]);
-end
-~ENDGENERATE
-
-reg [0:23] a;
-genvar i1;
-~GENERATE
-for (i1=0;i1<8;i1=i1+1) begin : mux_stage1
-  localparam n = 2;
-  logic [3:0] i;
-  assign i = e[i1*4:i1*4+3];
-  always @(*) begin
-    case (i[n-1+n])
-      1'b0    : a[i1*3:i1*3+2] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
-      default : a[i1*3:i1*3+2] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
-    endcase
-  end
-end
-~ENDGENERATE
-
-reg [0:15] b;
-genvar i2;
-~GENERATE
-for (i2=0;i2<4;i2=i2+1) begin : mux_stage2
-  localparam n = 3;
-  logic [5:0] i;
-  assign i = a[i2*6:i2*6+5];
-  always @(*) begin
-    case (i[n-1+n])
-      1'b0    : b[i2*4:i2*4+3] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
-      default : b[i2*4:i2*4+3] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
-    endcase
-  end
-end
-~ENDGENERATE
-
-reg [0:9] c;
-genvar i3;
-~GENERATE
-for (i3=0;i3<2;i3=i3+1) begin : mux_stage3
-  localparam n = 4;
-  logic [7:0] i;
-  assign i = b[i3*8:i3*8+7];
-  always @(*) begin
-    case (i[n-1+n])
-      1'b0    : c[i3*5:i3*5+4] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
-      default : c[i3*5:i3*5+4] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
-    endcase
-  end
-end
-~ENDGENERATE
-
-reg [0:5] res;
-~GENERATE
-if (1) begin
-localparam n = 5;
-logic [9:0] i;
-assign i = c[0:9];
-always @(*) begin
-  case (i[n-1+n])
-    1'b0    : res = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
-    default : res = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
-  endcase
-end
-end
-~ENDGENERATE
-~FI
-assign ~RESULT = $unsigned(res);
-end
-~ENDGENERATE
-// clz end"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.ctz8#"
-    , "type"      : "ctz8 :: Word# -> Word#"
-    , "templateD" :
-"// ctz8 begin
-~GENERATE
-if (1) begin
-function [1:0] enc;
-  input [1:0] a;
-  case (a)
-    2'b00:   enc = 2'b10;
-    2'b01:   enc = 2'b01;
-    2'b10:   enc = 2'b00;
-    default: enc = 2'b00;
-  endcase
-endfunction
-
-logic [0:7] v;
-genvar k;
-~GENERATE
-for (k=0;k<8;k=k+1) begin : reverse
-  assign v[k] = ~ARG[0][k];
-end
-~ENDGENERATE
-
-logic [0:7] e;
-genvar i;
-~GENERATE
-for (i=0;i<4;i=i+1) begin : enc_stage
-  assign e[i*2:i*2+1] = enc(v[i*2:i*2+1]);
-end
-~ENDGENERATE
-
-reg [0:5] a;
-genvar i1;
-~GENERATE
-for (i1=0;i1<2;i1=i1+1) begin : mux_stage1
-  localparam n = 2;
-  logic [3:0] i;
-  assign i = e[i1*4:i1*4+3];
-  always @(*) begin
-    case (i[n-1+n])
-      1'b0    : a[i1*3:i1*3+2] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
-      default : a[i1*3:i1*3+2] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
-    endcase
-  end
-end
-~ENDGENERATE
-
-reg [0:3] res;
-~GENERATE
-if (1) begin
-localparam n = 3;
-logic [5:0] i;
-assign i = a[0:5];
-always @(*) begin
-  case (i[n-1+n])
-    1'b0    : res = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
-    default : res = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
-  endcase
-end
-end
-~ENDGENERATE
-
-assign ~RESULT = $unsigned(res);
-end
-~ENDGENERATE
-// ctz8 end"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.ctz16#"
-    , "type"      : "ctz16 :: Word# -> Word#"
-    , "templateD" :
-"// ctz16 begin
-~GENERATE
-if (1) begin
-function [1:0] enc;
-  input [1:0] a;
-  case (a)
-    2'b00:   enc = 2'b10;
-    2'b01:   enc = 2'b01;
-    2'b10:   enc = 2'b00;
-    default: enc = 2'b00;
-  endcase
-endfunction
-
-logic [0:15] v;
-genvar k;
-~GENERATE
-for (k=0;k<16;k=k+1) begin : reverse
-  assign v[k] = ~ARG[0][k];
-end
-~ENDGENERATE
-
-logic [0:15] e;
-genvar i;
-~GENERATE
-for (i=0;i<8;i=i+1) begin : enc_stage
-  assign e[i*2:i*2+1] = enc(v[i*2:i*2+1]);
-end
-~ENDGENERATE
-
-reg [0:11] a;
-genvar i1;
-~GENERATE
-for (i1=0;i1<4;i1=i1+1) begin : mux_stage1
-  localparam n = 2;
-  logic [3:0] i;
-  assign i = e[i1*4:i1*4+3];
-  always @(*) begin
-    case (i[n-1+n])
-      1'b0    : a[i1*3:i1*3+2] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
-      default : a[i1*3:i1*3+2] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
-    endcase
-  end
-end
-~ENDGENERATE
-
-reg [0:7] b;
-genvar i2;
-~GENERATE
-for (i2=0;i2<2;i2=i2+1) begin : mux_stage2
-  localparam n = 3;
-  logic [5:0] i;
-  assign i = a[i2*6:i2*6+5];
-  always @(*) begin
-    case (i[n-1+n])
-      1'b0    : b[i2*4:i2*4+3] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
-      default : b[i2*4:i2*4+3] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
-    endcase
-  end
-end
-~ENDGENERATE
-
-reg [0:4] res;
-~GENERATE
-if (1) begin
-localparam n = 4;
-logic [7:0] i;
-assign i = b[0:7];
-always @(*) begin
-  case (i[n-1+n])
-    1'b0    : res = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
-    default : res = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
-  endcase
-end
-end
-~ENDGENERATE
-
-assign ~RESULT = $unsigned(res);
-end
-~ENDGENERATE
-// ctz16 end"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.ctz32#"
-    , "type"      : "ctz32 :: Word# -> Word#"
-    , "templateD" :
-"// ctz32 begin
-~GENERATE
-if (1) begin
-function [1:0] enc;
-  input [1:0] a;
-  case (a)
-    2'b00:   enc = 2'b10;
-    2'b01:   enc = 2'b01;
-    2'b10:   enc = 2'b00;
-    default: enc = 2'b00;
-  endcase
-endfunction
-
-logic [0:31] v;
-genvar k;
-~GENERATE
-for (k=0;k<32;k=k+1) begin : reverse
-  assign v[k] = ~ARG[0][k];
-end
-~ENDGENERATE
-
-logic [0:31] e;
-genvar i;
-~GENERATE
-for (i=0;i<16;i=i+1) begin : enc_stage
-  assign e[i*2:i*2+1] = enc(v[i*2:i*2+1]);
-end
-~ENDGENERATE
-
-reg [0:23] a;
-genvar i1;
-~GENERATE
-for (i1=0;i1<8;i1=i1+1) begin : mux_stage1
-  localparam n = 2;
-  logic [3:0] i;
-  assign i = e[i1*4:i1*4+3];
-  always @(*) begin
-    case (i[n-1+n])
-      1'b0    : a[i1*3:i1*3+2] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
-      default : a[i1*3:i1*3+2] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
-    endcase
-  end
-end
-~ENDGENERATE
-
-reg [0:15] b;
-genvar i2;
-~GENERATE
-for (i2=0;i2<4;i2=i2+1) begin : mux_stage2
-  localparam n = 3;
-  logic [5:0] i;
-  assign i = a[i2*6:i2*6+5];
-  always @(*) begin
-    case (i[n-1+n])
-      1'b0    : b[i2*4:i2*4+3] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
-      default : b[i2*4:i2*4+3] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
-    endcase
-  end
-end
-~ENDGENERATE
-
-reg [0:9] c;
-genvar i3;
-~GENERATE
-for (i3=0;i3<2;i3=i3+1) begin : mux_stage3
-  localparam n = 4;
-  logic [7:0] i;
-  assign i = b[i3*8:i3*8+7];
-  always @(*) begin
-    case (i[n-1+n])
-      1'b0    : c[i3*5:i3*5+4] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
-      default : c[i3*5:i3*5+4] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
-    endcase
-  end
-end
-~ENDGENERATE
-
-reg [0:5] res;
-~GENERATE
-if (1) begin
-localparam n = 5;
-logic [9:0] i;
-assign i = c[0:9];
-always @(*) begin
-  case (i[n-1+n])
-    1'b0    : res = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
-    default : res = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
-  endcase
-end
-end
-~ENDGENERATE
-
-assign ~RESULT = $unsigned(res);
-end
-~ENDGENERATE
-// ctz32 end"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.ctz64#"
-    , "type"      : "ctz64 :: Word# -> Word#"
-    , "templateD" :
-"// ctz64 begin
-~GENERATE
-if (1) begin
-function [1:0] enc;
-  input [1:0] a;
-  case (a)
-    2'b00:   enc = 2'b10;
-    2'b01:   enc = 2'b01;
-    2'b10:   enc = 2'b00;
-    default: enc = 2'b00;
-  endcase
-endfunction
-
-logic [0:63] v;
-genvar k;
-~GENERATE
-for (k=0;k<64;k=k+1) begin : reverse
-  assign v[k] = ~ARG[0][k];
-end
-~ENDGENERATE
-
-logic [0:63] e;
-genvar i;
-~GENERATE
-for (i=0;i<32;i=i+1) begin : enc_stage
-  assign e[i*2:i*2+1] = enc(v[i*2:i*2+1]);
-end
-~ENDGENERATE
-
-reg [0:47] a;
-genvar i1;
-~GENERATE
-for (i1=0;i1<16;i1=i1+1) begin : mux_stage1
-  localparam n = 2;
-  logic [3:0] i;
-  assign i = e[i1*4:i1*4+3];
-  always @(*) begin
-    case (i[n-1+n])
-      1'b0    : a[i1*3:i1*3+2] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
-      default : a[i1*3:i1*3+2] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
-    endcase
-  end
-end
-~ENDGENERATE
-
-reg [0:31] b;
-genvar i2;
-~GENERATE
-for (i2=0;i2<8;i2=i2+1) begin : mux_stage2
-  localparam n = 3;
-  logic [5:0] i;
-  assign i = a[i2*6:i2*6+5];
-  always @(*) begin
-    case (i[n-1+n])
-      1'b0    : b[i2*4:i2*4+3] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
-      default : b[i2*4:i2*4+3] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
-    endcase
-  end
-end
-~ENDGENERATE
-
-reg [0:19] c;
-genvar i3;
-~GENERATE
-for (i3=0;i3<4;i3=i3+1) begin : mux_stage3
-  localparam n = 4;
-  logic [7:0] i;
-  assign i = b[i3*8:i3*8+7];
-  always @(*) begin
-    case (i[n-1+n])
-      1'b0    : c[i3*5:i3*5+4] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
-      default : c[i3*5:i3*5+4] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
-    endcase
-  end
-end
-~ENDGENERATE
-
-reg [0:11] d;
-genvar i4;
-~GENERATE
-for (i4=0;i4<2;i4=i4+1) begin : mux_stage4
-  localparam n = 5;
-  logic [9:0] i;
-  assign i = c[i4*10:i4*10+9];
-  always @(*) begin
-    case (i[n-1+n])
-      1'b0    : d[i4*6:i4*6+5] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
-      default : d[i4*6:i4*6+5] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
-    endcase
-  end
-end
-~ENDGENERATE
-
-reg [0:6] res;
-~GENERATE
-if (1) begin
-localparam n = 6;
-logic [11:0] i;
-assign i = d[0:11];
-always @(*) begin
-  case (i[n-1+n])
-    1'b0    : res = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
-    default : res = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
-  endcase
-end
-end
-~ENDGENERATE
-
-assign ~RESULT = $unsigned(res);
-end
-~ENDGENERATE
-// ctz64 end"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.ctz#"
-    , "type"      : "ctz :: Word# -> Word#"
-    , "templateD" :
-"// ctz begin
-~GENERATE
-if (1) begin
-function [1:0] enc;
-  input [1:0] a;
-  case (a)
-    2'b00:   enc = 2'b10;
-    2'b01:   enc = 2'b01;
-    2'b10:   enc = 2'b00;
-    default: enc = 2'b00;
-  endcase
-endfunction
-~IF ~IW64 ~THEN
-logic [0:63] v;
-genvar k;
-~GENERATE
-for (k=0;k<64;k=k+1) begin : reverse
-  assign v[k] = ~ARG[0][k];
-end
-~ENDGENERATE
-
-logic [0:63] e;
-genvar i;
-~GENERATE
-for (i=0;i<32;i=i+1) begin : enc_stage
-  assign e[i*2:i*2+1] = enc(v[i*2:i*2+1]);
-end
-~ENDGENERATE
-
-reg [0:47] a;
-genvar i1;
-~GENERATE
-for (i1=0;i1<16;i1=i1+1) begin : mux_stage1
-  localparam n = 2;
-  logic [3:0] i;
-  assign i = e[i1*4:i1*4+3];
-  always @(*) begin
-    case (i[n-1+n])
-      1'b0    : a[i1*3:i1*3+2] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
-      default : a[i1*3:i1*3+2] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
-    endcase
-  end
-end
-~ENDGENERATE
-
-reg [0:31] b;
-genvar i2;
-~GENERATE
-for (i2=0;i2<8;i2=i2+1) begin : mux_stage2
-  localparam n = 3;
-  logic [5:0] i;
-  assign i = a[i2*6:i2*6+5];
-  always @(*) begin
-    case (i[n-1+n])
-      1'b0    : b[i2*4:i2*4+3] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
-      default : b[i2*4:i2*4+3] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
-    endcase
-  end
-end
-~ENDGENERATE
-
-reg [0:19] c;
-genvar i3;
-~GENERATE
-for (i3=0;i3<4;i3=i3+1) begin : mux_stage3
-  localparam n = 4;
-  logic [7:0] i;
-  assign i = b[i3*8:i3*8+7];
-  always @(*) begin
-    case (i[n-1+n])
-      1'b0    : c[i3*5:i3*5+4] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
-      default : c[i3*5:i3*5+4] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
-    endcase
-  end
-end
-~ENDGENERATE
-
-reg [0:11] d;
-genvar i4;
-~GENERATE
-for (i4=0;i4<2;i4=i4+1) begin : mux_stage4
-  localparam n = 5;
-  logic [9:0] i;
-  assign i = c[i4*10:i4*10+9];
-  always @(*) begin
-    case (i[n-1+n])
-      1'b0    : d[i4*6:i4*6+5] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
-      default : d[i4*6:i4*6+5] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
-    endcase
-  end
-end
-~ENDGENERATE
-
-reg [0:6] res;
-~GENERATE
-if (1) begin
-localparam n = 6;
-logic [11:0] i;
-assign i = d[0:11];
-always @(*) begin
-  case (i[n-1+n])
-    1'b0    : res = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
-    default : res = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
-  endcase
-end
-end
-~ENDGENERATE
-~ELSE
-logic [0:31] v;
-genvar k;
-~GENERATE
-for (k=0;k<32;k=k+1) begin : reverse
-  assign v[k] = ~ARG[0][k];
-end
-~ENDGENERATE
-
-logic [0:31] e;
-genvar i;
-~GENERATE
-for (i=0;i<16;i=i+1) begin : enc_stage
-  assign e[i*2:i*2+1] = enc(v[i*2:i*2+1]);
-end
-~ENDGENERATE
-
-reg [0:23] a;
-genvar i1;
-~GENERATE
-for (i1=0;i1<8;i1=i1+1) begin : mux_stage1
-  localparam n = 2;
-  logic [3:0] i;
-  assign i = e[i1*4:i1*4+3];
-  always @(*) begin
-    case (i[n-1+n])
-      1'b0    : a[i1*3:i1*3+2] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
-      default : a[i1*3:i1*3+2] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
-    endcase
-  end
-end
-~ENDGENERATE
-
-reg [0:15] b;
-genvar i2;
-~GENERATE
-for (i2=0;i2<4;i2=i2+1) begin : mux_stage2
-  localparam n = 3;
-  logic [5:0] i;
-  assign i = a[i2*6:i2*6+5];
-  always @(*) begin
-    case (i[n-1+n])
-      1'b0    : b[i2*4:i2*4+3] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
-      default : b[i2*4:i2*4+3] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
-    endcase
-  end
-end
-~ENDGENERATE
-
-reg [0:9] c;
-genvar i3;
-~GENERATE
-for (i3=0;i3<2;i3=i3+1) begin : mux_stage3
-  localparam n = 4;
-  logic [7:0] i;
-  assign i = b[i3*8:i3*8+7];
-  always @(*) begin
-    case (i[n-1+n])
-      1'b0    : c[i3*5:i3*5+4] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
-      default : c[i3*5:i3*5+4] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
-    endcase
-  end
-end
-~ENDGENERATE
-
-reg [0:5] res;
-~GENERATE
-if (1) begin
-localparam n = 5;
-logic [9:0] i;
-assign i = c[0:9];
-always @(*) begin
-  case (i[n-1+n])
-    1'b0    : res = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
-    default : res = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
-  endcase
-end
-end
-~ENDGENERATE
-~FI
-assign ~RESULT = $unsigned(res);
-end
-~ENDGENERATE
-// ctz end"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.byteSwap16#"
-    , "type"      : "byteSwap16# :: Word# -> Word#"
-    , "templateD" :
-"// byteSwap16 begin
-~SIGDO[~SYM[0]];
-assign ~SYM[0] = ~ARG[0];
-~IF ~IW64 ~THEN
-assign ~RESULT = {~SYM[0][63:16],~SYM[0][7:0],~SYM[0][15:8]};
-~ELSE
-assign ~RESULT = {~SYM[0][31:16],~SYM[0][7:0],~SYM[0][15:8]};
-~FI
-// byteSwap16 end"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.byteSwap32#"
-    , "type"      : "byteSwap32# :: Word# -> Word#"
-    , "templateD" :
-"// byteSwap32 begin
-~SIGDO[~SYM[0]];
-assign ~SYM[0] = ~ARG[0];
-~IF ~IW64 ~THEN
-assign ~RESULT = {~SYM[0][63:32],~SYM[0][7:0],~SYM[0][15:8],~SYM[0][23:16],~SYM[0][31:24]};
-~ELSE
-assign ~RESULT = {~SYM[0][7:0],~SYM[0][15:8],~SYM[0][23:16],~SYM[0][31:24]};
-~FI
-// byteSwap32 end"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.byteSwap64#"
-    , "type"      : "byteSwap64# :: Word# -> Word#"
-    , "templateD" :
-"// byteSwap64 begin
-~SIGDO[~SYM[1]];
-assign ~SYM[1] = ~ARG[0];
-assign ~RESULT = {~SYM[1][7:0],~SYM[1][15:8],~SYM[1][23:16],~SYM[1][31:24]
-                 ,~SYM[1][39:32],~SYM[1][47:40],~SYM[1][55:48],~SYM[1][63:56]};
-// byteSwap64 end"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.byteSwap#"
-    , "type"      : "byteSwap# :: Word# -> Word#"
-    , "templateD" :
-"// byteSwap begin
-~SIGDO[~SYM[1]];
-assign ~SYM[1] = ~ARG[0];
-~IF ~IW64 ~THEN
-assign ~RESULT = {~SYM[1][7:0],~SYM[1][15:8],~SYM[1][23:16],~SYM[1][31:24]
-                 ,~SYM[1][39:32],~SYM[1][47:40],~SYM[1][55:48],~SYM[1][63:56]};
-~ELSE
-assign ~RESULT = {~SYM[1][7:0],~SYM[1][15:8],~SYM[1][23:16],~SYM[1][31:24]};
-~FI
-// byteSwap end"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.narrow8Int#"
-    , "type"      : "narrow8Int# :: Int# -> Int#"
-    , "templateD" :
-"// narrow8Int begin
-~SIGD[~SYM[0]][0];
-assign ~SYM[0] = ~ARG[0];
-
-assign ~RESULT = $signed(~SYM[0][7:0]);
-// narrow8Int end"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.narrow16Int#"
-    , "type"      : "narrow16Int# :: Int# -> Int#"
-    , "templateD" :
-"// narrow16Int begin
-~SIGD[~SYM[0]][0];
-assign ~SYM[0] = ~ARG[0];
-
-assign ~RESULT = $signed(~SYM[0][15:0]);
-// narrow16Int end"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.narrow32Int#"
-    , "type"      : "narrow32Int# :: Int# -> Int#"
-    , "templateD" :
-"// narrow32Int begin
-~SIGD[~SYM[0]][0];
-assign ~SYM[0] = ~ARG[0];
-
-assign ~RESULT = $signed(~SYM[0][31:0]);
-// narrow32Int end"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.narrow8Word#"
-    , "type"      : "narrow8Int# :: Word# -> Word#"
-    , "templateD" :
-"// narrow8Word begin
-~SIGD[~SYM[0]][0];
-assign ~SYM[0] = ~ARG[0];
-
-assign ~RESULT = $unsigned(~SYM[0][7:0]);
-// narrow8Word end"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.narrow16Word#"
-    , "type"      : "narrow16Word# :: Word# -> Word#"
-    , "templateD" :
-"// narrow16Word begin
-~SIGD[~SYM[0]][0];
-assign ~SYM[0] = ~ARG[0];
-
-assign ~RESULT = $unsigned(~SYM[0][15:0]);
-// narrow16Word end"
-    }
-  }
-, { "BlackBox" :
-    { "name"      : "GHC.Prim.narrow32Word#"
-    , "type"      : "narrow32Int# :: Word# -> Word#"
-    , "templateD" :
-"// narrow32Word begin
-~SIGD[~SYM[0]][0];
+~SIGD[~GENSYM[quot_res][0]][0];
+~SIGD[~GENSYM[rem_res][1]][0];
+assign ~SYM[0] = ~ARG[0] / ~ARG[1];
+assign ~SYM[1] = ~ARG[0] % ~ARG[1];
+
+assign ~RESULT = {~SYM[0],~SYM[1]};
+// quotRemInt end"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.andI#"
+    , "type"      : "andI# :: Int# -> Int# -> Int#"
+    , "templateE" : "~ARG[0] & ~ARG[1]"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.orI#"
+    , "type"      : "orI# :: Int# -> Int# -> Int#"
+    , "templateE" : "~ARG[0] | ~ARG[1]"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.xorI#"
+    , "type"      : "xorI# :: Int# -> Int# -> Int#"
+    , "templateE" : "~ARG[0] ^ ~ARG[1]"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.notI#"
+    , "type"      : "notI# :: Int# -> Int#"
+    , "templateE" : "~ ~ARG[0]"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.negateInt#"
+    , "type"      : "negateInt# :: Int# -> Int#"
+    , "templateE" : "-(~ARG[0])"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.>#"
+     , "type"     : "(>#) :: Int# -> Int# -> Int#"
+    , "templateE" : "(~ARG[0] > ~ARG[1]) ? ~SIZE[~TYPO]'sd1 : ~SIZE[~TYPO]'sd0"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.>=#"
+    , "type"      : "(>=#) :: Int# -> Int# -> Int#"
+    , "templateE" : "(~ARG[0] >= ~ARG[1]) ? ~SIZE[~TYPO]'sd1 : ~SIZE[~TYPO]'sd0"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.==#"
+    , "type"      : "(==) :: Int# -> Int# -> Int#"
+    , "templateE" : "(~ARG[0] == ~ARG[1]) ? ~SIZE[~TYPO]'sd1 : ~SIZE[~TYPO]'sd0"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim./=#"
+    , "type"      : "(/=#) :: Int# -> Int# -> Int#"
+    , "templateE" : "(~ARG[0] != ~ARG[1]) ? ~SIZE[~TYPO]'sd1 : ~SIZE[~TYPO]'sd0"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.<#"
+    , "type"      : "(<#) :: Int# -> Int# -> Int#"
+    , "templateE" : "(~ARG[0] < ~ARG[1]) ? ~SIZE[~TYPO]'sd1 : ~SIZE[~TYPO]'sd0"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.<=#"
+    , "type"      : "(<=#) :: Int# -> Int# -> Int#"
+    , "templateE" : "(~ARG[0] <= ~ARG[1]) ? ~SIZE[~TYPO]'sd1 : ~SIZE[~TYPO]'sd0"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.chr#"
+    , "type"      : "ord :: Int# -> Char#"
+    , "templateD" : "assign ~RESULT = $unsigned(~ARG[0]);"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.int2Word#"
+    , "type"      : "int2Word# :: Int# -> Word#"
+    , "templateE" : "$unsigned(~ARG[0])"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.uncheckedIShiftL#"
+    , "type"      : "uncheckedIShiftL# :: Int# -> Int# -> Int#"
+    , "templateE" : "~ARG[0] <<< ~ARG[1]"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.uncheckedIShiftRA#"
+    , "type"      : "uncheckedIShiftRA# :: Int# -> Int# -> Int#"
+    , "templateE" : "~ARG[0] >>> ~ARG[1]"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.uncheckedIShiftRL#"
+    , "type"      : "uncheckedIShiftRL# :: Int# -> Int# -> Int#"
+    , "templateE" : "~ARG[0] >> ~ARG[1]"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.plusWord#"
+    , "type"      : "plusWord# :: Word# -> Word# -> Word#"
+    , "templateE" : "~ARG[0] + ~ARG[1]"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.minusWord#"
+    , "type"      : "minusWord# :: Word# -> Word# -> Word#"
+    , "templateE" : "~ARG[0] - ~ARG[1]"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.timesWord#"
+    , "type"      : "timesWord# :: Word# -> Word# -> Word#"
+    , "templateE" : "~ARG[0] * ~ARG[1]"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.quotWord#"
+    , "type"      : "quotWord# :: Word# -> Word# -> Word#"
+    , "templateE" : "~ARG[0] / ~ARG[1]"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.remWord#"
+    , "type"      : "remWord# :: Word# -> Word# -> Word#"
+    , "templateE" : "~ARG[0] % ~ARG[1]"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.quotRemWord#"
+    , "type"      : "quotRemWord# :: Word# -> Word# -> (#Word#, Word##)"
+    , "templateD" :
+"// quotRemWord begin
+~SIGD[~GENSYM[quot_res][0]][0];
+~SIGD[~GENSYM[rem_res][1]][0];
+assign ~SYM[0] = ~ARG[0] / ~ARG[1];
+assign ~SYM[1] = ~ARG[0] % ~ARG[1];
+
+assign ~RESULT = {~SYM[0],~SYM[1]};
+// quotRemWord end"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.and#"
+    , "type"      : "and# :: Word# -> Word# -> Word#"
+    , "templateE" : "~ARG[0] & ~ARG[1]"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.or#"
+    , "type"      : "or# :: Word# -> Word# -> Word#"
+    , "templateE" : "~ARG[0] | ~ARG[1]"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.xor#"
+    , "type"      : "xor# :: Word# -> Word# -> Word#"
+    , "templateE" : "~ARG[0] ^ ~ARG[1]"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.not#"
+    , "type"      : "not# :: Word# -> Word#"
+    , "templateE" : "~ ~ARG[0]"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.uncheckedShiftL#"
+    , "type"      : "uncheckedShiftL# :: Word# -> Int# -> Word#"
+    , "templateE" : "~ARG[0] << ~ARG[1]"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.uncheckedIShiftL#"
+    , "type"      : "uncheckedShiftRL# :: Word# -> Int# -> Word#"
+    , "templateE" : "~ARG[0] >> ~ARG[1]"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.word2Int#"
+    , "type"      : "int2Word# :: Word# -> Int#"
+    , "templateE" : "$signed(~ARG[0])"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.gtWord#"
+     , "type"     : "gtWord# :: Word# -> Word# -> Int#"
+    , "templateE" : "(~ARG[0] > ~ARG[1]) ? ~SIZE[~TYPO]'sd1 : ~SIZE[~TYPO]'sd0"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.geWord#"
+    , "type"      : "geWord# :: Word# -> Word# -> Int#"
+    , "templateE" : "(~ARG[0] >= ~ARG[1]) ? ~SIZE[~TYPO]'sd1 : ~SIZE[~TYPO]'sd0"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.eqWord#"
+    , "type"      : "eqWord# :: Word# -> Word# -> Int#"
+    , "templateE" : "(~ARG[0] == ~ARG[1]) ? ~SIZE[~TYPO]'sd1 : ~SIZE[~TYPO]'sd0"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.neWord#"
+    , "type"      : "neWord# :: Word# -> Word# -> Int#"
+    , "templateE" : "(~ARG[0] != ~ARG[1]) ? ~SIZE[~TYPO]'sd1 : ~SIZE[~TYPO]'sd0"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.ltWord#"
+    , "type"      : "ltWord# :: Word# -> Word# -> Int#"
+    , "templateE" : "(~ARG[0] < ~ARG[1]) ? ~SIZE[~TYPO]'sd1 : ~SIZE[~TYPO]'sd0"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.leWord#"
+    , "type"      : "leWord# :: Word# -> Word# -> Int#"
+    , "templateE" : "(~ARG[0] <= ~ARG[1]) ? ~SIZE[~TYPO]'sd1 : ~SIZE[~TYPO]'sd0"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.popCnt8#"
+    , "type"      : "popCnt8# :: Word# -> Word#"
+    , "templateD" :
+"// popCnt8 begin
+localparam ~GENSYM[width][0] = 8;
+
+// depth of the tree
+localparam ~GENSYM[levels][2] = $clog2(~SYM[0]);
+
+logic [~SYM[2]:0] ~GENSYM[intermediate][3] [0:(2*~SYM[0])-2];
+
+// put input into the first half of the intermediate array
+genvar ~GENSYM[i][4];
+~GENERATE
+for (~SYM[4] = 0; ~SYM[4] < ~SYM[0]; ~SYM[4]=~SYM[4]+1) begin : ~GENSYM[mk_array][11]
+  assign ~SYM[3][~SYM[4]] = $unsigned(~ARG[0][~SYM[4]]);
+end
+~ENDGENERATE
+
+// given a level and a depth, calculate the corresponding index into the
+// intermediate array
+function integer ~GENSYM[depth2Index][5];
+  input integer levels;
+  input integer depth;
+
+  ~SYM[5] = (2 ** levels) - (2 ** depth);
+endfunction
+
+// Create the tree of instantiated components
+genvar ~GENSYM[d][6];
+genvar ~GENSYM[i][7];
+~GENERATE
+if (~SYM[2] != 0) begin : ~GENSYM[make_tree][8]
+  for (~SYM[6] = (~SYM[2] - 1); ~SYM[6] >= 0; ~SYM[6]=~SYM[6]-1) begin : ~GENSYM[tree_depth][9]
+    for (~SYM[7] = 0; ~SYM[7] < (2**~SYM[6]); ~SYM[7] = ~SYM[7]+1) begin : ~GENSYM[tree_depth_loop][10]
+      assign ~SYM[3][~SYM[5](~SYM[2]+1,~SYM[6]+1)+~SYM[7]] =
+             ~SYM[3][~SYM[5](~SYM[2]+1,~SYM[6]+2)+(2*~SYM[7])] +
+             ~SYM[3][~SYM[5](~SYM[2]+1,~SYM[6]+2)+(2*~SYM[7])+1];
+    end
+  end
+end
+~ENDGENERATE
+
+// The last element of the intermediate array holds the result
+assign ~RESULT = $unsigned(~SYM[3][(2*~SYM[0])-2]);
+// popCnt8 end"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.popCnt16#"
+    , "type"      : "popCnt16# :: Word# -> Word#"
+    , "templateD" :
+"// popCnt16 begin
+localparam ~GENSYM[width][0] = 16;
+
+// depth of the tree
+localparam ~GENSYM[levels][2] = $clog2(~SYM[0]);
+
+logic [~SYM[2]:0] ~GENSYM[intermediate][3] [0:(2*~SYM[0])-2];
+
+// put input into the first half of the intermediate array
+genvar ~GENSYM[i][4];
+~GENERATE
+for (~SYM[4] = 0; ~SYM[4] < ~SYM[0]; ~SYM[4]=~SYM[4]+1) begin : ~GENSYM[mk_array][11]
+  assign ~SYM[3][~SYM[4]] = $unsigned(~ARG[0][~SYM[4]]);
+end
+~ENDGENERATE
+
+// given a level and a depth, calculate the corresponding index into the
+// intermediate array
+function integer ~GENSYM[depth2Index][5];
+  input integer levels;
+  input integer depth;
+
+  ~SYM[5] = (2 ** levels) - (2 ** depth);
+endfunction
+
+// Create the tree of instantiated components
+genvar ~GENSYM[d][6];
+genvar ~GENSYM[i][7];
+~GENERATE
+if (~SYM[2] != 0) begin : ~GENSYM[make_tree][8]
+  for (~SYM[6] = (~SYM[2] - 1); ~SYM[6] >= 0; ~SYM[6]=~SYM[6]-1) begin : ~GENSYM[tree_depth][9]
+    for (~SYM[7] = 0; ~SYM[7] < (2**~SYM[6]); ~SYM[7] = ~SYM[7]+1) begin : ~GENSYM[tree_depth_loop][10]
+      assign ~SYM[3][~SYM[5](~SYM[2]+1,~SYM[6]+1)+~SYM[7]] =
+             ~SYM[3][~SYM[5](~SYM[2]+1,~SYM[6]+2)+(2*~SYM[7])] +
+             ~SYM[3][~SYM[5](~SYM[2]+1,~SYM[6]+2)+(2*~SYM[7])+1];
+    end
+  end
+end
+~ENDGENERATE
+
+// The last element of the intermediate array holds the result
+assign ~RESULT = $unsigned(~SYM[3][(2*~SYM[0])-2]);
+// popCnt16 end"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.popCnt32#"
+    , "type"      : "popCnt32# :: Word# -> Word#"
+    , "templateD" :
+"// popCnt32 begin
+localparam ~GENSYM[width][0] = 32;
+
+// depth of the tree
+localparam ~GENSYM[levels][2] = $clog2(~SYM[0]);
+
+logic [~SYM[2]:0] ~GENSYM[intermediate][3] [0:(2*~SYM[0])-2];
+
+// put input into the first half of the intermediate array
+genvar ~GENSYM[i][4];
+~GENERATE
+for (~SYM[4] = 0; ~SYM[4] < ~SYM[0]; ~SYM[4]=~SYM[4]+1) begin : ~GENSYM[mk_array][11]
+  assign ~SYM[3][~SYM[4]] = $unsigned(~ARG[0][~SYM[4]]);
+end
+~ENDGENERATE
+
+// given a level and a depth, calculate the corresponding index into the
+// intermediate array
+function integer ~GENSYM[depth2Index][5];
+  input integer levels;
+  input integer depth;
+
+  ~SYM[5] = (2 ** levels) - (2 ** depth);
+endfunction
+
+// Create the tree of instantiated components
+genvar ~GENSYM[d][6];
+genvar ~GENSYM[i][7];
+~GENERATE
+if (~SYM[2] != 0) begin : ~GENSYM[make_tree][8]
+  for (~SYM[6] = (~SYM[2] - 1); ~SYM[6] >= 0; ~SYM[6]=~SYM[6]-1) begin : ~GENSYM[tree_depth][9]
+    for (~SYM[7] = 0; ~SYM[7] < (2**~SYM[6]); ~SYM[7] = ~SYM[7]+1) begin : ~GENSYM[tree_depth_loop][10]
+      assign ~SYM[3][~SYM[5](~SYM[2]+1,~SYM[6]+1)+~SYM[7]] =
+             ~SYM[3][~SYM[5](~SYM[2]+1,~SYM[6]+2)+(2*~SYM[7])] +
+             ~SYM[3][~SYM[5](~SYM[2]+1,~SYM[6]+2)+(2*~SYM[7])+1];
+    end
+  end
+end
+~ENDGENERATE
+
+// The last element of the intermediate array holds the result
+assign ~RESULT = $unsigned(~SYM[3][(2*~SYM[0])-2]);
+// popCnt32 end"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.popCnt64#"
+    , "type"      : "popCnt64# :: Word# -> Word#"
+    , "templateD" :
+"// popCnt64 begin
+localparam ~GENSYM[width][0] = 64;
+
+// depth of the tree
+localparam ~GENSYM[levels][2] = $clog2(~SYM[0]);
+
+logic [~SYM[2]:0] ~GENSYM[intermediate][3] [0:(2*~SYM[0])-2];
+
+// put input into the first half of the intermediate array
+genvar ~GENSYM[i][4];
+~GENERATE
+for (~SYM[4] = 0; ~SYM[4] < ~SYM[0]; ~SYM[4]=~SYM[4]+1) begin : ~GENSYM[mk_array][11]
+  assign ~SYM[3][~SYM[4]] = $unsigned(~ARG[0][~SYM[4]]);
+end
+~ENDGENERATE
+
+// given a level and a depth, calculate the corresponding index into the
+// intermediate array
+function integer ~GENSYM[depth2Index][5];
+  input integer levels;
+  input integer depth;
+
+  ~SYM[5] = (2 ** levels) - (2 ** depth);
+endfunction
+
+// Create the tree of instantiated components
+genvar ~GENSYM[d][6];
+genvar ~GENSYM[i][7];
+~GENERATE
+if (~SYM[2] != 0) begin : ~GENSYM[make_tree][8]
+  for (~SYM[6] = (~SYM[2] - 1); ~SYM[6] >= 0; ~SYM[6]=~SYM[6]-1) begin : ~GENSYM[tree_depth][9]
+    for (~SYM[7] = 0; ~SYM[7] < (2**~SYM[6]); ~SYM[7] = ~SYM[7]+1) begin : ~GENSYM[tree_depth_loop][10]
+      assign ~SYM[3][~SYM[5](~SYM[2]+1,~SYM[6]+1)+~SYM[7]] =
+             ~SYM[3][~SYM[5](~SYM[2]+1,~SYM[6]+2)+(2*~SYM[7])] +
+             ~SYM[3][~SYM[5](~SYM[2]+1,~SYM[6]+2)+(2*~SYM[7])+1];
+    end
+  end
+end
+~ENDGENERATE
+
+// The last element of the intermediate array holds the result
+assign ~RESULT = $unsigned(~SYM[3][(2*~SYM[0])-2]);
+// popCnt64 end"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.popCnt#"
+    , "type"      : "popCnt8# :: Word# -> Word#"
+    , "templateD" :
+"// popCnt begin
+localparam ~GENSYM[width][0] = ~SIZE[~TYPO];
+
+// depth of the tree
+localparam ~GENSYM[levels][2] = $clog2(~SYM[0]);
+
+logic [~SYM[2]:0] ~GENSYM[intermediate][3] [0:(2*~SYM[0])-2];
+
+// put input into the first half of the intermediate array
+genvar ~GENSYM[i][4];
+~GENERATE
+for (~SYM[4] = 0; ~SYM[4] < ~SYM[0]; ~SYM[4]=~SYM[4]+1) begin : ~GENSYM[mk_array][11]
+  assign ~SYM[3][~SYM[4]] = $unsigned(~ARG[0][~SYM[4]]);
+end
+~ENDGENERATE
+
+// given a level and a depth, calculate the corresponding index into the
+// intermediate array
+function integer ~GENSYM[depth2Index][5];
+  input integer levels;
+  input integer depth;
+
+  ~SYM[5] = (2 ** levels) - (2 ** depth);
+endfunction
+
+// Create the tree of instantiated components
+genvar ~GENSYM[d][6];
+genvar ~GENSYM[i][7];
+~GENERATE
+if (~SYM[2] != 0) begin : ~GENSYM[make_tree][8]
+  for (~SYM[6] = (~SYM[2] - 1); ~SYM[6] >= 0; ~SYM[6]=~SYM[6]-1) begin : ~GENSYM[tree_depth][9]
+    for (~SYM[7] = 0; ~SYM[7] < (2**~SYM[6]); ~SYM[7] = ~SYM[7]+1) begin : ~GENSYM[tree_depth_loop][10]
+      assign ~SYM[3][~SYM[5](~SYM[2]+1,~SYM[6]+1)+~SYM[7]] =
+             ~SYM[3][~SYM[5](~SYM[2]+1,~SYM[6]+2)+(2*~SYM[7])] +
+             ~SYM[3][~SYM[5](~SYM[2]+1,~SYM[6]+2)+(2*~SYM[7])+1];
+    end
+  end
+end
+~ENDGENERATE
+
+// The last element of the intermediate array holds the result
+assign ~RESULT = $unsigned(~SYM[3][(2*~SYM[0])-2]);
+// popCnt end"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.clz8#"
+    , "type"      : "clz8 :: Word# -> Word#"
+    , "templateD" :
+"// clz8 begin
+function [1:0] ~GENSYM[enc][0];
+  input [1:0] a;
+  case (a)
+    2'b00:   ~SYM[0] = 2'b10;
+    2'b01:   ~SYM[0] = 2'b01;
+    2'b10:   ~SYM[0] = 2'b00;
+    default: ~SYM[0] = 2'b00;
+  endcase
+endfunction
+
+logic [0:7] ~GENSYM[v][1];
+assign ~SYM[1] = ~ARG[0][7:0];
+
+logic [0:7] ~GENSYM[e][2];
+genvar ~GENSYM[n][3];
+~GENERATE
+for (~SYM[3]=0;~SYM[3]<4;~SYM[3]=~SYM[3]+1) begin : ~GENSYM[enc_stage][8]
+  assign ~SYM[2][~SYM[3]*2:~SYM[3]*2+1] = ~SYM[0](~SYM[1][~SYM[3]*2:~SYM[3]*2+1]);
+end
+~ENDGENERATE
+
+logic [0:5] ~GENSYM[a][4];
+genvar ~GENSYM[i1][5];
+~GENERATE
+for (~SYM[5]=0;~SYM[5]<2;~SYM[5]=~SYM[5]+1) begin : ~GENSYM[mux_stage1][6]
+  localparam n = 2;
+  logic [3:0] i;
+  assign i = ~SYM[2][~SYM[5]*4:~SYM[5]*4+3];
+  always_comb begin
+    case (i[n-1+n])
+      1'b0    : ~SYM[4][~SYM[5]*3:~SYM[5]*3+2] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
+      default : ~SYM[4][~SYM[5]*3:~SYM[5]*3+2] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
+    endcase
+  end
+end
+~ENDGENERATE
+
+logic [0:3] ~GENSYM[res][7];
+~GENERATE
+if (1) begin
+localparam n = 3;
+logic [5:0] i;
+assign i = ~SYM[4][0:5];
+always_comb begin
+  case (i[n-1+n])
+    1'b0    : ~SYM[7] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
+    default : ~SYM[7] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
+  endcase
+end
+end
+~ENDGENERATE
+
+assign ~RESULT = $unsigned(~SYM[7]);
+// clz8 end"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.clz16#"
+    , "type"      : "clz16 :: Word# -> Word#"
+    , "templateD" :
+"// clz16 begin
+function [1:0] ~GENSYM[enc][0];
+  input [1:0] a;
+  case (a)
+    2'b00:   ~SYM[0] = 2'b10;
+    2'b01:   ~SYM[0] = 2'b01;
+    2'b10:   ~SYM[0] = 2'b00;
+    default: ~SYM[0] = 2'b00;
+  endcase
+endfunction
+
+logic [0:15] ~GENSYM[v][1];
+assign ~SYM[1] = ~ARG[0][15:0];
+
+logic [0:15] ~GENSYM[e][2];
+genvar ~GENSYM[i][3];
+~GENERATE
+for (~SYM[3]=0;~SYM[3]<8;~SYM[3]=~SYM[3]+1) begin : ~GENSYM[enc_stage][8]
+  assign ~SYM[2][~SYM[3]*2:~SYM[3]*2+1] = ~SYM[0](~SYM[1][~SYM[3]*2:~SYM[3]*2+1]);
+end
+~ENDGENERATE
+
+logic [0:11] ~GENSYM[a][4];
+genvar ~GENSYM[i1][5];
+~GENERATE
+for (~SYM[5]=0;~SYM[5]<4;~SYM[5]=~SYM[5]+1) begin : ~GENSYM[mux_stage][6]
+  localparam n = 2;
+  logic [3:0] i;
+  assign i = ~SYM[2][~SYM[5]*4:~SYM[5]*4+3];
+  always_comb begin
+    case (i[n-1+n])
+      1'b0    : ~SYM[4][~SYM[5]*3:~SYM[5]*3+2] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
+      default : ~SYM[4][~SYM[5]*3:~SYM[5]*3+2] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
+    endcase
+  end
+end
+~ENDGENERATE
+
+logic [0:7] ~GENSYM[b][9];
+genvar ~GENSYM[i2][10];
+~GENERATE
+for (~SYM[10]=0;~SYM[10]<2;~SYM[10]=~SYM[10]+1) begin : ~GENSYM[mux_stage2][11]
+  localparam n = 3;
+  logic [5:0] i;
+  assign i = ~SYM[4][~SYM[10]*6:~SYM[10]*6+5];
+  always_comb begin
+    case (i[n-1+n])
+      1'b0    : ~SYM[9][~SYM[10]*4:~SYM[10]*4+3] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
+      default : ~SYM[9][~SYM[10]*4:~SYM[10]*4+3] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
+    endcase
+  end
+end
+~ENDGENERATE
+
+logic [0:4] ~GENSYM[res][7];
+~GENERATE
+if (1) begin
+localparam n = 4;
+logic [7:0] i;
+assign i = ~SYM[9][0:7];
+always_comb begin
+  case (i[n-1+n])
+    1'b0    : ~SYM[7] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
+    default : ~SYM[7] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
+  endcase
+end
+end
+~ENDGENERATE
+
+assign ~RESULT = $unsigned(~SYM[7]);
+// clz16 end"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.clz32#"
+    , "type"      : "clz32 :: Word# -> Word#"
+    , "templateD" :
+"// clz32 begin
+function [1:0] ~GENSYM[enc][0];
+  input [1:0] a;
+  case (a)
+    2'b00:   ~SYM[0] = 2'b10;
+    2'b01:   ~SYM[0] = 2'b01;
+    2'b10:   ~SYM[0] = 2'b00;
+    default: ~SYM[0] = 2'b00;
+  endcase
+endfunction
+
+logic [0:31] ~GENSYM[v][1];
+assign ~SYM[1] = ~ARG[0][31:0];
+
+logic [0:31] ~GENSYM[e][2];
+genvar ~GENSYM[i][3];
+~GENERATE
+for (~SYM[3]=0;~SYM[3]<16;~SYM[3]=~SYM[3]+1) begin : ~GENSYM[enc_stage][8]
+  assign ~SYM[2][~SYM[3]*2:~SYM[3]*2+1] = ~SYM[0](~SYM[1][~SYM[3]*2:~SYM[3]*2+1]);
+end
+~ENDGENERATE
+
+logic [0:23] ~GENSYM[a][4];
+genvar ~GENSYM[i1][5];
+~GENERATE
+for (~SYM[5]=0;~SYM[5]<8;~SYM[5]=~SYM[5]+1) begin : ~GENSYM[mux_stage][6]
+  localparam n = 2;
+  logic [3:0] i;
+  assign i = ~SYM[2][~SYM[5]*4:~SYM[5]*4+3];
+  always_comb begin
+    case (i[n-1+n])
+      1'b0    : ~SYM[4][~SYM[5]*3:~SYM[5]*3+2] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
+      default : ~SYM[4][~SYM[5]*3:~SYM[5]*3+2] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
+    endcase
+  end
+end
+~ENDGENERATE
+
+logic [0:15] ~GENSYM[b][9];
+genvar ~GENSYM[i2][10];
+~GENERATE
+for (~SYM[10]=0;~SYM[10]<4;~SYM[10]=~SYM[10]+1) begin : ~GENSYM[mux_stage2][11]
+  localparam n = 3;
+  logic [5:0] i;
+  assign i = ~SYM[4][~SYM[10]*6:~SYM[10]*6+5];
+  always_comb begin
+    case (i[n-1+n])
+      1'b0    : ~SYM[9][~SYM[10]*4:~SYM[10]*4+3] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
+      default : ~SYM[9][~SYM[10]*4:~SYM[10]*4+3] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
+    endcase
+  end
+end
+~ENDGENERATE
+
+logic [0:9] ~GENSYM[c][12];
+genvar ~GENSYM[i3][13];
+~GENERATE
+for (~SYM[13]=0;~SYM[13]<2;~SYM[13]=~SYM[13]+1) begin : ~GENSYM[mux_stage3][14]
+  localparam n = 4;
+  logic [7:0] i;
+  assign i = ~SYM[9][~SYM[13]*8:~SYM[13]*8+7];
+  always_comb begin
+    case (i[n-1+n])
+      1'b0    : ~SYM[12][~SYM[13]*5:~SYM[13]*5+4] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
+      default : ~SYM[12][~SYM[13]*5:~SYM[13]*5+4] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
+    endcase
+  end
+end
+~ENDGENERATE
+
+logic [0:5] ~GENSYM[res][7];
+~GENERATE
+if (1) begin
+localparam n = 5;
+logic [9:0] i;
+assign i = ~SYM[12][0:9];
+always_comb begin
+  case (i[n-1+n])
+    1'b0    : ~SYM[7] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
+    default : ~SYM[7] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
+  endcase
+end
+end
+~ENDGENERATE
+
+assign ~RESULT = $unsigned(~SYM[7]);
+// clz32 end"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.clz64#"
+    , "type"      : "clz64 :: Word# -> Word#"
+    , "templateD" :
+"// clz64 begin
+function [1:0] ~GENSYM[enc][0];
+  input [1:0] a;
+  case (a)
+    2'b00:   ~SYM[0] = 2'b10;
+    2'b01:   ~SYM[0] = 2'b01;
+    2'b10:   ~SYM[0] = 2'b00;
+    default: ~SYM[0] = 2'b00;
+  endcase
+endfunction
+
+logic [0:63] ~GENSYM[v][1];
+assign ~SYM[1] = ~ARG[0][63:0];
+
+logic [0:63] ~GENSYM[e][2];
+genvar ~GENSYM[i][3];
+~GENERATE
+for (~SYM[3]=0;~SYM[3]<32;~SYM[3]=~SYM[3]+1) begin : ~GENSYM[enc_stage][8]
+  assign ~SYM[2][~SYM[3]*2:~SYM[3]*2+1] = ~SYM[0](~SYM[1][~SYM[3]*2:~SYM[3]*2+1]);
+end
+~ENDGENERATE
+
+logic [0:47] ~GENSYM[a][4];
+genvar ~GENSYM[i1][5];
+~GENERATE
+for (~SYM[5]=0;~SYM[5]<16;~SYM[5]=~SYM[5]+1) begin : ~GENSYM[mux_stage][6]
+  localparam n = 2;
+  logic [3:0] i;
+  assign i = ~SYM[2][~SYM[5]*4:~SYM[5]*4+3];
+  always_comb begin
+    case (i[n-1+n])
+      1'b0    : ~SYM[4][~SYM[5]*3:~SYM[5]*3+2] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
+      default : ~SYM[4][~SYM[5]*3:~SYM[5]*3+2] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
+    endcase
+  end
+end
+~ENDGENERATE
+
+logic [0:31] ~GENSYM[b][9];
+genvar ~GENSYM[i2][10];
+~GENERATE
+for (~SYM[10]=0;~SYM[10]<8;~SYM[10]=~SYM[10]+1) begin : ~GENSYM[mux_stage2][11]
+  localparam n = 3;
+  logic [5:0] i;
+  assign i = ~SYM[4][~SYM[10]*6:~SYM[10]*6+5];
+  always_comb begin
+    case (i[n-1+n])
+      1'b0    : ~SYM[9][~SYM[10]*4:~SYM[10]*4+3] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
+      default : ~SYM[9][~SYM[10]*4:~SYM[10]*4+3] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
+    endcase
+  end
+end
+~ENDGENERATE
+
+logic [0:19] ~GENSYM[c][12];
+genvar ~GENSYM[i3][13];
+~GENERATE
+for (~SYM[13]=0;~SYM[13]<4;~SYM[13]=~SYM[13]+1) begin : ~GENSYM[mux_stage3][14]
+  localparam n = 4;
+  logic [7:0] i;
+  assign i = ~SYM[9][~SYM[13]*8:~SYM[13]*8+7];
+  always_comb begin
+    case (i[n-1+n])
+      1'b0    : ~SYM[12][~SYM[13]*5:~SYM[13]*5+4] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
+      default : ~SYM[12][~SYM[13]*5:~SYM[13]*5+4] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
+    endcase
+  end
+end
+~ENDGENERATE
+
+logic [0:11] ~GENSYM[d][15];
+genvar ~GENSYM[i4][16];
+~GENERATE
+for (~SYM[16]=0;~SYM[16]<2;~SYM[16]=~SYM[16]+1) begin : ~GENSYM[mux_stage4][17]
+  localparam n = 5;
+  logic [9:0] i;
+  assign i = ~SYM[12][~SYM[16]*10:~SYM[16]*10+9];
+  always_comb begin
+    case (i[n-1+n])
+      1'b0    : ~SYM[15][~SYM[16]*6:~SYM[16]*6+5] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
+      default : ~SYM[15][~SYM[16]*6:~SYM[16]*6+5] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
+    endcase
+  end
+end
+~ENDGENERATE
+
+logic [0:6] ~GENSYM[res][7];
+~GENERATE
+if (1) begin
+localparam n = 6;
+logic [11:0] i;
+assign i = ~SYM[15][0:11];
+always_comb begin
+  case (i[n-1+n])
+    1'b0    : ~SYM[7] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
+    default : ~SYM[7] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
+  endcase
+end
+end
+~ENDGENERATE
+
+assign ~RESULT = $unsigned(~SYM[7]);
+// clz64 end"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.clz#"
+    , "type"      : "clz :: Word# -> Word#"
+    , "templateD" :
+"// clz begin
+function [1:0] ~GENSYM[enc][0];
+  input [1:0] a;
+  case (a)
+    2'b00:   ~SYM[0] = 2'b10;
+    2'b01:   ~SYM[0] = 2'b01;
+    2'b10:   ~SYM[0] = 2'b00;
+    default: ~SYM[0] = 2'b00;
+  endcase
+endfunction
+~IF ~IW64 ~THEN
+logic [0:63] ~GENSYM[v][1];
+assign ~SYM[1] = ~ARG[0][63:0];
+
+logic [0:63] ~GENSYM[e][2];
+genvar ~GENSYM[i][3];
+~GENERATE
+for (~SYM[3]=0;~SYM[3]<32;~SYM[3]=~SYM[3]+1) begin : ~GENSYM[enc_stage][8]
+  assign ~SYM[2][~SYM[3]*2:~SYM[3]*2+1] = ~SYM[0](~SYM[1][~SYM[3]*2:~SYM[3]*2+1]);
+end
+~ENDGENERATE
+
+logic [0:47] ~GENSYM[a][4];
+genvar ~GENSYM[i1][5];
+~GENERATE
+for (~SYM[5]=0;~SYM[5]<16;~SYM[5]=~SYM[5]+1) begin : ~GENSYM[mux_stage][6]
+  localparam n = 2;
+  logic [3:0] i;
+  assign i = ~SYM[2][~SYM[5]*4:~SYM[5]*4+3];
+  always_comb begin
+    case (i[n-1+n])
+      1'b0    : ~SYM[4][~SYM[5]*3:~SYM[5]*3+2] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
+      default : ~SYM[4][~SYM[5]*3:~SYM[5]*3+2] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
+    endcase
+  end
+end
+~ENDGENERATE
+
+logic [0:31] ~GENSYM[b][9];
+genvar ~GENSYM[i2][10];
+~GENERATE
+for (~SYM[10]=0;~SYM[10]<8;~SYM[10]=~SYM[10]+1) begin : ~GENSYM[mux_stage2][11]
+  localparam n = 3;
+  logic [5:0] i;
+  assign i = ~SYM[4][~SYM[10]*6:~SYM[10]*6+5];
+  always_comb begin
+    case (i[n-1+n])
+      1'b0    : ~SYM[9][~SYM[10]*4:~SYM[10]*4+3] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
+      default : ~SYM[9][~SYM[10]*4:~SYM[10]*4+3] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
+    endcase
+  end
+end
+~ENDGENERATE
+
+logic [0:19] ~GENSYM[c][12];
+genvar ~GENSYM[i3][13];
+~GENERATE
+for (~SYM[13]=0;~SYM[13]<4;~SYM[13]=~SYM[13]+1) begin : ~GENSYM[mux_stage3][14]
+  localparam n = 4;
+  logic [7:0] i;
+  assign i = ~SYM[9][~SYM[13]*8:~SYM[13]*8+7];
+  always_comb begin
+    case (i[n-1+n])
+      1'b0    : ~SYM[12][~SYM[13]*5:~SYM[13]*5+4] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
+      default : ~SYM[12][~SYM[13]*5:~SYM[13]*5+4] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
+    endcase
+  end
+end
+~ENDGENERATE
+
+logic [0:11] ~GENSYM[d][15];
+genvar ~GENSYM[i4][16];
+~GENERATE
+for (~SYM[16]=0;~SYM[16]<2;~SYM[16]=~SYM[16]+1) begin : ~GENSYM[mux_stage4][17]
+  localparam n = 5;
+  logic [9:0] i;
+  assign i = ~SYM[12][~SYM[16]*10:~SYM[16]*10+9];
+  always_comb begin
+    case (i[n-1+n])
+      1'b0    : ~SYM[15][~SYM[16]*6:~SYM[16]*6+5] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
+      default : ~SYM[15][~SYM[16]*6:~SYM[16]*6+5] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
+    endcase
+  end
+end
+~ENDGENERATE
+
+logic [0:6] ~GENSYM[res][7];
+~GENERATE
+if (1) begin
+localparam n = 6;
+logic [11:0] i;
+assign i = ~SYM[15][0:11];
+always_comb begin
+  case (i[n-1+n])
+    1'b0    : ~SYM[7] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
+    default : ~SYM[7] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
+  endcase
+end
+end
+~ENDGENERATE
+~ELSE
+logic [0:31] ~SYM[1];
+assign ~SYM[1] = ~ARG[0][31:0];
+
+logic [0:31] ~SYM[2];
+genvar ~SYM[3];
+~GENERATE
+for (~SYM[3]=0;~SYM[3]<16;~SYM[3]=~SYM[3]+1) begin : ~SYM[8]
+  assign ~SYM[2][~SYM[3]*2:~SYM[3]*2+1] = ~SYM[0](~SYM[1][~SYM[3]*2:~SYM[3]*2+1]);
+end
+~ENDGENERATE
+
+logic [0:23] ~SYM[4];
+genvar ~SYM[5];
+~GENERATE
+for (~SYM[5]=0;~SYM[5]<8;~SYM[5]=~SYM[5]+1) begin : ~SYM[6]
+  localparam n = 2;
+  logic [3:0] i;
+  assign i = ~SYM[2][~SYM[5]*4:~SYM[5]*4+3];
+  always_comb begin
+    case (i[n-1+n])
+      1'b0    : ~SYM[4][~SYM[5]*3:~SYM[5]*3+2] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
+      default : ~SYM[4][~SYM[5]*3:~SYM[5]*3+2] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
+    endcase
+  end
+end
+~ENDGENERATE
+
+logic [0:15] ~SYM[9];
+genvar ~SYM[10];
+~GENERATE
+for (~SYM[10]=0;~SYM[10]<4;~SYM[10]=~SYM[10]+1) begin : ~SYM[11]
+  localparam n = 3;
+  logic [5:0] i;
+  assign i = ~SYM[4][~SYM[10]*6:~SYM[10]*6+5];
+  always_comb begin
+    case (i[n-1+n])
+      1'b0    : ~SYM[9][~SYM[10]*4:~SYM[10]*4+3] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
+      default : ~SYM[9][~SYM[10]*4:~SYM[10]*4+3] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
+    endcase
+  end
+end
+~ENDGENERATE
+
+logic [0:9] ~SYM[12];
+genvar ~SYM[13];
+~GENERATE
+for (~SYM[13]=0;~SYM[13]<2;~SYM[13]=~SYM[13]+1) begin : ~SYM[14]
+  localparam n = 4;
+  logic [7:0] i;
+  assign i = ~SYM[9][~SYM[13]*8:~SYM[13]*8+7];
+  always_comb begin
+    case (i[n-1+n])
+      1'b0    : ~SYM[12][~SYM[13]*5:~SYM[13]*5+4] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
+      default : ~SYM[12][~SYM[13]*5:~SYM[13]*5+4] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
+    endcase
+  end
+end
+~ENDGENERATE
+
+logic [0:5] ~SYM[7];
+~GENERATE
+if (1) begin
+localparam n = 5;
+logic [9:0] i;
+assign i = ~SYM[12][0:9];
+always_comb begin
+  case (i[n-1+n])
+    1'b0    : ~SYM[7] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
+    default : ~SYM[7] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
+  endcase
+end
+end
+~ENDGENERATE
+~FI
+assign ~RESULT = $unsigned(~SYM[7]);
+// clz end"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.ctz8#"
+    , "type"      : "ctz8 :: Word# -> Word#"
+    , "templateD" :
+"// ctz8 begin
+function [1:0] ~GENSYM[enc][0];
+  input [1:0] a;
+  case (a)
+    2'b00:   ~SYM[0] = 2'b10;
+    2'b01:   ~SYM[0] = 2'b01;
+    2'b10:   ~SYM[0] = 2'b00;
+    default: ~SYM[0] = 2'b00;
+  endcase
+endfunction
+
+logic [0:7] ~GENSYM[v][1];
+genvar ~GENSYM[k][18];
+~GENERATE
+for (~SYM[18]=0;~SYM[18]<8;~SYM[18]=~SYM[18]+1) begin : ~GENSYM[reverse][19]
+  assign ~SYM[1][~SYM[18]] = ~ARG[0][~SYM[18]];
+end
+~ENDGENERATE
+
+logic [0:7] ~GENSYM[e][2];
+genvar ~GENSYM[i][3];
+~GENERATE
+for (~SYM[3]=0;~SYM[3]<4;~SYM[3]=~SYM[3]+1) begin : ~GENSYM[enc_stage][8]
+  assign ~SYM[2][~SYM[3]*2:~SYM[3]*2+1] = ~SYM[0](~SYM[1][~SYM[3]*2:~SYM[3]*2+1]);
+end
+~ENDGENERATE
+
+logic [0:5] ~GENSYM[a][4];
+genvar ~GENSYM[i1][5];
+~GENERATE
+for (~SYM[5]=0;~SYM[5]<2;~SYM[5]=~SYM[5]+1) begin : ~GENSYM[mux_stage][6]
+  localparam n = 2;
+  logic [3:0] i;
+  assign i = ~SYM[2][~SYM[5]*4:~SYM[5]*4+3];
+  always_comb begin
+    case (i[n-1+n])
+      1'b0    : ~SYM[4][~SYM[5]*3:~SYM[5]*3+2] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
+      default : ~SYM[4][~SYM[5]*3:~SYM[5]*3+2] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
+    endcase
+  end
+end
+~ENDGENERATE
+
+logic [0:3] ~GENSYM[res][7];
+~GENERATE
+if (1) begin
+localparam n = 3;
+logic [5:0] i;
+assign i = ~SYM[4][0:5];
+always_comb begin
+  case (i[n-1+n])
+    1'b0    : ~SYM[7] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
+    default : ~SYM[7] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
+  endcase
+end
+end
+~ENDGENERATE
+
+assign ~RESULT = $unsigned(~SYM[7]);
+// ctz8 end"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.ctz16#"
+    , "type"      : "ctz16 :: Word# -> Word#"
+    , "templateD" :
+"// ctz16 begin
+function [1:0] ~GENSYM[enc][0];
+  input [1:0] a;
+  case (a)
+    2'b00:   ~SYM[0] = 2'b10;
+    2'b01:   ~SYM[0] = 2'b01;
+    2'b10:   ~SYM[0] = 2'b00;
+    default: ~SYM[0] = 2'b00;
+  endcase
+endfunction
+
+logic [0:15] ~GENSYM[v][1];
+genvar ~GENSYM[k][18];
+~GENERATE
+for (~SYM[18]=0;~SYM[18]<16;~SYM[18]=~SYM[18]+1) begin : ~GENSYM[reverse][19]
+  assign ~SYM[1][~SYM[18]] = ~ARG[0][~SYM[18]];
+end
+~ENDGENERATE
+
+logic [0:15] ~GENSYM[e][2];
+genvar ~GENSYM[i][3];
+~GENERATE
+for (~SYM[3]=0;~SYM[3]<8;~SYM[3]=~SYM[3]+1) begin : ~GENSYM[enc_stage][8]
+  assign ~SYM[2][~SYM[3]*2:~SYM[3]*2+1] = ~SYM[0](~SYM[1][~SYM[3]*2:~SYM[3]*2+1]);
+end
+~ENDGENERATE
+
+logic [0:11] ~GENSYM[a][4];
+genvar ~GENSYM[i1][5];
+~GENERATE
+for (~SYM[5]=0;~SYM[5]<4;~SYM[5]=~SYM[5]+1) begin : ~GENSYM[mux_stage][6]
+  localparam n = 2;
+  logic [3:0] i;
+  assign i = ~SYM[2][~SYM[5]*4:~SYM[5]*4+3];
+  always_comb begin
+    case (i[n-1+n])
+      1'b0    : ~SYM[4][~SYM[5]*3:~SYM[5]*3+2] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
+      default : ~SYM[4][~SYM[5]*3:~SYM[5]*3+2] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
+    endcase
+  end
+end
+~ENDGENERATE
+
+logic [0:7] ~GENSYM[b][9];
+genvar ~GENSYM[i2][10];
+~GENERATE
+for (~SYM[10]=0;~SYM[10]<2;~SYM[10]=~SYM[10]+1) begin : ~GENSYM[mux_stage2][11]
+  localparam n = 3;
+  logic [5:0] i;
+  assign i = ~SYM[4][~SYM[10]*6:~SYM[10]*6+5];
+  always_comb begin
+    case (i[n-1+n])
+      1'b0    : ~SYM[9][~SYM[10]*4:~SYM[10]*4+3] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
+      default : ~SYM[9][~SYM[10]*4:~SYM[10]*4+3] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
+    endcase
+  end
+end
+~ENDGENERATE
+
+logic [0:4] ~GENSYM[res][7];
+~GENERATE
+if (1) begin
+localparam n = 4;
+logic [7:0] i;
+assign i = ~SYM[9][0:7];
+always_comb begin
+  case (i[n-1+n])
+    1'b0    : ~SYM[7] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
+    default : ~SYM[7] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
+  endcase
+end
+end
+~ENDGENERATE
+
+assign ~RESULT = $unsigned(~SYM[7]);
+// ctz16 end"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.ctz32#"
+    , "type"      : "ctz32 :: Word# -> Word#"
+    , "templateD" :
+"// ctz32 begin
+function [1:0] ~GENSYM[enc][0];
+  input [1:0] a;
+  case (a)
+    2'b00:   ~SYM[0] = 2'b10;
+    2'b01:   ~SYM[0] = 2'b01;
+    2'b10:   ~SYM[0] = 2'b00;
+    default: ~SYM[0] = 2'b00;
+  endcase
+endfunction
+
+logic [0:31] ~GENSYM[v][1];
+genvar ~GENSYM[k][18];
+~GENERATE
+for (~SYM[18]=0;~SYM[18]<32;~SYM[18]=~SYM[18]+1) begin : ~GENSYM[reverse][19]
+  assign ~SYM[1][~SYM[18]] = ~ARG[0][~SYM[18]];
+end
+~ENDGENERATE
+
+logic [0:31] ~GENSYM[e][2];
+genvar ~GENSYM[i][3];
+~GENERATE
+for (~SYM[3]=0;~SYM[3]<16;~SYM[3]=~SYM[3]+1) begin : ~GENSYM[enc_stage][8]
+  assign ~SYM[2][~SYM[3]*2:~SYM[3]*2+1] = ~SYM[0](~SYM[1][~SYM[3]*2:~SYM[3]*2+1]);
+end
+~ENDGENERATE
+
+logic [0:23] ~GENSYM[a][4];
+genvar ~GENSYM[i1][5];
+~GENERATE
+for (~SYM[5]=0;~SYM[5]<8;~SYM[5]=~SYM[5]+1) begin : ~GENSYM[mux_stage][6]
+  localparam n = 2;
+  logic [3:0] i;
+  assign i = ~SYM[2][~SYM[5]*4:~SYM[5]*4+3];
+  always_comb begin
+    case (i[n-1+n])
+      1'b0    : ~SYM[4][~SYM[5]*3:~SYM[5]*3+2] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
+      default : ~SYM[4][~SYM[5]*3:~SYM[5]*3+2] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
+    endcase
+  end
+end
+~ENDGENERATE
+
+logic [0:15] ~GENSYM[b][9];
+genvar ~GENSYM[i2][10];
+~GENERATE
+for (~SYM[10]=0;~SYM[10]<4;~SYM[10]=~SYM[10]+1) begin : ~GENSYM[mux_stage2][11]
+  localparam n = 3;
+  logic [5:0] i;
+  assign i = ~SYM[4][~SYM[10]*6:~SYM[10]*6+5];
+  always_comb begin
+    case (i[n-1+n])
+      1'b0    : ~SYM[9][~SYM[10]*4:~SYM[10]*4+3] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
+      default : ~SYM[9][~SYM[10]*4:~SYM[10]*4+3] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
+    endcase
+  end
+end
+~ENDGENERATE
+
+logic [0:9] ~GENSYM[c][12];
+genvar ~GENSYM[i3][13];
+~GENERATE
+for (~SYM[13]=0;~SYM[13]<2;~SYM[13]=~SYM[13]+1) begin : ~GENSYM[mux_stage3][14]
+  localparam n = 4;
+  logic [7:0] i;
+  assign i = ~SYM[9][~SYM[13]*8:~SYM[13]*8+7];
+  always_comb begin
+    case (i[n-1+n])
+      1'b0    : ~SYM[12][~SYM[13]*5:~SYM[13]*5+4] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
+      default : ~SYM[12][~SYM[13]*5:~SYM[13]*5+4] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
+    endcase
+  end
+end
+~ENDGENERATE
+
+logic [0:5] ~GENSYM[res][7];
+~GENERATE
+if (1) begin
+localparam n = 5;
+logic [9:0] i;
+assign i = ~SYM[12][0:9];
+always_comb begin
+  case (i[n-1+n])
+    1'b0    : ~SYM[7] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
+    default : ~SYM[7] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
+  endcase
+end
+end
+~ENDGENERATE
+
+assign ~RESULT = $unsigned(~SYM[7]);
+// ctz32 end"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.ctz64#"
+    , "type"      : "ctz64 :: Word# -> Word#"
+    , "templateD" :
+"// ctz64 begin
+function [1:0] ~GENSYM[enc][0];
+  input [1:0] a;
+  case (a)
+    2'b00:   ~SYM[0] = 2'b10;
+    2'b01:   ~SYM[0] = 2'b01;
+    2'b10:   ~SYM[0] = 2'b00;
+    default: ~SYM[0] = 2'b00;
+  endcase
+endfunction
+
+logic [0:63] ~GENSYM[v][1];
+genvar ~GENSYM[k][18];
+~GENERATE
+for (~SYM[18]=0;~SYM[18]<64;~SYM[18]=~SYM[18]+1) begin : ~GENSYM[reverse][19]
+  assign ~SYM[1][~SYM[18]] = ~ARG[0][~SYM[18]];
+end
+~ENDGENERATE
+
+logic [0:63] ~GENSYM[e][2];
+genvar ~GENSYM[i][3];
+~GENERATE
+for (~SYM[3]=0;~SYM[3]<32;~SYM[3]=~SYM[3]+1) begin : ~GENSYM[enc_stage][8]
+  assign ~SYM[2][~SYM[3]*2:~SYM[3]*2+1] = ~SYM[0](~SYM[1][~SYM[3]*2:~SYM[3]*2+1]);
+end
+~ENDGENERATE
+
+logic [0:47] a;
+genvar ~GENSYM[i1][5];
+~GENERATE
+for (~SYM[5]=0;~SYM[5]<16;~SYM[5]=~SYM[5]+1) begin : ~GENSYM[mux_stage][6]
+  localparam n = 2;
+  logic [3:0] i;
+  assign i = ~SYM[2][~SYM[5]*4:~SYM[5]*4+3];
+  always_comb begin
+    case (i[n-1+n])
+      1'b0    : ~SYM[4][~SYM[5]*3:~SYM[5]*3+2] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
+      default : ~SYM[4][~SYM[5]*3:~SYM[5]*3+2] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
+    endcase
+  end
+end
+~ENDGENERATE
+
+logic [0:31] ~GENSYM[b][9];
+genvar ~GENSYM[i2][10];
+~GENERATE
+for (~SYM[10]=0;~SYM[10]<8;~SYM[10]=~SYM[10]+1) begin : ~GENSYM[mux_stage2][11]
+  localparam n = 3;
+  logic [5:0] i;
+  assign i = ~SYM[4][~SYM[10]*6:~SYM[10]*6+5];
+  always_comb begin
+    case (i[n-1+n])
+      1'b0    : ~SYM[9][~SYM[10]*4:~SYM[10]*4+3] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
+      default : ~SYM[9][~SYM[10]*4:~SYM[10]*4+3] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
+    endcase
+  end
+end
+~ENDGENERATE
+
+logic [0:19] ~GENSYM[c][12];
+genvar ~GENSYM[i3][13];
+~GENERATE
+for (~SYM[13]=0;~SYM[13]<4;~SYM[13]=~SYM[13]+1) begin : ~GENSYM[mux_stage3][14]
+  localparam n = 4;
+  logic [7:0] i;
+  assign i = ~SYM[9][~SYM[13]*8:~SYM[13]*8+7];
+  always_comb begin
+    case (i[n-1+n])
+      1'b0    : ~SYM[12][~SYM[13]*5:~SYM[13]*5+4] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
+      default : ~SYM[12][~SYM[13]*5:~SYM[13]*5+4] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
+    endcase
+  end
+end
+~ENDGENERATE
+
+logic [0:11] ~GENSYM[d][15];
+genvar ~GENSYM[i4][16];
+~GENERATE
+for (~SYM[16]=0;~SYM[16]<2;~SYM[16]=~SYM[16]+1) begin : ~GENSYM[mux_stage4][17]
+  localparam n = 5;
+  logic [9:0] i;
+  assign i = ~SYM[12][~SYM[16]*10:~SYM[16]*10+9];
+  always_comb begin
+    case (i[n-1+n])
+      1'b0    : ~SYM[15][~SYM[16]*6:~SYM[16]*6+5] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
+      default : ~SYM[15][~SYM[16]*6:~SYM[16]*6+5] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
+    endcase
+  end
+end
+~ENDGENERATE
+
+logic [0:6] ~GENSYM[res][7];
+~GENERATE
+if (1) begin
+localparam n = 6;
+logic [11:0] i;
+assign i = ~SYM[15][0:11];
+always_comb begin
+  case (i[n-1+n])
+    1'b0    : ~SYM[7] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
+    default : ~SYM[7] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
+  endcase
+end
+end
+~ENDGENERATE
+
+assign ~RESULT = $unsigned(~SYM[7]);
+// ctz64 end"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.ctz#"
+    , "type"      : "ctz :: Word# -> Word#"
+    , "templateD" :
+"// ctz begin
+function [1:0] ~GENSYM[enc][0];
+  input [1:0] a;
+  case (a)
+    2'b00:   ~SYM[0] = 2'b10;
+    2'b01:   ~SYM[0] = 2'b01;
+    2'b10:   ~SYM[0] = 2'b00;
+    default: ~SYM[0] = 2'b00;
+  endcase
+endfunction
+~IF ~IW64 ~THEN
+logic [0:63] ~GENSYM[v][1];
+genvar ~GENSYM[k][18];
+~GENERATE
+for (~SYM[18]=0;~SYM[18]<64;~SYM[18]=~SYM[18]+1) begin : ~GENSYM[reverse][19]
+  assign ~SYM[1][~SYM[18]] = ~ARG[0][~SYM[18]];
+end
+~ENDGENERATE
+
+logic [0:63] ~GENSYM[e][2];
+genvar ~GENSYM[i][3];
+~GENERATE
+for (~SYM[3]=0;~SYM[3]<32;~SYM[3]=~SYM[3]+1) begin : ~GENSYM[enc_stage][8]
+  assign ~SYM[2][~SYM[3]*2:~SYM[3]*2+1] = ~SYM[0](~SYM[1][~SYM[3]*2:~SYM[3]*2+1]);
+end
+~ENDGENERATE
+
+logic [0:47] ~GENSYM[a][4];
+genvar ~GENSYM[i1][5];
+~GENERATE
+for (~SYM[5]=0;~SYM[5]<16;~SYM[5]=~SYM[5]+1) begin : ~GENSYM[mux_stage][6]
+  localparam n = 2;
+  logic [3:0] i;
+  assign i = ~SYM[2][~SYM[5]*4:~SYM[5]*4+3];
+  always_comb begin
+    case (i[n-1+n])
+      1'b0    : ~SYM[4][~SYM[5]*3:~SYM[5]*3+2] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
+      default : ~SYM[4][~SYM[5]*3:~SYM[5]*3+2] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
+    endcase
+  end
+end
+~ENDGENERATE
+
+logic [0:31] ~GENSYM[b][9];
+genvar ~GENSYM[i2][10];
+~GENERATE
+for (~SYM[10]=0;~SYM[10]<8;~SYM[10]=~SYM[10]+1) begin : ~GENSYM[mux_stage2][11]
+  localparam n = 3;
+  logic [5:0] i;
+  assign i = ~SYM[4][~SYM[10]*6:~SYM[10]*6+5];
+  always_comb begin
+    case (i[n-1+n])
+      1'b0    : ~SYM[9][~SYM[10]*4:~SYM[10]*4+3] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
+      default : ~SYM[9][~SYM[10]*4:~SYM[10]*4+3] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
+    endcase
+  end
+end
+~ENDGENERATE
+
+logic [0:19] ~GENSYM[c][12];
+genvar ~GENSYM[i3][13];
+~GENERATE
+for (~SYM[13]=0;~SYM[13]<4;~SYM[13]=~SYM[13]+1) begin : ~GENSYM[mux_stage3][14]
+  localparam n = 4;
+  logic [7:0] i;
+  assign i = ~SYM[9][~SYM[13]*8:~SYM[13]*8+7];
+  always_comb begin
+    case (i[n-1+n])
+      1'b0    : ~SYM[12][~SYM[13]*5:~SYM[13]*5+4] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
+      default : ~SYM[12][~SYM[13]*5:~SYM[13]*5+4] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
+    endcase
+  end
+end
+~ENDGENERATE
+
+logic [0:11] ~GENSYM[d][15];
+genvar ~GENSYM[i4][16];
+~GENERATE
+for (~SYM[16]=0;~SYM[16]<2;~SYM[16]=~SYM[16]+1) begin : ~GENSYM[mux_stage4][17]
+  localparam n = 5;
+  logic [9:0] i;
+  assign i = ~SYM[12][~SYM[16]*10:~SYM[16]*10+9];
+  always_comb begin
+    case (i[n-1+n])
+      1'b0    : ~SYM[15][~SYM[16]*6:~SYM[16]*6+5] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
+      default : ~SYM[15][~SYM[16]*6:~SYM[16]*6+5] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
+    endcase
+  end
+end
+~ENDGENERATE
+
+logic [0:6] ~GENSYM[res][7];
+~GENERATE
+if (1) begin
+localparam n = 6;
+logic [11:0] i;
+assign i = ~SYM[15][0:11];
+always_comb begin
+  case (i[n-1+n])
+    1'b0    : ~SYM[7] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
+    default : ~SYM[7] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
+  endcase
+end
+end
+~ENDGENERATE
+~ELSE
+logic [0:31] ~SYM[1];
+genvar ~SYM[18];
+~GENERATE
+for (~SYM[18]=0;~SYM[18]<32;~SYM[18]=~SYM[18]+1) begin : ~SYM[19]
+  assign ~SYM[1][~SYM[18]] = ~ARG[0][~SYM[18]];
+end
+~ENDGENERATE
+
+logic [0:31] ~SYM[2];
+genvar ~SYM[3];
+~GENERATE
+for (~SYM[3]=0;~SYM[3]<16;~SYM[3]=~SYM[3]+1) begin : ~SYM[8]
+  assign ~SYM[2][~SYM[3]*2:~SYM[3]*2+1] = ~SYM[0](~SYM[1][~SYM[3]*2:~SYM[3]*2+1]);
+end
+~ENDGENERATE
+
+logic [0:23] ~SYM[4];
+genvar ~SYM[5];
+~GENERATE
+for (~SYM[5]=0;~SYM[5]<8;~SYM[5]=~SYM[5]+1) begin : ~SYM[6]
+  localparam n = 2;
+  logic [3:0] i;
+  assign i = ~SYM[2][~SYM[5]*4:~SYM[5]*4+3];
+  always_comb begin
+    case (i[n-1+n])
+      1'b0    : ~SYM[4][~SYM[5]*3:~SYM[5]*3+2] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
+      default : ~SYM[4][~SYM[5]*3:~SYM[5]*3+2] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
+    endcase
+  end
+end
+~ENDGENERATE
+
+logic [0:15] ~SYM[9];
+genvar ~SYM[10];
+~GENERATE
+for (~SYM[10]=0;~SYM[10]<4;~SYM[10]=~SYM[10]+1) begin : ~SYM[11]
+  localparam n = 3;
+  logic [5:0] i;
+  assign i = ~SYM[4][~SYM[10]*6:~SYM[10]*6+5];
+  always_comb begin
+    case (i[n-1+n])
+      1'b0    : ~SYM[9][~SYM[10]*4:~SYM[10]*4+3] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
+      default : ~SYM[9][~SYM[10]*4:~SYM[10]*4+3] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
+    endcase
+  end
+end
+~ENDGENERATE
+
+logic [0:9] ~SYM[12];
+genvar ~SYM[13];
+~GENERATE
+for (~SYM[13]=0;~SYM[13]<2;~SYM[13]=~SYM[13]+1) begin : ~SYM[14]
+  localparam n = 4;
+  logic [7:0] i;
+  assign i = ~SYM[9][~SYM[13]*8:~SYM[13]*8+7];
+  always_comb begin
+    case (i[n-1+n])
+      1'b0    : ~SYM[12][~SYM[13]*5:~SYM[13]*5+4] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
+      default : ~SYM[12][~SYM[13]*5:~SYM[13]*5+4] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
+    endcase
+  end
+end
+~ENDGENERATE
+
+logic [0:5] ~SYM[7];
+~GENERATE
+if (1) begin
+localparam n = 5;
+logic [9:0] i;
+assign i = ~SYM[12][0:9];
+always_comb begin
+  case (i[n-1+n])
+    1'b0    : ~SYM[7] = {i[n-1+n] && i[n-1],1'b0,i[2*n-2:n]};
+    default : ~SYM[7] = {i[n-1+n] && i[n-1],~ i[n-1],i[n-2:0]};
+  endcase
+end
+end
+~ENDGENERATE
+~FI
+assign ~RESULT = $unsigned(~SYM[7]);
+// ctz end"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.byteSwap16#"
+    , "type"      : "byteSwap16# :: Word# -> Word#"
+    , "templateD" :
+"// byteSwap16 begin
+~SIGDO[~GENSYM[w][0]];
+assign ~SYM[0] = ~ARG[0];~IF ~IW64 ~THEN
+assign ~RESULT = {~SYM[0][63:16],~SYM[0][7:0],~SYM[0][15:8]};~ELSE
+assign ~RESULT = {~SYM[0][31:16],~SYM[0][7:0],~SYM[0][15:8]};~FI
+// byteSwap16 end"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.byteSwap32#"
+    , "type"      : "byteSwap32# :: Word# -> Word#"
+    , "templateD" :
+"// byteSwap32 begin
+~SIGDO[~GENSYM[w][0]];
+assign ~SYM[0] = ~ARG[0];~IF ~IW64 ~THEN
+assign ~RESULT = {~SYM[0][63:32],~SYM[0][7:0],~SYM[0][15:8],~SYM[0][23:16],~SYM[0][31:24]};~ELSE
+assign ~RESULT = {~SYM[0][7:0],~SYM[0][15:8],~SYM[0][23:16],~SYM[0][31:24]};~FI
+// byteSwap32 end"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.byteSwap64#"
+    , "type"      : "byteSwap64# :: Word# -> Word#"
+    , "templateD" :
+"// byteSwap64 begin
+~SIGDO[~GENSYM[w][1]];
+assign ~SYM[1] = ~ARG[0];
+assign ~RESULT = {~SYM[1][7:0],~SYM[1][15:8],~SYM[1][23:16],~SYM[1][31:24]
+                 ,~SYM[1][39:32],~SYM[1][47:40],~SYM[1][55:48],~SYM[1][63:56]};
+// byteSwap64 end"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.byteSwap#"
+    , "type"      : "byteSwap# :: Word# -> Word#"
+    , "templateD" :
+"// byteSwap begin
+~SIGDO[~GENSYM[w][1]];
+assign ~SYM[1] = ~ARG[0];~IF ~IW64 ~THEN
+assign ~RESULT = {~SYM[1][7:0],~SYM[1][15:8],~SYM[1][23:16],~SYM[1][31:24]
+                 ,~SYM[1][39:32],~SYM[1][47:40],~SYM[1][55:48],~SYM[1][63:56]};~ELSE
+assign ~RESULT = {~SYM[1][7:0],~SYM[1][15:8],~SYM[1][23:16],~SYM[1][31:24]};~FI
+// byteSwap end"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.narrow8Int#"
+    , "type"      : "narrow8Int# :: Int# -> Int#"
+    , "templateD" :
+"// narrow8Int begin
+~SIGD[~GENSYM[s][0]][0];
+assign ~SYM[0] = ~ARG[0];
+
+assign ~RESULT = $signed(~SYM[0][7:0]);
+// narrow8Int end"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.narrow16Int#"
+    , "type"      : "narrow16Int# :: Int# -> Int#"
+    , "templateD" :
+"// narrow16Int begin
+~SIGD[~GENSYM[s][0]][0];
+assign ~SYM[0] = ~ARG[0];
+
+assign ~RESULT = $signed(~SYM[0][15:0]);
+// narrow16Int end"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.narrow32Int#"
+    , "type"      : "narrow32Int# :: Int# -> Int#"
+    , "templateD" :
+"// narrow32Int begin
+~SIGD[~GENSYM[s][0]][0];
+assign ~SYM[0] = ~ARG[0];
+
+assign ~RESULT = $signed(~SYM[0][31:0]);
+// narrow32Int end"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.narrow8Word#"
+    , "type"      : "narrow8Int# :: Word# -> Word#"
+    , "templateD" :
+"// narrow8Word begin
+~SIGD[~GENSYM[w][0]][0];
+assign ~SYM[0] = ~ARG[0];
+
+assign ~RESULT = $unsigned(~SYM[0][7:0]);
+// narrow8Word end"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.narrow16Word#"
+    , "type"      : "narrow16Word# :: Word# -> Word#"
+    , "templateD" :
+"// narrow16Word begin
+~SIGD[~GENSYM[w][0]][0];
+assign ~SYM[0] = ~ARG[0];
+
+assign ~RESULT = $unsigned(~SYM[0][15:0]);
+// narrow16Word end"
+    }
+  }
+, { "BlackBox" :
+    { "name"      : "GHC.Prim.narrow32Word#"
+    , "type"      : "narrow32Int# :: Word# -> Word#"
+    , "templateD" :
+"// narrow32Word begin
+~SIGD[~GENSYM[w][0]][0];
 assign ~SYM[0] = ~ARG[0];
 
 assign ~RESULT = $unsigned(~SYM[0][31:0]);
diff --git a/src/CLaSH/Backend/SystemVerilog.hs b/src/CLaSH/Backend/SystemVerilog.hs
--- a/src/CLaSH/Backend/SystemVerilog.hs
+++ b/src/CLaSH/Backend/SystemVerilog.hs
@@ -7,6 +7,7 @@
 -}
 
 {-# LANGUAGE CPP               #-}
+{-# LANGUAGE LambdaCase        #-}
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE RecursiveDo       #-}
 {-# LANGUAGE TemplateHaskell   #-}
@@ -17,23 +18,26 @@
 
 import qualified Control.Applicative                  as A
 import           Control.Lens                         hiding (Indexed)
-import           Control.Monad                        (join,liftM,zipWithM)
+import           Control.Monad                        (liftM,zipWithM)
 import           Control.Monad.State                  (State)
 import           Data.Graph.Inductive                 (Gr, mkGraph, topsort')
 import           Data.HashMap.Lazy                    (HashMap)
 import qualified Data.HashMap.Lazy                    as HashMap
 import           Data.HashSet                         (HashSet)
 import qualified Data.HashSet                         as HashSet
-import           Data.List                            (mapAccumL,nubBy)
+import           Data.List                            (nubBy)
 import           Data.Maybe                           (catMaybes,mapMaybe)
 import           Data.Text.Lazy                       (pack,unpack)
+import qualified Data.Text.Lazy                       as Text
 import           Prelude                              hiding ((<$>))
 import           Text.PrettyPrint.Leijen.Text.Monadic
 
 import           CLaSH.Backend
+import           CLaSH.Netlist.BlackBox.Types         (HdlSyn (..))
 import           CLaSH.Netlist.BlackBox.Util          (extractLiterals, renderBlackBox)
+import           CLaSH.Netlist.Id                     (mkBasicId')
 import           CLaSH.Netlist.Types                  hiding (_intWidth, intWidth)
-import           CLaSH.Netlist.Util
+import           CLaSH.Netlist.Util                   hiding (mkBasicId)
 import           CLaSH.Util                           (curLoc, makeCached, (<:>))
 
 #ifdef CABAL
@@ -46,16 +50,20 @@
 data SystemVerilogState =
   SystemVerilogState
     { _tyCache   :: HashSet HWType -- ^ Previously encountered  HWTypes
-    , _tyCount   :: Int -- ^ Product type counter
+    , _tySeen    :: [Identifier] -- ^ Product type counter
     , _nameCache :: HashMap HWType Doc -- ^ Cache for previously generated product type names
     , _genDepth  :: Int -- ^ Depth of current generative block
+    , _modNm     :: String
+    , _idSeen    :: [Identifier]
+    , _oports    :: [Identifier]
     , _intWidth  :: Int -- ^ Int/Word/Integer bit-width
+    , _hdlsyn    :: HdlSyn
     }
 
 makeLenses ''SystemVerilogState
 
 instance Backend SystemVerilogState where
-  initBackend     = SystemVerilogState HashSet.empty 0 HashMap.empty 0
+  initBackend     = SystemVerilogState HashSet.empty [] HashMap.empty 0 "" [] []
 #ifdef CABAL
   primDir         = const (Paths_clash_systemverilog.getDataFileName "primitives")
 #else
@@ -84,29 +92,73 @@
   inst            = inst_
   expr            = expr_
   iwWidth         = use intWidth
-  toBV hty id_    = verilogTypeMark hty <> "_to_lv" <> parens (text id_)
-  fromBV hty id_  = fromSLV hty id_ (typeSize hty - 1) 0
+  toBV hty id_    = toSLV hty (Identifier id_ Nothing)
+  fromBV hty id_  = simpleFromSLV hty id_
+  hdlSyn          = use hdlsyn
+  mkBasicId       = return (filterReserved . mkBasicId' True)
+  setModName nm s = s {_modNm = nm}
 
 type SystemVerilogM a = State SystemVerilogState a
 
+-- List of reserved SystemVerilog-2012 keywords
+reservedWords :: [Identifier]
+reservedWords = ["accept_on","alias","always","always_comb","always_ff"
+  ,"always_latch","and","assert","assign","assume","automatic","before","begin"
+  ,"bind","bins","binsof","bit","break","buf","bufif0","bufif1","byte","case"
+  ,"casex","casez","cell","chandle","checker","class","clocking","cmos","config"
+  ,"const","constraint","context","continue","cover","covergroup","coverpoint"
+  ,"cross","deassign","default","defparam","design","disable","dist","do","edge"
+  ,"else","end","endcase","endchecker","endclass","endclocking","endconfig"
+  ,"endfunction","endgenerate","endgroup","endinterface","endmodule","endpackage"
+  ,"endprimitive","endprogram","endproperty","endspecify","endsequence"
+  ,"endtable","endtask","enum","event","eventually","expect","export","extends"
+  ,"extern","final","first_match","for","force","foreach","forever","fork"
+  ,"forkjoin","function","generate","genvar","global","highz0","highz1","if"
+  ,"iff","ifnone","ignore_bins","illegal_bins","implements","implies","import"
+  ,"incdir","include","initial","inout","input","inside","instance","int"
+  ,"integer","interconnect","interface","intersect","join","join_any"
+  ,"join_none","large","let","liblist","library","local","localparam","logic"
+  ,"longint","macromodule","matches","medium","modport","module","nand"
+  ,"negedge","nettype","new","nexttime","nmos","nor","noshowcancelled","not"
+  ,"notif0","notif1","null","or","output","package","packed","parameter","pmos"
+  ,"posedge","primitive","priority","program","property","protected","pull0"
+  ,"pull1","pulldown","pullup","pulsestyle_ondetect","pulsestyle_onevent"
+  ,"pure","rand","randc","randcase","randsequence","rcmos","real","realtime"
+  ,"ref","reg","reject_on","release","repeat","restrict","return","rnmos"
+  ,"rpmos","rtran","rtranif0","rtranif1","s_always","s_eventually","s_nexttime"
+  ,"s_until","s_until_with","scalared","sequence","shortint","shortreal"
+  ,"showcancelled","signed","small","soft","solve","specify","specparam"
+  ,"static","string","strong","strong0","strong1","struct","super","supply0"
+  ,"supply1","sync_accept_on","sync_reject_on","table","tagged","task","this"
+  ,"throughout","time","timeprecision","timeunit","tran","tranif0","tranif1"
+  ,"tri","tri0","tri1","triand","trior","trireg","type","typedef","union"
+  ,"unique","unique0","unsigned","until","until_with","untyped","use","uwire"
+  ,"var","vectored","virtual","void","wait","wait_order","wand","weak","weak0"
+  ,"weak1","while","wildcard","wire","with","within","wor","xnor","xor"]
+
+filterReserved :: Identifier -> Identifier
+filterReserved s = if s `elem` reservedWords
+  then s `Text.append` "_r"
+  else s
+
 -- | Generate VHDL for a Netlist component
 genVerilog :: String -> Component -> SystemVerilogM (String,Doc)
-genVerilog modName c = (unpack cName,) A.<$> verilog
+genVerilog _ c = (unpack cName,) A.<$> verilog
   where
     cName   = componentName c
     verilog = "// Automatically generated SystemVerilog-2005" <$$>
-              tyImports modName <$$>
               module_ c
 
 -- | Generate a SystemVerilog package containing type definitions for the given HWTypes
 mkTyPackage_ :: String
              -> [HWType]
              -> SystemVerilogM [(String,Doc)]
-mkTyPackage_ modName hwtys = (:[]) A.<$> (modName ++ "_types",) A.<$>
-    "package" <+> modNameD <> "_types" <> semi <$>
-      indent 2 packageDec <$>
-      indent 2 funDecs <$>
-    "endpackage" <+> colon <+> modNameD <> "_types"
+mkTyPackage_ modName hwtys =
+    (:[]) A.<$> (modName ++ "_types",) A.<$>
+       "package" <+> modNameD <> "_types" <> semi <$>
+         indent 2 packageDec <$>
+         indent 2 funDecs <$>
+       "endpackage" <+> colon <+> modNameD <> "_types"
   where
     modNameD    = text (pack modName)
     usedTys     = concatMap mkUsedTys hwtys
@@ -158,12 +210,20 @@
     edge _                 = []
 
 tyDec :: HWType -> SystemVerilogM Doc
-tyDec (Vector n elTy) = "typedef" <+> verilogType elTy <+>  "array_of_" <> int n <> "_" <> tyName elTy <+> brackets (int 0 <> colon <> int (n-1)) <> semi
-
+tyDec ty@(Vector n elTy) = do
+  syn <- hdlSyn
+  case syn of
+    Vivado -> "typedef" <+> "logic" <+> brackets (int (typeSize elTy - 1) <> colon <> int 0) <+>
+              tyName ty <+> brackets (int 0 <> colon <> int (n-1)) <> semi
+    _ -> do case splitVecTy ty of
+              Just (ns,elTy') -> do
+                let ranges = hcat (mapM (\n' -> brackets (int 0 <> colon <> int (n'-1))) (tail ns))
+                "typedef" <+> elTy' <+> ranges <+> tyName ty <+> brackets (int 0 <> colon <> int (head ns - 1)) <> semi
+              _ -> error $ $(curLoc) ++ "impossible"
 tyDec ty@(Product _ tys) = prodDec
   where
-    prodDec = "typedef struct {" <$>
-                indent 2 (vcat $ zipWithM (\x y -> sigDecl x y <> semi) selNames tys) <$>
+    prodDec = "typedef struct packed {" <$>
+                indent 2 (vcat $ zipWithM (\x y -> lvType y <+> x <> semi) selNames tys) <$>
               "}" <+> tName <> semi
 
     tName    = tyName ty
@@ -171,27 +231,80 @@
 
 tyDec _ = empty
 
+splitVecTy :: HWType -> Maybe ([Int],SystemVerilogM Doc)
+splitVecTy = fmap splitElemTy . go
+  where
+    splitElemTy (ns,t) = case t of
+      Product _ _ -> (ns, verilogType t)
+      Vector _ _  -> error $ $(curLoc) ++ "impossible"
+      Clock _ _   -> (ns, "logic")
+      Reset _ _   -> (ns, "logic")
+      String      -> (ns, "string")
+      Signed n    -> (ns ++ [n],"logic signed")
+      _           -> (ns ++ [typeSize t], "logic")
+
+    go (Vector n elTy) = case go elTy of
+      Just (ns,elTy') -> Just (n:ns,elTy')
+      _               -> Just ([n],elTy)
+    go _ = Nothing
+
+lvType :: HWType -> SystemVerilogM Doc
+lvType ty@(Vector n elTy) = do
+  syn <- hdlSyn
+  case syn of
+    Vivado -> "logic" <+> brackets (int 0 <> colon <> int (n-1)) <> brackets (int (typeSize elTy - 1) <> colon <> int 0)
+    _ -> case splitVecTy ty of
+      Just (ns,elTy') -> do
+        let ranges = hcat (mapM (\n' -> brackets (int 0 <> colon <> int (n'-1))) ns)
+        elTy' <> ranges
+      _ -> error $ $(curLoc) ++ "impossible"
+lvType ty = verilogType ty
+
 funDec :: HWType -> SystemVerilogM Doc
-funDec (Clock _ _) = empty
-funDec (Reset _ _) = empty
-funDec t =
-  "function logic" <+> brackets (int (typeSize t - 1) <> colon <> int 0)  <+> verilogTypeMark t <> "_to_lv" <> parens (sigDecl "i" t) <> semi <$>
-  indent 2 (verilogTypeMark t <> "_to_lv" <+> "=" <+>
-    (case t of
-       Vector n elTy -> listBraces (sequence [verilogTypeMark elTy <> "_to_lv" <> parens ("i" <> brackets (int i)) | i <- [0..(n-1)]])
-       Product _ tys -> listBraces (zipWithM (\elTy i -> verilogTypeMark elTy <> "_to_lv" <> parens ("i" <> dot <> verilogTypeMark t <> "_sel" <> int i)) tys [0..])
-       _             -> "i")
-       <> semi) <$>
+funDec ty@(Vector n elTy) =
+  "function" <+> "logic" <+> ranges <+> tName <> "_to_lv" <> parens (sigDecl "i" ty) <> semi <$>
+  indent 2
+    ("for" <+> parens ("int n = 0" <> semi <+> "n <" <+> int n <> semi <+> "n=n+1") <$>
+      indent 2 (tName <> "_to_lv" <> brackets "n" <+> "=" <+> "i[n]" <> semi)) <$>
+  "endfunction" <$>
+  "function" <+> tName <+> tName <> "_from_lv" <> parens ("logic" <+> ranges <+> "i") <> semi <$>
+  indent 2
+    ("for" <+> parens ("int n = 0" <> semi <+> "n <" <+> int n <> semi <+> "n=n+1") <$>
+      indent 2 (tName <> "_from_lv" <> brackets "n" <+> "=" <+> "i[n]" <> semi)) <$>
+  "endfunction" <$>
+  "function" <+> tName <+> tName <> "_cons" <> parens (sigDecl "x" elTy <> comma <> vecSigDecl "xs") <> semi <$>
+  indent 2
+    (tName <> "_cons" <> brackets (int 0) <+> "=" <+> (toSLV elTy (Identifier "x" Nothing)) <> semi <$>
+     tName <> "_cons" <> brackets (int 1 <> colon <> int (n-1)) <+> "=" <+> "xs" <> semi) <$>
   "endfunction"
+  where
+    tName  = tyName ty
+    ranges = brackets (int 0 <> colon <> int (n-1)) <>
+             brackets (int (typeSize elTy - 1) <> colon <> int 0)
 
-tyImports :: String -> SystemVerilogM Doc
-tyImports modName = "import" <+> text (pack modName) <> "_types::*;"
+    vecSigDecl :: SystemVerilogM Doc -> SystemVerilogM Doc
+    vecSigDecl d = do
+      syn <- hdlSyn
+      case syn of
+        Vivado -> "logic" <+> brackets (int (typeSize elTy - 1) <> colon <> int 0) <+>
+                  d <+> brackets (int 0 <> colon <> int (n-2))
+        _ -> do case splitVecTy ty of
+                  Just (ns,elTy') -> do
+                    let ranges' = hcat (mapM (\n' -> brackets (int 0 <> colon <> int (n'-1))) (tail ns))
+                    elTy' <+> ranges' <+> d <+> brackets (int 0 <> colon <> int (head ns - 2))
+                  _ -> error $ $(curLoc) ++ "impossible"
+funDec _ = empty
 
 module_ :: Component -> SystemVerilogM Doc
-module_ c =
-    "module" <+> text (componentName c) <> tupled ports <> semi <$>
-    indent 2 (inputPorts <$> outputPorts <$$> decls (declarations c)) <$$> insts (declarations c) <$>
-    "endmodule"
+module_ c = do
+    { addSeen c
+    ; m <- "module" <+> text (componentName c) <> tupled ports <> semi <$>
+           indent 2 (inputPorts <$> outputPorts <$$> decls (declarations c)) <$$> insts (declarations c) <$>
+           "endmodule"
+    ; idSeen .= []
+    ; oports .= []
+    ; return m
+    }
   where
     ports = sequence
           $ [ encodingNote hwty <$> text i | (i,hwty) <- inputs c ] ++
@@ -206,17 +319,49 @@
                    [] -> empty
                    p  -> vcat (punctuate semi (sequence [ "output" <+> sigDecl (text i) ty | (i,ty) <- p ])) <> semi
 
+addSeen :: Component -> SystemVerilogM ()
+addSeen c = do
+  let iport = map fst $ inputs c
+      hport = map fst $ hiddenPorts c
+      oport = map fst $ outputs c
+      nets  = mapMaybe (\case {NetDecl i _ -> Just i; _ -> Nothing}) $ declarations c
+  idSeen .= concat [iport,hport,oport,nets]
+  oports .= oport
+
+mkUniqueId :: Identifier -> SystemVerilogM Identifier
+mkUniqueId i = do
+  mkId <- mkBasicId
+  seen <- use idSeen
+  let i' = mkId i
+  case i `elem` seen of
+    True  -> go mkId seen i' 0
+    False -> do idSeen %= (i':)
+                return i'
+  where
+    go :: (Identifier -> Identifier) -> [Identifier] -> Identifier
+       -> Int -> SystemVerilogM Identifier
+    go mkId seen i' n = do
+      let i'' = mkId (Text.append i' (Text.pack ('_':show n)))
+      case i'' `elem` seen of
+        True  -> go mkId seen i' (n+1)
+        False -> do idSeen %= (i'':)
+                    return i''
+
 verilogType :: HWType -> SystemVerilogM Doc
 verilogType t = do
   tyCache %= HashSet.insert t
   case t of
-    (Vector _ _)  -> tyName t
-    (Product _ _) -> tyName t
-    (Signed n)    -> "logic signed" <+> brackets (int (n-1) <> colon <> int 0)
-    (Clock _ _)   -> "logic"
-    (Reset _ _)   -> "logic"
+    Product _ _   -> do
+      nm <- use modNm
+      text (pack nm) <> "_types::" <> tyName t
+    Vector _ _ -> do
+      nm <- use modNm
+      text (pack nm) <> "_types::" <> tyName t
+    Signed n      -> "logic signed" <+> brackets (int (n-1) <> colon <> int 0)
+    Clock _ _     -> "logic"
+    Reset _ _     -> "logic"
     String        -> "string"
-    _             -> "logic" <+> brackets (int (typeSize t -1) <> colon <> int 0)
+    _ -> "logic" <+> brackets (int (typeSize t -1) <> colon <> int 0)
 
 sigDecl :: SystemVerilogM Doc -> HWType -> SystemVerilogM Doc
 sigDecl d t = verilogType t <+> d
@@ -225,7 +370,12 @@
 verilogTypeMark :: HWType -> SystemVerilogM Doc
 verilogTypeMark t = do
   tyCache %= HashSet.insert t
-  tyName t
+  nm <- use modNm
+  let m = tyName t
+  case t of
+    Product _ _ -> text (pack nm) <> "_types::" <> m
+    Vector _ _ -> text (pack nm) <> "_types::" <> m
+    _ -> empty
 
 tyName :: HWType -> SystemVerilogM Doc
 tyName Bool              = "logic_vector_1"
@@ -235,27 +385,40 @@
 tyName (Signed n)        = "signed_" <> int n
 tyName (Unsigned n)      = "logic_vector_" <> int n
 tyName t@(Sum _ _)       = "logic_vector_" <> int (typeSize t)
-tyName t@(Product _ _)   = makeCached t nameCache prodName
+tyName t@(Product nm _)  = makeCached t nameCache prodName
   where
-    prodName = do i <- tyCount <<%= (+1)
-                  "product" <> int i
-tyName t@(SP _ _)        = "logic_vector_" <> int (typeSize t)
+    prodName = do
+      seen <- use tySeen
+      mkId <- mkBasicId
+      let nm'  = (mkId . last . Text.splitOn ".") nm
+          nm'' = if Text.null nm'
+                    then "product"
+                    else nm'
+          nm3  = if nm'' `elem` seen
+                    then go mkId seen (0::Integer) nm''
+                    else nm''
+      tySeen %= (nm3:)
+      text nm3
+
+    go mkId s i n =
+      let n' = n `Text.append` Text.pack ('_':show i)
+      in  if n' `elem` s
+             then go mkId s (i+1) n
+             else n'
+tyName t@(SP _ _)  = "logic_vector_" <> int (typeSize t)
 tyName (Clock _ _) = "logic"
 tyName (Reset _ _) = "logic"
 tyName t =  error $ $(curLoc) ++ "tyName: " ++ show t
 
 -- | Convert a Netlist HWType to an error VHDL value for that type
 verilogTypeErrValue :: HWType -> SystemVerilogM Doc
-verilogTypeErrValue Bool            = "1'bx"
-verilogTypeErrValue (Unsigned n)    = braces (int n <+> braces "1'bx")
-verilogTypeErrValue (Signed n)      = braces (int n <+> braces "1'bx")
-verilogTypeErrValue (Vector n elTy) = "'" <> braces (int n <+> braces (verilogTypeErrValue elTy))
-verilogTypeErrValue t@(Sum _ _)     = braces (int (typeSize t) <+> braces "1'bx")
-verilogTypeErrValue (Product _ elTys)   = "'" <> listBraces (mapM verilogTypeErrValue elTys)
-verilogTypeErrValue (BitVector 1)   = "1'bx"
-verilogTypeErrValue (BitVector n)   = braces (int n <+> braces "1'bx")
-verilogTypeErrValue t@(SP _ _)      = braces (int (typeSize t) <+> braces "1'bx")
-verilogTypeErrValue e = error $ $(curLoc) ++ "no error value defined for: " ++ show e
+verilogTypeErrValue (Vector n elTy) = do
+  syn <- hdlSyn
+  case syn of
+    Vivado -> braces (int n <+> braces (int (typeSize elTy) <+> braces "1'bx"))
+    _ -> braces (int n <+> braces (verilogTypeErrValue elTy))
+verilogTypeErrValue String = "\"ERROR\""
+verilogTypeErrValue ty  = braces (int (typeSize ty) <+> braces "1'bx")
 
 decls :: [Declaration] -> SystemVerilogM Doc
 decls [] = empty
@@ -279,33 +442,62 @@
 inst_ (Assignment id_ e) = fmap Just $
   "assign" <+> text id_ <+> equals <+> expr_ False e <> semi
 
-inst_ (CondAssignment id_ _ scrut _ [(Just (BoolLit b), l),(_,r)]) = fmap Just $
-    "always_comb begin" <$>
-    indent 2 ("if" <> parens (expr_ True scrut) <$>
-                (indent 2 $ text id_ <+> equals <+> expr_ False t <> semi) <$>
-             "else" <$>
-                (indent 2 $ text id_ <+> equals <+> expr_ False f <> semi)) <$>
-    "end"
+inst_ (CondAssignment id_ ty scrut _ [(Just (BoolLit b), l),(_,r)]) = fmap Just $ do
+    { syn <- hdlSyn
+    ; p   <- use oports
+    ; if syn == Vivado && id_ `elem` p
+         then do
+              { regId <- mkUniqueId (Text.append id_ "_reg")
+              ; verilogType ty <+> text regId <> semi <$>
+                "always_comb begin" <$>
+                indent 2 ("if" <> parens (expr_ True scrut) <$>
+                            (indent 2 $ text regId <+> equals <+> expr_ False t <> semi) <$>
+                         "else" <$>
+                            (indent 2 $ text regId <+> equals <+> expr_ False f <> semi)) <$>
+                "end" <$>
+                "assign" <+> text id_ <+> equals <+> text regId <> semi
+              }
+         else "always_comb begin" <$>
+              indent 2 ("if" <> parens (expr_ True scrut) <$>
+                          (indent 2 $ text id_ <+> equals <+> expr_ False t <> semi) <$>
+                       "else" <$>
+                          (indent 2 $ text id_ <+> equals <+> expr_ False f <> semi)) <$>
+              "end"
+    }
   where
     (t,f) = if b then (l,r) else (r,l)
 
-inst_ (CondAssignment id_ _ scrut scrutTy es) = fmap Just $
-    "always_comb begin" <$>
-    indent 2 ("case" <> parens (expr_ True scrut) <$>
-                (indent 2 $ vcat $ punctuate semi (conds es)) <> semi <$>
-              "endcase") <$>
-    "end"
+inst_ (CondAssignment id_ ty scrut scrutTy es) = fmap Just $ do
+    { syn <- hdlSyn
+    ; p <- use oports
+    ; if syn == Vivado && id_ `elem` p
+         then do
+           { regId <- mkUniqueId (Text.append id_ "_reg")
+           ; verilogType ty <+> text regId <> semi <$>
+             "always_comb begin" <$>
+             indent 2 ("case" <> parens (expr_ True scrut) <$>
+                         (indent 2 $ vcat $ punctuate semi (conds regId es)) <> semi <$>
+                       "endcase") <$>
+             "end" <$>
+             "assign" <+> text id_ <+> equals <+> text regId <> semi
+           }
+         else "always_comb begin" <$>
+              indent 2 ("case" <> parens (expr_ True scrut) <$>
+                          (indent 2 $ vcat $ punctuate semi (conds id_ es)) <> semi <$>
+                        "endcase") <$>
+              "end"
+    }
   where
-    conds :: [(Maybe Literal,Expr)] -> SystemVerilogM [Doc]
-    conds []                = return []
-    conds [(_,e)]           = ("default" <+> colon <+> text id_ <+> equals <+> expr_ False e) <:> return []
-    conds ((Nothing,e):_)   = ("default" <+> colon <+> text id_ <+> equals <+> expr_ False e) <:> return []
-    conds ((Just c ,e):es') = (exprLit (Just (scrutTy,conSize scrutTy)) c <+> colon <+> text id_ <+> equals <+> expr_ False e) <:> conds es'
+    conds :: Identifier -> [(Maybe Literal,Expr)] -> SystemVerilogM [Doc]
+    conds _ []                = return []
+    conds i [(_,e)]           = ("default" <+> colon <+> text i <+> equals <+> expr_ False e) <:> return []
+    conds i ((Nothing,e):_)   = ("default" <+> colon <+> text i <+> equals <+> expr_ False e) <:> return []
+    conds i ((Just c ,e):es') = (exprLit (Just (scrutTy,conSize scrutTy)) c <+> colon <+> text i <+> equals <+> expr_ False e) <:> conds i es'
 
 inst_ (InstDecl nm lbl pms) = fmap Just $
     text nm <+> text lbl <$$> pms' <> semi
   where
-    pms' = tupled $ sequence [dot <> text i <+> parens (expr_ False e) | (i,e) <- pms]
+    pms' = tupled $ sequence [dot <> text i <+> parens (expr_ False e) | (i,_,_,e) <- pms]
 
 inst_ (BlackBoxD _ bs bbCtx) = do
   t <- renderBlackBox bs bbCtx
@@ -328,15 +520,22 @@
     start    = typeSize ty - 1 - conSize ty - other
     end      = start - argSize + 1
 
-expr_ _ (Identifier id_ (Just (Indexed (ty@(Product _ _),_,fI)))) = text id_ <> dot <> verilogTypeMark ty <> "_sel" <> int fI
+expr_ _ (Identifier id_ (Just (Indexed (ty@(Product _ tys),_,fI)))) = do
+  id'<- fmap (displayT . renderOneLine) (text id_ <> dot <> tyName ty <> "_sel" <> int fI)
+  simpleFromSLV (tys !! fI) id'
 
-expr_ _ (Identifier id_ (Just (Indexed ((Vector _ _),1,1)))) = text id_ <> brackets (int 0)
+expr_ _ (Identifier id_ (Just (Indexed ((Vector _ elTy),1,1)))) = do
+  id' <- fmap (displayT . renderOneLine) (text id_ <> brackets (int 0))
+  simpleFromSLV elTy id'
+
 expr_ _ (Identifier id_ (Just (Indexed ((Vector n _),1,2)))) = text id_ <> brackets (int 1 <> colon <> int (n-1))
 
 -- This is a HACK for CLaSH.Driver.TopWrapper.mkOutput
 -- Vector's don't have a 10'th constructor, this is just so that we can
 -- recognize the particular case
-expr_ _ (Identifier id_ (Just (Indexed ((Vector _ _),10,fI)))) = text id_ <> brackets (int fI)
+expr_ _ (Identifier id_ (Just (Indexed ((Vector _ elTy),10,fI)))) = do
+  id' <- fmap (displayT . renderOneLine) (text id_ <> brackets (int fI))
+  simpleFromSLV elTy id'
 
 expr_ _ (Identifier id_ (Just (DC (ty@(SP _ _),_)))) = text id_ <> brackets (int start <> colon <> int end)
   where
@@ -345,15 +544,17 @@
 
 expr_ _ (Identifier id_ (Just _))                      = text id_
 
+expr_ b (DataCon _ (DC (Void, -1)) [e]) =  expr_ b e
+
 expr_ _ (DataCon (Vector 0 _) _ _) =
   error $ $(curLoc) ++ "SystemVerilog: Trying to create a Nil vector."
 
-expr_ _ (DataCon (Vector 1 _) _ [e]) = "'" <> braces (expr_ False e)
-expr_ _ e@(DataCon (Vector n _) _ [e1,e2]) = "'" <> case vectorChain e of
-                                                     Just es -> listBraces (mapM (expr_ False) es)
-                                                     Nothing -> let e2' = expr_ False e2
-                                                                in  listBraces $ sequence ((expr_ False e1):[e2' <> brackets (int i) | i <- [0..(n-2)] ])
+expr_ _ (DataCon (Vector 1 elTy) _ [e]) = "'" <> braces (toSLV elTy e)
 
+expr_ _ e@(DataCon ty@(Vector _ elTy) _ [e1,e2]) = case vectorChain e of
+  Just es -> "'" <> listBraces (mapM (toSLV elTy) es)
+  Nothing -> verilogTypeMark ty <> "_cons" <> parens (expr_ False e1 <> comma <+> expr_ False e2)
+
 expr_ _ (DataCon ty@(SP _ args) (DC (_,i)) es) = assignExpr
   where
     argTys     = snd $ args !! i
@@ -366,7 +567,7 @@
     assignExpr = braces (hcat $ punctuate comma $ sequence (dcExpr:argExprs ++ extraArg))
 
 expr_ _ (DataCon ty@(Sum _ _) (DC (_,i)) []) = int (typeSize ty) <> "'d" <> int i
-expr_ _ (DataCon ty@(Product _ _) _ es) = "'" <> listBraces (zipWithM (\i e -> verilogTypeMark ty <> "_sel" <> int i <> colon <+> expr_ False e) [0..] es)
+expr_ _ (DataCon (Product _ tys) _ es) = listBraces (zipWithM toSLV tys es)
 
 expr_ _ (BlackBoxE pNm _ bbCtx _)
   | pNm == "CLaSH.Sized.Internal.Signed.fromInteger#"
@@ -383,6 +584,11 @@
   , [Literal _ (NumLit n), Literal _ i] <- extractLiterals bbCtx
   = exprLit (Just (BitVector (fromInteger n),fromInteger n)) i
 
+expr_ _ (BlackBoxE pNm _ bbCtx _)
+  | pNm == "CLaSH.Sized.Internal.Index.fromInteger#"
+  , [Literal _ (NumLit n), Literal _ i] <- extractLiterals bbCtx
+  = exprLit (Just (Index (fromInteger n),fromInteger n)) i
+
 expr_ b (BlackBoxE _ bs bbCtx b') = do
   t <- renderBlackBox bs bbCtx
   parenIf (b || b') $ string t
@@ -460,45 +666,19 @@
 bit_char Z = char 'z'
 
 toSLV :: HWType -> Expr -> SystemVerilogM Doc
-toSLV t@(Product _ tys) (Identifier id_ Nothing) = do
-    selIds' <- sequence selIds
-    listBraces (zipWithM toSLV tys selIds')
-  where
-    tName    = verilogTypeMark t
-    selNames = map (fmap (displayT . renderOneLine) ) [text id_ <> dot <> tName <> "_sel" <> int i | i <- [0..(length tys)-1]]
-    selIds   = map (fmap (\n -> Identifier n Nothing)) selNames
-toSLV (Product _ tys) (DataCon _ _ es) = listBraces (zipWithM toSLV tys es)
-
-toSLV (Vector n elTy) (Identifier id_ Nothing) = do
-    selIds' <- sequence (reverse selIds)
-    listBraces (mapM (toSLV elTy) selIds')
-  where
-    selNames = map (fmap (displayT . renderOneLine) ) $ reverse [text id_ <> brackets (int i) | i <- [0 .. (n-1)]]
-    selIds   = map (fmap (`Identifier` Nothing)) selNames
-toSLV (Vector n elTy) (DataCon _ _ es) = listBraces (zipWithM toSLV [elTy,Vector (n-1) elTy] es)
-
-toSLV _ e = expr_ False e
+toSLV t e = case t of
+  Vector _ _ -> verilogTypeMark t <> "_to_lv" <> parens (expr_ False e)
+  _ -> expr_ False e
 
 fromSLV :: HWType -> Identifier -> Int -> Int -> SystemVerilogM Doc
-fromSLV t@(Product _ tys) id_ start _ = "'" <> listBraces (zipWithM (\s e -> s <> colon <+> e) selNames args)
-  where
-    tName      = tyName t
-    selNames   = [tName <> "_sel" <> int i | i <- [0..]]
-    argLengths = map typeSize tys
-    starts     = start : snd (mapAccumL ((join (,) .) . (-)) start argLengths)
-    ends       = map (+1) (tail starts)
-    args       = zipWith3 (`fromSLV` id_) tys starts ends
-
-fromSLV t@(Vector n elTy) id_ start _ = verilogTypeMark t <> "'" <> parens ("'" <> listBraces (fmap reverse args))
-  where
-    argLength = typeSize elTy
-    starts    = take (n + 1) $ iterate (subtract argLength) start
-    ends      = map (+1) (tail starts)
-    args      = zipWithM (fromSLV elTy id_) starts ends
-
+fromSLV t@(Vector _ _) id_ start end = verilogTypeMark t <> "_from_lv" <> parens (text id_ <> brackets (int start <> colon <> int end))
 fromSLV (Signed _) id_ start end = "$signed" <> parens (text id_ <> brackets (int start <> colon <> int end))
-
 fromSLV _ id_ start end = text id_ <> brackets (int start <> colon <> int end)
+
+simpleFromSLV :: HWType -> Identifier -> SystemVerilogM Doc
+simpleFromSLV t@(Vector _ _) id_ = verilogTypeMark t <> "_from_lv" <> parens (text id_)
+simpleFromSLV (Signed _) id_ = "$signed" <> parens (text id_)
+simpleFromSLV _ id_ = text id_
 
 dcToExpr :: HWType -> Int -> Expr
 dcToExpr ty i = Literal (Just (ty,conSize ty)) (NumLit (toInteger i))
