diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,12 @@
 # Changelog for the [`clash-vhdl`](http://hackage.haskell.org/package/clash-vhdl) package
 
-## 0.6.7
+## 0.6.8 *March 11th 2016*
+* Support `clash-lib` 0.6.11
+* 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.7 *February 10th 2016*
 * Fixes bugs:
   * insufficient type-qualifiers for concatenation operator [#121](https://github.com/clash-lang/clash-compiler/issues/121)
 
diff --git a/clash-vhdl.cabal b/clash-vhdl.cabal
--- a/clash-vhdl.cabal
+++ b/clash-vhdl.cabal
@@ -1,5 +1,5 @@
 Name:                 clash-vhdl
-Version:              0.6.7
+Version:              0.6.8
 Synopsis:             CAES Language for Synchronous Hardware - VHDL 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,9 +2,9 @@
     { "name"      : "CLaSH.TopWrapper.syncReset"
     , "templateD" :
 "-- reset ~RESULT is asynchronously asserted, but synchronously de-asserted
-resetSync_~SYM[0] : block
-  signal ~SYM[1] : ~TYP[0];
-  signal ~SYM[2] : ~TYP[0];
+~GENSYM[resetSync][0] : block
+  signal ~GENSYM[r1][1] : ~TYP[0];
+  signal ~GENSYM[r2][2] : ~TYP[0];
 begin
   process(~CLKO,~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,13 +12,13 @@
                -> Signal' clk (BitVector m)"
     , "templateD" :
 "-- blockRamFile begin
-blockRamFile_~COMPNAME_~SYM[0] : block
-  type RamType is array(natural range <>) of bit_vector(~LIT[0]-1 downto 0);
+~GENSYM[~COMPNAME_blockRamFile][0] : block
+  type ~GENSYM[RamType][6] is array(natural range <>) of bit_vector(~LIT[0]-1 downto 0);
 
-  impure function InitRamFromFile (RamFileName : in string) return RamType is
+  impure function ~GENSYM[InitRamFromFile][1] (RamFileName : in string) return ~SYM[6] is
     FILE RamFile : text open read_mode is RamFileName;
     variable RamFileLine : line;
-    variable RAM : RamType(0 to ~LIT[2]-1);
+    variable RAM : ~SYM[6](0 to ~LIT[2]-1);
   begin
     for i in RAM'range loop
       readline(RamFile,RamFileLine);
@@ -27,35 +27,34 @@
     return RAM;
   end function;
 
-  signal RAM_~SYM[1]  : RamType(0 to ~LIT[2]-1) := InitRamFromFile(~FILE[~LIT[3]]);
-  signal dout_~SYM[2] : ~TYP[7];
-  signal wr_~SYM[3]   : integer range 0 to ~LIT[2]-1;
-  signal rd_~SYM[4]   : integer range 0 to ~LIT[2]-1;
+  signal ~GENSYM[RAM][2] : ~SYM[6](0 to ~LIT[2]-1) := ~SYM[1](~FILE[~LIT[3]]);
+  signal ~GENSYM[dout][3] : ~TYP[7];
+  signal ~GENSYM[wr][4] : integer range 0 to ~LIT[2]-1;
+  signal ~GENSYM[rd][5] : integer range 0 to ~LIT[2]-1;
 begin
-  wr_~SYM[3] <= to_integer(~ARG[4])
+  ~SYM[4] <= to_integer(~ARG[4])
   -- pragma translate_off
                 mod ~LIT[2]
   -- pragma translate_on
                 ;
 
-  rd_~SYM[4] <= to_integer(~ARG[5])
+  ~SYM[5] <= to_integer(~ARG[5])
   -- pragma translate_off
                 mod ~LIT[2]
   -- pragma translate_on
                 ;
 
-  blockRamFile_sync : process(~CLK[1])
+  ~GENSYM[blockRamFile_sync][7] : process(~CLK[1])
   begin
     if (rising_edge(~CLK[1])) then
       if ~ARG[6] then
-        RAM_~SYM[1](wr_~SYM[3]) <= to_bitvector(~ARG[7]);
+        ~SYM[2](~SYM[4]) <= to_bitvector(~ARG[7]);
       end if;
-
-      dout_~SYM[2] <= to_stdlogicvector(RAM_~SYM[1](rd_~SYM[4]));
+      ~SYM[3] <= to_stdlogicvector(~SYM[2](~SYM[5]));
     end if;
   end process;
 
-  ~RESULT <= dout_~SYM[2];
+  ~RESULT <= ~SYM[3];
 end block;
 -- 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,46 +11,37 @@
            -> Signal' clk a"
     , "templateD" :
 "-- blockRam begin
-blockRam_~COMPNAME_~SYM[0] : block
-  type RamType is array(natural range <>) of std_logic_vector(~SIZE[~TYPO]-1 downto 0);
-
-  function init_to_bv (arg : in ~TYP[2]) return RamType is
-    variable RAM_init : RamType(0 to ~LENGTH[~TYP[2]]-1);
-  begin
-    for i in RAM_init'range loop
-      RAM_init(i) := ~TOBV[arg(i)][6];
-    end loop;
-    return RAM_init;
-  end function;
-
-  signal RAM_~SYM[1]  : RamType (0 to ~LENGTH[~TYP[2]]-1) := init_to_bv(~LIT[2]);
-  signal dout_~SYM[2] : std_logic_vector(~SIZE[~TYP[6]]-1 downto 0);
-  signal wr_~SYM[3]   : integer range 0 to ~LIT[0] - 1;
-  signal rd_~SYM[4]   : integer range 0 to ~LIT[0] - 1;
+~GENSYM[~COMPNAME_blockRam][0] : block
+  signal ~GENSYM[RAM][1] : ~TYP[2] := ~LIT[2];~IF ~VIVADO ~THEN
+  signal ~GENSYM[dout][2] : std_logic_vector(~SIZE[~TYP[6]]-1 downto 0);~ELSE
+  signal ~SYM[2] : ~TYP[6];~FI
+  signal ~GENSYM[wr][3] : integer range 0 to ~LIT[0] - 1;
+  signal ~GENSYM[rd][4] : integer range 0 to ~LIT[0] - 1;
 begin
-  wr_~SYM[3] <= to_integer(~ARG[3])
+  ~SYM[3] <= to_integer(~ARG[3])
   -- pragma translate_off
                 mod ~LIT[0]
   -- pragma translate_on
                 ;
 
-  rd_~SYM[4] <= to_integer(~ARG[4])
+  ~SYM[4] <= to_integer(~ARG[4])
   -- pragma translate_off
                 mod ~LIT[0]
   -- pragma translate_on
                 ;
 
-  blockRam_sync : process(~CLK[1])
+  ~GENSYM[blockRam_sync][5] : process(~CLK[1])
   begin
     if rising_edge(~CLK[1]) then
-      if ~ARG[5] then
-        RAM_~SYM[1](wr_~SYM[3]) <= ~TOBV[~ARG[6]][6];
+      if ~ARG[5] then~IF ~VIVADO ~THEN
+        ~SYM[1](~SYM[3]) <= ~TOBV[~ARG[6]][~TYP[6]];~ELSE
+        ~SYM[1](~SYM[3]) <= ~ARG[6];~FI
       end if;
-      dout_~SYM[2] <= RAM_~SYM[1](rd_~SYM[4]);
+      ~SYM[2] <= ~SYM[1](~SYM[4]);
     end if;
-  end process;
-
-  ~RESULT <= ~FROMBVO[dout_~SYM[2]];
+  end process;~IF ~VIVADO ~THEN
+  ~RESULT <= ~FROMBV[~SYM[2]][~TYPO];~ELSE
+  ~RESULT <= ~SYM[2];~FI
 end block;
 -- 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,34 +11,36 @@
            -> Signal' rclk a"
     , "templateD" :
 "-- asyncRam begin
-asyncRam_~COMPNAME_~SYM[0] : block
-  type RamType is array(natural range <>) of ~TYP[6];
-  signal RAM_~SYM[1] : RamType(0 to ~LIT[2]-1);
-  signal wr_~SYM[2]  : integer range 0 to ~LIT[2] - 1;
-  signal rd_~SYM[3]  : integer range 0 to ~LIT[2] - 1;
+~GENSYM[~COMPNAME_asyncRam][0] : block~IF ~VIVADO ~THEN
+  type ~GENSYM[RamType][4] is array(natural range <>) of std_logic_vector(~SIZE[~TYP[6]]-1 downto 0);~ELSE
+  type ~SYM[4] is array(natural range <>) of ~TYP[6];~FI
+  signal ~GENSYM[RAM][1] : ~SYM[4](0 to ~LIT[2]-1);
+  signal ~GENSYM[wr][2] : integer range 0 to ~LIT[2] - 1;
+  signal ~GENSYM[rd][3] : integer range 0 to ~LIT[2] - 1;
 begin
-  wr_~SYM[2] <= to_integer(~ARG[3])
+  ~SYM[2] <= to_integer(~ARG[3])
   -- pragma translate_off
                 mod ~LIT[2]
   -- pragma translate_on
                 ;
 
-  rd_~SYM[3] <= to_integer(~ARG[4])
+  ~SYM[3] <= to_integer(~ARG[4])
   -- pragma translate_off
                 mod ~LIT[2]
   -- pragma translate_on
                 ;
 
-  asyncRam_sync : process(~CLK[0])
+  ~GENSYM[asyncRam_sync][5] : process(~CLK[0])
   begin
     if rising_edge(~CLK[0]) then
-      if ~ARG[5] then
-        RAM_~SYM[1](wr_~SYM[2]) <= ~ARG[6];
+      if ~ARG[5] then~IF ~VIVADO ~THEN
+        ~SYM[1](~SYM[2]) <= ~TOBV[~ARG[6]][~TYP[6]];~ELSE
+        ~SYM[1](~SYM[2]) <= ~ARG[6];~FI
       end if;
     end if;
-  end process;
-
-  ~RESULT <= RAM_~SYM[1](rd_~SYM[3]);
+  end process;~IF ~VIVADO ~THEN
+  ~RESULT <= ~FROMBV[~SYM[1](~SYM[3])][~TYP[6]];~ELSE
+  ~RESULT <= ~SYM[1](~SYM[3]);~FI
 end block;
 -- 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
-asyncROMFile_~SYM[0] : block
-  type RomType is array(natural range <>) of bit_vector(~LIT[0]-1 downto 0);
+~GENSYM[asyncROMFile][0] : block
+  type ~GENSYM[RomType][4] is array(natural range <>) of bit_vector(~LIT[0]-1 downto 0);
 
-  impure function InitRomFromFile (RomFileName : in string) return RomType is
+  impure function ~GENSYM[InitRomFromFile][1] (RomFileName : in string) return ~SYM[4] is
     FILE RomFile : text open read_mode is RomFileName;
     variable RomFileLine : line;
-    variable ROM : RomType(0 to ~LIT[1]-1);
+    variable ROM : ~SYM[4](0 to ~LIT[1]-1);
   begin
     for i in ROM'range loop
       readline(RomFile,RomFileLine);
@@ -23,16 +23,16 @@
     return ROM;
   end function;
 
-  signal ROM_~SYM[1] : RomType(0 to ~LIT[1]-1) := InitRomFromFile(~FILE[~LIT[2]]);
-  signal rd_~SYM[2]  : integer range 0 to ~LIT[1]-1;
+  signal ~GENSYM[ROM][2] : ~SYM[4](0 to ~LIT[1]-1) := ~SYM[1](~FILE[~LIT[2]]);
+  signal ~GENSYM[rd][3] : integer range 0 to ~LIT[1]-1;
 begin
-  rd_~SYM[2] <= to_integer(~ARG[3])
+  ~SYM[3] <= to_integer(~ARG[3])
   -- pragma translate_off
                 mod ~LIT[1]
   -- pragma translate_on
                 ;
 
-  ~RESULT <= to_stdlogicvector(ROM_~SYM[1](rd_~SYM[2]));
+  ~RESULT <= to_stdlogicvector(~SYM[2](~SYM[3]));
 end block;
 -- asyncRomFile end"
     }
@@ -48,13 +48,13 @@
           -> Signal' clk (BitVector m)"
     , "templateD" :
 "-- romFile begin
-romFile_~COMPNAME_~SYM[0] : block
-  type RomType is array(natural range <>) of bit_vector(~LIT[0]-1 downto 0);
+~GENSYM[~COMPNAME_romFile][0] : block
+  type ~GENSYM[RomType][4] is array(natural range <>) of bit_vector(~LIT[0]-1 downto 0);
 
-  impure function InitRomFromFile (RomFileName : in string) return RomType is
+  impure function ~GENSYM[InitRomFromFile][1] (RomFileName : in string) return ~SYM[4] is
     FILE RomFile : text open read_mode is RomFileName;
     variable RomFileLine : line;
-    variable ROM : RomType(0 to ~LIT[2]-1);
+    variable ROM : ~SYM[4](0 to ~LIT[2]-1);
   begin
     for i in ROM'range loop
       readline(RomFile,RomFileLine);
@@ -63,24 +63,21 @@
     return ROM;
   end function;
 
-  signal ROM_~SYM[1]  : RomType(0 to ~LIT[2]-1) := InitRomFromFile(~FILE[~LIT[3]]);
-  signal rd_~SYM[2]   : integer range 0 to ~LIT[2]-1;
-  signal dout_~SYM[3] : ~TYPO;
+  signal ~GENSYM[ROM][2] : ~SYM[4](0 to ~LIT[2]-1) := ~SYM[1](~FILE[~LIT[3]]);
+  signal ~GENSYM[rd][3] : integer range 0 to ~LIT[2]-1;
 begin
-  rd_~SYM[2] <= to_integer(~ARG[4])
+  ~SYM[3] <= to_integer(~ARG[4])
   -- pragma translate_off
                 mod ~LIT[2]
   -- pragma translate_on
                 ;
 
-  romFileSync : process (~CLK[1])
+  ~GENSYM[romFileSync][5] : process (~CLK[1])
   begin
     if (rising_edge(~CLK[1])) then
-      dout_~SYM[3] <= to_stdlogicvector(ROM_~SYM[1](rd_~SYM[2]));
+      ~RESULT <= to_stdlogicvector(~SYM[2](~SYM[3]));
     end if;
   end process;
-
-  ~RESULT <= dout_~SYM[3];
 end block;
 -- 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,19 +7,19 @@
            -> a"
     , "templateD" :
 "-- asyncRom begin
-asyncRom_~SYM[0] : block
-  signal ROM_~SYM[1]       : ~TYP[1];
-  signal rom_index_~SYM[2] : integer range 0 to ~LIT[0]-1;
+~GENSYM[asyncRom][0] : block
+  signal ~GENSYM[ROM][1] : ~TYP[1];
+  signal ~GENSYM[rd][2] : integer range 0 to ~LIT[0]-1;
 begin
-  ROM_~SYM[1] <= ~ARG[1];
+  ~SYM[1] <= ~ARG[1];
 
-  rom_index~SYM[2] <= to_integer(~ARG[2])
+  ~SYM[2] <= to_integer(~ARG[2])
   -- pragma translate_off
                       mod ~LIT[0]
   -- pragma translate_on
-                      ;
-
-  ~RESULT <= ROM_~SYM[1](rom_index_~SYM[2]);
+                      ;~IF ~VIVADO ~THEN
+  ~RESULT <= ~FROMBV[~SYM[1](~SYM[2])][~TYPO];~ELSE
+  ~RESULT <= ~SYM[1](~SYM[2]);~FI
 end block;
 -- asyncRom end"
     }
@@ -34,27 +34,25 @@
       -> Signal' clk a"
     , "templateD" :
 "-- rom begin
-rom_~COMPNAME_~SYM[0] : block
-  signal ROM_~SYM[1]  : ~TYP[2];
-  signal rd_~SYM[2]   : integer range 0 to ~LIT[0]-1;
-  signal dout_~SYM[3] : ~TYPO;
+~GENSYM[~COMPNAME_rom][0] : block
+  signal ~GENSYM[ROM][1] : ~TYP[2];
+  signal ~GENSYM[rd][2] : integer range 0 to ~LIT[0]-1;
 begin
-  ROM_~SYM[1] <= ~ARG[2];
+  ~SYM[1] <= ~ARG[2];
 
-  rd_~SYM[2] <= to_integer(~ARG[3])
+  ~SYM[2] <= to_integer(~ARG[3])
   -- pragma translate_off
                 mod ~LIT[0]
   -- pragma translate_on
                 ;
 
-  romSync : process (~CLK[1])
+  ~GENSYM[romSync][3] : process (~CLK[1])
   begin
-    if (rising_edge(~CLK[1])) then
-      dout_~SYM[3] <= ROM_~SYM[1](rd_~SYM[2]);
+    if (rising_edge(~CLK[1])) then~IF ~VIVADO ~THEN
+      ~RESULT <= ~FROMBV[~SYM[1](~SYM[2])][~TYPO];~ELSE
+      ~RESULT <= ~SYM[1](~SYM[2]);~FI
     end if;
   end process;
-
-  ~RESULT <= dout_~SYM[3];
 end block;
 -- 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
@@ -10,9 +10,9 @@
          -> Signal' t b"
     , "templateD" :
 "-- assert begin
-assert_~SYM[0] : block
+~GENSYM[assert][0] : block
   -- pragma translate_off
-  function slv2string (slv : std_logic_vector) return STRING is
+  function ~GENSYM[slv2string][1] (slv : std_logic_vector) return STRING is
      variable result : string (1 to slv'length);
      variable res_l : string (1 to 3);
      variable r : integer;
@@ -25,17 +25,17 @@
      end loop;
      return result;
   end;
-  signal actual_~SYM[1]   : ~TYP[4];
-  signal expected_~SYM[2] : ~TYP[5];
+  signal ~GENSYM[actual][2] : ~TYP[4];
+  signal ~GENSYM[expected][3] : ~TYP[5];
   -- pragma translate_on
 begin
   -- pragma translate_off
-  actual_~SYM[1]   <= ~ARG[4];
-  expected_~SYM[2] <= ~ARG[5];
+  ~SYM[2] <= ~ARG[4];
+  ~SYM[3] <= ~ARG[5];
   process(~CLK[2],~RST[2]) is
   begin
     if (rising_edge(~CLK[2]) or rising_edge(~RST[2])) then
-      assert (actual_~SYM[1] = expected_~SYM[2]) report (~LIT[3] & \", expected: \" & slv2string(toSLV(expected_~SYM[2])) & \", actual: \" & slv2string(toSLV(actual_~SYM[1]))) severity error;
+      assert (~SYM[2] = ~SYM[3]) report (~LIT[3] & \", expected: \" & ~SYM[1](toSLV(~SYM[3])) & \", actual: \" & ~SYM[1](toSLV(~SYM[2]))) severity error;
     end if;
   end process;
   -- pragma translate_on
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,23 +7,14 @@
            -> Signal' clk a"
     , "templateD" :
 "-- register begin
-register_~COMPNAME_~SYM[0] : block
-  signal ~SYM[1] : ~TYP[1];
-  signal ~SYM[2] : ~TYP[2];
+~GENSYM[~COMPNAME_register][0] : process(~CLK[0],~RST[0]~VARS[1])
 begin
-  ~SYM[1] <= ~ARG[1];
-
-  process(~CLK[0],~RST[0],~SYM[1])
-  begin
-    if ~RST[0] = '0' then
-      ~SYM[2] <= ~SYM[1];
-    elsif rising_edge(~CLK[0]) then
-      ~SYM[2] <= ~ARG[2];
-    end if;
-  end process;
-
-  ~RESULT <= ~SYM[2];
-end block;
+  if ~RST[0] = '0' then
+    ~RESULT <= ~ARG[1];
+  elsif rising_edge(~CLK[0]) then
+    ~RESULT <= ~ARG[2];
+  end if;
+end process;
 -- register end"
     }
   }
@@ -37,27 +28,16 @@
         -> Signal' clk a"
     , "templateD" :
 "-- regEn begin
-regEn_~COMPNAME_~SYM[0] : block
-  signal ~SYM[1] : ~TYP[1];
-  signal ~SYM[2] : ~TYP[2];
-  signal ~SYM[3] : ~TYP[3];
+~GENSYM[~COMPNAME_regEn][0] : process(~CLK[0],~RST[0]~VARS[1]~VARS[2])
 begin
-  ~SYM[1] <= ~ARG[1];
-  ~SYM[2] <= ~ARG[2];
-
-  process(~CLK[0],~RST[0],~SYM[1],~SYM[2])
-  begin
-    if ~RST[0] = '0' then
-      ~SYM[3] <= ~SYM[1];
-    elsif rising_edge(~CLK[0]) then
-      if ~SYM[2] then
-        ~SYM[3] <= ~ARG[3];
-      end if;
+  if ~RST[0] = '0' then
+    ~RESULT <= ~ARG[1];
+  elsif rising_edge(~CLK[0]) then
+    if ~ARG[2] then
+      ~RESULT <= ~ARG[3];
     end if;
-  end process;
-
-  ~RESULT <= ~SYM[3];
-end block;
+  end if;
+end process;
 -- regEn end"
     }
   }
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
@@ -33,7 +33,7 @@
     , "type"      : "reduceAnd# :: KnownNat n => BitVector n -> BitVector 1"
     , "templateD" :
 "-- reduceAnd begin
-reduceAnd_~SYM[0] : block
+~GENSYM[reduceAnd][0] : block
   function and_reduce (arg : std_logic_vector) return std_logic is
     variable upper, lower : std_logic;
     variable half         : integer;
@@ -66,7 +66,7 @@
     , "type"      : "reduceOr# :: BitVector n -> BitVector 1"
     , "templateD" :
 "-- reduceOr begin
-reduceOr_~SYM[0] : block
+~GENSYM[reduceOr][0] : block
   function or_reduce (arg : std_logic_vector) return std_logic is
     variable upper, lower : std_logic;
     variable half         : integer;
@@ -99,7 +99,7 @@
     , "type"      : "reduceXor# :: BitVector n -> BitVector 1"
     , "templateD" :
 "-- reduceXor begin
-reduceXor_~SYM[0] : block
+~GENSYM[reduceXor][0] : block
   function xor_reduce (arg : std_logic_vector) return std_logic is
     variable upper, lower : std_logic;
     variable half         : integer;
@@ -135,21 +135,31 @@
         -> Int         -- ARG[2]
         -> Bit"
     , "templateD" :
-"-- indexBitVector begin
-indexBitVector_~SYM[0] : block
-  signal vec       : ~TYP[1];
-  signal vec_index : integer range 0 to ~LIT[0]-1;
+"-- indexBitVector begin~IF ~ISVAR[1] ~THEN
+~GENSYM[indexBitVector][0] : block
+  signal ~GENSYM[vec_index][1] : integer range 0 to ~LIT[0]-1;
 begin
-  vec <= ~ARG[1];
+  ~SYM[1] <= to_integer(~ARG[2])
+  -- pragma translate_off
+               mod ~LIT[0]
+  -- pragma translate_on
+               ;
 
-  vec_index <= to_integer(~ARG[2])
+  ~RESULT <= ~ARG[1](~SYM[1] downto ~SYM[1]);
+end block;~ELSE
+~SYM[0] : block
+  signal ~GENSYM[bv][2] : ~TYP[1];
+  signal ~SYM[1] : integer range 0 to ~LIT[0]-1;
+begin
+  ~SYM[2] <= ~ARG[1];
+  ~SYM[1] <= to_integer(~ARG[2])
   -- pragma translate_off
                mod ~LIT[0]
   -- pragma translate_on
                ;
 
-  ~RESULT <= vec(vec_index downto vec_index);
-end block;
+  ~RESULT <= ~SYM[2](~SYM[1] downto ~SYM[1]);
+end block;~FI
 -- indexBitVector end"
     }
   }
@@ -163,25 +173,21 @@
              -> BitVector n"
     , "templateD" :
 "-- replaceBit begin
-replaceBit_~SYM[0] : block
-  signal vec       : ~TYP[1];
-  signal vec_index : integer range 0 to ~LIT[0]-1;
-  signal din       : ~TYP[3];
+~GENSYM[replaceBit][0] : block
+  signal ~GENSYM[vec_index][1] : integer range 0 to ~LIT[0]-1;
 begin
-  vec <= ~ARG[1];
-  vec_index <= to_integer(~ARG[2])
+  ~SYM[1] <= to_integer(~ARG[2])
   -- pragma translate_off
                mod ~LIT[0]
   -- pragma translate_on
                ;
-  din <= ~ARG[3];
 
-  process(vec,vec_index,din)
-    variable ivec : ~TYP[1];
+  process(~SYM[1]~VARS[1]~VARS[3])
+    variable ~GENSYM[ivec][2] : ~TYP[1];
   begin
-    ivec := vec;
-    ivec(vec_index downto vec_index) := din;
-    ~RESULT <= ivec;
+    ~SYM[2] := ~ARG[1];
+    ~SYM[2](~SYM[1] downto ~SYM[1]) := ~ARG[3];
+    ~RESULT <= ~SYM[2];
   end process;
 end block;
 -- replaceBit end"
@@ -196,21 +202,26 @@
            -> BitVector (m + 1 - n) -- ARG[3]
            -> BitVector (m + 1 + i)"
     , "templateD" :
-"-- setSlice begin
-setSlice_~SYM[0] : block
-  signal ~SYM[1] : ~TYP[0];
-  signal ~SYM[2] : ~TYP[3];
+"-- setSlice begin~IF ~ISVAR[0] ~THEN
+~GENSYM[setSlice][0] : process(~ARG[0]~VARS[3])
+  variable ~GENSYM[ivec][1] : ~TYP[0];
 begin
-  ~SYM[1] <= ~ARG[0];
-  ~SYM[2] <= ~ARG[3];
-  process(~SYM[1],~SYM[2])
-    variable ~SYM[3] : ~TYP[0];
+  ~SYM[1] := ~ARG[0];
+  ~SYM[1](~LIT[1] downto ~LIT[2]) := ~ARG[3];
+  ~RESULT <= ~SYM[1];
+end process;~ELSE
+~SYM[0] : block
+  signal ~GENSYM[bv][2] : ~TYP[0];
+begin
+  ~SYM[2] <= ~ARG[0];
+  process(~SYM[2]~VARS[3])
+    variable ~SYM[1] : ~TYP[0];
   begin
-    ~SYM[3] := ~SYM[1];
-    ~SYM[3](~LIT[1] downto ~LIT[2]) := ~SYM[2];
-    ~RESULT <= ~SYM[3];
+    ~SYM[1] := ~SYM[2];
+    ~SYM[1](~LIT[1] downto ~LIT[2]) := ARG[3];
+    ~RESULT <= ~SYM[1];
   end process;
-end block;
+end block;~FI
 -- setSlice end"
     }
   }
@@ -222,13 +233,14 @@
         -> SNat n                -- ARG[2]
         -> BitVector (m + 1 - n)"
     , "templateD" :
-"-- slice begin
-slice_~SYM[0] : block
-  signal ~SYM[1] : ~TYP[0];
+"-- slice begin~IF ~ISVAR[0] ~THEN
+~RESULT <= ~ARG[0](~LIT[1] downto ~LIT[2]);~ELSE
+~GENSYM[slice][0] : block
+  signal ~GENSYM[bv][1] : ~TYP[0];
 begin
   ~SYM[1] <= ~ARG[0];
   ~RESULT <= ~SYM[1](~LIT[1] downto ~LIT[2]);
-end block;
+end block;~FI
 -- slice end"
     }
   }
@@ -239,16 +251,18 @@
         => BitVector (m + n) -- ARG[1]
         -> (BitVector m, BitVector n)"
     , "templateD" :
-"-- split begin
-split_~SYM[0]: block
-  signal ~SYM[1] : ~TYP[1];
+"-- split begin~IF ~ISVAR[1] ~THEN
+~RESULT <= (~ARG[1](~ARG[1]'high downto ~LIT[0])
+           ,~ARG[1](~LIT[0]-1 downto 0)
+           );~ELSE
+~GENSYM[split][0]: block
+  signal ~GENSYM[bv][1] : ~TYP[1];
 begin
   ~SYM[1] <= ~ARG[1];
-  ~RESULT <= ( ~SYM[1](~RESULT.~TYPMO_sel0'left + ~RESULT.~TYPMO_sel1'length downto
-               ~RESULT.~TYPMO_sel0'right + ~RESULT.~TYPMO_sel1'length)
-             , ~SYM[1](~RESULT.~TYPMO_sel1'left downto ~RESULT.~TYPMO_sel1'right)
+  ~RESULT <= (~SYM[1](~SYM[1]'high downto ~LIT[0])
+             ,~SYM[1](~LIT[0]-1 downto 0)
              );
-end block;
+end block;~FI
 -- split end"
     }
   }
@@ -259,16 +273,16 @@
       => BitVector n -- ARG[1]
       -> Bit"
     , "templateD" :
-"-- msb begin~IF ~LIT[0] ~THEN
-msb_~SYM[0] : block
-  signal ~SYM[1] : ~TYP[1];
+"-- msb begin~IF ~LIT[0] ~THEN ~IF ~ISVAR[1] ~THEN
+~RESULT <= ~ARG[1](~ARG[1]'high downto ~ARG[1]'high);~ELSE
+~GENSYM[msb][0] : block
+  signal ~GENSYM[bv][1] : ~TYP[1];
 begin
   ~SYM[1] <= ~ARG[1];
   ~RESULT <= ~SYM[1](~SYM[1]'high downto ~SYM[1]'high);
-end block;
-~ELSE
-~RESULT <= \"0\";
-~FI-- msb end"
+end block;~FI~ELSE
+~RESULT <= \"0\";~FI
+-- msb end"
     }
   }
 , { "BlackBox" :
@@ -277,16 +291,16 @@
 "lsb# :: BitVector n -- ARG[0]
       -> Bit"
     , "templateD" :
-"-- lsb begin~IF ~SIZE[~TYP[0]] ~THEN
-lsb_~SYM[0] : block
-  signal ~SYM[1] : ~TYP[0];
+"-- lsb begin~IF ~SIZE[~TYP[0]] ~THEN ~IF ~ISVAR[0] ~THEN
+~RESULT <= ~ARG[0](0 downto 0);~ELSE
+~GENSYM[lsb][0] : block
+  signal ~GENSYM[bv][1] : ~TYP[0];
 begin
   ~SYM[1] <= ~ARG[0];
   ~RESULT <= ~SYM[1](0 downto 0);
-end block;
-~ELSE
-~RESULT <= \"0\";
-~FI-- lsb end"
+end block;~FI~ELSE
+~RESULT <= \"0\";~FI
+-- lsb end"
     }
   }
 , { "BlackBox" :
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
@@ -138,10 +138,17 @@
     { "name"      : "CLaSH.Sized.Internal.Signed.div#"
     , "type"      : "div# :: Signed n -> Signed n -> Signed n"
     , "templateD" :
-"-- divSigned begin
-divSigned_~SYM[0] : block
-  signal ~SYM[1] : ~TYP[0];
-  signal ~SYM[2] : ~TYP[1];
+"-- divSigned begin~IF ~AND[~ISVAR[0],~ISVAR[1]] ~THEN
+~GENSYM[divSigned][0] : block
+  signal ~GENSYM[quot_res][3] : ~TYP[0];
+begin
+  ~SYM[3] <= ~ARG[0] / ~ARG[1];
+  ~RESULT <= ~SYM[3] - to_signed(1,~SIZE[~TYPO]) when ~ARG[0](~ARG[0]'high) = not (~ARG[1](~ARG[1]'high)) else
+             ~SYM[3];
+end block;~ELSE
+~SYM[0] : block
+  signal ~GENSYM[dividend][1] : ~TYP[0];
+  signal ~GENSYM[divider][2] : ~TYP[1];
   signal ~SYM[3] : ~TYP[0];
 begin
   ~SYM[1] <= ~ARG[0];
@@ -149,7 +156,7 @@
   ~SYM[3] <= ~SYM[1] / ~SYM[2];
   ~RESULT <= ~SYM[3] - to_signed(1,~SIZE[~TYPO]) when ~SYM[1](~SYM[1]'high) = not (~SYM[2](~SYM[2]'high)) else
              ~SYM[3];
-end block;
+end block;~FI
 -- divSigned end"
     }
   }
@@ -223,13 +230,14 @@
     { "name"      : "CLaSH.Sized.Internal.Signed.truncateB#"
     , "type"      : "truncateB# :: KnownNat m => Signed (n + m) -> Signed m"
     , "templateD" :
-"-- truncateB begin
-truncateB_~SYM[0] : block
-  signal ~SYM[1] : ~TYP[1];
+"-- truncateB begin~IF ~ISVAR[1] ~THEN
+~RESULT <= ~ARG[1](~LIT[0]-1 downto 0);~ELSE
+~GENSYM[truncateB][0] : block
+  signal ~GENSYM[s][1] : ~TYP[1];
 begin
   ~SYM[1] <= ~ARG[1];
   ~RESULT <= ~SYM[1](~LIT[0]-1 downto 0);
-end block;
+end block;~FI
 -- truncateB 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
@@ -2,13 +2,16 @@
     { "name"      : "CLaSH.Sized.Vector.head"
     , "type"      : "head :: Vec (n + 1) a -> a"
     , "templateD" :
-"-- head begin
-head_~SYM[0] : block
-  signal ~SYM[1] : ~TYP[0];
+"-- head begin~IF ~ISVAR[0] ~THEN ~IF ~VIVADO ~THEN
+~RESULT <= ~FROMBV[~ARG[0](0)][~TYPO];~ELSE
+~RESULT <= ~ARG[0](0);~FI~ELSE
+~GENSYM[head][0] : block
+  signal ~GENSYM[vec][1] : ~TYP[0];
 begin
-  ~SYM[1] <= ~ARG[0];
-  ~RESULT <= ~SYM[1](0);
-end block;
+  ~SYM[1] <= ~ARG[0];~IF ~VIVADO ~THEN
+  ~RESULT <= ~FROMBV[~SYM[1](0)][~TYPO];~ELSE
+  ~RESULT <= ~SYM[1](0);~FI
+end block;~FI
 -- head end"
     }
   }
@@ -16,13 +19,14 @@
     { "name"      : "CLaSH.Sized.Vector.tail"
     , "type"      : "tail :: Vec (n + 1) a -> Vec n a"
     , "templateD" :
-"-- tail begin
-tail_~SYM[0] : block
-  signal ~SYM[1] : ~TYP[0];
+"-- tail begin~IF ~ISVAR[0] ~THEN
+~RESULT <= ~ARG[0](1 to ~ARG[0]'high);~ELSE
+~GENSYM[tail][0] : block
+  signal ~GENSYM[vec][1] : ~TYP[0];
 begin
   ~SYM[1] <= ~ARG[0];
   ~RESULT <= ~SYM[1](1 to ~SYM[1]'high);
-end block;
+end block;~FI
 -- tail end"
     }
   }
@@ -30,13 +34,16 @@
     { "name"      : "CLaSH.Sized.Vector.last"
     , "type"      : "Vec (n + 1) a -> a"
     , "templateD" :
-"-- last begin
-last_~SYM[0] : block
-  signal ~SYM[1] : ~TYP[0];
+"-- last begin~IF ~ISVAR[0] ~THEN ~IF ~VIVADO ~THEN
+~RESULT <= ~FROMBV[~ARG[0](~ARG[0]'high)][~TYPO];~ELSE
+~RESULT <= ~ARG[0](~ARG[0]'high);~FI~ELSE
+~GENSYM[last][0] : block
+  signal ~GENSYM[vec][1] : ~TYP[0];
 begin
-  ~SYM[1] <= ~ARG[0];
-  ~RESULT <= ~SYM[1](~SYM[1]'high);
-end block;
+  ~SYM[1] <= ~ARG[0];~IF ~VIVADO ~THEN
+  ~RESULT <= ~FROMBV[~SYM[1](~SYM[1]'high)][~TYPO];~ELSE
+  ~RESULT <= ~SYM[1](~SYM[1]'high);~FI
+end block;~FI
 -- last end"
     }
   }
@@ -44,13 +51,14 @@
     { "name"      : "CLaSH.Sized.Vector.init"
     , "type"      : "Vec (n + 1) a -> Vec n a"
     , "templateD" :
-"-- init begin
-init_~SYM[0] : block
-  signal ~SYM[1] : ~TYP[0];
+"-- init begin~IF ~ISVAR[0] ~THEN
+~RESULT <= ~ARG[0](0 to ~ARG[0]'high - 1);~ELSE
+~GENSYM[init][0] : block
+  signal ~GENSYM[vec][1] : ~TYP[0];
 begin
   ~SYM[1] <= ~ARG[0];
   ~RESULT <= ~SYM[1](0 to ~SYM[1]'high - 1);
-end block;
+end block;~FI
 -- init end"
     }
   }
@@ -64,17 +72,19 @@
         -> Vec i a                       -- ARG[4]
         -> Vec n a"
     , "templateD" :
-"-- select begin
-select_~SYM[0] : block
-  signal ~SYM[1] : ~TYP[4];
+"-- select begin~IF ~ISVAR[4] ~THEN
+~GENSYM[select][0] : for ~GENSYM[i][1] in ~RESULT'range generate
+  ~RESULT(~SYM[1]) <= ~ARG[4](~LIT[1]+(~LIT[2]*~SYM[1]));
+end generate;~ELSE
+~GENSYM[select][2] : block
+  signal ~GENSYM[vec][3] : ~TYP[4];
 begin
-  ~SYM[1] <= ~ARG[4];
-
-  select_loop : for ~SYM[2] in ~RESULT'range generate
+  ~SYM[3] <= ~ARG[4];
+  ~SYM[0] : for ~SYM[1] in ~RESULT'range generate
   begin
-      ~RESULT(~SYM[2]) <= ~SYM[1](~LIT[1]+(~LIT[2]*~SYM[2]));
+    ~RESULT(~SYM[1]) <= ~SYM[3](~LIT[1]+(~LIT[2]*~SYM[1]));
   end generate;
-end block;
+end block;~FI
 -- select end"
     }
   }
@@ -88,17 +98,22 @@
     { "name"      : "CLaSH.Sized.Vector.concat"
     , "type"      : "concat :: Vec n (Vec m a) -> Vec (n * m) a"
     , "templateD" :
-"-- concat begin
-concat_~SYM[0] : block
-  signal ~SYM[1] : ~TYP[0];
+"-- concat begin~IF ~ISVAR[0] ~THEN
+~GENSYM[concat][0] : for ~GENSYM[i][1] in ~ARG[0]'range generate
+begin~IF ~VIVADO ~THEN
+~RESULT(~SYM[1] * ~LENGTH[~TYPEL[~TYP[0]]] to ((~SYM[1]+1) * ~LENGTH[~TYPEL[~TYP[0]]]) - 1) <= ~FROMBV[~ARG[0](~SYM[1])][~TYPEL[~TYP[0]]];~ELSE
+~RESULT(~SYM[1] * ~LENGTH[~TYPEL[~TYP[0]]] to ((~SYM[1]+1) * ~LENGTH[~TYPEL[~TYP[0]]]) - 1) <= ~ARG[0](~SYM[1]);~FI
+end generate;~ELSE
+~SYM[0] : block
+  signal ~GENSYM[vec][2] : ~TYP[0];
 begin
-  ~SYM[1] <= ~ARG[0];
-
-  concat_loop : for ~SYM[2] in ~SYM[1]'range generate
-  begin
-    ~RESULT(~SYM[2] * ~LENGTH[~TYPEL[~TYP[0]]] to ((~SYM[2]+1) * ~LENGTH[~TYPEL[~TYP[0]]]) - 1) <= ~SYM[1](~SYM[2]);
+  ~SYM[2] <= ~ARG[0];
+  ~SYM[3] : for ~SYM[1] in ~SYM[2]'range generate
+  begin~IF ~VIVADO ~THEN
+    ~RESULT(~SYM[1] * ~LENGTH[~TYPEL[~TYP[0]]] to ((~SYM[1]+1) * ~LENGTH[~TYPEL[~TYP[0]]]) - 1) <= ~FROMBV[~SYM[2](~SYM[1])][~TYPEL[~TYP[0]]];~ELSE
+    ~RESULT(~SYM[1] * ~LENGTH[~TYPEL[~TYP[0]]] to ((~SYM[1]+1) * ~LENGTH[~TYPEL[~TYP[0]]]) - 1) <= ~SYM[2](~SYM[1]);~FI
   end generate;
-end block;
+end block;~FI
 -- concat end"
     }
   }
@@ -106,14 +121,16 @@
     { "name"      : "CLaSH.Sized.Vector.splitAt"
     , "type"      : "splitAt :: SNat m -> Vec (m + n) a -> (Vec m a, Vec n a)"
     , "templateD" :
-"-- sliptAt begin
-splitAt_~SYM[0] : block
-  signal ~SYM[1] : ~TYP[1];
+"-- splitAt begin~IF ~ISVAR[1] ~THEN
+~RESULT <= (~ARG[1](0 to ~LIT[0]-1)
+           ,~ARG[1](~LIT[0] to ~ARG[1]'high));~ELSE
+~GENSYM[splitAt][0] : block
+  signal ~GENSYM[vec][1] : ~TYP[1];
 begin
   ~SYM[1] <= ~ARG[1];
-  ~RESULT <= (~SYM[1](~RESULT.~TYPMO_sel0'left to ~RESULT.~TYPMO_sel0'right)
-             ,~SYM[1](~RESULT.~TYPMO_sel1'left + ~RESULT.~TYPMO_sel0'length to ~RESULT.~TYPMO_sel1'right + ~RESULT.~TYPMO_sel0'length));
-end block;
+  ~RESULT <= (~SYM[1](0 to ~LIT[0]-1)
+             ,~SYM[1](~LIT[0] to ~SYM[1]'high));
+end block;~FI
 -- splitAt end"
     }
   }
@@ -125,17 +142,22 @@
           -> Vec (n * m) a  -- ARG[2]
           -> Vec n (Vec m a)"
     , "templateD" :
-"-- unconcat begin
-unconcat_~SYM[0] : block
-  signal ~SYM[1] : ~TYP[2];
+"-- unconcat begin~IF ~ISVAR[2] ~THEN
+~GENSYM[unconcat][0] : for ~GENSYM[i][2] in ~RESULT'range generate
+begin~IF ~VIVADO ~THEN
+  ~RESULT(~SYM[2]) <= ~TOBV[~ARG[2]((~SYM[2] * ~LIT[1]) to ((~SYM[2] * ~LIT[1]) + ~LIT[1] - 1))][~TYPEL[~TYPO]];~ELSE
+  ~RESULT(~SYM[2]) <= ~ARG[2]((~SYM[2] * ~LIT[1]) to ((~SYM[2] * ~LIT[1]) + ~LIT[1] - 1));~FI
+end generate;~ELSE
+~SYM[0] : block
+  signal ~GENSYM[vec][1] : ~TYP[2];
 begin
   ~SYM[1] <= ~ARG[2];
-
-  unconcat_loop : for ~SYM[2] in ~RESULT'range generate
-  begin
-    ~RESULT(~SYM[2]) <= ~SYM[1]((~SYM[2] * ~LIT[1]) to ((~SYM[2] * ~LIT[1]) + ~LIT[1] - 1));
+  ~GENSYM[unconcat][3] : for ~SYM[2] in ~RESULT'range generate
+  begin~IF ~VIVADO ~THEN
+    ~RESULT(~SYM[2]) <= ~TOBV[~SYM[1]((~SYM[2] * ~LIT[1]) to ((~SYM[2] * ~LIT[1]) + ~LIT[1] - 1))][~TYPEL[~TYPO]];~ELSE
+    ~RESULT(~SYM[2]) <= ~SYM[1]((~SYM[2] * ~LIT[1]) to ((~SYM[2] * ~LIT[1]) + ~LIT[1] - 1));~FI
   end generate;
-end block;
+end block;~FI
 -- unconcat end"
     }
   }
@@ -143,20 +165,46 @@
     { "name"      : "CLaSH.Sized.Vector.map"
     , "type"      : "map :: (a -> b) -> Vec n a -> Vec n b"
     , "templateD" :
-"-- map begin
-map_~SYM[0] : block
-  signal ~SYM[1] : ~TYP[1];
+"-- map begin~IF ~ISVAR[1] ~THEN
+~GENSYM[map][0] : for ~GENSYM[i][1] in ~RESULT'range generate~IF ~VIVADO ~THEN
+  signal ~GENSYM[map_in][2] : ~TYPEL[~TYP[1]];
+  signal ~GENSYM[map_out][3] : ~TYPEL[~TYPO];
 begin
-  ~SYM[1] <= ~ARG[1];
-
-  map_loop : for ~SYM[2] in ~RESULT'range generate
+  ~SYM[2] <= ~FROMBV[~ARG[1](~SYM[1])][~TYPEL[~TYP[1]]];
+  ~INST 0
+    ~OUTPUT <= ~SYM[3]~ ~TYPEL[~TYPO]~
+    ~INPUT  <= ~SYM[2]~ ~TYPEL[~TYP[1]]~
+  ~INST
+  ~RESULT(~SYM[1]) <= ~TOBV[~SYM[3]][~TYPEL[~TYPO]];
+end generate;~ELSE
+begin
+  ~INST 0
+    ~OUTPUT <= ~RESULT(~SYM[1])~ ~TYPEL[~TYPO]~
+    ~INPUT  <= ~ARG[1](~SYM[1])~ ~TYPEL[~TYP[1]]~
+  ~INST
+end generate;~FI~ELSE
+~SYM[0] : block
+  signal ~GENSYM[vec][4] : ~TYP[1];
+begin
+  ~SYM[4] <= ~ARG[1];
+  ~GENSYM[map][5] : for ~SYM[1] in ~RESULT'range generate~IF ~VIVADO ~THEN
+    signal ~SYM[2] : ~TYPEL[~TYP[1]];
+    signal ~SYM[3] : ~TYPEL[~TYPO];
   begin
+    ~SYM[2] <= ~FROMBV[~SYM[4](~SYM[1])][~TYPEL[~TYP[1]]];
     ~INST 0
-      ~OUTPUT <= ~RESULT(~SYM[2])~ ~TYPEL[~TYPO]~
-      ~INPUT  <= ~SYM[1](~SYM[2])~ ~TYPEL[~TYP[1]]~
+      ~OUTPUT <= ~SYM[3]~ ~TYPEL[~TYPO]~
+      ~INPUT  <= ~SYM[2]~ ~TYPEL[~TYP[1]]~
     ~INST
-  end generate;
-end block;
+    ~RESULT(~SYM[1]) <= ~TOBV[~SYM[3]][~TYPEL[~TYPO]];
+  end generate;~ELSE
+  begin
+    ~INST 0
+      ~OUTPUT <= ~RESULT(~SYM[1])~ ~TYPEL[~TYPO]~
+      ~INPUT  <= ~SYM[4](~SYM[1])~ ~TYPEL[~TYP[1]]~
+    ~INST
+  end generate;~FI
+end block;~FI
 -- map end"
     }
   }
@@ -164,28 +212,65 @@
     { "name"      : "CLaSH.Sized.Vector.imap"
     , "type"      : "imap :: KnownNat n => (Index n -> a -> b) -> Vec n a -> Vec n b"
     , "templateD" :
-"-- imap begin
-imap_~SYM[0] : block
-  signal ~SYM[1] : ~TYP[2];
-
-  function max (l,r : in natural) return natural is
+"-- imap begin~IF ~ISVAR[2] ~THEN
+~GENSYM[imap][0] : block
+  function ~GENSYM[max][6] (l,r : in natural) return natural is
   begin
     if l > r then return l;
     else return r;
     end if;
   end function;
 begin
-  ~SYM[1] <= ~ARG[2];
-
-  imap_loop : for ~SYM[2] in ~RESULT'range generate
+  ~GENSYM[imap][5] : for ~GENSYM[i][1] in ~RESULT'range generate~IF ~VIVADO ~THEN
+    signal ~GENSYM[map_in][2] : ~TYPEL[~TYP[2]];
+    signal ~GENSYM[map_out][3] : ~TYPEL[~TYPO];
   begin
+    ~SYM[2] <= ~FROMBV[~ARG[2](~SYM[1])][~TYPEL[~TYP[2]]];
     ~INST 1
-      ~OUTPUT <= ~RESULT(~SYM[2])~ ~TYPEL[~TYPO]~
-      ~INPUT  <= to_unsigned(~SYM[2],max(1,integer(ceil(log2(real(~LIT[0]))))))~ ~INDEXTYPE[~LIT[0]]~
-      ~INPUT  <= ~SYM[1](~SYM[2])~ ~TYPEL[~TYP[2]]~
+      ~OUTPUT <= ~SYM[3]~ ~TYPEL[~TYPO]~
+      ~INPUT  <= to_unsigned(~SYM[1],~SYM[6](1,integer(ceil(log2(real(~LIT[0]))))))~ ~INDEXTYPE[~LIT[0]]~
+      ~INPUT  <= ~SYM[2]~ ~TYPEL[~TYP[1]]~
     ~INST
-  end generate;
-end block;
+    ~RESULT(~SYM[1]) <= ~TOBV[~SYM[3]][~TYPEL[~TYPO]];
+  end generate;~ELSE
+  begin
+    ~INST 1
+      ~OUTPUT <= ~RESULT(~SYM[1])~ ~TYPEL[~TYPO]~
+      ~INPUT  <= to_unsigned(~SYM[1],~SYM[6](1,integer(ceil(log2(real(~LIT[0]))))))~ ~INDEXTYPE[~LIT[0]]~
+      ~INPUT  <= ~ARG[2](~SYM[1])~ ~TYPEL[~TYP[1]]~
+    ~INST
+  end generate;~FI
+end block;~ELSE
+~SYM[0] : block
+  function ~SYM[6] (l,r : in natural) return natural is
+  begin
+    if l > r then return l;
+    else return r;
+    end if;
+  end function;
+  signal ~GENSYM[vec][4] : ~TYP[2];
+begin
+  ~SYM[4] <= ~ARG[2];
+  ~SYM[5] : for ~SYM[1] in ~RESULT'range generate~IF ~VIVADO ~THEN
+    signal ~SYM[2] : ~TYPEL[~TYP[1]];
+    signal ~SYM[3] : ~TYPEL[~TYPO];
+  begin
+    ~SYM[2] <= ~FROMBV[~SYM[4](~SYM[1])][~TYPEL[~TYP[1]]];
+    ~INST 1
+      ~OUTPUT <= ~SYM[3]~ ~TYPEL[~TYPO]~
+      ~INPUT  <= to_unsigned(~SYM[1],~SYM[6](1,integer(ceil(log2(real(~LIT[0]))))))~ ~INDEXTYPE[~LIT[0]]~
+      ~INPUT  <= ~SYM[2]~ ~TYPEL[~TYP[1]]~
+    ~INST
+    ~RESULT(~SYM[1]) <= ~TOBV[~SYM[3]][~TYPEL[~TYPO]];
+  end generate;~ELSE
+  begin
+    ~INST 1
+      ~OUTPUT <= ~RESULT(~SYM[1])~ ~TYPEL[~TYPO]~
+      ~INPUT  <= to_unsigned(~SYM[1],~SYM[6](1,integer(ceil(log2(real(~LIT[0]))))))~ ~INDEXTYPE[~LIT[0]]~
+      ~INPUT  <= ~SYM[4](~SYM[1])~ ~TYPEL[~TYP[1]]~
+    ~INST
+  end generate;~FI
+end block;~FI
 -- imap end"
     }
   }
@@ -193,23 +278,56 @@
     { "name"      : "CLaSH.Sized.Vector.zipWith"
     , "type"      : "zipWith :: (a -> b -> c) -> Vec n a -> Vec n b -> Vec n c"
     , "templateD" :
-"-- zipWith begin
-zipWith_~SYM[0] : block
-  signal ~SYM[1] : ~TYP[1];
-  signal ~SYM[2] : ~TYP[2];
+"-- zipWith begin~IF ~AND[~ISVAR[1],~ISVAR[2]] ~THEN
+~GENSYM[zipWith][0] : for ~GENSYM[i][1] in ~RESULT'range generate~IF ~VIVADO ~THEN
+  signal ~GENSYM[zipWith_in1][2] : ~TYPEL[~TYP[1]];
+  signal ~GENSYM[zipWith_in2][6] : ~TYPEL[~TYP[2]];
+  signal ~GENSYM[zipWith_out][3] : ~TYPEL[~TYPO];
 begin
-  ~SYM[1] <= ~ARG[1];
-  ~SYM[2] <= ~ARG[2];
-
-  zipWith_loop : for ~SYM[3] in ~RESULT'range generate
+  ~SYM[2] <= ~FROMBV[~ARG[1](~SYM[1])][~TYPEL[~TYP[1]]];
+  ~SYM[6] <= ~FROMBV[~ARG[2](~SYM[1])][~TYPEL[~TYP[2]]];
+  ~INST 0
+    ~OUTPUT <= ~SYM[3]~ ~TYPEL[~TYPO]~
+    ~INPUT  <= ~SYM[2]~ ~TYPEL[~TYP[1]]~
+    ~INPUT  <= ~SYM[6]~ ~TYPEL[~TYP[2]]~
+  ~INST
+  ~RESULT(~SYM[1]) <= ~TOBV[~SYM[3]][~TYPEL[~TYPO]];
+end generate;~ELSE
+begin
+  ~INST 0
+    ~OUTPUT <= ~RESULT(~SYM[1])~ ~TYPEL[~TYPO]~
+    ~INPUT  <= ~ARG[1](~SYM[1])~ ~TYPEL[~TYP[1]]~
+    ~INPUT  <= ~ARG[2](~SYM[1])~ ~TYPEL[~TYP[2]]~
+  ~INST
+end generate;~FI~ELSE
+~SYM[0] : block
+  signal ~GENSYM[vec1][4] : ~TYP[1];
+  signal ~GENSYM[vec2][7] : ~TYP[2];
+begin
+  ~SYM[4] <= ~ARG[1];
+  ~SYM[7] <= ~ARG[2];
+  ~GENSYM[zipWith][5] : for ~SYM[1] in ~RESULT'range generate~IF ~VIVADO ~THEN
+    signal ~SYM[2] : ~TYPEL[~TYP[1]];
+    signal ~SYM[6] : ~TYPEL[~TYP[2]];
+    signal ~SYM[3] : ~TYPEL[~TYPO];
   begin
+    ~SYM[2] <= ~FROMBV[~SYM[4](~SYM[1])][~TYPEL[~TYP[1]]];
+    ~SYM[6] <= ~FROMBV[~SYM[7](~SYM[1])][~TYPEL[~TYP[2]]];
     ~INST 0
-      ~OUTPUT <= ~RESULT(~SYM[3])~ ~TYPEL[~TYPO]~
-      ~INPUT  <= ~SYM[1](~SYM[3])~ ~TYPEL[~TYP[1]]~
-      ~INPUT  <= ~SYM[2](~SYM[3])~ ~TYPEL[~TYP[2]]~
+      ~OUTPUT <= ~SYM[3]~ ~TYPEL[~TYPO]~
+      ~INPUT  <= ~SYM[2]~ ~TYPEL[~TYP[1]]~
+      ~INPUT  <= ~SYM[6]~ ~TYPEL[~TYP[2]]~
     ~INST
-  end generate;
-end block;
+    ~RESULT(~SYM[1]) <= ~TOBV[~SYM[3]][~TYPEL[~TYPO]];
+  end generate;~ELSE
+  begin
+    ~INST 0
+      ~OUTPUT <= ~RESULT(~SYM[1])~ ~TYPEL[~TYPO]~
+      ~INPUT  <= ~SYM[4](~SYM[1])~ ~TYPEL[~TYP[1]]~
+      ~INPUT  <= ~SYM[7](~SYM[1])~ ~TYPEL[~TYP[2]]~
+    ~INST
+  end generate;~FI
+end block;~FI
 -- zipWith end"
     }
   }
@@ -217,28 +335,63 @@
     { "name"      : "CLaSH.Sized.Vector.foldr"
     , "type"      : "foldr :: (a -> b -> b) -> b -> Vec n a -> b"
     , "templateD" :
-"-- foldr begin~IF ~LENGTH[~TYP[2]] ~THEN
-foldr_~SYM[0] : block
-  type foldr_res_vec is array (natural range <>) of ~TYP[1];
-  signal intermediate_~SYM[2] : foldr_res_vec (0 to ~LENGTH[~TYP[2]]);
-  signal xs_~SYM[3] : ~TYP[2];
+"-- foldr begin~IF ~LENGTH[~TYP[2]] ~THEN ~IF ~ISVAR[2] ~THEN
+~GENSYM[foldr][0] : block
+  type ~GENSYM[foldr_res_type][1] is array (natural range <>) of ~TYP[1];
+  signal ~GENSYM[intermediate][2] : ~SYM[1] (0 to ~LENGTH[~TYP[2]]);
 begin
-  intermediate_~SYM[2](~LENGTH[~TYP[2]]) <= ~ARG[1];
-  xs_~SYM[3] <= ~ARG[2];
+  ~SYM[2](~LENGTH[~TYP[2]]) <= ~ARG[1];
 
-  foldr_loop : for i_~SYM[4] in xs_~SYM[3]'range generate
+  foldr_loop : for ~GENSYM[i][3] in ~ARG[2]'range generate~IF ~VIVADO ~THEN
+    signal ~GENSYM[foldr_in][4] : ~TYPEL[~TYP[2]];
+  begin
+    ~SYM[4] <= ~FROMBV[~ARG[2](~SYM[3])][~TYPEL[~TYP[2]]];
     ~INST 0
-      ~OUTPUT <= intermediate_~SYM[2](i_~SYM[4])~ ~TYP[1]~
-      ~INPUT  <= xs_~SYM[3](i_~SYM[4])~ ~TYPEL[~TYP[2]]~
-      ~INPUT  <= intermediate_~SYM[2](i_~SYM[4]+1)~ ~TYP[1]~
+      ~OUTPUT <= ~SYM[2](~SYM[3])~ ~TYP[1]~
+      ~INPUT  <= ~SYM[4]~ ~TYPEL[~TYP[2]]~
+      ~INPUT  <= ~SYM[2](~SYM[3]+1)~ ~TYP[1]~
     ~INST
-  end generate;
+  end generate;~ELSE
+  begin
+    ~INST 0
+      ~OUTPUT <= ~SYM[2](~SYM[3])~ ~TYP[1]~
+      ~INPUT  <= ~ARG[2](~SYM[3])~ ~TYPEL[~TYP[2]]~
+      ~INPUT  <= ~SYM[2](~SYM[3]+1)~ ~TYP[1]~
+    ~INST
+  end generate;~FI
 
-  ~RESULT <= intermediate_~SYM[2](0);
-end block;
-~ELSE
-~RESULT <= ~ARG[1];
-~FI-- foldr end"
+  ~RESULT <= ~SYM[2](0);
+end block;~ELSE
+~SYM[0] : block
+  type ~SYM[1] is array (natural range <>) of ~TYP[1];
+  signal ~SYM[2] : ~SYM[1] (0 to ~LENGTH[~TYP[2]]);
+  signal ~GENSYM[vec][5] : ~TYP[2];
+begin
+  ~SYM[5] <= ~ARG[2];
+  ~SYM[2](~LENGTH[~TYP[2]]) <= ~ARG[1];
+
+  foldr_loop : for ~SYM[3] in ~SYM[5]'range generate~IF ~VIVADO ~THEN
+    signal ~SYM[4] : ~TYPEL[~TYP[2]];
+  begin
+    ~SYM[4] <= ~FROMBV[~SYM[5](~SYM[3])][~TYPEL[~TYP[2]]];
+    ~INST 0
+      ~OUTPUT <= ~SYM[2](~SYM[3])~ ~TYP[1]~
+      ~INPUT  <= ~SYM[4]~ ~TYPEL[~TYP[2]]~
+      ~INPUT  <= ~SYM[2](~SYM[3]+1)~ ~TYP[1]~
+    ~INST
+  end generate;~ELSE
+  begin
+    ~INST 0
+      ~OUTPUT <= ~SYM[2](~SYM[3])~ ~TYP[1]~
+      ~INPUT  <= ~SYM[5](~SYM[3])~ ~TYPEL[~TYP[2]]~
+      ~INPUT  <= ~SYM[2](~SYM[3]+1)~ ~TYP[1]~
+    ~INST
+  end generate;~FI
+
+  ~RESULT <= ~SYM[2](0);
+end block;~FI~ELSE
+~RESULT <= ~ARG[1];~FI
+-- foldr end"
     }
   }
 , { "BlackBox" :
@@ -247,35 +400,45 @@
     , "comment"   : "THIS ONLY WORKS FOR POWER OF TWO LENGTH VECTORS"
     , "templateD" :
 "-- fold begin
-fold_~SYM[0] : block
+~GENSYM[fold][0] : block
   -- given a level and a depth, calculate the corresponding index into the
   -- intermediate array
-  function depth2Index (levels,depth : in natural) return natural is
+  function ~GENSYM[depth2Index][1] (levels,depth : in natural) return natural is
   begin
     return (2 ** levels - 2 ** depth);
   end function;
-
-  signal intermediate_~SYM[1] : ~TYPM[1](0 to (2*~LENGTH[~TYP[1]])-2);
-  constant levels : natural := natural (ceil (log2 (real (~LENGTH[~TYP[1]]))));
+~IF ~VIVADO ~THEN
+  type ~GENSYM[fold_res_type][2] is array(natural range <>) of ~TYPO;
+  signal ~GENSYM[intermediate][3] : ~SYM[2](0 to (2*~LENGTH[~TYP[1]])-2);~IF ~ISLIT[1] ~THEN
+  signal ~GENSYM[vec][4] : ~TYP[1];~ELSE ~FI ~ELSE
+  signal ~SYM[3] : ~TYPM[1](0 to (2*~LENGTH[~TYP[1]])-2);~FI
+  constant ~GENSYM[levels][5] : natural := natural (ceil (log2 (real (~LENGTH[~TYP[1]]))));
 begin
-  -- put input array into the first half of the intermediate array
-  intermediate_~SYM[1](0 to ~LENGTH[~TYP[1]]-1) <= ~ARG[1];
+  -- put input array into the first half of the intermediate array~IF ~VIVADO ~THEN~IF ~ISLIT[1] ~THEN
+  ~SYM[4] <= ~ARG[1];
+  ~GENSYM[fill_tree][6] : for ~GENSYM[d][7] in ~SYM[4]'range generate
+    ~SYM[3](~SYM[7]) <= ~FROMBV[~SYM[3](~SYM[7])][~TYPO];
+  end generate;~ELSE
+  ~SYM[6] : for ~SYM[7] in ~ARG[1]'range generate
+    ~SYM[3](~SYM[7]) <= ~FROMBV[~ARG[1](~SYM[7])][~TYPO];
+  end generate;~FI~ELSE
+  ~SYM[3](0 to ~LENGTH[~TYP[1]]-1) <= ~ARG[1];~FI
 
   -- Create the tree of instantiated components
-  make_tree : if levels /= 0 generate
-    tree_depth : for d in levels-1 downto 0 generate
-      tree_depth_loop: for i in 0 to (natural(2**d) - 1) generate
+  ~GENSYM[make_tree][8] : if ~SYM[5] /= 0 generate
+    ~GENSYM[tree_depth][9] : for ~GENSYM[d][10] in ~SYM[5]-1 downto 0 generate
+      ~GENSYM[tree_depth_loop][11] : for ~GENSYM[i][12] in 0 to (natural(2**~SYM[10]) - 1) generate
         ~INST 0
-          ~OUTPUT <= intermediate_~SYM[1](depth2Index(levels+1,d+1)+i)~ ~TYPO~
-          ~INPUT  <= intermediate_~SYM[1](depth2Index(levels+1,d+2)+(2*i))~ ~TYPO~
-          ~INPUT  <= intermediate_~SYM[1](depth2Index(levels+1,d+2)+(2*i)+1)~ ~TYPO~
+          ~OUTPUT <= ~SYM[3](~SYM[1](~SYM[5]+1,~SYM[10]+1)+~SYM[12])~ ~TYPO~
+          ~INPUT  <= ~SYM[3](~SYM[1](~SYM[5]+1,~SYM[10]+2)+(2*~SYM[12]))~ ~TYPO~
+          ~INPUT  <= ~SYM[3](~SYM[1](~SYM[5]+1,~SYM[10]+2)+(2*~SYM[12])+1)~ ~TYPO~
         ~INST
       end generate;
     end generate;
   end generate;
 
   -- The last element of the intermediate array holds the result
-  ~RESULT <= intermediate_~SYM[1]((2*~LENGTH[~TYP[1]])-2);
+  ~RESULT <= ~SYM[3]((2*~LENGTH[~TYP[1]])-2);
 end block;
 -- fold end"
     }
@@ -285,20 +448,29 @@
     , "type"      : "index_int :: KnownNat n => Vec n a -> Int -> a"
     , "templateD" :
 "-- index begin
-indexVec_~SYM[0] : block
-  signal vec       : ~TYP[1];
-  signal vec_index : integer range 0 to ~LIT[0]-1;
+~GENSYM[indexVec][0] : block ~IF ~ISVAR[1] ~THEN
+  signal ~GENSYM[vec_index][1] : integer range 0 to ~LIT[0]-1;
 begin
-  vec <= ~ARG[1];
-
-  vec_index <= to_integer(~ARG[2])
+  ~SYM[1] <= to_integer(~ARG[2])
   -- pragma translate_off
                mod ~LIT[0]
   -- pragma translate_on
-               ;
-
-  ~RESULT <= vec(vec_index);
-end block;
+               ;~IF ~VIVADO ~THEN
+  ~RESULT <= ~FROMBV[~ARG[1](~SYM[1])][~TYPO];~ELSE
+  ~RESULT <= ~ARG[1](~SYM[1]);~FI
+end block;~ELSE
+signal ~GENSYM[vec][2] : ~TYP[1];
+signal ~SYM[1] : integer range 0 to ~LIT[0]-1;
+begin
+  ~SYM[2] <= ~ARG[1];
+  ~SYM[1] <= to_integer(~ARG[2])
+  -- pragma translate_off
+               mod ~LIT[0]
+  -- pragma translate_on
+               ;~IF ~VIVADO ~THEN
+  ~RESULT <= ~FROMBV[~SYM[2](~SYM[1])][~TYPO];~ELSE
+  ~RESULT <= ~SYM[2](~SYM[1]);~FI
+end block;~FI
 -- index end"
     }
   }
@@ -307,25 +479,22 @@
     , "type"      : "replace_int :: KnownNat n => Vec n a -> Int -> a -> Vec n a"
     , "templateD" :
 "-- replace begin
-replaceVec_~SYM[0] : block
-  signal vec       : ~TYP[1];
-  signal vec_index : integer range 0 to ~LIT[0]-1;
-  signal din       : ~TYP[3];
+~GENSYM[replaceVec][0] : block
+  signal ~GENSYM[vec_index][1] : integer range 0 to ~LIT[0]-1;
 begin
-  vec <= ~ARG[1];
-  vec_index <= to_integer(~ARG[2])
+  ~SYM[1] <= to_integer(~ARG[2])
   -- pragma translate_off
                mod ~LIT[0]
   -- pragma translate_on
                ;
-  din <= ~ARG[3];
 
-  process(vec,vec_index,din)
-    variable ivec : ~TYP[1];
+  process(~SYM[1]~VARS[1]~VARS[3])
+    variable ~GENSYM[ivec][2] : ~TYP[1];
   begin
-    ivec := vec;
-    ivec(vec_index) := din;
-    ~RESULT <= ivec;
+    ~SYM[2] := ~ARG[1];~IF ~VIVADO ~THEN
+    ~SYM[2](~SYM[1]) := ~TOBV[~ARG[3]][~TYP[3]];~ELSE
+    ~SYM[2](~SYM[1]) := ~ARG[3];~FI
+    ~RESULT <= ~SYM[2];
   end process;
 end block;
 -- replace end"
@@ -346,7 +515,7 @@
 , { "BlackBox" :
     { "name"      : "CLaSH.Sized.Vector.replicate"
     , "type"      : "replicate :: SNat n -> a -> Vec n a"
-    , "templateE" : "~TYPMO'(0 to ~LIT[0]-1 => ~ARG[1])"
+    , "templateE" : "~TYPMO'(0 to ~LIT[0]-1 => ~IF ~VIVADO ~THEN ~TOBV[~TYPM[1]'(~ARG[1])][~TYP[1]] ~ELSE ~ARG[1] ~FI)"
     }
   }
 , { "BlackBox" :
@@ -354,14 +523,15 @@
     , "type"      : "transpose :: KnownNat n => Vec m (Vec n a) -> Vec n (Vec m a)"
     , "templateD" :
 "-- transpose begin
-transpose_~SYM[0] : block
-  signal ~SYM[1] : ~TYP[1];
+~GENSYM[transpose][0] : block
+  signal ~GENSYM[matrix][1] : ~TYP[1];
 begin
   ~SYM[1] <= ~ARG[1];
 
-  transpose_outer : for row_index in ~SYM[1]'range generate
-    transpose_inner : for col_index in ~RESULT'range generate
-      ~RESULT(col_index)(row_index) <= ~SYM[1](row_index)(col_index);
+  ~GENSYM[transpose_outer][2] : for ~GENSYM[row_index][3] in ~SYM[1]'range generate
+    ~GENSYM[transpose_inner][4] : for ~GENSYM[col_index][5] in ~RESULT'range generate~IF ~VIVADO ~THEN
+      ~RESULT(~SYM[5])((~SYM[1]'length-~SYM[3])*~SIZE[~TYPEL[~TYPEL[~TYPO]]]-1 downto (~SYM[1]'length-~SYM[3]-1)*~SIZE[~TYPEL[~TYPEL[~TYPO]]]) <= ~SYM[1](~SYM[3])((~RESULT'length-~SYM[5])*~SIZE[~TYPEL[~TYPEL[~TYPO]]]-1 downto (~RESULT'length-~SYM[5]-1)*~SIZE[~TYPEL[~TYPEL[~TYPO]]]);~ELSE
+      ~RESULT(~SYM[5])(~SYM[3]) <= ~SYM[1](~SYM[3])(~SYM[5]);~FI
     end generate;
   end generate;
 end block;
@@ -373,13 +543,12 @@
     , "type"      : "reverse :: Vec n a -> Vec n a"
     , "templateD" :
 "-- reverse begin
-reverse_~SYM[0] : block
-  signal ~SYM[1] : ~TYP[0];
+~GENSYM[reverse][0] : block
+  signal ~GENSYM[vec][1] : ~TYP[0];
 begin
   ~SYM[1] <= ~ARG[0];
-
-  reverse_loop : for ~SYM[2] in ~SYM[1]'range generate
-    ~RESULT(~SYM[1]'high - ~SYM[2]) <= ~SYM[1](~SYM[2]);
+  ~GENSYM[reverse_loop][2] : for ~GENSYM[i][3] in ~SYM[1]'range generate
+    ~RESULT(~SYM[1]'high - ~SYM[3]) <= ~SYM[1](~SYM[3]);
   end generate;
 end block;
 -- reverse end"
@@ -399,13 +568,12 @@
                   -> BitVector (n * m)"
     , "templateD" :
 "-- concatBitVector begin
-concatBitVector_~SYM[0] : block
-  signal ~SYM[1] : ~TYP[1];
+~GENSYM[concatBitVector][0] : block
+  signal ~GENSYM[vec][1] : ~TYP[1];
 begin
   ~SYM[1] <= ~ARG[1];
-
-  concatBitVectorIter_loop : for ~SYM[2] in ~SYM[1]'range generate
-    ~RESULT(((~SYM[2] * ~LIT[0]) + ~LIT[0] - 1) downto (~SYM[2] * ~LIT[0])) <= ~TYPMO(~SYM[1](~SYM[1]'high - ~SYM[2]));
+  ~GENSYM[concatBitVectorIter_loop][2] : for ~GENSYM[i][3] in ~SYM[1]'range generate
+    ~RESULT(((~SYM[3] * ~LIT[0]) + ~LIT[0] - 1) downto (~SYM[3] * ~LIT[0])) <= ~TYPMO'(~SYM[1](~SYM[1]'high - ~SYM[3]));
   end generate;
 end block;
 -- concatBitVector end"
@@ -419,13 +587,12 @@
                     -> Vec n (BitVector m)"
     , "templateD" :
 "-- unconcatBitVector begin
-unconcatBitVector_~SYM[0] : block
-  signal ~SYM[1] : ~TYP[2];
+~GENSYM[unconcatBitVector][0] : block
+  signal ~GENSYM[vec][1] : ~TYP[2];
 begin
   ~SYM[1] <= ~ARG[2];
-
-  unconcatBitVectorIter_loop : for ~SYM[2] in ~RESULT'range generate
-    ~RESULT(~RESULT'high - ~SYM[2]) <= ~SYM[1](((~SYM[2] * ~LIT[1]) + ~LIT[1] - 1) downto (~SYM[2] * ~LIT[1]));
+  ~GENSYM[unconcatBitVectorIter_loop][2] : for ~GENSYM[i][3] in ~RESULT'range generate
+    ~RESULT(~RESULT'high - ~SYM[3]) <= ~SYM[1](((~SYM[3] * ~LIT[1]) + ~LIT[1] - 1) downto (~SYM[3] * ~LIT[1]));
   end generate;
 end block;
 -- unconcatBitVector end"
@@ -436,19 +603,19 @@
     , "type"      : "rotateLeftS :: KnownNat n => Vec n a -> SNat d -> Vec n a"
     , "templateD" :
 "-- rotateLeftS begin
-rotateLeftS_~SYM[0] : block
-  signal ~SYM[1] : ~TYP[1];
-  constant shift_amount_~SYM[2] : natural := ~LIT[2] mod ~LIT[0];
+~GENSYM[rotateLeftS][0] : block
+  signal ~GENSYM[vec][1] : ~TYP[1];
+  constant ~GENSYM[shift_amount][2] : natural := ~LIT[2] mod ~LIT[0];
 begin
   ~SYM[1] <= ~ARG[1];
 
-  no_shift : if shift_amount_~SYM[2] = 0 generate
+  ~GENSYM[no_shift][3] : if ~SYM[2] = 0 generate
     ~RESULT <= ~SYM[1];
   end generate;
 
-  do_shift : if shift_amount_~SYM[2] /= 0 generate
-    ~RESULT <= ~SYM[1](shift_amount_~SYM[2] to ~LIT[0]-1) &
-               ~SYM[1](0 to shift_amount_~SYM[2]-1);
+  ~GENSYM[do_shift][4] : if ~SYM[2] /= 0 generate
+    ~RESULT <= ~SYM[1](~SYM[2] to ~LIT[0]-1) &
+               ~SYM[1](0 to ~SYM[2]-1);
   end generate;
 end block;
 -- rotateLeftS end"
@@ -459,19 +626,19 @@
     , "type"      : "rotateRightS :: KnownNat n => Vec n a -> SNat d -> Vec n a"
     , "templateD" :
 "-- rotateRightS begin
-rotateLeftS_~SYM[0] : block
-  signal ~SYM[1] : ~TYP[1];
-  constant shift_amount_~SYM[2] : natural := ~LIT[2] mod ~LIT[0];
+~GENSYM[rotateLeftS][0] : block
+  signal ~GENSYM[vec][1] : ~TYP[1];
+  constant ~GENSYM[shift_amount][2] : natural := ~LIT[2] mod ~LIT[0];
 begin
   ~SYM[1] <= ~ARG[1];
 
-  no_shift : if shift_amount_~SYM[2] = 0 generate
+  ~GENSYM[no_shift][3] : if ~SYM[2] = 0 generate
     ~RESULT <= ~SYM[1];
   end generate;
 
-  do_shift : if shift_amount_~SYM[2] /= 0 generate
-    ~RESULT <= ~SYM[1](~LIT[0]-shift_amount_~SYM[2] to ~LIT[0]-1) &
-               ~SYM[1](0 to ~LIT[0]-shift_amount_~SYM[2]-1);
+  ~GENSYM[do_shift][4] : if ~SYM[2] /= 0 generate
+    ~RESULT <= ~SYM[1](~LIT[0]-~SYM[2] to ~LIT[0]-1) &
+               ~SYM[1](0 to ~LIT[0]-~SYM[2]-1);
   end generate;
 end block;
 -- 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,8 +20,8 @@
     , "type"      : "divInt :: Int -> Int -> Int"
     , "templateD" :
 "-- divInt begin
-divInt_~SYM[0] : block
-  signal ~SYM[1] : ~TYP[1];
+~GENSYM[divInt][0] : block
+  signal ~GENSYM[quot_res][1] : ~TYP[1];
 begin
   ~SYM[1] <= ~ARG[0] / ~ARG[1];
   ~RESULT <= ~SYM[1] - 1 when ((~ARG[0] = abs ~ARG[0]) /= (~ARG[1] = abs ~ARG[1])) else
diff --git a/primitives/GHC.Classes.json b/primitives/GHC.Classes.json
--- a/primitives/GHC.Classes.json
+++ b/primitives/GHC.Classes.json
@@ -57,8 +57,8 @@
     , "type"      : "divInt# :: Int# -> Int# -> Int#"
     , "templateD" :
 "-- divInt begin
-divInt_~SYM[0] : block
-  signal ~SYM[1] : ~TYP[1];
+~GENSYM[divInt][0] : block
+  signal ~GENSYM[quot_res][1] : ~TYP[1];
 begin
   ~SYM[1] <= ~ARG[0] / ~ARG[1];
   ~RESULT <= ~SYM[1] - 1 when ((~ARG[0] = abs ~ARG[0]) /= (~ARG[1] = abs ~ARG[1])) else
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,8 +45,8 @@
     , "type"      : "divInteger :: Integer -> Integer -> Integer"
     , "templateD" :
 "-- divInteger begin
-divInteger_~SYM[0] : block
-  signal ~SYM[1] : ~TYP[1];
+~GENSYM[divInteger][0] : block
+  signal ~GENSYM[quot_res][1] : ~TYP[1];
 begin
   ~SYM[1] <= ~ARG[0] / ~ARG[1];
   ~RESULT <= ~SYM[1] - 1 when ((~ARG[0] = abs ~ARG[0]) /= (~ARG[1] = abs ~ARG[1])) else
diff --git a/primitives/GHC.Prim.json b/primitives/GHC.Prim.json
--- a/primitives/GHC.Prim.json
+++ b/primitives/GHC.Prim.json
@@ -291,37 +291,37 @@
     , "type"      : "popCnt8 :: Word# -> Word#"
     , "templateD" :
 "-- popCnt8 begin
-popCnt8_~SYM[0] : block
+~GENSYM[popCnt8][0] : block
   -- given a level and a depth, calculate the corresponding index into the
   -- intermediate array
-  function depth2Index (levels,depth : in natural) return natural is
+  function ~GENSYM[depth2Index][1] (levels,depth : in natural) return natural is
   begin
     return (2 ** levels - 2 ** depth);
   end function;
 
-  constant width : natural := 8;
-  constant levels : natural := natural (ceil (log2 (real (width))));
-  type popCnt_res_vec is array (natural range <>) of unsigned(levels downto 0);
-  signal intermediate_~SYM[1] : popCnt_res_vec(0 to (2*width)-2);
+  constant ~GENSYM[width][2] : natural := 8;
+  constant ~GENSYM[levels][3] : natural := natural (ceil (log2 (real (~SYM[2]))));
+  type ~GENSYM[popCnt_res_vec][4] is array (natural range <>) of unsigned(~SYM[3] downto 0);
+  signal ~GENSYM[intermediate][5] : ~SYM[4](0 to (2*~SYM[2])-2);
 begin
   -- put input into the first half of the intermediate array
-  make_array: for i in 0 to (width - 1) generate
-    intermediate_~SYM[1](i) <= resize(~ARG[0](i downto i),levels+1);
+  ~GENSYM[make_array][6]: for ~GENSYM[i][7] in 0 to (~SYM[2] - 1) generate
+    ~SYM[5](i) <= resize(~ARG[0](~SYM[7] downto ~SYM[7]),~SYM[3]+1);
   end generate;
 
   -- Create the tree of adders
-  make_tree : if levels /= 0 generate
-    tree_depth : for d in levels-1 downto 0 generate
-      tree_depth_loop: for i in 0 to (natural(2**d) - 1) generate
-        intermediate_~SYM[1](depth2Index(levels+1,d+1)+i) <=
-          intermediate_~SYM[1](depth2Index(levels+1,d+2)+(2*i)) +
-          intermediate_~SYM[1](depth2Index(levels+1,d+2)+(2*i)+1);
+  ~GENSYM[make_tree][8] : if ~SYM[3] /= 0 generate
+    ~GENSYM[tree_depth][9] : for ~GENSYM[d][10] in ~SYM[3]-1 downto 0 generate
+      ~GENSYM[tree_depth_loop][11] : for ~GENSYM[i][12] in 0 to (natural(2**~SYM[10]) - 1) generate
+        ~SYM[5](~SYM[1](~SYM[3]+1,~SYM[10]+1)+~SYM[12]) <=
+          ~SYM[5](~SYM[1](~SYM[3]+1,~SYM[10]+2)+(2*~SYM[12])) +
+          ~SYM[5](~SYM[1](~SYM[3]+1,~SYM[10]+2)+(2*~SYM[12])+1);
       end generate;
     end generate;
   end generate;
 
   -- The last element of the intermediate array holds the result
-  ~RESULT <= resize(intermediate_~SYM[1]((2*width)-2),~SIZE[~TYPO]);
+  ~RESULT <= resize(~SYM[5]((2*~SYM[2])-2),~SIZE[~TYPO]);
 end block;
 -- popCnt8 end"
     }
@@ -331,37 +331,37 @@
     , "type"      : "popCnt16 :: Word# -> Word#"
     , "templateD" :
 "-- popCnt16 begin
-popCnt16_~SYM[0] : block
+~GENSYM[popCnt16][0] : block
   -- given a level and a depth, calculate the corresponding index into the
   -- intermediate array
-  function depth2Index (levels,depth : in natural) return natural is
+  function ~GENSYM[depth2Index][1] (levels,depth : in natural) return natural is
   begin
     return (2 ** levels - 2 ** depth);
   end function;
 
-  constant width : natural := 16;
-  constant levels : natural := natural (ceil (log2 (real (width))));
-  type popCnt_res_vec is array (natural range <>) of unsigned(levels downto 0);
-  signal intermediate_~SYM[1] : popCnt_res_vec(0 to (2*width)-2);
+  constant ~GENSYM[width][2] : natural := 16;
+  constant ~GENSYM[levels][3] : natural := natural (ceil (log2 (real (~SYM[2]))));
+  type ~GENSYM[popCnt_res_vec][4] is array (natural range <>) of unsigned(~SYM[3] downto 0);
+  signal ~GENSYM[intermediate][5] : ~SYM[4](0 to (2*~SYM[2])-2);
 begin
   -- put input into the first half of the intermediate array
-  make_array: for i in 0 to (width - 1) generate
-    intermediate_~SYM[1](i) <= resize(~ARG[0](i downto i),levels+1);
+  ~GENSYM[make_array][6]: for ~GENSYM[i][7] in 0 to (~SYM[2] - 1) generate
+    ~SYM[5](i) <= resize(~ARG[0](~SYM[7] downto ~SYM[7]),~SYM[3]+1);
   end generate;
 
   -- Create the tree of adders
-  make_tree : if levels /= 0 generate
-    tree_depth : for d in levels-1 downto 0 generate
-      tree_depth_loop: for i in 0 to (natural(2**d) - 1) generate
-        intermediate_~SYM[1](depth2Index(levels+1,d+1)+i) <=
-          intermediate_~SYM[1](depth2Index(levels+1,d+2)+(2*i)) +
-          intermediate_~SYM[1](depth2Index(levels+1,d+2)+(2*i)+1);
+  ~GENSYM[make_tree][8] : if ~SYM[3] /= 0 generate
+    ~GENSYM[tree_depth][9] : for ~GENSYM[d][10] in ~SYM[3]-1 downto 0 generate
+      ~GENSYM[tree_depth_loop][11] : for ~GENSYM[i][12] in 0 to (natural(2**~SYM[10]) - 1) generate
+        ~SYM[5](~SYM[1](~SYM[3]+1,~SYM[10]+1)+~SYM[12]) <=
+          ~SYM[5](~SYM[1](~SYM[3]+1,~SYM[10]+2)+(2*~SYM[12])) +
+          ~SYM[5](~SYM[1](~SYM[3]+1,~SYM[10]+2)+(2*~SYM[12])+1);
       end generate;
     end generate;
   end generate;
 
   -- The last element of the intermediate array holds the result
-  ~RESULT <= resize(intermediate_~SYM[1]((2*width)-2),~SIZE[~TYPO]);
+  ~RESULT <= resize(~SYM[5]((2*~SYM[2])-2),~SIZE[~TYPO]);
 end block;
 -- popCnt16 end"
     }
@@ -371,37 +371,37 @@
     , "type"      : "popCnt16 :: Word# -> Word#"
     , "templateD" :
 "-- popCnt32 begin
-popCnt32_~SYM[0] : block
+~GENSYM[popCnt32][0] : block
   -- given a level and a depth, calculate the corresponding index into the
   -- intermediate array
-  function depth2Index (levels,depth : in natural) return natural is
+  function ~GENSYM[depth2Index][1] (levels,depth : in natural) return natural is
   begin
     return (2 ** levels - 2 ** depth);
   end function;
 
-  constant width : natural := 32;
-  constant levels : natural := natural (ceil (log2 (real (width))));
-  type popCnt_res_vec is array (natural range <>) of unsigned(levels downto 0);
-  signal intermediate_~SYM[1] : popCnt_res_vec(0 to (2*width)-2);
+  constant ~GENSYM[width][2] : natural := 32;
+  constant ~GENSYM[levels][3] : natural := natural (ceil (log2 (real (~SYM[2]))));
+  type ~GENSYM[popCnt_res_vec][4] is array (natural range <>) of unsigned(~SYM[3] downto 0);
+  signal ~GENSYM[intermediate][5] : ~SYM[4](0 to (2*~SYM[2])-2);
 begin
   -- put input into the first half of the intermediate array
-  make_array: for i in 0 to (width - 1) generate
-    intermediate_~SYM[1](i) <= resize(~ARG[0](i downto i),levels+1);
+  ~GENSYM[make_array][6]: for ~GENSYM[i][7] in 0 to (~SYM[2] - 1) generate
+    ~SYM[5](i) <= resize(~ARG[0](~SYM[7] downto ~SYM[7]),~SYM[3]+1);
   end generate;
 
   -- Create the tree of adders
-  make_tree : if levels /= 0 generate
-    tree_depth : for d in levels-1 downto 0 generate
-      tree_depth_loop: for i in 0 to (natural(2**d) - 1) generate
-        intermediate_~SYM[1](depth2Index(levels+1,d+1)+i) <=
-          intermediate_~SYM[1](depth2Index(levels+1,d+2)+(2*i)) +
-          intermediate_~SYM[1](depth2Index(levels+1,d+2)+(2*i)+1);
+  ~GENSYM[make_tree][8] : if ~SYM[3] /= 0 generate
+    ~GENSYM[tree_depth][9] : for ~GENSYM[d][10] in ~SYM[3]-1 downto 0 generate
+      ~GENSYM[tree_depth_loop][11] : for ~GENSYM[i][12] in 0 to (natural(2**~SYM[10]) - 1) generate
+        ~SYM[5](~SYM[1](~SYM[3]+1,~SYM[10]+1)+~SYM[12]) <=
+          ~SYM[5](~SYM[1](~SYM[3]+1,~SYM[10]+2)+(2*~SYM[12])) +
+          ~SYM[5](~SYM[1](~SYM[3]+1,~SYM[10]+2)+(2*~SYM[12])+1);
       end generate;
     end generate;
   end generate;
 
   -- The last element of the intermediate array holds the result
-  ~RESULT <= resize(intermediate_~SYM[1]((2*width)-2),~SIZE[~TYPO]);
+  ~RESULT <= resize(~SYM[5]((2*~SYM[2])-2),~SIZE[~TYPO]);
 end block;
 -- popCnt32 end"
     }
@@ -411,37 +411,37 @@
     , "type"      : "popCnt16 :: Word# -> Word#"
     , "templateD" :
 "-- popCnt64 begin
-popCnt64_~SYM[0] : block
+~GENSYM[popCnt64][0] : block
   -- given a level and a depth, calculate the corresponding index into the
   -- intermediate array
-  function depth2Index (levels,depth : in natural) return natural is
+  function ~GENSYM[depth2Index][1] (levels,depth : in natural) return natural is
   begin
     return (2 ** levels - 2 ** depth);
   end function;
 
-  constant width : natural := 64;
-  constant levels : natural := natural (ceil (log2 (real (width))));
-  type popCnt_res_vec is array (natural range <>) of unsigned(levels downto 0);
-  signal intermediate_~SYM[1] : popCnt_res_vec(0 to (2*width)-2);
+  constant ~GENSYM[width][2] : natural := 64;
+  constant ~GENSYM[levels][3] : natural := natural (ceil (log2 (real (~SYM[2]))));
+  type ~GENSYM[popCnt_res_vec][4] is array (natural range <>) of unsigned(~SYM[3] downto 0);
+  signal ~GENSYM[intermediate][5] : ~SYM[4](0 to (2*~SYM[2])-2);
 begin
   -- put input into the first half of the intermediate array
-  make_array: for i in 0 to (width - 1) generate
-    intermediate_~SYM[1](i) <= resize(~ARG[0](i downto i),levels+1);
+  ~GENSYM[make_array][6]: for ~GENSYM[i][7] in 0 to (~SYM[2] - 1) generate
+    ~SYM[5](i) <= resize(~ARG[0](~SYM[7] downto ~SYM[7]),~SYM[3]+1);
   end generate;
 
   -- Create the tree of adders
-  make_tree : if levels /= 0 generate
-    tree_depth : for d in levels-1 downto 0 generate
-      tree_depth_loop: for i in 0 to (natural(2**d) - 1) generate
-        intermediate_~SYM[1](depth2Index(levels+1,d+1)+i) <=
-          intermediate_~SYM[1](depth2Index(levels+1,d+2)+(2*i)) +
-          intermediate_~SYM[1](depth2Index(levels+1,d+2)+(2*i)+1);
+  ~GENSYM[make_tree][8] : if ~SYM[3] /= 0 generate
+    ~GENSYM[tree_depth][9] : for ~GENSYM[d][10] in ~SYM[3]-1 downto 0 generate
+      ~GENSYM[tree_depth_loop][11] : for ~GENSYM[i][12] in 0 to (natural(2**~SYM[10]) - 1) generate
+        ~SYM[5](~SYM[1](~SYM[3]+1,~SYM[10]+1)+~SYM[12]) <=
+          ~SYM[5](~SYM[1](~SYM[3]+1,~SYM[10]+2)+(2*~SYM[12])) +
+          ~SYM[5](~SYM[1](~SYM[3]+1,~SYM[10]+2)+(2*~SYM[12])+1);
       end generate;
     end generate;
   end generate;
 
   -- The last element of the intermediate array holds the result
-  ~RESULT <= resize(intermediate_~SYM[1]((2*width)-2),~SIZE[~TYPO]);
+  ~RESULT <= resize(~SYM[5]((2*~SYM[2])-2),~SIZE[~TYPO]);
 end block;
 -- popCnt64 end"
     }
@@ -451,37 +451,37 @@
     , "type"      : "popCnt :: Word# -> Word#"
     , "templateD" :
 "-- popCnt begin
-popCnt_~SYM[0] : block
+~GENSYM[popCnt][0] : block
   -- given a level and a depth, calculate the corresponding index into the
   -- intermediate array
-  function depth2Index (levels,depth : in natural) return natural is
+  function ~GENSYM[depth2Index][1] (levels,depth : in natural) return natural is
   begin
     return (2 ** levels - 2 ** depth);
   end function;
 
-  constant width : natural := ~SIZE[~TYPO];
-  constant levels : natural := natural (ceil (log2 (real (width))));
-  type popCnt_res_vec is array (natural range <>) of unsigned(levels downto 0);
-  signal intermediate_~SYM[1] : popCnt_res_vec(0 to (2*width)-2);
+  constant ~GENSYM[width][2] : natural := ~SIZE[~TYPO];
+  constant ~GENSYM[levels][3] : natural := natural (ceil (log2 (real (~SYM[2]))));
+  type ~GENSYM[popCnt_res_vec][4] is array (natural range <>) of unsigned(~SYM[3] downto 0);
+  signal ~GENSYM[intermediate][5] : ~SYM[4](0 to (2*~SYM[2])-2);
 begin
   -- put input into the first half of the intermediate array
-  make_array: for i in 0 to (width - 1) generate
-    intermediate_~SYM[1](i) <= resize(~ARG[0](i downto i),levels+1);
+  ~GENSYM[make_array][6]: for ~GENSYM[i][7] in 0 to (~SYM[2] - 1) generate
+    ~SYM[5](i) <= resize(~ARG[0](~SYM[7] downto ~SYM[7]),~SYM[3]+1);
   end generate;
 
   -- Create the tree of adders
-  make_tree : if levels /= 0 generate
-    tree_depth : for d in levels-1 downto 0 generate
-      tree_depth_loop: for i in 0 to (natural(2**d) - 1) generate
-        intermediate_~SYM[1](depth2Index(levels+1,d+1)+i) <=
-          intermediate_~SYM[1](depth2Index(levels+1,d+2)+(2*i)) +
-          intermediate_~SYM[1](depth2Index(levels+1,d+2)+(2*i)+1);
+  ~GENSYM[make_tree][8] : if ~SYM[3] /= 0 generate
+    ~GENSYM[tree_depth][9] : for ~GENSYM[d][10] in ~SYM[3]-1 downto 0 generate
+      ~GENSYM[tree_depth_loop][11] : for ~GENSYM[i][12] in 0 to (natural(2**~SYM[10]) - 1) generate
+        ~SYM[5](~SYM[1](~SYM[3]+1,~SYM[10]+1)+~SYM[12]) <=
+          ~SYM[5](~SYM[1](~SYM[3]+1,~SYM[10]+2)+(2*~SYM[12])) +
+          ~SYM[5](~SYM[1](~SYM[3]+1,~SYM[10]+2)+(2*~SYM[12])+1);
       end generate;
     end generate;
   end generate;
 
   -- The last element of the intermediate array holds the result
-  ~RESULT <= resize(intermediate_~SYM[1]((2*width)-2),~SIZE[~TYPO]);
+  ~RESULT <= resize(~SYM[5]((2*~SYM[2])-2),~SIZE[~TYPO]);
 end block;
 -- popCnt end"
     }
@@ -491,8 +491,8 @@
     , "type"      : "clz8 :: Word# -> Word#"
     , "templateD" :
 "-- clz8 begin
-clz8~SYM[0] : block
-  function enc(constant a : unsigned(1 downto 0)) return unsigned is
+~GENSYM[clz8][0] : block
+  function ~GENSYM[enc][1] (constant a : unsigned(1 downto 0)) return unsigned is
   begin
     case a is
       when \"00\" => return \"10\";
@@ -502,7 +502,7 @@
     end case;
   end function;
 
-  function clzi(
+  function ~GENSYM[clzi][2] (
     constant n : in natural;
     constant i : in unsigned) return unsigned is
     variable v : unsigned(i'length-1 downto 0):=i;
@@ -514,16 +514,16 @@
     end if;
   end function;
 
-  function clz8 (constant v : unsigned(0 to 7)) return unsigned is
+  function ~GENSYM[clz8][3] (constant v : unsigned(0 to 7)) return unsigned is
     variable e : unsigned(0 to 7);     -- 8
     variable a : unsigned(0 to 2*3-1); -- 6
   begin
-    for i in 0 to 3 loop e(i*2 to i*2+1):=enc(v(i*2 to i*2+1));    end loop;
-    for i in 0 to 1 loop a(i*3 to i*3+2):=clzi(2,e(i*4 to i*4+3)); end loop;
-    return clzi(3,a(0 to 5));
+    for i in 0 to 3 loop e(i*2 to i*2+1):=~SYM[1](v(i*2 to i*2+1));    end loop;
+    for i in 0 to 1 loop a(i*3 to i*3+2):=~SYM[2](2,e(i*4 to i*4+3)); end loop;
+    return ~SYM[2](3,a(0 to 5));
   end function;
 begin
-  ~RESULT <= resize(clz8(~ARG[0](7 downto 0)),~SIZE[~TYPO]);
+  ~RESULT <= resize(~SYM[3](~ARG[0](7 downto 0)),~SIZE[~TYPO]);
 end block;
 -- clz8 end"
     }
@@ -534,7 +534,7 @@
     , "templateD" :
 "-- clz16 begin
 clz16~SYM[0] : block
-  function enc(constant a : unsigned(1 downto 0)) return unsigned is
+  function ~GENSYM[enc][1] (constant a : unsigned(1 downto 0)) return unsigned is
   begin
     case a is
       when \"00\" => return \"10\";
@@ -544,7 +544,7 @@
     end case;
   end function;
 
-  function clzi(
+  function ~GENSYM[clzi][2] (
     constant n : in natural;
     constant i : in unsigned) return unsigned is
     variable v : unsigned(i'length-1 downto 0):=i;
@@ -556,18 +556,18 @@
     end if;
   end function;
 
-  function clz16 (constant v : unsigned(0 to 15)) return unsigned is
+  function ~GENSYM[clz16][3] (constant v : unsigned(0 to 15)) return unsigned is
     variable e : unsigned(0 to 15);    -- 16
     variable a : unsigned(0 to 4*3-1); -- 12
     variable b : unsigned(0 to 2*4-1); -- 8
   begin
-    for i in 0 to 7 loop e(i*2 to i*2+1):=enc(v(i*2 to i*2+1));    end loop;
-    for i in 0 to 3 loop a(i*3 to i*3+2):=clzi(2,e(i*4 to i*4+3)); end loop;
-    for i in 0 to 1 loop b(i*4 to i*4+3):=clzi(3,a(i*6 to i*6+5)); end loop;
-    return clzi(4,b(0 to 7));
+    for i in 0 to 7 loop e(i*2 to i*2+1):=~SYM[1](v(i*2 to i*2+1));    end loop;
+    for i in 0 to 3 loop a(i*3 to i*3+2):=~SYM[2](2,e(i*4 to i*4+3)); end loop;
+    for i in 0 to 1 loop b(i*4 to i*4+3):=~SYM[2](3,a(i*6 to i*6+5)); end loop;
+    return ~SYM[2](4,b(0 to 7));
   end function;
 begin
-  ~RESULT <= resize(clz16(~ARG[0](15 downto 0)),~SIZE[~TYPO]);
+  ~RESULT <= resize(~SYM[3](~ARG[0](15 downto 0)),~SIZE[~TYPO]);
 end block;
 -- clz16 end"
     }
@@ -578,7 +578,7 @@
     , "templateD" :
 "-- clz32 begin
 clz32~SYM[0] : block
-  function enc(constant a : unsigned(1 downto 0)) return unsigned is
+  function ~GENSYM[enc][1] (constant a : unsigned(1 downto 0)) return unsigned is
   begin
     case a is
       when \"00\" => return \"10\";
@@ -588,7 +588,7 @@
     end case;
   end function;
 
-  function clzi(
+  function ~GENSYM[clzi][2] (
     constant n : in natural;
     constant i : in unsigned) return unsigned is
     variable v : unsigned(i'length-1 downto 0):=i;
@@ -600,20 +600,20 @@
     end if;
   end function;
 
-  function clz32 (constant v : unsigned(0 to 31)) return unsigned is
+  function ~GENSYM[clz32][3] (constant v : unsigned(0 to 31)) return unsigned is
     variable e : unsigned(0 to 31);    -- 32
     variable a : unsigned(0 to 8*3-1); -- 24
     variable b : unsigned(0 to 4*4-1); -- 16
     variable c : unsigned(0 to 2*5-1); -- 10
   begin
-    for i in 0 to 15 loop e(i*2 to i*2+1):=enc(v(i*2 to i*2+1));    end loop;
-    for i in 0 to 7  loop a(i*3 to i*3+2):=clzi(2,e(i*4 to i*4+3)); end loop;
-    for i in 0 to 3  loop b(i*4 to i*4+3):=clzi(3,a(i*6 to i*6+5)); end loop;
-    for i in 0 to 1  loop c(i*5 to i*5+4):=clzi(4,b(i*8 to i*8+7)); end loop;
-    return clzi(5,c(0 to 9));
+    for i in 0 to 15 loop e(i*2 to i*2+1):=~SYM[1](v(i*2 to i*2+1));    end loop;
+    for i in 0 to 7  loop a(i*3 to i*3+2):=~SYM[2](2,e(i*4 to i*4+3)); end loop;
+    for i in 0 to 3  loop b(i*4 to i*4+3):=~SYM[2](3,a(i*6 to i*6+5)); end loop;
+    for i in 0 to 1  loop c(i*5 to i*5+4):=~SYM[2](4,b(i*8 to i*8+7)); end loop;
+    return ~SYM[2](5,c(0 to 9));
   end function;
 begin
-  ~RESULT <= resize(clz32(~ARG[0](31 downto 0)),~SIZE[~TYPO]);
+  ~RESULT <= resize(~SYM[3](~ARG[0](31 downto 0)),~SIZE[~TYPO]);
 end block;
 -- clz32 end"
     }
@@ -624,7 +624,7 @@
     , "templateD" :
 "-- clz64 begin
 clz64~SYM[0] : block
-  function enc(constant a : unsigned(1 downto 0)) return unsigned is
+  function ~GENSYM[enc][1] (constant a : unsigned(1 downto 0)) return unsigned is
   begin
     case a is
       when \"00\" => return \"10\";
@@ -634,7 +634,7 @@
     end case;
   end function;
 
-  function clzi(
+  function ~GENSYM[clzi][2] (
     constant n : in natural;
     constant i : in unsigned) return unsigned is
     variable v : unsigned(i'length-1 downto 0):=i;
@@ -646,22 +646,22 @@
     end if;
   end function;
 
-  function clz64 (constant v : unsigned(0 to 63)) return unsigned is
+  function ~GENSYM[clz64][3] (constant v : unsigned(0 to 63)) return unsigned is
     variable e : unsigned(0 to 63);     -- 64
     variable a : unsigned(0 to 16*3-1); -- 48
     variable b : unsigned(0 to 8*4-1);  -- 32
     variable c : unsigned(0 to 4*5-1);  -- 20
     variable d : unsigned(0 to 2*6-1);  -- 12
   begin
-    for i in 0 to 31 loop e(i*2 to i*2+1):=enc(v(i*2 to i*2+1));      end loop;
-    for i in 0 to 15 loop a(i*3 to i*3+2):=clzi(2,e(i*4 to i*4+3));   end loop;
-    for i in 0 to 7  loop b(i*4 to i*4+3):=clzi(3,a(i*6 to i*6+5));   end loop;
-    for i in 0 to 3  loop c(i*5 to i*5+4):=clzi(4,b(i*8 to i*8+7));   end loop;
-    for i in 0 to 1  loop d(i*6 to i*6+5):=clzi(5,c(i*10 to i*10+9)); end loop;
-    return clzi(6,d(0 to 11));
+    for i in 0 to 31 loop e(i*2 to i*2+1):=~SYM[1](v(i*2 to i*2+1));      end loop;
+    for i in 0 to 15 loop a(i*3 to i*3+2):=~SYM[2](2,e(i*4 to i*4+3));   end loop;
+    for i in 0 to 7  loop b(i*4 to i*4+3):=~SYM[2](3,a(i*6 to i*6+5));   end loop;
+    for i in 0 to 3  loop c(i*5 to i*5+4):=~SYM[2](4,b(i*8 to i*8+7));   end loop;
+    for i in 0 to 1  loop d(i*6 to i*6+5):=~SYM[2](5,c(i*10 to i*10+9)); end loop;
+    return ~SYM[2](6,d(0 to 11));
   end function;
 begin
-  ~RESULT <= resize(clz64(~ARG[0]),~SIZE[~TYPO]);
+  ~RESULT <= resize(~SYM[3](~ARG[0]),~SIZE[~TYPO]);
 end block;
 -- clz64 end"
     }
@@ -672,7 +672,7 @@
     , "templateD" :
 "-- clz begin
 clz~SYM[0] : block
-  function enc(constant a : unsigned(1 downto 0)) return unsigned is
+  function ~GENSYM[enc][1] (constant a : unsigned(1 downto 0)) return unsigned is
   begin
     case a is
       when \"00\" => return \"10\";
@@ -682,7 +682,7 @@
     end case;
   end function;
 
-  function clzi(
+  function ~GENSYM[clzi][2] (
     constant n : in natural;
     constant i : in unsigned) return unsigned is
     variable v : unsigned(i'length-1 downto 0):=i;
@@ -694,39 +694,39 @@
     end if;
   end function;
 ~IF ~IW64 ~THEN
-  function clz64 (constant v : unsigned(0 to 63)) return unsigned is
+  function ~GENSYM[clz64][3] (constant v : unsigned(0 to 63)) return unsigned is
     variable e : unsigned(0 to 63);     -- 64
     variable a : unsigned(0 to 16*3-1); -- 48
     variable b : unsigned(0 to 8*4-1);  -- 32
     variable c : unsigned(0 to 4*5-1);  -- 20
     variable d : unsigned(0 to 2*6-1);  -- 12
   begin
-    for i in 0 to 31 loop e(i*2 to i*2+1):=enc(v(i*2 to i*2+1));      end loop;
-    for i in 0 to 15 loop a(i*3 to i*3+2):=clzi(2,e(i*4 to i*4+3));   end loop;
-    for i in 0 to 7  loop b(i*4 to i*4+3):=clzi(3,a(i*6 to i*6+5));   end loop;
-    for i in 0 to 3  loop c(i*5 to i*5+4):=clzi(4,b(i*8 to i*8+7));   end loop;
-    for i in 0 to 1  loop d(i*6 to i*6+5):=clzi(5,c(i*10 to i*10+9)); end loop;
-    return clzi(6,d(0 to 11));
+    for i in 0 to 31 loop e(i*2 to i*2+1):=~SYM[1](v(i*2 to i*2+1));      end loop;
+    for i in 0 to 15 loop a(i*3 to i*3+2):=~SYM[2](2,e(i*4 to i*4+3));   end loop;
+    for i in 0 to 7  loop b(i*4 to i*4+3):=~SYM[2](3,a(i*6 to i*6+5));   end loop;
+    for i in 0 to 3  loop c(i*5 to i*5+4):=~SYM[2](4,b(i*8 to i*8+7));   end loop;
+    for i in 0 to 1  loop d(i*6 to i*6+5):=~SYM[2](5,c(i*10 to i*10+9)); end loop;
+    return ~SYM[2](6,d(0 to 11));
   end function;
 ~ELSE
-  function clz32 (constant v : unsigned(0 to 31)) return unsigned is
+  function ~GENSYM[clz32][4] (constant v : unsigned(0 to 31)) return unsigned is
     variable e : unsigned(0 to 31);    -- 32
     variable a : unsigned(0 to 8*3-1); -- 24
     variable b : unsigned(0 to 4*4-1); -- 16
     variable c : unsigned(0 to 2*5-1); -- 10
   begin
-    for i in 0 to 15 loop e(i*2 to i*2+1):=enc(v(i*2 to i*2+1));    end loop;
-    for i in 0 to 7  loop a(i*3 to i*3+2):=clzi(2,e(i*4 to i*4+3)); end loop;
-    for i in 0 to 3  loop b(i*4 to i*4+3):=clzi(3,a(i*6 to i*6+5)); end loop;
-    for i in 0 to 1  loop c(i*5 to i*5+4):=clzi(4,b(i*8 to i*8+7)); end loop;
-    return clzi(5,c(0 to 9));
+    for i in 0 to 15 loop e(i*2 to i*2+1):=~SYM[1](v(i*2 to i*2+1));    end loop;
+    for i in 0 to 7  loop a(i*3 to i*3+2):=~SYM[2](2,e(i*4 to i*4+3)); end loop;
+    for i in 0 to 3  loop b(i*4 to i*4+3):=~SYM[2](3,a(i*6 to i*6+5)); end loop;
+    for i in 0 to 1  loop c(i*5 to i*5+4):=~SYM[2](4,b(i*8 to i*8+7)); end loop;
+    return ~SYM[2](5,c(0 to 9));
   end function;
 ~FI
 begin
 ~IF ~IW64 ~THEN
-  ~RESULT <= resize(clz64(~ARG[0]),~SIZE[~TYPO]);
+  ~RESULT <= resize(~SYM[3](~ARG[0]),~SIZE[~TYPO]);
 ~ELSE
-  ~RESULT <= resize(clz32(~ARG[0]),~SIZE[~TYPO]);
+  ~RESULT <= resize(~SYM[4](~ARG[0]),~SIZE[~TYPO]);
 ~FI
 end block;
 -- clz end"
@@ -737,8 +737,8 @@
     , "type"      : "ctz8 :: Word# -> Word#"
     , "templateD" :
 "-- ctz8 begin
-ctz8~SYM[0] : block
-  function enc(constant a : unsigned(1 downto 0)) return unsigned is
+~GENSYM[ctz8][0] : block
+  function ~GENSYM[enc][1] (constant a : unsigned(1 downto 0)) return unsigned is
   begin
     case a is
       when \"00\" => return \"10\";
@@ -748,7 +748,7 @@
     end case;
   end function;
 
-  function clzi(
+  function ~GENSYM[clzi][2] (
     constant n : in natural;
     constant i : in unsigned) return unsigned is
     variable v : unsigned(i'length-1 downto 0):=i;
@@ -760,26 +760,26 @@
     end if;
   end function;
 
-  function clz8 (constant v : unsigned(0 to 7)) return unsigned is
+  function ~GENSYM[clz8][3] (constant v : unsigned(0 to 7)) return unsigned is
     variable e : unsigned(0 to 7);     -- 8
     variable a : unsigned(0 to 2*3-1); -- 6
   begin
-    for i in 0 to 3 loop e(i*2 to i*2+1):=enc(v(i*2 to i*2+1));    end loop;
-    for i in 0 to 1 loop a(i*3 to i*3+2):=clzi(2,e(i*4 to i*4+3)); end loop;
-    return clzi(3,a(0 to 5));
+    for i in 0 to 3 loop e(i*2 to i*2+1):=~SYM[1](v(i*2 to i*2+1));    end loop;
+    for i in 0 to 1 loop a(i*3 to i*3+2):=~SYM[2](2,e(i*4 to i*4+3)); end loop;
+    return ~SYM[2](3,a(0 to 5));
   end function;
 
-  signal ~SYM[1] : ~TYP[0];
-  signal ~SYM[2] : ~TYP[0];
+  signal ~GENSYM[s][4] : ~TYP[0];
+  signal ~GENSYM[s_reversed][5] : ~TYP[0];
 begin
-  ~SYM[1] <= ~ARG[0];
-  reverse_loop : for ~SYM[3] in ~SYM[1]'range generate
-    ~SYM[2](~SYM[1]'high - ~SYM[3]) <= ~SYM[1](~SYM[3]);
+  ~SYM[4] <= ~ARG[0];
+  ~GENSYM[reverse_loop][6] : for ~GENSYM[n][7] in ~SYM[4]'range generate
+    ~SYM[5](~SYM[4]'high - ~SYM[7]) <= ~SYM[4](~SYM[7]);
   end generate;
 ~IF ~IW64 ~THEN
-  ~RESULT <= resize(clz8(~SYM[2](63 downto 56)),~SIZE[~TYPO]);
+  ~RESULT <= resize(~SYM[3](~SYM[5](63 downto 56)),~SIZE[~TYPO]);
 ~ELSE
-  ~RESULT <= resize(clz8(~SYM[2](31 downto 24)),~SIZE[~TYPO]);
+  ~RESULT <= resize(~SYM[3](~SYM[5](31 downto 24)),~SIZE[~TYPO]);
 ~FI
 end block;
 -- ctz8 end"
@@ -790,8 +790,8 @@
     , "type"      : "ctz16 :: Word# -> Word#"
     , "templateD" :
 "-- ctz16 begin
-ctz16~SYM[0] : block
-  function enc(constant a : unsigned(1 downto 0)) return unsigned is
+~GENSYM[ctz16][0] : block
+  function ~GENSYM[enc][1] (constant a : unsigned(1 downto 0)) return unsigned is
   begin
     case a is
       when \"00\" => return \"10\";
@@ -801,7 +801,7 @@
     end case;
   end function;
 
-  function clzi(
+  function ~GENSYM[clzi][2] (
     constant n : in natural;
     constant i : in unsigned) return unsigned is
     variable v : unsigned(i'length-1 downto 0):=i;
@@ -813,28 +813,28 @@
     end if;
   end function;
 
-  function clz16 (constant v : unsigned(0 to 15)) return unsigned is
+  function ~GENSYM[clz16][3] (constant v : unsigned(0 to 15)) return unsigned is
     variable e : unsigned(0 to 15);    -- 16
     variable a : unsigned(0 to 4*3-1); -- 12
     variable b : unsigned(0 to 2*4-1); -- 8
   begin
-    for i in 0 to 7 loop e(i*2 to i*2+1):=enc(v(i*2 to i*2+1));    end loop;
-    for i in 0 to 3 loop a(i*3 to i*3+2):=clzi(2,e(i*4 to i*4+3)); end loop;
-    for i in 0 to 1 loop b(i*4 to i*4+3):=clzi(3,a(i*6 to i*6+5)); end loop;
-    return clzi(4,b(0 to 7));
+    for i in 0 to 7 loop e(i*2 to i*2+1):=~SYM[1](v(i*2 to i*2+1));    end loop;
+    for i in 0 to 3 loop a(i*3 to i*3+2):=~SYM[2](2,e(i*4 to i*4+3)); end loop;
+    for i in 0 to 1 loop b(i*4 to i*4+3):=~SYM[2](3,a(i*6 to i*6+5)); end loop;
+    return ~SYM[2](4,b(0 to 7));
   end function;
 
-  signal ~SYM[1] : ~TYP[0];
-  signal ~SYM[2] : ~TYP[0];
+  signal ~GENSYM[s][4] : ~TYP[0];
+  signal ~GENSYM[s_reversed][5] : ~TYP[0];
 begin
-  ~SYM[1] <= ~ARG[0];
-  reverse_loop : for ~SYM[3] in ~SYM[1]'range generate
-    ~SYM[2](~SYM[1]'high - ~SYM[3]) <= ~SYM[1](~SYM[3]);
+  ~SYM[4] <= ~ARG[0];
+  ~GENSYM[reverse_loop][6] : for ~GENSYM[n][7] in ~SYM[4]'range generate
+    ~SYM[5](~SYM[4]'high - ~SYM[7]) <= ~SYM[4](~SYM[7]);
   end generate;
 ~IF ~IW64 ~THEN
-  ~RESULT <= resize(clz16(~SYM[2](63 downto 48)),~SIZE[~TYPO]);
+  ~RESULT <= resize(~SYM[3](~SYM[5](63 downto 48)),~SIZE[~TYPO]);
 ~ELSE
-  ~RESULT <= resize(clz16(~SYM[2](31 downto 16)),~SIZE[~TYPO]);
+  ~RESULT <= resize(~SYM[3](~SYM[5](31 downto 16)),~SIZE[~TYPO]);
 ~FI
 end block;
 -- ctz16 end"
@@ -845,8 +845,8 @@
     , "type"      : "ctz32 :: Word# -> Word#"
     , "templateD" :
 "-- ctz32 begin
-ctz32~SYM[0] : block
-  function enc(constant a : unsigned(1 downto 0)) return unsigned is
+~GENSYM[ctz32][0] : block
+  function ~GENSYM[enc][1] (constant a : unsigned(1 downto 0)) return unsigned is
   begin
     case a is
       when \"00\" => return \"10\";
@@ -856,7 +856,7 @@
     end case;
   end function;
 
-  function clzi(
+  function ~GENSYM[clzi][2] (
     constant n : in natural;
     constant i : in unsigned) return unsigned is
     variable v : unsigned(i'length-1 downto 0):=i;
@@ -868,30 +868,30 @@
     end if;
   end function;
 
-  function clz32 (constant v : unsigned(0 to 31)) return unsigned is
+  function ~GENSYM[clz32][3] (constant v : unsigned(0 to 31)) return unsigned is
     variable e : unsigned(0 to 31);    -- 32
     variable a : unsigned(0 to 8*3-1); -- 24
     variable b : unsigned(0 to 4*4-1); -- 16
     variable c : unsigned(0 to 2*5-1); -- 10
   begin
-    for i in 0 to 15 loop e(i*2 to i*2+1):=enc(v(i*2 to i*2+1));    end loop;
-    for i in 0 to 7  loop a(i*3 to i*3+2):=clzi(2,e(i*4 to i*4+3)); end loop;
-    for i in 0 to 3  loop b(i*4 to i*4+3):=clzi(3,a(i*6 to i*6+5)); end loop;
-    for i in 0 to 1  loop c(i*5 to i*5+4):=clzi(4,b(i*8 to i*8+7)); end loop;
-    return clzi(5,c(0 to 9));
+    for i in 0 to 15 loop e(i*2 to i*2+1):=~SYM[1](v(i*2 to i*2+1));    end loop;
+    for i in 0 to 7  loop a(i*3 to i*3+2):=~SYM[2](2,e(i*4 to i*4+3)); end loop;
+    for i in 0 to 3  loop b(i*4 to i*4+3):=~SYM[2](3,a(i*6 to i*6+5)); end loop;
+    for i in 0 to 1  loop c(i*5 to i*5+4):=~SYM[2](4,b(i*8 to i*8+7)); end loop;
+    return ~SYM[2](5,c(0 to 9));
   end function;
 
-  signal ~SYM[1] : ~TYP[0];
-  signal ~SYM[2] : ~TYP[0];
+  signal ~GENSYM[s][4] : ~TYP[0];
+  signal ~GENSYM[s_reversed][5] : ~TYP[0];
 begin
-  ~SYM[1] <= ~ARG[0];
-  reverse_loop : for ~SYM[3] in ~SYM[1]'range generate
-    ~SYM[2](~SYM[1]'high - ~SYM[3]) <= ~SYM[1](~SYM[3]);
+  ~SYM[4] <= ~ARG[0];
+  ~GENSYM[reverse_loop][6] : for ~GENSYM[n][7] in ~SYM[4]'range generate
+    ~SYM[5](~SYM[4]'high - ~SYM[7]) <= ~SYM[4](~SYM[3]);
   end generate;
 ~IF ~IW64 ~THEN
-  ~RESULT <= resize(clz32(~SYM[2](63 downto 32)),~SIZE[~TYPO]);
+  ~RESULT <= resize(~SYM[3](~SYM[5](63 downto 32)),~SIZE[~TYPO]);
 ~ELSE
-  ~RESULT <= resize(clz32(~SYM[2]),~SIZE[~TYPO]);
+  ~RESULT <= resize(~SYM[3](~SYM[5]),~SIZE[~TYPO]);
 ~FI
 end block;
 -- ctz32 end"
@@ -902,8 +902,8 @@
     , "type"      : "ctz64 :: Word# -> Word#"
     , "templateD" :
 "-- ctz64 begin
-ctz64~SYM[0] : block
-  function enc(constant a : unsigned(1 downto 0)) return unsigned is
+~GENSYM[ctz64][0] : block
+  function ~GENSYM[enc][1] (constant a : unsigned(1 downto 0)) return unsigned is
   begin
     case a is
       when \"00\" => return \"10\";
@@ -913,7 +913,7 @@
     end case;
   end function;
 
-  function clzi(
+  function ~GENSYM[clzi][2] (
     constant n : in natural;
     constant i : in unsigned) return unsigned is
     variable v : unsigned(i'length-1 downto 0):=i;
@@ -925,30 +925,30 @@
     end if;
   end function;
 
-  function clz64 (constant v : unsigned(0 to 63)) return unsigned is
+  function ~GENSYM[clz64][3] (constant v : unsigned(0 to 63)) return unsigned is
     variable e : unsigned(0 to 63);     -- 64
     variable a : unsigned(0 to 16*3-1); -- 48
     variable b : unsigned(0 to 8*4-1);  -- 32
     variable c : unsigned(0 to 4*5-1);  -- 20
     variable d : unsigned(0 to 2*6-1);  -- 12
   begin
-    for i in 0 to 31 loop e(i*2 to i*2+1):=enc(v(i*2 to i*2+1));      end loop;
-    for i in 0 to 15 loop a(i*3 to i*3+2):=clzi(2,e(i*4 to i*4+3));   end loop;
-    for i in 0 to 7  loop b(i*4 to i*4+3):=clzi(3,a(i*6 to i*6+5));   end loop;
-    for i in 0 to 3  loop c(i*5 to i*5+4):=clzi(4,b(i*8 to i*8+7));   end loop;
-    for i in 0 to 1  loop d(i*6 to i*6+5):=clzi(5,c(i*10 to i*10+9)); end loop;
-    return clzi(6,d(0 to 11));
+    for i in 0 to 31 loop e(i*2 to i*2+1):=~SYM[1](v(i*2 to i*2+1));      end loop;
+    for i in 0 to 15 loop a(i*3 to i*3+2):=~SYM[2](2,e(i*4 to i*4+3));   end loop;
+    for i in 0 to 7  loop b(i*4 to i*4+3):=~SYM[2](3,a(i*6 to i*6+5));   end loop;
+    for i in 0 to 3  loop c(i*5 to i*5+4):=~SYM[2](4,b(i*8 to i*8+7));   end loop;
+    for i in 0 to 1  loop d(i*6 to i*6+5):=~SYM[2](5,c(i*10 to i*10+9)); end loop;
+    return ~SYM[2](6,d(0 to 11));
   end function;
 
-  signal ~SYM[1] : ~TYP[0];
-  signal ~SYM[2] : ~TYP[0];
+  signal ~GENSYM[s][4] : ~TYP[0];
+  signal ~GENSYM[s_reversed][5] : ~TYP[0];
 begin
-  ~SYM[1] <= ~ARG[0];
-  reverse_loop : for ~SYM[3] in ~SYM[1]'range generate
-    ~SYM[2](~SYM[1]'high - ~SYM[3]) <= ~SYM[1](~SYM[3]);
+  ~SYM[4] <= ~ARG[0];
+  ~GENSYM[reverse_loop][6] : for ~GENSYM[n][7] in ~SYM[4]'range generate
+    ~SYM[5](~SYM[4]'high - ~SYM[7]) <= ~SYM[4](~SYM[7]);
   end generate;
 
-  ~RESULT <= resize(clz64(~SYM[2]),~SIZE[~TYPO]);
+  ~RESULT <= resize(~SYM[3](~SYM[5]),~SIZE[~TYPO]);
 end block;
 -- ctz64 end"
     }
@@ -958,8 +958,8 @@
     , "type"      : "ctz :: Word# -> Word#"
     , "templateD" :
 "-- ctz begin
-ctz~SYM[0] : block
-  function enc(constant a : unsigned(1 downto 0)) return unsigned is
+~GENSYM[ctz][0] : block
+  function ~GENSYM[enc][1] (constant a : unsigned(1 downto 0)) return unsigned is
   begin
     case a is
       when \"00\" => return \"10\";
@@ -969,7 +969,7 @@
     end case;
   end function;
 
-  function clzi(
+  function ~GENSYM[clzi][2] (
     constant n : in natural;
     constant i : in unsigned) return unsigned is
     variable v : unsigned(i'length-1 downto 0):=i;
@@ -982,46 +982,46 @@
   end function;
 
 ~IF ~IW64 ~THEN
-  function clz64 (constant v : unsigned(0 to 63)) return unsigned is
+  function ~GENSYM[clz64][3] (constant v : unsigned(0 to 63)) return unsigned is
     variable e : unsigned(0 to 63);     -- 64
     variable a : unsigned(0 to 16*3-1); -- 48
     variable b : unsigned(0 to 8*4-1);  -- 32
     variable c : unsigned(0 to 4*5-1);  -- 20
     variable d : unsigned(0 to 2*6-1);  -- 12
   begin
-    for i in 0 to 31 loop e(i*2 to i*2+1):=enc(v(i*2 to i*2+1));      end loop;
-    for i in 0 to 15 loop a(i*3 to i*3+2):=clzi(2,e(i*4 to i*4+3));   end loop;
-    for i in 0 to 7  loop b(i*4 to i*4+3):=clzi(3,a(i*6 to i*6+5));   end loop;
-    for i in 0 to 3  loop c(i*5 to i*5+4):=clzi(4,b(i*8 to i*8+7));   end loop;
-    for i in 0 to 1  loop d(i*6 to i*6+5):=clzi(5,c(i*10 to i*10+9)); end loop;
-    return clzi(6,d(0 to 11));
+    for i in 0 to 31 loop e(i*2 to i*2+1):=~SYM[1](v(i*2 to i*2+1));      end loop;
+    for i in 0 to 15 loop a(i*3 to i*3+2):=~SYM[2](2,e(i*4 to i*4+3));   end loop;
+    for i in 0 to 7  loop b(i*4 to i*4+3):=~SYM[2](3,a(i*6 to i*6+5));   end loop;
+    for i in 0 to 3  loop c(i*5 to i*5+4):=~SYM[2](4,b(i*8 to i*8+7));   end loop;
+    for i in 0 to 1  loop d(i*6 to i*6+5):=~SYM[2](5,c(i*10 to i*10+9)); end loop;
+    return ~SYM[2](6,d(0 to 11));
   end function;
 ~ELSE
-  function clz32 (constant v : unsigned(0 to 31)) return unsigned is
+  function ~GENSYM[clz32][4] (constant v : unsigned(0 to 31)) return unsigned is
     variable e : unsigned(0 to 31);    -- 32
     variable a : unsigned(0 to 8*3-1); -- 24
     variable b : unsigned(0 to 4*4-1); -- 16
     variable c : unsigned(0 to 2*5-1); -- 10
   begin
-    for i in 0 to 15 loop e(i*2 to i*2+1):=enc(v(i*2 to i*2+1));    end loop;
-    for i in 0 to 7  loop a(i*3 to i*3+2):=clzi(2,e(i*4 to i*4+3)); end loop;
-    for i in 0 to 3  loop b(i*4 to i*4+3):=clzi(3,a(i*6 to i*6+5)); end loop;
-    for i in 0 to 1  loop c(i*5 to i*5+4):=clzi(4,b(i*8 to i*8+7)); end loop;
-    return clzi(5,c(0 to 9));
+    for i in 0 to 15 loop e(i*2 to i*2+1):=~SYM[1](v(i*2 to i*2+1));    end loop;
+    for i in 0 to 7  loop a(i*3 to i*3+2):=~SYM[2](2,e(i*4 to i*4+3)); end loop;
+    for i in 0 to 3  loop b(i*4 to i*4+3):=~SYM[2](3,a(i*6 to i*6+5)); end loop;
+    for i in 0 to 1  loop c(i*5 to i*5+4):=~SYM[2](4,b(i*8 to i*8+7)); end loop;
+    return ~SYM[2](5,c(0 to 9));
   end function;
 ~FI
 
-  signal ~SYM[1] : ~TYP[0];
-  signal ~SYM[2] : ~TYP[0];
+  signal ~GENSYM[s][5] : ~TYP[0];
+  signal ~GENSYM[s_reversed][6] : ~TYP[0];
 begin
-  ~SYM[1] <= ~ARG[0];
-  reverse_loop : for ~SYM[3] in ~SYM[1]'range generate
-    ~SYM[2](~SYM[1]'high - ~SYM[3]) <= ~SYM[1](~SYM[3]);
+  ~SYM[5] <= ~ARG[0];
+  ~GENSYM[reverse_loop][7] : for ~GENSYM[n][8] in ~SYM[5]'range generate
+    ~SYM[6](~SYM[5]'high - ~SYM[8]) <= ~SYM[5](~SYM[8]);
   end generate;
 ~IF ~IW64 ~THEN
-  ~RESULT <= resize(clz64(~SYM[2]),~SIZE[~TYPO]);
+  ~RESULT <= resize(~SYM[3](~SYM[6]),~SIZE[~TYPO]);
 ~ELSE
-  ~RESULT <= resize(clz32(~SYM[2]),~SIZE[~TYPO]);
+  ~RESULT <= resize(~SYM[4](~SYM[6]),~SIZE[~TYPO]);
 ~FI
 end block;
 -- ctz end"
@@ -1032,15 +1032,12 @@
     , "type"      : "byteSwap16# :: Word# -> Word#"
     , "templateD" :
 "-- byteSwap16 begin
-msb_~SYM[0] : block
-  signal ~SYM[1] : ~TYP[0];
+~GENSYM[byteSwap16][0] : block
+  signal ~GENSYM[s][1] : ~TYP[0];
 begin
-  ~SYM[1] <= ~ARG[0];
-~IF ~IW64 ~THEN
-  ~RESULT <= ~SYM[1](63 downto 16) & ~SYM[1](7 downto 0) & ~SYM[1](15 downto 8);
-~ELSE
-  ~RESULT <= ~SYM[1](31 downto 16) & ~SYM[1](7 downto 0) & ~SYM[1](15 downto 8);
-~FI
+  ~SYM[1] <= ~ARG[0];~IF ~IW64 ~THEN
+  ~RESULT <= ~SYM[1](63 downto 16) & ~SYM[1](7 downto 0) & ~SYM[1](15 downto 8);~ELSE
+  ~RESULT <= ~SYM[1](31 downto 16) & ~SYM[1](7 downto 0) & ~SYM[1](15 downto 8);~FI
 end block;
 -- byteSwap16 end"
     }
@@ -1050,17 +1047,14 @@
     , "type"      : "byteSwap32# :: Word# -> Word#"
     , "templateD" :
 "-- byteSwap32 begin
-msb_~SYM[0] : block
-  signal ~SYM[1] : ~TYP[0];
+~GENSYM[byteSwap32][0] : block
+  signal ~GENSYM[s][1] : ~TYP[0];
 begin
-  ~SYM[1] <= ~ARG[0];
-~IF ~IW64 ~THEN
+  ~SYM[1] <= ~ARG[0];~IF ~IW64 ~THEN
   ~RESULT <= ~SYM[1](63 downto 32) & ~SYM[1](7  downto 0 ) & ~SYM[1](15 downto 8)
-                                   & ~SYM[1](23 downto 16) & ~SYM[1](31 downto 24);
-~ELSE
+                                   & ~SYM[1](23 downto 16) & ~SYM[1](31 downto 24);~ELSE
   ~RESULT <= ~SYM[1](7  downto 0 ) & ~SYM[1](15 downto 8)
-           & ~SYM[1](23 downto 16) & ~SYM[1](31 downto 24);
-~FI
+           & ~SYM[1](23 downto 16) & ~SYM[1](31 downto 24);~FI
 end block;
 -- byteSwap32 end"
     }
@@ -1070,8 +1064,8 @@
     , "type"      : "byteSwap64# :: Word# -> Word#"
     , "templateD" :
 "-- byteSwap64 begin
-msb_~SYM[0] : block
-  signal ~SYM[1] : ~TYP[0];
+~GENSYM[byteSwap64][0] : block
+  signal ~GENSYM[s][1] : ~TYP[0];
 begin
   ~SYM[1] <= ~ARG[0];
   ~RESULT <= ~SYM[1](7  downto 0 ) & ~SYM[1](15 downto 8)
@@ -1087,19 +1081,16 @@
     , "type"      : "byteSwap# :: Word# -> Word#"
     , "templateD" :
 "-- byteSwap begin
-msb_~SYM[0] : block
-  signal ~SYM[1] : ~TYP[0];
+~GENSYM[byteSwap][0] : block
+  signal ~GENSYM[s][1] : ~TYP[0];
 begin
-  ~SYM[1] <= ~ARG[0];
-~IF ~IW64 ~THEN
+  ~SYM[1] <= ~ARG[0];~IF ~IW64 ~THEN
   ~RESULT <= ~SYM[1](7  downto 0 ) & ~SYM[1](15 downto 8)
            & ~SYM[1](23 downto 16) & ~SYM[1](31 downto 24)
            & ~SYM[1](39 downto 32) & ~SYM[1](47 downto 40)
-           & ~SYM[1](55 downto 48) & ~SYM[1](63 downto 56);
-~ELSE
+           & ~SYM[1](55 downto 48) & ~SYM[1](63 downto 56);~ELSE
   ~RESULT <= ~SYM[1](7  downto 0 ) & ~SYM[1](15 downto 8)
-           & ~SYM[1](23 downto 16) & ~SYM[1](31 downto 24);
-~FI
+           & ~SYM[1](23 downto 16) & ~SYM[1](31 downto 24);~FI
 end block;
 -- byteSwap end"
     }
@@ -1109,8 +1100,8 @@
     , "type"      : "narrow8Int# :: Int# -> Int#"
     , "templateD" :
 "-- narrow8Int begin
-msb_~SYM[0] : block
-  signal ~SYM[1] : ~TYP[0];
+~GENSYM[narrow8Int][0] : block
+  signal ~GENSYM[s][1] : ~TYP[0];
 begin
   ~SYM[1] <= ~ARG[0];
   ~RESULT <= resize(~SYM[1](7 downto 0),~SIZE[~TYPO]);
@@ -1123,8 +1114,8 @@
     , "type"      : "narrow16Int# :: Int# -> Int#"
     , "templateD" :
 "-- narrow16Int begin
-msb_~SYM[0] : block
-  signal ~SYM[1] : ~TYP[0];
+~GENSYM[narrow16Int][0] : block
+  signal ~GENSYM[s][1] : ~TYP[0];
 begin
   ~SYM[1] <= ~ARG[0];
   ~RESULT <= resize(~SYM[1](15 downto 0),~SIZE[~TYPO]);
@@ -1137,8 +1128,8 @@
     , "type"      : "narrow32Int# :: Int# -> Int#"
     , "templateD" :
 "-- narrow32Int begin
-msb_~SYM[0] : block
-  signal ~SYM[1] : ~TYP[0];
+~GENSYM[narrow32Int][0] : block
+  signal ~GENSYM[s][1] : ~TYP[0];
 begin
   ~SYM[1] <= ~ARG[0];
   ~RESULT <= resize(~SYM[1](31 downto 0),~SIZE[~TYPO]);
@@ -1151,8 +1142,8 @@
     , "type"      : "narrow8Word# :: Word# -> Word#"
     , "templateD" :
 "-- narrow8Word begin
-msb_~SYM[0] : block
-  signal ~SYM[1] : ~TYP[0];
+~GENSYM[narrow8Word][0] : block
+  signal ~GENSYM[s][1] : ~TYP[0];
 begin
   ~SYM[1] <= ~ARG[0];
   ~RESULT <= resize(~SYM[1](7 downto 0),~SIZE[~TYPO]);
@@ -1165,8 +1156,8 @@
     , "type"      : "narrow16Word# :: Word# -> Word#"
     , "templateD" :
 "-- narrow16Word begin
-msb_~SYM[0] : block
-  signal ~SYM[1] : ~TYP[0];
+~GENSYM[narrow16Word][0] : block
+  signal ~GENSYM[s][1] : ~TYP[0];
 begin
   ~SYM[1] <= ~ARG[0];
   ~RESULT <= resize(~SYM[1](15 downto 0),~SIZE[~TYPO]);
@@ -1179,8 +1170,8 @@
     , "type"      : "narrow32Word# :: Word# -> Word#"
     , "templateD" :
 "-- narrow32Word begin
-msb_~SYM[0] : block
-  signal ~SYM[1] : ~TYP[0];
+~GENSYM[narrow32Word][0] : block
+  signal ~GENSYM[s][1] : ~TYP[0];
 begin
   ~SYM[1] <= ~ARG[0];
   ~RESULT <= resize(~SYM[1](31 downto 0),~SIZE[~TYPO]);
diff --git a/src/CLaSH/Backend/VHDL.hs b/src/CLaSH/Backend/VHDL.hs
--- a/src/CLaSH/Backend/VHDL.hs
+++ b/src/CLaSH/Backend/VHDL.hs
@@ -32,9 +32,11 @@
 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                           (clog2, curLoc, first, makeCached, on, (<:>))
 
 #ifdef CABAL
@@ -47,15 +49,17 @@
 data VHDLState =
   VHDLState
   { _tyCache   :: (HashSet HWType)     -- ^ Previously encountered HWTypes
-  , _tyCount   :: Int                  -- ^ Product type counter
+  , _tySeen    :: [Identifier]         -- ^ Generated product types
   , _nameCache :: (HashMap HWType Doc) -- ^ Cache for previously generated product type names
+  , _modNm     :: String
   , _intWidth  :: Int                  -- ^ Int/Word/Integer bit-width
+  , _hdlsyn    :: HdlSyn               -- ^ For which HDL synthesis tool are we generating VHDL
   }
 
 makeLenses ''VHDLState
 
 instance Backend VHDLState where
-  initBackend     = VHDLState HashSet.empty 0 HashMap.empty
+  initBackend     = VHDLState HashSet.empty [] HashMap.empty ""
 #ifdef CABAL
   primDir         = const (Paths_clash_vhdl.getDataFileName "primitives")
 #else
@@ -75,18 +79,50 @@
   inst            = inst_
   expr            = expr_
   iwWidth         = use intWidth
-  toBV _ id_      = "toSLV" <> parens (text id_)
+  toBV _ id_      = do
+    nm <- use modNm
+    text (T.toLower $ T.pack nm) <> "_types.toSLV" <> parens (text id_)
   fromBV hty id_  = fromSLV hty id_ (typeSize hty - 1) 0
+  hdlSyn          = use hdlsyn
+  mkBasicId       = return (filterReserved . T.toLower . mkBasicId' True)
+  setModName nm s = s {_modNm = nm}
 
 type VHDLM a = State VHDLState a
 
+-- List of reserved VHDL-2008 keywords
+-- + used internal names: toslv, fromslv, tagtoenum, datatotag
+-- + used IEEE library names: integer, boolean, std_logic, std_logic_vector,
+--   signed, unsigned, to_integer, to_signed, to_unsigned, string
+reservedWords :: [Identifier]
+reservedWords = ["abs","access","after","alias","all","and","architecture"
+  ,"array","assert","assume","assume_guarantee","attribute","begin","block"
+  ,"body","buffer","bus","case","component","configuration","constant","context"
+  ,"cover","default","disconnect","downto","else","elsif","end","entity","exit"
+  ,"fairness","file","for","force","function","generate","generic","group"
+  ,"guarded","if","impure","in","inertial","inout","is","label","library"
+  ,"linkage","literal","loop","map","mod","nand","new","next","nor","not","null"
+  ,"of","on","open","or","others","out","package","parameter","port","postponed"
+  ,"procedure","process","property","protected","pure","range","record"
+  ,"register","reject","release","rem","report","restrict","restrict_guarantee"
+  ,"return","rol","ror","select","sequence","severity","signal","shared","sla"
+  ,"sll","sra","srl","strong","subtype","then","to","transport","type"
+  ,"unaffected","units","until","use","variable","vmode","vprop","vunit","wait"
+  ,"when","while","with","xnor","xor","toslv","fromslv","tagtoenum","datatotag"
+  ,"integer", "boolean", "std_logic", "std_logic_vector", "signed", "unsigned"
+  ,"to_integer", "to_signed", "to_unsigned", "string"]
+
+filterReserved :: Identifier -> Identifier
+filterReserved s = if s `elem` reservedWords
+  then s `T.append` "_r"
+  else s
+
 -- | Generate VHDL for a Netlist component
 genVHDL :: String -> Component -> VHDLM (String,Doc)
-genVHDL modName c = (unpack cName,) A.<$> vhdl
+genVHDL nm c = (unpack cName,) A.<$> vhdl
   where
     cName   = componentName c
     vhdl    = "-- Automatically generated VHDL-93" <$$>
-              tyImports modName <$$> linebreak <>
+              tyImports nm <$$> linebreak <>
               entity c <$$> linebreak <>
               architecture c
 
@@ -94,43 +130,50 @@
 mkTyPackage_ :: String
              -> [HWType]
              -> VHDLM [(String,Doc)]
-mkTyPackage_ modName hwtys = (:[]) A.<$> (modName ++ "_types",) A.<$>
-   "library IEEE;" <$>
-   "use IEEE.STD_LOGIC_1164.ALL;" <$>
-   "use IEEE.NUMERIC_STD.ALL;" <$$> linebreak <>
-   "package" <+> modNameD <> "_types" <+> "is" <$>
-      indent 2 ( packageDec <$>
-                 vcat (sequence funDecs)
-               ) <$>
-   "end" <> semi <> packageBodyDec
-  where
-    modNameD    = text (T.pack modName)
-    usedTys     = concatMap mkUsedTys hwtys
-    needsDec    = nubBy eqReprTy . map mkVecZ $ (hwtys ++ usedTys)
-    hwTysSorted = topSortHWTys needsDec
-    packageDec  = vcat $ mapM tyDec hwTysSorted
-    (funDecs,funBodies) = unzip . catMaybes $ map funDec (nubBy eqTypM hwTysSorted)
+mkTyPackage_ modName hwtys = do
+    { syn <- hdlSyn
+    ; mkId <- mkBasicId
+    ; let usedTys     = concatMap mkUsedTys hwtys
+          needsDec = nubBy (eqReprTy syn) . map mkVecZ $ (hwtys ++ usedTys)
+          hwTysSorted = topSortHWTys needsDec
+          packageDec  = vcat $ mapM tyDec hwTysSorted
+          (funDecs,funBodies) = unzip . catMaybes $ map (funDec syn) (nubBy (eqTypM syn) hwTysSorted)
 
-    packageBodyDec :: VHDLM Doc
-    packageBodyDec = case funBodies of
-        [] -> empty
-        _  -> linebreak <$>
-              "package" <+> "body" <+> modNameD <> "_types" <+> "is" <$>
-                indent 2 (vcat (sequence funBodies)) <$>
-              "end" <> semi
+    ; (:[]) A.<$> (unpack $ mkId (T.pack modName `T.append` "_types"),) A.<$>
+      "library IEEE;" <$>
+      "use IEEE.STD_LOGIC_1164.ALL;" <$>
+      "use IEEE.NUMERIC_STD.ALL;" <$$> linebreak <>
+      "package" <+> text (mkId (T.pack modName `T.append` "_types")) <+> "is" <$>
+         indent 2 ( packageDec <$>
+                    vcat (sequence funDecs)
+                  ) <$>
+      "end" <> semi <> packageBodyDec funBodies
+    }
+  where
+    packageBodyDec :: [VHDLM Doc] -> VHDLM Doc
+    packageBodyDec funBodies = case funBodies of
+      [] -> empty
+      _  -> do
+        { mkId <- mkBasicId
+        ; linebreak <$>
+         "package" <+> "body" <+> text (mkId (T.pack modName `T.append` "_types")) <+> "is" <$>
+           indent 2 (vcat (sequence funBodies)) <$>
+         "end" <> semi
+        }
 
-    eqReprTy :: HWType -> HWType -> Bool
-    eqReprTy (Vector n ty1) (Vector m ty2)  = n == m && eqReprTy ty1 ty2
-    eqReprTy ty1 ty2
+    eqReprTy :: HdlSyn -> HWType -> HWType -> Bool
+    eqReprTy h (Vector n ty1) (Vector m ty2)  = n == m && eqReprTy h ty1 ty2
+    eqReprTy h ty1 ty2
       | isUnsigned ty1 && isUnsigned ty2 ||
-        isSLV ty1 && isSLV ty2              = typeSize ty1 == typeSize ty2
+        isSLV h ty1 && isSLV h ty2          = typeSize ty1 == typeSize ty2
       | otherwise                           = ty1 == ty2
 
-    eqTypM (Vector n ty1) (Vector m ty2) = n == m && eqReprTy ty1 ty2
-    eqTypM (Signed _) (Signed _) = True
-    eqTypM ty1 ty2 = isUnsigned ty1 && isUnsigned ty2 ||
-                     isSLV      ty1 && isSLV      ty2 ||
-                     ty1 == ty2
+    eqTypM :: HdlSyn -> HWType -> HWType -> Bool
+    eqTypM h (Vector n ty1) (Vector m ty2) = n == m && eqReprTy h ty1 ty2
+    eqTypM _ (Signed _) (Signed _) = True
+    eqTypM h ty1 ty2 = isUnsigned ty1 && isUnsigned ty2 ||
+                       isSLV h    ty1 && isSLV h    ty2 ||
+                       ty1 == ty2
 
     isUnsigned :: HWType -> Bool
     isUnsigned (Unsigned _)  = True
@@ -138,10 +181,10 @@
     isUnsigned (Sum _ _)     = True
     isUnsigned _             = False
 
-    isSLV :: HWType -> Bool
-    isSLV (BitVector _) = True
-    isSLV (SP _ _)      = True
-    isSLV _             = False
+    isSLV :: HdlSyn -> HWType -> Bool
+    isSLV _ (BitVector _) = True
+    isSLV _ (SP _ _)      = True
+    isSLV _ _             = False
 
 mkUsedTys :: HWType
         -> [HWType]
@@ -173,9 +216,15 @@
 mkVecZ t               = t
 
 tyDec :: HWType -> VHDLM Doc
-tyDec (Vector _ elTy) = "type" <+> "array_of_" <> tyName elTy <+> "is array (integer range <>) of" <+> vhdlType elTy <> semi
+tyDec (Vector _ elTy) = do
+  syn <- hdlSyn
+  case syn of
+    Vivado -> "type" <+> "array_of_" <> tyName elTy <+> "is array (integer range <>) of"
+              <+> "std_logic_vector" <> parens (int (typeSize elTy - 1) <+> "downto 0") <> semi
+    _ -> "type" <+> "array_of_" <> tyName elTy <+> "is array (integer range <>) of"
+         <+> vhdlType elTy <> semi
 
-tyDec ty@(Product _ tys) = prodDec
+tyDec ty@(Product _ tys@(_:_:_)) = prodDec
   where
     prodDec = "type" <+> tName <+> "is record" <$>
                 indent 2 (vcat $ zipWithM (\x y -> x <+> colon <+> y <> semi) selNames selTys) <$>
@@ -188,10 +237,12 @@
 tyDec _ = empty
 
 
-funDec :: HWType -> Maybe (VHDLM Doc,VHDLM Doc)
-funDec Bool = Just
+funDec :: HdlSyn -> HWType -> Maybe (VHDLM Doc,VHDLM Doc)
+funDec _ Bool = Just
   ( "function" <+> "toSLV" <+> parens ("b" <+> colon <+> "in" <+> "boolean") <+> "return" <+> "std_logic_vector" <> semi <$>
-    "function" <+> "fromSLV" <+> parens ("sl" <+> colon <+> "in" <+> "std_logic_vector") <+> "return" <+> "boolean" <> semi
+    "function" <+> "fromSLV" <+> parens ("sl" <+> colon <+> "in" <+> "std_logic_vector") <+> "return" <+> "boolean" <> semi <$>
+    "function" <+> "tagToEnum" <+> parens ("s" <+> colon <+> "in" <+> "signed") <+> "return" <+> "boolean" <> semi <$>
+    "function" <+> "dataToTag" <+> parens ("b" <+> colon <+> "in" <+> "boolean") <+> "return" <+> "signed" <> semi
   , "function" <+> "toSLV" <+> parens ("b" <+> colon <+> "in" <+> "boolean") <+> "return" <+> "std_logic_vector" <+> "is" <$>
     "begin" <$>
       indent 2 (vcat $ sequence ["if" <+> "b" <+> "then"
@@ -209,12 +260,30 @@
                                 ,   indent 2 ("return" <+> "false" <> semi)
                                 ,"end" <+> "if" <> semi
                                 ]) <$>
+    "end" <> semi <$>
+    "function" <+> "tagToEnum" <+> parens ("s" <+> colon <+> "in" <+> "signed") <+> "return" <+> "boolean" <+> "is" <$>
+    "begin" <$>
+      indent 2 (vcat $ sequence ["if" <+> "s" <+> "=" <+> "to_signed" <> parens (int 0 <> comma <> (use intWidth >>= int)) <+> "then"
+                                ,   indent 2 ("return" <+> "false" <> semi)
+                                ,"else"
+                                ,   indent 2 ("return" <+> "true" <> semi)
+                                ,"end" <+> "if" <> semi
+                                ]) <$>
+    "end" <> semi <$>
+    "function" <+> "dataToTag" <+> parens ("b" <+> colon <+> "in" <+> "boolean") <+> "return" <+> "signed" <+> "is" <$>
+    "begin" <$>
+      indent 2 (vcat $ sequence ["if" <+> "b" <+> "then"
+                                ,  indent 2 ("return" <+> "to_signed" <> parens (int 1 <> comma <> (use intWidth >>= int)) <> semi)
+                                ,"else"
+                                ,  indent 2 ("return" <+> "to_signed" <> parens (int 0 <> comma <> (use intWidth >>= int)) <> semi)
+                                ,"end" <+> "if" <> semi
+                                ]) <$>
     "end" <> semi
   )
 
-funDec (Index _) = Just unsignedToSlvDec
+funDec _ (Index _) = Just unsignedToSlvDec
 
-funDec (Signed _) = Just
+funDec _ (Signed _) = Just
   ( "function" <+> "toSLV" <+> parens ("s" <+> colon <+> "in" <+> "signed") <+> "return" <+> "std_logic_vector" <> semi
   , "function" <+> "toSLV" <+> parens ("s" <+> colon <+> "in" <+> "signed") <+> "return" <+> "std_logic_vector" <+> "is" <$>
     "begin" <$>
@@ -222,11 +291,11 @@
     "end" <> semi
   )
 
-funDec (Unsigned _) = Just unsignedToSlvDec
+funDec _ (Unsigned _) = Just unsignedToSlvDec
 
-funDec (Sum _ _) = Just unsignedToSlvDec
+funDec _ (Sum _ _) = Just unsignedToSlvDec
 
-funDec t@(Product _ elTys) = Just
+funDec _ t@(Product _ elTys) = Just
   ( "function" <+> "toSLV" <+> parens ("p :" <+> vhdlType t) <+> "return std_logic_vector" <> semi
   , "function" <+> "toSLV" <+> parens ("p :" <+> vhdlType t) <+> "return std_logic_vector" <+> "is" <$>
     "begin" <$>
@@ -236,9 +305,9 @@
   where
     elTyPrint = forM [0..(length elTys - 1)]
                      (\i -> "toSLV" <>
-                            parens ("p." <> vhdlType t <> "_sel" <> int i))
+                            parens ("p." <> tyName t <> "_sel" <> int i))
 
-funDec t@(Vector _ elTy) = Just
+funDec syn t@(Vector _ elTy) = Just
   ( "function" <+> "toSLV" <+> parens ("value : " <+> vhdlTypeMark t) <+> "return std_logic_vector" <> semi
   , "function" <+> "toSLV" <+> parens ("value : " <+> vhdlTypeMark t) <+> "return std_logic_vector" <+> "is" <$>
       indent 2
@@ -251,7 +320,9 @@
             indent 2
               (  "result" <> parens (parens ("(i - 1) * " <> int (typeSize elTy)) <+> "+ 1" <+>
                                              "to i*" <> int (typeSize elTy)) <+>
-                          ":=" <+> "toSLV" <> parens ("ivalue" <> parens ("i")) <> semi
+                          ":=" <+> (case syn of
+                                      Vivado -> "ivalue" <> parens ("i")
+                                      _  -> "toSLV" <> parens ("ivalue" <> parens ("i"))) <> semi
               ) <$>
          "end" <+> "loop" <> semi <$>
          "return" <+> "result" <> semi
@@ -259,10 +330,10 @@
     "end" <> semi
   )
 
-funDec (BitVector _) = Just slvToSlvDec
-funDec (SP _ _)      = Just slvToSlvDec
+funDec _ (BitVector _) = Just slvToSlvDec
+funDec _ (SP _ _)      = Just slvToSlvDec
 
-funDec _ = Nothing
+funDec _ _ = Nothing
 
 unsignedToSlvDec :: (VHDLM Doc, VHDLM Doc)
 unsignedToSlvDec =
@@ -283,7 +354,8 @@
   )
 
 tyImports :: String -> VHDLM Doc
-tyImports modName =
+tyImports nm = do
+  mkId <- mkBasicId
   punctuate' semi $ sequence
     [ "library IEEE"
     , "use IEEE.STD_LOGIC_1164.ALL"
@@ -291,7 +363,7 @@
     , "use IEEE.MATH_REAL.ALL"
     , "use std.textio.all"
     , "use work.all"
-    , "use work." <> text (T.pack modName) <> "_types.all"
+    , "use" <+> text (mkId (T.pack nm `T.append` "_types")) <> ".all"
     ]
 
 
@@ -343,12 +415,16 @@
                                       else "signed" <> parens (int (n-1) <+> "downto 0")
 vhdlType' (Unsigned n)    = if n == 0 then "unsigned (0 downto 1)"
                                       else "unsigned" <> parens ( int (n-1) <+> "downto 0")
-vhdlType' (Vector n elTy) = "array_of_" <> tyName elTy <> parens ("0 to " <> int (n-1))
+vhdlType' (Vector n elTy) = do
+  nm <- use modNm
+  text (T.toLower $ T.pack nm) <> "_types.array_of_" <> tyName elTy <> parens ("0 to " <> int (n-1))
 vhdlType' t@(SP _ _)      = "std_logic_vector" <> parens (int (typeSize t - 1) <+> "downto 0")
 vhdlType' t@(Sum _ _)     = case typeSize t of
                               0 -> "unsigned (0 downto 1)"
                               n -> "unsigned" <> parens (int (n -1) <+> "downto 0")
-vhdlType' t@(Product _ _) = tyName t
+vhdlType' t@(Product _ _) = do
+  nm <- use modNm
+  text (T.toLower $ T.pack nm) <> "_types." <> tyName t
 vhdlType' Void            = "std_logic_vector" <> parens (int (-1) <+> "downto 0")
 vhdlType' String          = "string"
 
@@ -368,10 +444,14 @@
     vhdlTypeMark' (Index _)       = "unsigned"
     vhdlTypeMark' (Signed _)      = "signed"
     vhdlTypeMark' (Unsigned _)    = "unsigned"
-    vhdlTypeMark' (Vector _ elTy) = "array_of_" <> tyName elTy
+    vhdlTypeMark' (Vector _ elTy) = do
+      nm <- use modNm
+      text (T.toLower $ T.pack nm) <> "_types.array_of_" <> tyName elTy
     vhdlTypeMark' (SP _ _)        = "std_logic_vector"
     vhdlTypeMark' (Sum _ _)       = "unsigned"
-    vhdlTypeMark' t@(Product _ _) = tyName t
+    vhdlTypeMark' t@(Product _ _) = do
+      nm <- use modNm
+      text (T.toLower $ T.pack nm) <> "_types." <> tyName t
     vhdlTypeMark' t               = error $ $(curLoc) ++ "vhdlTypeMark: " ++ show t
 
 tyName :: HWType -> VHDLM Doc
@@ -384,28 +464,45 @@
 tyName (Signed n)        = "signed_" <> int n
 tyName (Unsigned n)      = "unsigned_" <> int n
 tyName t@(Sum _ _)       = "unsigned_" <> 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
+    prodName = do
+      seen <- use tySeen
+      mkId <- mkBasicId
+      let nm'  = (mkId . last . T.splitOn ".") nm
+          nm'' = if T.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 `T.append` T.pack ('_':show i)
+      in  if n' `elem` s
+             then go mkId s (i+1) n
+             else n'
 tyName t@(SP _ _)        = "std_logic_vector_" <> int (typeSize t)
 tyName _ = empty
 
 -- | Convert a Netlist HWType to an error VHDL value for that type
 vhdlTypeErrValue :: HWType -> VHDLM Doc
 vhdlTypeErrValue Bool                = "true"
-vhdlTypeErrValue (BitVector _)       = "(others => 'X')"
-vhdlTypeErrValue (Index _)           = "(others => 'X')"
-vhdlTypeErrValue (Signed _)          = "(others => 'X')"
-vhdlTypeErrValue (Unsigned _)        = "(others => 'X')"
-vhdlTypeErrValue (Vector _ elTy)     = parens ("others" <+> rarrow <+> vhdlTypeErrValue elTy)
-vhdlTypeErrValue (SP _ _)            = "(others => 'X')"
-vhdlTypeErrValue (Sum _ _)           = "(others => 'X')"
-vhdlTypeErrValue (Product _ elTys)   = tupled $ mapM vhdlTypeErrValue elTys
+vhdlTypeErrValue t@(Vector n elTy)   = do
+  syn <-hdlSyn
+  case syn of
+    Vivado -> vhdlTypeMark t <> "'" <> parens (int 0 <+> "to" <+> int (n-1) <+> rarrow <+>
+                "std_logic_vector'" <> parens (int 0 <+> "to" <+> int (typeSize elTy - 1) <+>
+                 rarrow <+> "'X'"))
+    _ -> vhdlTypeMark t <> "'" <> parens (int 0 <+> "to" <+> int (n-1) <+> rarrow <+> vhdlTypeErrValue elTy)
+vhdlTypeErrValue t@(Product _ elTys) = vhdlTypeMark t <> "'" <> tupled (mapM vhdlTypeErrValue elTys)
 vhdlTypeErrValue (Reset _ _)         = "'X'"
 vhdlTypeErrValue (Clock _ _)         = "'X'"
-vhdlTypeErrValue Void                = "(0 downto 1 => 'X')"
+vhdlTypeErrValue Void                = "std_logic_vector'(0 downto 1 => 'X')"
 vhdlTypeErrValue String              = "\"ERROR\""
+vhdlTypeErrValue t                   = vhdlTypeMark t <> "'" <> parens (int 0 <+> "to" <+> int (typeSize t - 1) <+> rarrow <+> "'X'")
 
 decls :: [Declaration] -> VHDLM Doc
 decls [] = empty
@@ -457,7 +554,7 @@
               <+> text nm <$$> pms' <> semi
   where
     pms' = do
-      rec (p,ls) <- fmap unzip $ sequence [ (,fromIntegral (T.length i)) A.<$> fill (maximum ls) (text i) <+> "=>" <+> expr_ False e | (i,e) <- pms]
+      rec (p,ls) <- fmap unzip $ sequence [ (,fromIntegral (T.length i)) A.<$> fill (maximum ls) (text i) <+> "=>" <+> expr_ False e | (i,_,_,e) <- pms]
       nest 2 $ "port map" <$$> tupled (A.pure p)
 
 inst_ (BlackBoxD _ bs bbCtx) = do t <- renderBlackBox bs bbCtx
@@ -480,15 +577,28 @@
     start    = typeSize ty - 1 - conSize ty - other
     end      = start - argSize + 1
 
-expr_ _ (Identifier id_ (Just (Indexed (ty@(Product _ _),_,fI)))) = text id_ <> dot <> tyName ty <> "_sel" <> int fI
+expr_ _ (Identifier id_ (Just (Indexed (ty@(Product _ _),_,fI)))) =
+  text id_ <> dot <> tyName ty <> "_sel" <> int fI
 
-expr_ _ (Identifier id_ (Just (Indexed ((Vector _ _),1,1)))) = text id_ <> parens (int 0)
+expr_ _ (Identifier id_ (Just (Indexed ((Vector _ elTy),1,1)))) = do
+  syn <- hdlSyn
+  case syn of
+    Vivado -> do
+      id' <- fmap (displayT . renderOneLine) (text id_ <> parens (int 0))
+      fromSLV elTy id' (typeSize elTy - 1) 0
+    _ -> text id_ <> parens (int 0)
 expr_ _ (Identifier id_ (Just (Indexed ((Vector n _),1,2)))) = text id_ <> parens (int 1 <+> "to" <+> 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_ <> parens (int fI)
+expr_ _ (Identifier id_ (Just (Indexed ((Vector _ elTy),10,fI)))) = do
+  syn <- hdlSyn
+  case syn of
+    Vivado -> do
+      id' <- fmap (displayT . renderOneLine) (text id_ <> parens (int fI))
+      fromSLV elTy id' (typeSize elTy - 1) 0
+    _ -> text id_ <> parens (int fI)
 
 expr_ _ (Identifier id_ (Just (DC (ty@(SP _ _),_)))) = text id_ <> parens (int start <+> "downto" <+> int end)
   where
@@ -504,13 +614,25 @@
 
 expr_ _ (Identifier id_ (Just _)) = text id_
 
+expr_ b (DataCon _ (DC (Void, -1)) [e]) =  expr_ b e
+
 expr_ _ (DataCon (Vector 0 _) _ _) =
   error $ $(curLoc) ++ "VHDL: Trying to create a Nil vector."
 
-expr_ _ (DataCon ty@(Vector 1 _) _ [e])          = vhdlTypeMark ty <> "'" <> parens (int 0 <+> rarrow <+> expr_ False e)
-expr_ _ e@(DataCon ty@(Vector _ elTy) _ [e1,e2]) = vhdlTypeMark ty <> "'" <> case vectorChain e of
-                                                    Just es -> tupled (mapM (expr_ False) es)
-                                                    Nothing -> parens (vhdlTypeMark elTy <> "'" <> parens (expr_ False e1) <+> "&" <+> expr_ False e2)
+expr_ _ (DataCon ty@(Vector 1 elTy) _ [e])       = do
+  syn <- hdlSyn
+  case syn of
+    Vivado -> vhdlTypeMark ty <> "'" <> parens (int 0 <+> rarrow <+> toSLV elTy e)
+    _ -> vhdlTypeMark ty <> "'" <> parens (int 0 <+> rarrow <+> expr_ False e)
+expr_ _ e@(DataCon ty@(Vector _ elTy) _ [e1,e2]) = do
+  syn <- hdlSyn
+  case syn of
+    Vivado -> vhdlTypeMark ty <> "'" <> case vectorChain e of
+      Just es -> tupled (mapM (toSLV elTy) es)
+      Nothing -> parens ("std_logic_vector'" <> parens (toSLV elTy e1) <+> "&" <+> expr_ False e2)
+    _ -> vhdlTypeMark ty <> "'" <> case vectorChain e of
+            Just es -> tupled (mapM (expr_ False) es)
+            Nothing -> parens (vhdlTypeMark elTy <> "'" <> parens (expr_ False e1) <+> "&" <+> expr_ False e2)
 expr_ _ (DataCon ty@(SP _ args) (DC (_,i)) es) = assignExpr
   where
     argTys     = snd $ args !! i
@@ -523,9 +645,8 @@
     assignExpr = "std_logic_vector'" <> parens (hcat $ punctuate " & " $ sequence (dcExpr:argExprs ++ extraArg))
 
 expr_ _ (DataCon ty@(Sum _ _) (DC (_,i)) []) = "to_unsigned" <> tupled (sequence [int i,int (typeSize ty)])
-expr_ _ (DataCon ty@(Product _ _) _ es)             = tupled $ zipWithM (\i e -> tName <> "_sel" <> int i <+> rarrow <+> expr_ False e) [0..] es
-  where
-    tName = tyName ty
+expr_ _ (DataCon ty@(Product _ _) _ es) =
+    tupled $ zipWithM (\i e' -> tyName ty <> "_sel" <> int i <+> rarrow <+> expr_ False e') [0..] es
 
 expr_ _ (BlackBoxE pNm _ bbCtx _)
   | pNm == "CLaSH.Sized.Internal.Signed.fromInteger#"
@@ -558,12 +679,8 @@
   t <- renderBlackBox bs bbCtx
   parenIf (b || b') $ string t
 
-expr_ _ (DataTag Bool (Left id_)) = "false when" <+> text id_ <+> "= 0 else true"
-expr_ _ (DataTag Bool (Right id_)) = do {
-  ; iw <- use intWidth
-  ; "to_signed" <> parens (int 1 <> "," <> int iw) <+> "when" <+> text id_ <+> "else" <+>
-    "to_signed" <> parens (int 0 <> "," <> int iw)
-  }
+expr_ _ (DataTag Bool (Left id_)) = "tagToEnum" <> parens (text id_)
+expr_ _ (DataTag Bool (Right id_)) = "dataToTag" <> parens (text id_)
 
 expr_ _ (DataTag hty@(Sum _ _) (Left id_)) =
   "resize" <> parens ("unsigned" <> parens ("std_logic_vector" <> parens (text id_)) <> "," <> int (typeSize hty))
@@ -649,7 +766,9 @@
 bit_char Z = char 'Z'
 
 toSLV :: HWType -> Expr -> VHDLM Doc
-toSLV Bool         e = "toSLV" <> parens (expr_ False e)
+toSLV Bool         e = do
+  nm <- use modNm
+  text (T.toLower $ T.pack nm) <> "_types.toSLV" <> parens (expr_ False e)
 toSLV (BitVector _) e = expr_ False e
 toSLV (Signed _)   e = "std_logic_vector" <> parens (expr_ False e)
 toSLV (Unsigned _) e = "std_logic_vector" <> parens (expr_ False e)
@@ -662,25 +781,34 @@
     tName    = tyName 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) = encloseSep lparen rparen " & " (zipWithM toSLV tys es)
+toSLV (Product _ tys) (DataCon _ _ es) = do
+  encloseSep lparen rparen " & " (zipWithM toSLV tys es)
 toSLV (SP _ _) e = expr_ False e
 toSLV (Vector n elTy) (Identifier id_ Nothing) = do
-    selIds' <- sequence (reverse selIds)
-    parens (encloseSep lparen rparen " & " (mapM (toSLV elTy) selIds'))
+    selIds' <- sequence selIds
+    syn <- hdlSyn
+    parens (vcat $ punctuate " & "
+      (case syn of
+        Vivado -> mapM (expr_ False) selIds'
+        _ -> mapM (toSLV elTy) selIds'))
   where
-    selNames = map (fmap (displayT . renderOneLine) ) $ reverse [text id_ <> parens (int i) | i <- [0 .. (n-1)]]
+    selNames = map (fmap (displayT . renderOneLine) ) $ [text id_ <> parens (int i) | i <- [0 .. (n-1)]]
     selIds   = map (fmap (`Identifier` Nothing)) selNames
-toSLV (Vector n elTy) (DataCon _ _ es) = encloseSep lparen rparen " & " (zipWithM toSLV [elTy,Vector (n-1) elTy] es)
+toSLV (Vector n elTy) (DataCon _ _ es) = parens $ vcat $ punctuate " & " (zipWithM toSLV [elTy,Vector (n-1) elTy] es)
+toSLV (Vector _ _) e = "toSLV" <> parens (expr_ False e)
 toSLV hty      e = error $ $(curLoc) ++  "toSLV: ty:" ++ show hty ++ "\n expr: " ++ show e
 
 fromSLV :: HWType -> Identifier -> Int -> Int -> VHDLM Doc
-fromSLV Bool              id_ start _   = "fromSLV" <> parens (text id_ <> parens (int start <+> "downto" <+> int start))
+fromSLV Bool              id_ start _   = do
+  nm <- use modNm
+  text (T.toLower $ T.pack nm) <> "_types.fromSLV" <> parens (text id_ <> parens (int start <+> "downto" <+> int start))
 fromSLV (BitVector _)     id_ start end = text id_ <> parens (int start <+> "downto" <+> int end)
 fromSLV (Index _)         id_ start end = "unsigned" <> parens (text id_ <> parens (int start <+> "downto" <+> int end))
 fromSLV (Signed _)        id_ start end = "signed" <> parens (text id_ <> parens (int start <+> "downto" <+> int end))
 fromSLV (Unsigned _)      id_ start end = "unsigned" <> parens (text id_ <> parens (int start <+> "downto" <+> int end))
 fromSLV (Sum _ _)         id_ start end = "unsigned" <> parens (text id_ <> parens (int start <+> "downto" <+> int end))
-fromSLV t@(Product _ tys) id_ start _   = tupled $ zipWithM (\s e -> s <+> rarrow <+> e) selNames args
+fromSLV t@(Product _ tys) id_ start _ = do
+    tupled $ zipWithM (\s e -> s <+> rarrow <+> e) selNames args
   where
     tName      = tyName t
     selNames   = [tName <> "_sel" <> int i | i <- [0..]]
@@ -690,12 +818,18 @@
     args       = zipWith3 (`fromSLV` id_) tys starts ends
 
 fromSLV (SP _ _)          id_ start end = text id_ <> parens (int start <+> "downto" <+> int end)
-fromSLV (Vector n elTy)   id_ start _   = tupled (fmap reverse args)
+fromSLV (Vector n elTy)   id_ start _   =
+    if n > 1 then tupled args
+             else parens (int 0 <+> rarrow <+> fmap head 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
+    args      = do syn <- hdlSyn
+                   let elTy' = case syn of
+                                 Vivado -> BitVector (argLength - 1)
+                                 _ -> elTy
+                   zipWithM (fromSLV elTy' id_) starts ends
 fromSLV hty               _   _     _   = error $ $(curLoc) ++ "fromSLV: " ++ show hty
 
 dcToExpr :: HWType -> Int -> Expr
