diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,47 @@
 # Changelog for the Clash project
 
+## 1.8.3 *Oct 6th 2025*
+
+Added:
+* `Counter` instances for `Bool`, `Bit`, `Int`, `Int8`, `Int16`, `Int32`, `Int64`, `Word`, `Word8`, `Word16`, `Word32`, `Word64`, `Identity` and `Maybe`. [#2692](https://github.com/clash-lang/clash-compiler/pull/2692)
+* The Vec type now has a [COMPLETE pragma](https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/pragmas.html#complete-pragma) to avoid incomplete pattern matches when using the `(:>)` pattern. [#3020](https://github.com/clash-lang/clash-compiler/pull/3020)
+* RamOp now has an AutoReg instance. [#2792](https://github.com/clash-lang/clash-compiler/pull/2792)
+* Added instance `NFDataX (SimOnly a)` [#2900](https://github.com/clash-lang/clash-compiler/pull/2900)
+* Support for GHC 9.10 on Windows (macOS and Linux were already supported) [#2945](https://github.com/clash-lang/clash-compiler/pull/2945)
+* Added a `BitPack` instance for `Char` [#2957](https://github.com/clash-lang/clash-compiler/pull/2957)
+* Support for GHC 9.10.2 [#3003](https://github.com/clash-lang/clash-compiler/pull/3003)
+
+Changed:
+* Functions defined on `Clash.Class.Counter` are now public [#2692](https://github.com/clash-lang/clash-compiler/pull/2692)
+
+Fixed:
+* Clash hanging when rendering `Index n` literals, for large values of `n` [#2813](https://github.com/clash-lang/clash-compiler/issues/2813)
+* Render overflowed Index literals as don't-cares in HDL [#2970](https://github.com/clash-lang/clash-compiler/pull/2970)
+* Clash errors out when `Clash.Sized.Vector.splitAt` is compile-time evaluated in an illegal context [#2831]https://github.com/clash-lang/clash-compiler/issues/2831
+* `Clash.Explicit.DDR`: [#2911](https://github.com/clash-lang/clash-compiler/pull/2911)
+  - `ddrIn`: VHDL: Remove data input from sensitivity list of `ddrIn_neg_latch` register as it is superfluous. This should not affect functionality.
+  - `ddrOut`: VHDL: Fix incorrect usage of `Enable` input when the domain is set to asynchronous resets. Deasserting the `Enable` exhibited wrong behavior before this fix.
+* `Clash.Xilinx.DDR`: [#2911](https://github.com/clash-lang/clash-compiler/pull/2911)
+  - These primitives only support clocks where the rising edge is the active edge. Using them in a domain with falling active edges now causes an error.
+  - `oddr`: Fix VHDL and SystemVerilog erroring out during HDL generation
+  - Symbols in HDL for both `iddr` and `oddr` were renamed to match their function.
+* `Clash.Intel.DDR`: [#2911](https://github.com/clash-lang/clash-compiler/pull/2911)
+  - These primitives only support clocks where the rising edge is the active edge. Using them in a domain with falling active edges now causes an error.
+  - Fix rendering HDL. It variously errored out or generated non-working HDL.
+  - Rendering HDL no longer causes Clash to issue a warning about an argument unused in Haskell but used in the primitive black box.
+* `makeTopEntity` now accounts for `SimOnly` constructs. This can prevent warnings in situtations where the `SimOnly` type would contain types `makeTopEntity` cannot handle. [#2897](https://github.com/clash-lang/clash-compiler/pull/2897)
+* Clash did not build on GHC 9.6.7 (but did on 9.6.6) [#2916](https://github.com/clash-lang/clash-compiler/issues/2916)
+* Ignore `Tick`s in `TermLiteral Integer`, `TermLiteral Char`, `TermLiteral Natural`, and `TermLiteral (SNat n)` [#2925](https://github.com/clash-lang/clash-compiler/pull/2925)
+* Fixed laziness issue in internal black box `imap_go` [#2542](https://github.com/clash-lang/clash-compiler/issues/2542)
+* Clash's evaluator now uses `TemplateHaskell` names to detect renamed symbols in `GHC.*` and `Clash.*`. Fixes errors similar to `No blackbox found for: GHC.Internal.Base.eqString` [#2972](https://github.com/clash-lang/clash-compiler/issues/2972)
+* No blackbox found for: `GHC.Internal.Control.Exception.Base.recSelError` on GHC 9.10 [#2966](https://github.com/clash-lang/clash-compiler/issues/2966)
+* Verilog and System Verilog code gen bug for `map head` [#2809](https://github.com/clash-lang/clash-compiler/issues/2809)
+* Error parsing blackbox: `Clash.Sized.Vector.head` [#2988](https://github.com/clash-lang/clash-compiler/issues/2988)
+* Clash no longer duplicates included datafiles when component is instantiated multiple times [#3008](https://github.com/clash-lang/clash-compiler/issues/3008)
+* Clash will no longer emit "no blackbox found for" `GHC.Real`'s exponentiation function if it is applied to constants [#3010](https://github.com/clash-lang/clash-compiler/pull/3010)
+* Clash will no longer error out when converting `ensureSpine` on Clash number types to HDL [#3021](https://github.com/clash-lang/clash-compiler/issues/3021)
+* Clash will no longer ignore Synthesize annotations when the function is used in an argument position [#3024](https://github.com/clash-lang/clash-compiler/issues/3024)
+
 ## 1.8.2 *Jan 3rd 2025*
 
 Added:
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -24,5 +24,13 @@
 
   * Support for multiple clock domains, with type safe clock domain crossing.
 
-# Support
-For updates and questions join the mailing list clash-language+subscribe@googlegroups.com or read the [forum](https://groups.google.com/d/forum/clash-language)
+# Open-source community
+Clash benefits from an active community. Whether you need a question answered or
+want to contribute to open-source features, browse the features below to make
+the most of Clash.
+
+- [Discourse: long form discussions and questions](https://clash-lang.discourse.group/)
+- [Discord: short form discussions and community chat room](https://discord.gg/rebGq25FB4)
+- [Slack: short form discussions and questions](https://functionalprogramming.slack.com/archives/CPGMJFF50)
+  (Invite yourself at [fpslack.com](https://fpslack.com))
+- [Github: issue tracker](https://github.com/clash-lang/clash-compiler/issues)
diff --git a/clash-lib.cabal b/clash-lib.cabal
--- a/clash-lib.cabal
+++ b/clash-lib.cabal
@@ -1,6 +1,6 @@
 Cabal-version:        2.2
 Name:                 clash-lib
-Version:              1.8.2
+Version:              1.8.3
 Synopsis:             Clash: a functional hardware description language - As a library
 Description:
   Clash is a functional hardware description language that borrows both its
@@ -151,16 +151,16 @@
                       base16-bytestring       >= 0.1.1    && < 1.1,
                       binary                  >= 0.8.5    && < 0.11,
                       bytestring              >= 0.10.0.2 && < 0.13,
-                      clash-prelude           == 1.8.2,
+                      clash-prelude           == 1.8.3,
                       containers              >= 0.5.0.0  && < 0.8,
                       cryptohash-sha256       >= 0.11     && < 0.12,
                       data-binary-ieee754     >= 0.4.4    && < 0.6,
-                      data-default            >= 0.7      && < 0.8,
+                      data-default            >= 0.7      && < 0.9,
                       deepseq                 >= 1.3.0.2  && < 1.6,
                       dlist                   >= 0.8      && < 1.1,
                       directory               >= 1.2.0.1  && < 1.4,
                       exceptions              >= 0.8.3    && < 0.11.0,
-                      extra                   >= 1.6.17   && < 1.8,
+                      extra                   >= 1.6.17   && < 1.9,
                       filepath                >= 1.3.0.1  && < 1.6,
                       ghc                     >= 8.6.0    && < 9.11,
                       ghc-boot-th,
diff --git a/prims/common/GHC_Internal_Control_Exception_Base.primitives.yaml b/prims/common/GHC_Internal_Control_Exception_Base.primitives.yaml
new file mode 100644
--- /dev/null
+++ b/prims/common/GHC_Internal_Control_Exception_Base.primitives.yaml
@@ -0,0 +1,63 @@
+- BlackBox:
+    name: GHC.Internal.Control.Exception.Base.recSelError
+    kind: Expression
+    type: 'recSelError ::
+      Addr# -> a'
+    template: ~ERRORO
+    workInfo: Constant
+- BlackBox:
+    name: GHC.Internal.Control.Exception.Base.recConError
+    kind: Expression
+    type: 'recConError ::
+      Addr# -> a'
+    template: ~ERRORO
+    workInfo: Constant
+- BlackBox:
+    name: GHC.Internal.Control.Exception.Base.irrefutPatError
+    kind: Expression
+    type: 'irrefutPatError
+      :: Addr# -> a'
+    template: ~ERRORO
+    workInfo: Constant
+- BlackBox:
+    name: GHC.Internal.Control.Exception.Base.runtimeError
+    kind: Expression
+    type: 'runtimeError ::
+      Addr# -> a'
+    template: ~ERRORO
+    workInfo: Constant
+- BlackBox:
+    name: GHC.Internal.Control.Exception.Base.nonExhaustiveGuardsError
+    kind: Expression
+    type: 'nonExhaustiveGuardsError
+      :: Addr# -> a'
+    template: ~ERRORO
+    workInfo: Constant
+- BlackBox:
+    name: GHC.Internal.Control.Exception.Base.patError
+    kind: Expression
+    type: 'patError :: Addr#
+      -> a'
+    template: ~ERRORO
+    workInfo: Constant
+- BlackBox:
+    name: GHC.Internal.Control.Exception.Base.noMethodBindingError
+    kind: Expression
+    type: 'noMethodBindingError
+      :: Addr# -> a'
+    template: ~ERRORO
+    workInfo: Constant
+- BlackBox:
+    name: GHC.Internal.Control.Exception.Base.absentError
+    kind: Expression
+    type: 'absentError ::
+      Addr# -> a'
+    template: ~ERRORO
+    workInfo: Constant
+- BlackBox:
+    name: GHC.Internal.Control.Exception.Base.typeError
+    kind: Expression
+    type: 'typeError :: Addr#
+      -> a'
+    template: ~ERRORO
+    workInfo: Constant
diff --git a/prims/commonverilog/Clash_Class_BitPack.primitives.yaml b/prims/commonverilog/Clash_Class_BitPack.primitives.yaml
new file mode 100644
--- /dev/null
+++ b/prims/commonverilog/Clash_Class_BitPack.primitives.yaml
@@ -0,0 +1,12 @@
+- BlackBox:
+    name: Clash.Class.BitPack.Internal.packChar#
+    kind: Expression
+    type: 'packChar# :: Char -> BitVector 21'
+    template: ~ARG[0]
+    workInfo: Never
+- BlackBox:
+    name: Clash.Class.BitPack.Internal.unpackChar#
+    kind: Expression
+    type: 'unpackChar# :: BitVector 21 -> Char'
+    template: ~ARG[0]
+    workInfo: Never
diff --git a/prims/systemverilog/Clash_Intel_DDR.primitives.yaml b/prims/systemverilog/Clash_Intel_DDR.primitives.yaml
--- a/prims/systemverilog/Clash_Intel_DDR.primitives.yaml
+++ b/prims/systemverilog/Clash_Intel_DDR.primitives.yaml
@@ -1,10 +1,10 @@
 - BlackBox:
-    name: Clash.Intel.DDR.altddioIn
+    name: Clash.Intel.DDR.altddioIn#
     kind: Declaration
     libraries:
     - altera_mf
     type: |-
-      altddioIn
+      altddioIn#
         :: ( HasCallStack               -- ARG[0]
            , KnownConfi~ fast domf      -- ARG[1]
            , KnownConfi~ slow doms      -- ARG[2]
@@ -36,7 +36,7 @@
           .sclr (1'b0),~FI
           .datain (~ARG[8]),
           .inclock (~ARG[5]),
-          .inclocken (~IF ~ISACTIVEENABLE[7] ~THEN~ARG[7]~ELSE1'b1,~FI),
+          .inclocken (~IF ~ISACTIVEENABLE[7] ~THEN~ARG[7]~ELSE1'b1~FI),
           .dataout_h (~SYM[2]),
           .dataout_l (~SYM[1]),
           .aset (1'b0),
diff --git a/prims/systemverilog/Clash_Sized_Vector.primitives.yaml b/prims/systemverilog/Clash_Sized_Vector.primitives.yaml
--- a/prims/systemverilog/Clash_Sized_Vector.primitives.yaml
+++ b/prims/systemverilog/Clash_Sized_Vector.primitives.yaml
@@ -1,29 +1,25 @@
 - BlackBox:
     name: Clash.Sized.Vector.head
     kind: Expression
-    type: 'head :: Vec (n
-      + 1) a -> a'
+    type: 'head :: Vec (n + 1) a -> a'
     template: ~FROMBV[~VAR[vec][0][\0\]][~TYPO]
     workInfo: Never
 - BlackBox:
     name: Clash.Sized.Vector.tail
     kind: Expression
-    type: 'tail :: Vec (n
-      + 1) a -> Vec n a'
+    type: 'tail :: Vec (n + 1) a -> Vec n a'
     template: '~VAR[vec][0][1 : $high(~VAR[vec][0])]'
     workInfo: Never
 - BlackBox:
     name: Clash.Sized.Vector.last
     kind: Expression
-    type: Vec (n + 1) a ->
-      a
+    type: Vec (n + 1) a -> a
     template: ~FROMBV[~VAR[vec][0][\$high(~VAR[vec][0])\]][~TYPO]
     workInfo: Never
 - BlackBox:
     name: Clash.Sized.Vector.init
     kind: Expression
-    type: Vec (n + 1) a ->
-      Vec n a
+    type: Vec (n + 1) a -> Vec n a
     template: '~VAR[vec][0][0 : $high(~VAR[vec][0]) - 1]'
     workInfo: Never
 - BlackBox:
@@ -49,15 +45,13 @@
 - BlackBox:
     name: Clash.Sized.Vector.++
     kind: Expression
-    type: '(++) :: Vec n a
-      -> Vec m a -> Vec (n + m) a'
+    type: '(++) :: Vec n a -> Vec m a -> Vec (n + m) a'
     template: ~FROMBV[{~TOBV[~ARG[0]][~TYP[0]],~TOBV[~ARG[1]][~TYP[1]]}][~TYPO]
     workInfo: Never
 - BlackBox:
     name: Clash.Sized.Vector.concat
     kind: Declaration
-    type: 'concat :: Vec n
-      (Vec m a) -> Vec (n * m) a'
+    type: 'concat :: Vec n (Vec m a) -> Vec (n * m) a'
     template: |-
       // concat begin
       genvar ~GENSYM[n][1];
@@ -71,8 +65,7 @@
 - BlackBox:
     name: Clash.Sized.Vector.splitAt
     kind: Declaration
-    type: 'splitAt :: SNat
-      m -> Vec (m + n) a -> (Vec m a, Vec n a)'
+    type: 'splitAt :: SNat m -> Vec (m + n) a -> (Vec m a, Vec n a)'
     template: |-
       // splitAt begin~IF~LENGTH[~TYPO]~THEN
       assign ~RESULT = ~ARG[1];~ELSE
@@ -110,8 +103,7 @@
 - BlackBox:
     name: Clash.Sized.Vector.map
     kind: Declaration
-    type: 'map :: (a -> b)
-      -> Vec n a -> Vec n b'
+    type: 'map :: (a -> b) -> Vec n a -> Vec n b'
     template: |-
       // map begin
       genvar ~GENSYM[n][1];
@@ -132,8 +124,7 @@
 - BlackBox:
     name: Clash.Sized.Vector.imap
     kind: Declaration
-    type: 'imap :: KnownNat
-      n => (Index n -> a -> b) -> Vec n a -> Vec n b'
+    type: 'imap :: KnownNat n => (Index n -> a -> b) -> Vec n a -> Vec n b'
     template: |-
       // imap begin
       genvar ~GENSYM[n][1];
@@ -157,22 +148,21 @@
 - BlackBox:
     name: Clash.Sized.Vector.imap_go
     kind: Declaration
-    type: 'imap_go :: Index
-      n -> (Index n -> a -> b) -> Vec m a -> Vec m b'
+    type: 'imap_go :: (Index n -> a -> b) -> Vec m a -> Index n -> Vec m b'
     template: |-
       // imap begin
       genvar ~GENSYM[n][1];
       ~GENERATE
       for (~SYM[1]=0; ~SYM[1] < $size(~RESULT); ~SYM[1] = ~SYM[1] + 1) begin : ~GENSYM[imap][2]
-        ~TYP[0] ~GENSYM[i][3];
-        assign ~SYM[3] = ~SYM[1] + ~ARG[0];~IF~SIZE[~TYP[2]]~THEN
-        ~TYPEL[~TYP[2]] ~GENSYM[imap_in][4];
-        assign ~SYM[4] = ~FROMBV[~VAR[vec][2][\~SYM[1]\]][~TYPEL[~TYP[2]]];~ELSE ~FI
+        ~TYP[2] ~GENSYM[i][3];
+        assign ~SYM[3] = ~SYM[1] + ~ARG[2];~IF~SIZE[~TYP[1]]~THEN
+        ~TYPEL[~TYP[1]] ~GENSYM[imap_in][4];
+        assign ~SYM[4] = ~FROMBV[~VAR[vec][1][\~SYM[1]\]][~TYPEL[~TYP[1]]];~ELSE ~FI
         ~TYPEL[~TYPO] ~GENSYM[imap_out][5];
-        ~INST 1
+        ~INST 0
           ~OUTPUT <= ~SYM[5]~ ~TYPEL[~TYPO]~
-          ~INPUT  <= ~SYM[3]~ ~TYP[0]~
-          ~INPUT  <= ~SYM[4]~ ~TYPEL[~TYP[2]]~
+          ~INPUT  <= ~SYM[3]~ ~TYP[2]~
+          ~INPUT  <= ~SYM[4]~ ~TYPEL[~TYP[1]]~
         ~INST
         assign ~RESULT[~SYM[1]] = ~TOBV[~SYM[5]][~TYPEL[~TYPO]];
       end
@@ -182,8 +172,7 @@
 - BlackBox:
     name: Clash.Sized.Vector.zipWith
     kind: Declaration
-    type: 'zipWith :: (a ->
-      b -> c) -> Vec n a -> Vec n b -> Vec n c'
+    type: 'zipWith :: (a -> b -> c) -> Vec n a -> Vec n b -> Vec n c'
     template: |-
       // zipWith begin
       genvar ~GENSYM[n][2];
@@ -207,8 +196,7 @@
 - BlackBox:
     name: Clash.Sized.Vector.foldr
     kind: Declaration
-    type: 'foldr :: (a ->
-      b -> b) -> b -> Vec n a -> b'
+    type: 'foldr :: (a -> b -> b) -> b -> Vec n a -> b'
     template: |-
       // foldr start~IF ~LENGTH[~TYP[2]] ~THEN
       ~SIGDO[~GENSYM[intermediate][0]] [0:~LENGTH[~TYP[2]]];
@@ -235,15 +223,13 @@
 - BlackBox:
     name: Clash.Sized.Vector.index_int
     kind: Expression
-    type: 'index_int :: KnownNat
-      n => Vec n a -> Int -> a'
+    type: 'index_int :: KnownNat n => Vec n a -> Int -> a'
     template: ~IF~SIZE[~TYP[1]]~THEN~FROMBV[~VAR[vec][1][\~ARG[2]\]][~TYPO]~ELSE~ERRORO~FI
 - BlackBox:
     name: Clash.Sized.Vector.replace_int
     kind: Declaration
     outputUsage: Blocking
-    type: 'replace_int ::
-      KnownNat n => Vec n a -> Int -> a -> Vec n a'
+    type: 'replace_int :: KnownNat n => Vec n a -> Int -> a -> Vec n a'
     template: |-
       // replaceVec start
       always_comb begin
@@ -254,15 +240,13 @@
 - BlackBox:
     name: Clash.Sized.Vector.replicate
     kind: Expression
-    type: 'replicate :: SNat
-      n -> a -> Vec n a'
-    template: '''{~LIT[0] {~TOBV[~ARG[1]][~TYP[1]]}}'
+    type: 'replicate :: SNat n -> a -> Vec n a'
+    template: "'{~LIT[0] {~TOBV[~ARG[1]][~TYP[1]]}}"
     workInfo: Never
 - BlackBox:
     name: Clash.Sized.Vector.transpose
     kind: Declaration
-    type: 'transpose :: KnownNat
-      n => Vec m (Vec n a) -> Vec n (Vec m a)'
+    type: 'transpose :: KnownNat n => Vec m (Vec n a) -> Vec n (Vec m a)'
     template: |-
       // transpose begin
       genvar ~GENSYM[row_index][1];
@@ -280,8 +264,7 @@
 - BlackBox:
     name: Clash.Sized.Vector.reverse
     kind: Declaration
-    type: 'reverse :: Vec
-      n a -> Vec n a'
+    type: 'reverse :: Vec n a -> Vec n a'
     template: |-
       // reverse begin
       genvar ~GENSYM[n][1];
@@ -313,8 +296,7 @@
 - BlackBox:
     name: Clash.Sized.Vector.rotateLeftS
     kind: Declaration
-    type: 'rotateLeftS ::
-      KnownNat n => Vec n a -> SNat d -> Vec n a'
+    type: 'rotateLeftS :: KnownNat n => Vec n a -> SNat d -> Vec n a'
     template: |-
       // rotateLeftS begin
       localparam ~GENSYM[shift_amount][2] = ~LIT[2] % ~LIT[0];
@@ -332,8 +314,7 @@
 - BlackBox:
     name: Clash.Sized.Vector.rotateRightS
     kind: Declaration
-    type: 'rotateRightS ::
-      KnownNat n => Vec n a -> SNat d -> Vec n a'
+    type: 'rotateRightS :: KnownNat n => Vec n a -> SNat d -> Vec n a'
     template: |-
       // rotateRightS begin
       localparam ~GENSYM[shift_amount][2] = ~LIT[2] % ~LIT[0];
diff --git a/prims/systemverilog/Clash_Xilinx_DDR.primitives.yaml b/prims/systemverilog/Clash_Xilinx_DDR.primitives.yaml
--- a/prims/systemverilog/Clash_Xilinx_DDR.primitives.yaml
+++ b/prims/systemverilog/Clash_Xilinx_DDR.primitives.yaml
@@ -1,8 +1,8 @@
 - BlackBox:
-    name: Clash.Xilinx.DDR.iddr
+    name: Clash.Xilinx.DDR.iddr#
     kind: Declaration
     type: |-
-      iddr
+      iddr#
         :: ( HasCallStack               -- ARG[0]
            , KnownConfi~ fast domf      -- ARG[1]
            , KnownConfi~ slow doms      -- ARG[2]
@@ -14,8 +14,8 @@
         -> Signal slow (BitVector m,BitVector m)
     template: |-
       // iddr begin
-      ~SIGD[~GENSYM[dataout_l][1]][7];
-      ~SIGD[~GENSYM[dataout_h][2]][7];
+      ~SIGD[~GENSYM[data_pos][1]][7];
+      ~SIGD[~GENSYM[data_neg][2]][7];
       ~SIGD[~GENSYM[d][3]][7];
       assign ~SYM[3] = ~ARG[7];
 
@@ -57,8 +57,8 @@
         -> Signal fast (BitVector m)
     template: |-
       // oddr begin
-      ~SIGD[~GENSYM[datain_l][1]][7];
-      ~SIGD[~GENSYM[datain_h][2]][7];
+      ~SIGD[~GENSYM[data_pos][1]][7];
+      ~SIGD[~GENSYM[data_neg][2]][7];
       ~SIGD[~GENSYM[q][3]][7];
 
       assign ~SYM[1] = ~ARG[6];
@@ -70,7 +70,7 @@
         ODDR #(
           .DDR_CLK_EDGE("SAME_EDGE"),
           .INIT(1'b0),
-          .SRTYPE(~IF ~ISSYNC[2] ~THEN "SYNC" ~ELSE "ASYNC" ~FI)
+          .SRTYPE(~IF ~ISSYNC[1] ~THEN "SYNC" ~ELSE "ASYNC" ~FI)
         ) ~GENSYM[~COMPNAME_ODDR][9] (
           .Q(~SYM[3][~SYM[8]]),
           .C(~ARG[3]),
diff --git a/prims/verilog/Clash_Intel_DDR.primitives.yaml b/prims/verilog/Clash_Intel_DDR.primitives.yaml
--- a/prims/verilog/Clash_Intel_DDR.primitives.yaml
+++ b/prims/verilog/Clash_Intel_DDR.primitives.yaml
@@ -1,10 +1,10 @@
 - BlackBox:
-    name: Clash.Intel.DDR.altddioIn
+    name: Clash.Intel.DDR.altddioIn#
     kind: Declaration
     libraries:
     - altera_mf
     type: |-
-      altddioIn
+      altddioIn#
         :: ( HasCallStack               -- ARG[0]
            , KnownConfi~ fast domf      -- ARG[1]
            , KnownConfi~ slow doms      -- ARG[2]
@@ -27,7 +27,7 @@
           .lpm_hint ("UNUSED"),
           .lpm_type ("altddio_in"),
           .power_up_high ("OFF"),
-          .width (~SIZE[~TYP[7]])
+          .width (~SIZE[~TYP[8]])
         )
         ~GENSYM[~COMPNAME_ALTDDIO_IN][7] (~IF ~ISSYNC[2] ~THEN
           .sclr (~ARG[6]),
diff --git a/prims/verilog/Clash_Sized_Vector.primitives.yaml b/prims/verilog/Clash_Sized_Vector.primitives.yaml
--- a/prims/verilog/Clash_Sized_Vector.primitives.yaml
+++ b/prims/verilog/Clash_Sized_Vector.primitives.yaml
@@ -1,29 +1,25 @@
 - BlackBox:
     name: Clash.Sized.Vector.head
     kind: Expression
-    type: 'head :: Vec (n
-      + 1) a -> a'
+    type: 'head :: Vec (n + 1) a -> a'
     template: '~FROMBV[~VAR[vec][0][\~SIZE[~TYP[0]]-1 -: ~SIZE[~TYPO]\]][~TYPO]'
     workInfo: Never
 - BlackBox:
     name: Clash.Sized.Vector.tail
     kind: Expression
-    type: 'tail :: Vec (n
-      + 1) a -> Vec n a'
+    type: 'tail :: Vec (n + 1) a -> Vec n a'
     template: '~VAR[vec][0][~SIZE[~TYPO]-1 : 0]'
     workInfo: Never
 - BlackBox:
     name: Clash.Sized.Vector.last
     kind: Expression
-    type: Vec (n + 1) a ->
-      a
+    type: Vec (n + 1) a -> a
     template: ~FROMBV[~VAR[vec][0][\~SIZE[~TYPO]-1:0\]][~TYPO]
     workInfo: Never
 - BlackBox:
     name: Clash.Sized.Vector.init
     kind: Expression
-    type: Vec (n + 1) a ->
-      Vec n a
+    type: Vec (n + 1) a -> Vec n a
     template: '~VAR[vec][0][~SIZE[~TYP[0]]-1 : ~SIZE[~TYPEL[~TYP[0]]]]'
     workInfo: Never
 - BlackBox:
@@ -57,22 +53,19 @@
 - BlackBox:
     name: Clash.Sized.Vector.++
     kind: Expression
-    type: '(++) :: Vec n a
-      -> Vec m a -> Vec (n + m) a'
+    type: '(++) :: Vec n a -> Vec m a -> Vec (n + m) a'
     template: '{~ARG[0],~ARG[1]}'
     workInfo: Never
 - BlackBox:
     name: Clash.Sized.Vector.concat
     kind: Expression
-    type: 'concat :: Vec n
-      (Vec m a) -> Vec (n * m) a'
+    type: 'concat :: Vec n (Vec m a) -> Vec (n * m) a'
     template: ~ARG[0]
     workInfo: Never
 - BlackBox:
     name: Clash.Sized.Vector.splitAt
     kind: Expression
-    type: 'splitAt :: SNat
-      m -> Vec (m + n) a -> (Vec m a, Vec n a)'
+    type: 'splitAt :: SNat m -> Vec (m + n) a -> (Vec m a, Vec n a)'
     template: ~ARG[1]
     workInfo: Never
 - BlackBox:
@@ -88,8 +81,7 @@
 - BlackBox:
     name: Clash.Sized.Vector.map
     kind: Declaration
-    type: 'map :: (a -> b)
-      -> Vec n a -> Vec n b'
+    type: 'map :: (a -> b) -> Vec n a -> Vec n b'
     template: |-
       // map begin
       genvar ~GENSYM[i][1];
@@ -110,8 +102,7 @@
 - BlackBox:
     name: Clash.Sized.Vector.imap
     kind: Declaration
-    type: 'imap :: KnownNat
-      n => (Index n -> a -> b) -> Vec n a -> Vec n b'
+    type: 'imap :: KnownNat n => (Index n -> a -> b) -> Vec n a -> Vec n b'
     template: |-
       // imap begin
       genvar ~GENSYM[i][1];
@@ -136,23 +127,22 @@
 - BlackBox:
     name: Clash.Sized.Vector.imap_go
     kind: Declaration
-    type: 'imap :: Index n
-      -> (Index n -> a -> b) -> Vec m a -> Vec m b'
+    type: 'imap_go :: (Index n -> a -> b) -> Vec m a -> Index n -> Vec m b'
     template: |-
       // imap begin
       genvar ~GENSYM[i][1];
       ~GENERATE
       for (~SYM[1]=0; ~SYM[1] < ~LENGTH[~TYPO]; ~SYM[1] = ~SYM[1] + 1) begin : ~GENSYM[imap][2]
-        wire ~TYP[0] ~GENSYM[map_index][3];~IF~SIZE[~TYP[2]]~THEN
-        wire ~TYPEL[~TYP[2]] ~GENSYM[map_in][4];
-        assign ~SYM[4] = ~VAR[vec][2][~SYM[1]*~SIZE[~TYPEL[~TYP[2]]]+:~SIZE[~TYPEL[~TYP[2]]]];~ELSE ~FI
-        ~OUTPUTUSAGE[1] ~TYPEL[~TYPO] ~GENSYM[map_out][5];
+        wire ~TYP[2] ~GENSYM[map_index][3];~IF~SIZE[~TYP[1]]~THEN
+        wire ~TYPEL[~TYP[1]] ~GENSYM[map_in][4];
+        assign ~SYM[4] = ~VAR[vec][1][~SYM[1]*~SIZE[~TYPEL[~TYP[1]]]+:~SIZE[~TYPEL[~TYP[1]]]];~ELSE ~FI
+        ~OUTPUTUSAGE[0] ~TYPEL[~TYPO] ~GENSYM[map_out][5];
 
-        assign ~SYM[3] = ~SIZE[~TYP[0]]'d~MAXINDEX[~TYPO] - ~SYM[1][0+:~SIZE[~TYP[0]]] + ~ARG[0];
-        ~INST 1
+        assign ~SYM[3] = ~SIZE[~TYP[2]]'d~MAXINDEX[~TYPO] - ~SYM[1][0+:~SIZE[~TYP[2]]] + ~ARG[2];
+        ~INST 0
           ~OUTPUT <= ~SYM[5]~ ~TYPEL[~TYPO]~
-          ~INPUT  <= ~SYM[3]~ ~TYP[0]~
-          ~INPUT  <= ~SYM[4]~ ~TYPEL[~TYP[2]]~
+          ~INPUT  <= ~SYM[3]~ ~TYP[2]~
+          ~INPUT  <= ~SYM[4]~ ~TYPEL[~TYP[1]]~
         ~INST
         assign ~RESULT[~SYM[1]*~SIZE[~TYPEL[~TYPO]]+:~SIZE[~TYPEL[~TYPO]]] = ~SYM[5];
       end
@@ -162,8 +152,7 @@
 - BlackBox:
     name: Clash.Sized.Vector.zipWith
     kind: Declaration
-    type: 'zipWith :: (a ->
-      b -> c) -> Vec n a -> Vec n b -> Vec n c'
+    type: 'zipWith :: (a -> b -> c) -> Vec n a -> Vec n b -> Vec n c'
     template: |-
       // zipWith start
       genvar ~GENSYM[i][2];
@@ -187,8 +176,7 @@
 - BlackBox:
     name: Clash.Sized.Vector.foldr
     kind: Declaration
-    type: 'foldr :: (a ->
-      b -> b) -> b -> Vec n a -> b'
+    type: 'foldr :: (a -> b -> b) -> b -> Vec n a -> b'
     template: |-
       // foldr start~IF ~LENGTH[~TYP[2]] ~THEN
       wire ~TYPO ~GENSYM[intermediate][0] [0:~LENGTH[~TYP[2]]];
@@ -223,8 +211,7 @@
 - BlackBox:
     name: Clash.Sized.Vector.replace_int
     kind: Declaration
-    type: 'replace_int ::
-      KnownNat n => Vec n a -> Int -> a -> Vec n a'
+    type: 'replace_int :: KnownNat n => Vec n a -> Int -> a -> Vec n a'
     template: |-
       // vector replace begin
       genvar ~GENSYM[i][0];
@@ -237,29 +224,25 @@
 - BlackBox:
     name: Clash.Sized.Vector.maxIndex
     kind: Expression
-    type: 'maxIndex :: KnownNat
-      n => Vec n a -> Int'
+    type: 'maxIndex :: KnownNat n => Vec n a -> Int'
     template: ~SIZE[~TYPO]'sd~LIT[0] - ~SIZE[~TYPO]'d1
     workInfo: Constant
 - BlackBox:
     name: Clash.Sized.Vector.length
     kind: Expression
-    type: 'length :: KnownNat
-      n => Vec n a -> Int'
+    type: 'length :: KnownNat n => Vec n a -> Int'
     template: ~SIZE[~TYPO]'sd~LIT[0]
     workInfo: Constant
 - BlackBox:
     name: Clash.Sized.Vector.replicate
     kind: Expression
-    type: 'replicate :: SNat
-      n -> a -> Vec n a'
+    type: 'replicate :: SNat n -> a -> Vec n a'
     template: '{~LIT[0] {~ARG[1]}}'
     workInfo: Never
 - BlackBox:
     name: Clash.Sized.Vector.transpose
     kind: Declaration
-    type: 'transpose :: KnownNat
-      n => Vec m (Vec n a) -> Vec n (Vec m a)'
+    type: 'transpose :: KnownNat n => Vec m (Vec n a) -> Vec n (Vec m a)'
     template: |-
       // transpose begin
       genvar ~GENSYM[row_index][1];
@@ -276,8 +259,7 @@
 - BlackBox:
     name: Clash.Sized.Vector.reverse
     kind: Declaration
-    type: 'reverse :: Vec
-      n a -> Vec n a'
+    type: 'reverse :: Vec n a -> Vec n a'
     template: |-
       // reverse begin
       genvar ~GENSYM[i][1];
@@ -309,8 +291,7 @@
 - BlackBox:
     name: Clash.Sized.Vector.rotateLeftS
     kind: Declaration
-    type: 'rotateLeftS ::
-      KnownNat n => Vec n a -> SNat d -> Vec n a'
+    type: 'rotateLeftS :: KnownNat n => Vec n a -> SNat d -> Vec n a'
     template: |-
       // rotateLeftS begin
       localparam ~GENSYM[shift_amount][2] = ~LIT[2] % ~LIT[0];
@@ -329,8 +310,7 @@
 - BlackBox:
     name: Clash.Sized.Vector.rotateRightS
     kind: Declaration
-    type: 'rotateRightS ::
-      KnownNat n => Vec n a -> SNat d -> Vec n a'
+    type: 'rotateRightS :: KnownNat n => Vec n a -> SNat d -> Vec n a'
     template: |-
       // rotateRightS begin
       localparam ~GENSYM[shift_amount][2] = ~LIT[2] % ~LIT[0];
diff --git a/prims/verilog/Clash_Xilinx_DDR.primitives.yaml b/prims/verilog/Clash_Xilinx_DDR.primitives.yaml
--- a/prims/verilog/Clash_Xilinx_DDR.primitives.yaml
+++ b/prims/verilog/Clash_Xilinx_DDR.primitives.yaml
@@ -1,8 +1,8 @@
 - BlackBox:
-    name: Clash.Xilinx.DDR.iddr
+    name: Clash.Xilinx.DDR.iddr#
     kind: Declaration
     type: |-
-      iddr
+      iddr#
         :: ( HasCallStack            -- ARG[0]
            , KnownConfi~ fast domf   -- ARG[1]
            , KnownConfi~ slow doms   -- ARG[2]
@@ -14,8 +14,8 @@
         -> Signal slow (BitVector m,BitVector m)
     template: |-
       // iddr begin
-      wire ~SIGD[~GENSYM[dataout_l][1]][7];
-      wire ~SIGD[~GENSYM[dataout_h][2]][7];
+      wire ~SIGD[~GENSYM[data_pos][1]][7];
+      wire ~SIGD[~GENSYM[data_neg][2]][7];
       wire ~SIGD[~GENSYM[d][3]][7];
       assign ~SYM[3] = ~ARG[7];
 
@@ -57,8 +57,8 @@
         -> Signal fast (BitVector m)
     template: |-
       // oddr begin
-      wire ~SIGD[~GENSYM[datain_l][1]][7];
-      wire ~SIGD[~GENSYM[datain_h][2]][7];
+      wire ~SIGD[~GENSYM[data_pos][1]][7];
+      wire ~SIGD[~GENSYM[data_neg][2]][7];
       wire ~SIGD[~GENSYM[q][3]][7];
 
       assign ~SYM[1] = ~ARG[6];
diff --git a/prims/vhdl/Clash_Class_BitPack.primitives.yaml b/prims/vhdl/Clash_Class_BitPack.primitives.yaml
new file mode 100644
--- /dev/null
+++ b/prims/vhdl/Clash_Class_BitPack.primitives.yaml
@@ -0,0 +1,12 @@
+- BlackBox:
+    name: Clash.Class.BitPack.Internal.packChar#
+    kind: Expression
+    type: 'packChar# :: Char -> BitVector 21'
+    template: std_logic_vector(~ARG[0])
+    workInfo: Never
+- BlackBox:
+    name: Clash.Class.BitPack.Internal.unpackChar#
+    kind: Expression
+    type: 'unpackChar# :: BitVector 21 -> Char'
+    template: unsigned(~ARG[0])
+    workInfo: Never
diff --git a/prims/vhdl/Clash_Explicit_DDR.primitives.yaml b/prims/vhdl/Clash_Explicit_DDR.primitives.yaml
--- a/prims/vhdl/Clash_Explicit_DDR.primitives.yaml
+++ b/prims/vhdl/Clash_Explicit_DDR.primitives.yaml
@@ -60,7 +60,7 @@
        ~ELSE
         -- async
         --------------
-        ~SYM[6] : process(~ARG[4],~ARG[5]~VARS[9])
+        ~SYM[6] : process(~ARG[4],~ARG[5])
         begin
           if ~ARG[5] = ~IF~ISACTIVEHIGH[2]~THEN'1'~ELSE'0'~FI then
             ~SYM[1] <= ~ARG[8];
@@ -69,7 +69,7 @@
           end if;
         end process;
 
-        ~SYM[7] : process(~ARG[4],~ARG[5]~VARS[9])
+        ~SYM[7] : process(~ARG[4],~ARG[5])
         begin
           if ~ARG[5] = ~IF~ISACTIVEHIGH[2]~THEN'1'~ELSE'0'~FI then
             ~SYM[2] <= ~ARG[9];
@@ -78,7 +78,7 @@
           end if;
         end process;
 
-        ~SYM[8] : process(~ARG[4],~ARG[5],~SYM[2])
+        ~SYM[8] : process(~ARG[4],~ARG[5])
         begin
           if ~ARG[5] = ~IF~ISACTIVEHIGH[2]~THEN'1'~ELSE'0'~FI then
             ~SYM[3] <= ~ARG[7];
@@ -107,7 +107,7 @@
                -> Signal fast a
     template: |-
       -- ddrOut begin
-      ~GENSYM[~COMPNAME_ddrIn][0] : block
+      ~GENSYM[~COMPNAME_ddrOut][0] : block
         signal ~GENSYM[data_Pos][1] : ~TYP[7];
         signal ~GENSYM[data_Neg][2] : ~TYP[7];
       begin
@@ -142,7 +142,7 @@
         begin
           if ~ARG[5] = ~IF~ISACTIVEHIGH[2]~THEN'1'~ELSE'0'~FI then
             ~SYM[1] <= ~ARG[7];
-          elsif ~IF~ACTIVEEDGE[Rising][2]~THENrising_edge~ELSEfalling_edge~FI(~ARG[4]) then
+          elsif ~IF ~ISACTIVEENABLE[6] ~THEN ~ARG[6] and ~ELSE ~FI ~IF~ACTIVEEDGE[Rising][2]~THENrising_edge~ELSEfalling_edge~FI(~ARG[4]) then
             ~SYM[1] <= ~ARG[8];
           end if;
         end process;
@@ -151,11 +151,11 @@
         begin
           if ~ARG[5] = ~IF~ISACTIVEHIGH[2]~THEN'1'~ELSE'0'~FI then
             ~SYM[2] <= ~ARG[7];
-          elsif ~IF~ACTIVEEDGE[Rising][2]~THENrising_edge~ELSEfalling_edge~FI(~ARG[4]) then
+          elsif ~IF ~ISACTIVEENABLE[6] ~THEN ~ARG[6] and ~ELSE ~FI ~IF~ACTIVEEDGE[Rising][2]~THENrising_edge~ELSEfalling_edge~FI(~ARG[4]) then
             ~SYM[2] <= ~ARG[9];
           end if;
         end process;
        ~FI
-        ~RESULT <= ~IF~ACTIVEEDGE[Rising][2]~THEN~SYM[1]~ELSE~SYM[2]~FI when (~ARG[4] = '1' ~IF ~ISACTIVEENABLE[6] ~THEN and ~ARG[6] ~ELSE ~FI) else ~IF~ACTIVEEDGE[Rising][2]~THEN~SYM[2]~ELSE~SYM[1]~FI;
+        ~RESULT <= ~IF~ACTIVEEDGE[Rising][2]~THEN~SYM[1]~ELSE~SYM[2]~FI when (~ARG[4] = '1') else ~IF~ACTIVEEDGE[Rising][2]~THEN~SYM[2]~ELSE~SYM[1]~FI;
       end block;
       -- ddrOut end
diff --git a/prims/vhdl/Clash_Intel_DDR.primitives.yaml b/prims/vhdl/Clash_Intel_DDR.primitives.yaml
--- a/prims/vhdl/Clash_Intel_DDR.primitives.yaml
+++ b/prims/vhdl/Clash_Intel_DDR.primitives.yaml
@@ -1,12 +1,12 @@
 - BlackBox:
-    name: Clash.Intel.DDR.altddioIn
+    name: Clash.Intel.DDR.altddioIn#
     imports:
     - altera_mf.altera_mf_components.all
     kind: Declaration
     libraries:
     - altera_mf
     type: |-
-      altddioIn
+      altddioIn#
         :: ( HasCallStack               -- ARG[0]
            , KnownConfi~ fast domf      -- ARG[1]
            , KnownConfi~ slow doms      -- ARG[2]
@@ -23,7 +23,7 @@
         signal ~GENSYM[dataout_l][1] : ~TYP[8];
         signal ~GENSYM[dataout_h][2] : ~TYP[8];~IF ~ISACTIVEENABLE[7] ~THEN
         signal ~GENSYM[ce_logic][4]: std_logic;~ELSE ~FI
-      begin~IF ~ISACTIVEENABLE[5] ~THEN
+      begin~IF ~ISACTIVEENABLE[7] ~THEN
         ~SYM[4] <= '1' when (~ARG[7]) else '0';~ELSE ~FI
         ~GENSYM[~COMPNAME_ALTDDIO_IN][7] : ALTDDIO_IN
         GENERIC MAP (
@@ -37,7 +37,7 @@
         PORT MAP (~IF ~ISSYNC[6] ~THEN
           sclr      => ~ARG[6],~ELSE
           aclr      => ~ARG[6],~FI
-          datain    => ~ARG[8],~IF ~ISACTIVEENABLE[5] ~THEN
+          datain    => ~ARG[8],~IF ~ISACTIVEENABLE[7] ~THEN
           inclocken => ~SYM[4],~ELSE ~FI
           inclock   => ~ARG[5],
           dataout_h => ~SYM[2],
@@ -71,7 +71,7 @@
       ~GENSYM[~COMPNAME_ALTDDIO_OUT][0] : block ~IF ~ISACTIVEENABLE[7] ~THEN
         signal ~GENSYM[ce_logic][1] : std_logic; ~ELSE ~FI
       begin~IF ~ISACTIVEENABLE[7] ~THEN
-        ~SYM[3] <= '1' when (~ARG[7]) else '0'; ~ELSE ~FI
+        ~SYM[1] <= '1' when (~ARG[7]) else '0'; ~ELSE ~FI
         ~GENSYM[~COMPNAME_ALTDDIO_OUT][7] : ALTDDIO_OUT
           GENERIC MAP (
             extend_oe_disable => "OFF",
@@ -88,8 +88,8 @@
             aclr       => ~ARG[6],~FI ~IF ~ISACTIVEENABLE[7] ~THEN
             outclocken => ~SYM[1],~ELSE ~FI
             outclock   => ~ARG[5],
-            datain_h   => ~ARG[7],
-            datain_l   => ~ARG[8],
+            datain_h   => ~ARG[8],
+            datain_l   => ~ARG[9],
             dataout    => ~RESULT
           );
       end block;
diff --git a/prims/vhdl/Clash_Sized_Vector.primitives.yaml b/prims/vhdl/Clash_Sized_Vector.primitives.yaml
--- a/prims/vhdl/Clash_Sized_Vector.primitives.yaml
+++ b/prims/vhdl/Clash_Sized_Vector.primitives.yaml
@@ -1,31 +1,27 @@
 - BlackBox:
     name: Clash.Sized.Vector.head
     kind: Expression
-    type: 'head :: Vec (n
-      + 1) a -> a'
+    type: 'head :: Vec (n + 1) a -> a'
     template: ~IF ~VIVADO ~THEN ~TYPMO'(fromSLV(~VAR[vec][0](0))) ~ELSE ~VAR[vec][0](0)
       ~FI
     workInfo: Never
 - BlackBox:
     name: Clash.Sized.Vector.tail
     kind: Expression
-    type: 'tail :: Vec (n
-      + 1) a -> Vec n a'
+    type: 'tail :: Vec (n + 1) a -> Vec n a'
     template: ~VAR[vec][0](1 to ~VAR[vec][0]'high)
     workInfo: Never
 - BlackBox:
     name: Clash.Sized.Vector.last
     kind: Expression
-    type: Vec (n + 1) a ->
-      a
+    type: Vec (n + 1) a -> a
     template: ~IF ~VIVADO ~THEN ~TYPMO'(fromSLV(~VAR[vec][0](~VAR[vec][0]'high)))
       ~ELSE ~VAR[vec][0](~VAR[vec][0]'high) ~FI
     workInfo: Never
 - BlackBox:
     name: Clash.Sized.Vector.init
     kind: Expression
-    type: Vec (n + 1) a ->
-      Vec n a
+    type: Vec (n + 1) a -> Vec n a
     template: ~VAR[vec][0](0 to ~VAR[vec][0]'high - 1)
     workInfo: Never
 - BlackBox:
@@ -48,15 +44,13 @@
 - BlackBox:
     name: Clash.Sized.Vector.++
     kind: Expression
-    type: '(++) :: Vec n a
-      -> Vec m a -> Vec (n + m) a'
+    type: '(++) :: Vec n a -> Vec m a -> Vec (n + m) a'
     template: ~TYPMO'(~TYPM[0]'(~ARG[0]) & ~TYPM[1]'(~ARG[1]))
     workInfo: Never
 - BlackBox:
     name: Clash.Sized.Vector.concat
     kind: Declaration
-    type: 'concat :: Vec n
-      (Vec m a) -> Vec (n * m) a'
+    type: 'concat :: Vec n (Vec m a) -> Vec (n * m) a'
     template: |-
       -- concat begin
       ~GENSYM[concat][0] : for ~GENSYM[i][1] in 0 to (~LENGTH[~TYP[0]] - 1) generate
@@ -69,8 +63,7 @@
 - BlackBox:
     name: Clash.Sized.Vector.splitAt
     kind: Expression
-    type: 'splitAt :: SNat
-      m -> Vec (m + n) a -> (Vec m a, Vec n a)'
+    type: 'splitAt :: SNat m -> Vec (m + n) a -> (Vec m a, Vec n a)'
     template: ~IF~LENGTH[~TYPO]~THEN~ARG[1]~ELSE(~VAR[vec][1](0 to ~LIT[0]-1),~VAR[vec][1](~LIT[0]
       to ~VAR[vec][1]'high))~FI
     workInfo: Never
@@ -94,8 +87,7 @@
 - BlackBox:
     name: Clash.Sized.Vector.map
     kind: Declaration
-    type: 'map :: (a -> b)
-      -> Vec n a -> Vec n b'
+    type: 'map :: (a -> b) -> Vec n a -> Vec n b'
     template: |-
       -- map begin
       ~GENSYM[map][0] : for ~GENSYM[i][1] in ~RESULT'range generate~IF ~VIVADO ~THEN~IF~SIZE[~TYP[1]]~THEN
@@ -120,8 +112,7 @@
 - BlackBox:
     name: Clash.Sized.Vector.imap
     kind: Declaration
-    type: 'imap :: KnownNat
-      n => (Index n -> a -> b) -> Vec n a -> Vec n b'
+    type: 'imap :: KnownNat n => (Index n -> a -> b) -> Vec n a -> Vec n b'
     template: |-
       -- imap begin
       ~GENSYM[imap][0] : block
@@ -157,31 +148,30 @@
 - BlackBox:
     name: Clash.Sized.Vector.imap_go
     kind: Declaration
-    type: 'imap_go :: Index
-      n -> (Index n -> a -> b) -> Vec m a -> Vec m b'
+    type: 'imap_go :: (Index n -> a -> b) -> Vec m a -> Index n -> Vec m b'
     template: |-
       -- imap_go begin
-      ~GENSYM[imap][5] : for ~GENSYM[i][1] in ~RESULT'range generate~IF ~VIVADO ~THEN~IF~SIZE[~TYP[2]]~THEN
-        signal ~GENSYM[map_in][2]  : ~TYPEL[~TYP[2]];~ELSE ~FI
+      ~GENSYM[imap][5] : for ~GENSYM[i][1] in ~RESULT'range generate~IF ~VIVADO ~THEN~IF~SIZE[~TYP[1]]~THEN
+        signal ~GENSYM[map_in][2]  : ~TYPEL[~TYP[1]];~ELSE ~FI
         signal ~GENSYM[map_out][3] : ~TYPEL[~TYPO];
-        signal ~GENSYM[i2][4]      : ~TYP[0];
-      begin~IF~SIZE[~TYP[2]]~THEN
-        ~SYM[2] <= fromSLV(~VAR[vec][2](~SYM[1]));~ELSE ~FI
-        ~SYM[4] <= ~ARG[0] + to_unsigned(~SYM[1],~SIZE[~TYP[0]]);
-        ~INST 1
+        signal ~GENSYM[i2][4]      : ~TYP[2];
+      begin~IF~SIZE[~TYP[1]]~THEN
+        ~SYM[2] <= fromSLV(~VAR[vec][1](~SYM[1]));~ELSE ~FI
+        ~SYM[4] <= ~ARG[2] + to_unsigned(~SYM[1],~SIZE[~TYP[2]]);
+        ~INST 0
           ~OUTPUT <= ~SYM[3]~ ~TYPEL[~TYPO]~
-          ~INPUT  <= ~SYM[4]~ ~TYP[0]~
-          ~INPUT  <= ~SYM[2]~ ~TYPEL[~TYP[2]]~
+          ~INPUT  <= ~SYM[4]~ ~TYP[2]~
+          ~INPUT  <= ~SYM[2]~ ~TYPEL[~TYP[1]]~
         ~INST
         ~RESULT(~SYM[1]) <= ~TOBV[~SYM[3]][~TYPEL[~TYPO]];
       end generate;~ELSE
-        signal ~SYM[4] : ~TYP[0];
+        signal ~SYM[4] : ~TYP[2];
       begin
-        ~SYM[4] <= ~ARG[0] + to_unsigned(~SYM[1],~SIZE[~TYP[0]]);
-        ~INST 1
+        ~SYM[4] <= ~ARG[2] + to_unsigned(~SYM[1],~SIZE[~TYP[2]]);
+        ~INST 0
           ~OUTPUT <= ~RESULT(~SYM[1])~ ~TYPEL[~TYPO]~
-          ~INPUT  <= ~SYM[4]~ ~TYP[0]~
-          ~INPUT  <= ~VAR[vec][2](~SYM[1])~ ~TYPEL[~TYP[2]]~
+          ~INPUT  <= ~SYM[4]~ ~TYP[2]~
+          ~INPUT  <= ~VAR[vec][1](~SYM[1])~ ~TYPEL[~TYP[1]]~
         ~INST
       end generate;~FI
       -- imap_go end
@@ -189,8 +179,7 @@
 - BlackBox:
     name: Clash.Sized.Vector.zipWith
     kind: Declaration
-    type: 'zipWith :: (a ->
-      b -> c) -> Vec n a -> Vec n b -> Vec n c'
+    type: 'zipWith :: (a -> b -> c) -> Vec n a -> Vec n b -> Vec n c'
     template: |-
       -- zipWith begin
       ~GENSYM[zipWith][0] : for ~GENSYM[i][1] in ~RESULT'range generate~IF ~VIVADO ~THEN~IF~SIZE[~TYP[1]]~THEN
@@ -219,8 +208,7 @@
 - BlackBox:
     name: Clash.Sized.Vector.foldr
     kind: Declaration
-    type: 'foldr :: (a ->
-      b -> b) -> b -> Vec n a -> b'
+    type: 'foldr :: (a -> b -> b) -> b -> Vec n a -> b'
     template: |-
       -- foldr begin~IF ~LENGTH[~TYP[2]] ~THEN
       ~GENSYM[foldr][0] : block
@@ -255,8 +243,7 @@
 - BlackBox:
     name: Clash.Sized.Vector.index_int
     kind: Declaration
-    type: 'index_int :: KnownNat
-      n => Vec n a -> Int -> a'
+    type: 'index_int :: KnownNat n => Vec n a -> Int -> a'
     template: |-
       -- index begin
       ~IF~SIZE[~TYP[1]]~THEN~GENSYM[indexVec][0] : block
@@ -275,8 +262,7 @@
     name: Clash.Sized.Vector.replace_int
     kind: Declaration
     outputUsage: NonBlocking
-    type: 'replace_int ::
-      KnownNat n => Vec n a -> Int -> a -> Vec n a'
+    type: 'replace_int :: KnownNat n => Vec n a -> Int -> a -> Vec n a'
     template: |-
       -- replace begin
       ~GENSYM[replaceVec][0] : block
@@ -301,23 +287,20 @@
 - BlackBox:
     name: Clash.Sized.Vector.length
     kind: Expression
-    type: 'length :: KnownNat
-      n => Vec n a -> Int'
+    type: 'length :: KnownNat n => Vec n a -> Int'
     template: to_signed(~LIT[0],~SIZE[~TYPO])
     workInfo: Constant
 - BlackBox:
     name: Clash.Sized.Vector.replicate
     kind: Expression
-    type: 'replicate :: SNat
-      n -> a -> Vec n a'
+    type: 'replicate :: SNat n -> a -> Vec n a'
     template: ~TYPMO'(0 to ~LIT[0]-1 => ~IF ~VIVADO ~THEN ~TOBV[~ARG[1]][~TYP[1]]
       ~ELSE ~ARG[1] ~FI)
     workInfo: Never
 - BlackBox:
     name: Clash.Sized.Vector.transpose
     kind: Declaration
-    type: 'transpose :: KnownNat
-      n => Vec m (Vec n a) -> Vec n (Vec m a)'
+    type: 'transpose :: KnownNat n => Vec m (Vec n a) -> Vec n (Vec m a)'
     template: |-
       -- transpose begin
       ~GENSYM[transpose_outer][2] : for ~GENSYM[row_index][3] in 0 to (~LENGTH[~TYP[1]] - 1) generate
@@ -331,8 +314,7 @@
 - BlackBox:
     name: Clash.Sized.Vector.reverse
     kind: Declaration
-    type: 'reverse :: Vec
-      n a -> Vec n a'
+    type: 'reverse :: Vec n a -> Vec n a'
     template: |-
       -- reverse begin
       ~GENSYM[reverse_loop][2] : for ~GENSYM[i][3] in 0 to (~LENGTH[~TYP[0]] - 1) generate
@@ -371,8 +353,7 @@
 - BlackBox:
     name: Clash.Sized.Vector.rotateLeftS
     kind: Declaration
-    type: 'rotateLeftS ::
-      KnownNat n => Vec n a -> SNat d -> Vec n a'
+    type: 'rotateLeftS :: KnownNat n => Vec n a -> SNat d -> Vec n a'
     template: |-
       -- rotateLeftS begin
       ~GENSYM[rotateLeftS][0] : block
@@ -392,8 +373,7 @@
 - BlackBox:
     name: Clash.Sized.Vector.rotateRightS
     kind: Declaration
-    type: 'rotateRightS ::
-      KnownNat n => Vec n a -> SNat d -> Vec n a'
+    type: 'rotateRightS :: KnownNat n => Vec n a -> SNat d -> Vec n a'
     template: |-
       -- rotateRightS begin
       ~GENSYM[rotateLeftS][0] : block
diff --git a/prims/vhdl/Clash_Xilinx_DDR.primitives.yaml b/prims/vhdl/Clash_Xilinx_DDR.primitives.yaml
--- a/prims/vhdl/Clash_Xilinx_DDR.primitives.yaml
+++ b/prims/vhdl/Clash_Xilinx_DDR.primitives.yaml
@@ -1,12 +1,12 @@
 - BlackBox:
-    name: Clash.Xilinx.DDR.iddr
+    name: Clash.Xilinx.DDR.iddr#
     imports:
     - UNISIM.vcomponents.all
     kind: Declaration
     libraries:
     - UNISIM
     type: |-
-      iddr
+      iddr#
         :: ( HasCallStack             -- ARG[0]
            , KnownConfi~ fast domf    -- ARG[1]
            , KnownConfi~ slow doms    -- ARG[2]
@@ -19,8 +19,8 @@
     template: |-
       -- iddr begin
       ~GENSYM[~COMPNAME_IDDR][0] : block
-        signal ~GENSYM[dataout_l][1] : ~TYP[7];
-        signal ~GENSYM[dataout_h][2] : ~TYP[7];
+        signal ~GENSYM[data_pos][1] : ~TYP[7];
+        signal ~GENSYM[data_neg][2] : ~TYP[7];
         signal ~GENSYM[d][3]         : ~TYP[7];~IF ~ISACTIVEENABLE[6] ~THEN
         signal ~GENSYM[ce_logic][4]: std_logic;~ELSE ~FI
       begin~IF ~ISACTIVEENABLE[6] ~THEN
@@ -70,8 +70,8 @@
     template: |-
       -- oddr begin
       ~GENSYM[~COMPNAME_ODDR][0] : block
-        signal ~GENSYM[dataout_l][1] : ~TYPO;
-        signal ~GENSYM[dataout_h][2] : ~TYPO;
+        signal ~GENSYM[data_pos][1] : ~TYPO;
+        signal ~GENSYM[data_neg][2] : ~TYPO;
         signal ~GENSYM[q][3]         : ~TYPO;~IF ~ISACTIVEENABLE[5] ~THEN
         signal ~GENSYM[ce_logic][4]  : std_logic;~ELSE ~FI
       begin~IF ~ISACTIVEENABLE[5] ~THEN
@@ -79,13 +79,13 @@
         ~SYM[1] <= ~ARG[6];
         ~SYM[2] <= ~ARG[7];
 
-        ~GENSYM[gen_iddr][7] : for ~GENSYM[i][8] in ~SYM[3]'range generate
+        ~GENSYM[gen_oddr][7] : for ~GENSYM[i][8] in ~SYM[3]'range generate
         begin
           ~GENSYM[~COMPNAME_ODDR_inst][9] : ODDR
           generic map(
             DDR_CLK_EDGE => "SAME_EDGE",
             INIT => '0',
-            SRTYPE => ~IF ~ISSYNC[2] ~THEN "SYNC" ~ELSE "ASYNC" ~FI)
+            SRTYPE => ~IF ~ISSYNC[1] ~THEN "SYNC" ~ELSE "ASYNC" ~FI)
           port map (
             Q  => ~SYM[3](~SYM[8]),    -- 1-bit DDR output
             C  => ~ARG[3],   -- 1-bit clock input
diff --git a/src/Clash/Backend/SystemVerilog.hs b/src/Clash/Backend/SystemVerilog.hs
--- a/src/Clash/Backend/SystemVerilog.hs
+++ b/src/Clash/Backend/SystemVerilog.hs
@@ -1,7 +1,7 @@
 {-|
   Copyright   :  (C) 2015-2016, University of Twente,
                      2017-2018, Google Inc.,
-                     2021-2023, QBayLogic B.V.,
+                     2021-2024, QBayLogic B.V.,
                      2022     , Google Inc.
   License     :  BSD2 (see the file LICENSE)
   Maintainer  :  QBayLogic B.V. <devops@qbaylogic.com>
@@ -31,6 +31,8 @@
 import qualified Data.HashMap.Lazy                    as HashMap
 import           Data.HashSet                         (HashSet)
 import qualified Data.HashSet                         as HashSet
+import qualified Data.Map                             as Map
+import           Data.Map                             (Map)
 import           Data.List                            (nub, nubBy)
 import           Data.List.Extra                      ((<:>), zipEqual)
 import           Data.Maybe                           (catMaybes,fromMaybe,mapMaybe)
@@ -40,6 +42,7 @@
 import qualified Data.Text                            as TextS
 import           Data.Text.Prettyprint.Doc.Extra
 import qualified Data.Text.Prettyprint.Doc.Extra      as PP
+import           Data.Tuple                           (swap)
 import qualified System.FilePath
 
 import           Clash.Annotations.Primitive          (HDL (..))
@@ -59,13 +62,13 @@
 import           Clash.Explicit.BlockRam.Internal     (unpackNats)
 import           Clash.Netlist.BlackBox.Types         (HdlSyn (..))
 import           Clash.Netlist.BlackBox.Util
-  (extractLiterals, renderBlackBox, renderFilePath)
+  (extractLiterals, renderBlackBox, addFilePath)
 import qualified Clash.Netlist.Id                     as Id
 import           Clash.Netlist.Types                  hiding (intWidth, usages, _usages)
 import           Clash.Netlist.Util
 import           Clash.Signal.Internal                (ActiveEdge (..))
 import           Clash.Util
-  (SrcSpan, noSrcSpan, curLoc, makeCached, indexNote)
+  (SrcSpan, clogBase, noSrcSpan, curLoc, makeCached, indexNote)
 import           Clash.Util.Graph                     (reverseTopSort)
 
 -- | State for the 'Clash.Backend.SystemVerilog.SystemVerilogM' monad:
@@ -82,8 +85,12 @@
     , _includes  :: [(String,Doc)]
     , _imports   :: [Text.Text]
     , _libraries :: [Text.Text]
-    , _dataFiles      :: [(String,FilePath)]
-    -- ^ Files to be copied: (filename, old path)
+    , _dataFiles :: Map FilePath String
+    -- ^ Files to be copied: (path to file, file name). The file name stored in
+    -- the map might differ from the file name in the path, to prevent name
+    -- collisions.
+    , _includeDirs :: [FilePath]
+    -- ^ Import directories passed in with @-i@
     , _memoryDataFiles:: [(String,String)]
     -- ^ Files to be stored: (filename, contents). These files are generated
     -- during the execution of 'genNetlist'.
@@ -119,7 +126,8 @@
     , _includes=[]
     , _imports=[]
     , _libraries=[]
-    , _dataFiles=[]
+    , _dataFiles=mempty
+    , _includeDirs = opt_importPaths opts
     , _memoryDataFiles=[]
     , _tyPkgCtx=False
     , _intWidth=opt_intWidth opts
@@ -188,10 +196,12 @@
   addImports inps = imports %= (inps ++)
   addAndSetData f = do
     fs <- use dataFiles
-    let (fs',f') = renderFilePath fs f
+    iDirs <- use includeDirs
+    let (fs',f') = addFilePath iDirs fs f
     dataFiles .= fs'
     return f'
-  getDataFiles = use dataFiles
+  getDataFiles :: State SystemVerilogState [(String, FilePath)]
+  getDataFiles = map swap . Map.assocs <$> use dataFiles
   addMemoryDataFile f = memoryDataFiles %= (f:)
   getMemoryDataFiles = use memoryDataFiles
   ifThenElseExpr _ = True
@@ -1228,7 +1238,9 @@
 expr_ _ (BlackBoxE pNm _ _ _ _ bbCtx _)
   | pNm == "Clash.Sized.Internal.Index.fromInteger#"
   , [Literal _ (NumLit n), Literal _ i] <- extractLiterals bbCtx
-  = exprLitSV (Just (Index (fromInteger n),fromInteger n)) i
+  , Just k <- clogBase 2 n
+  , let k' = max 1 k
+  = exprLitSV (Just (Index (fromInteger n),k')) i
 
 expr_ b (BlackBoxE _ libs imps inc bs bbCtx b') =
   parenIf (b || b') (Ap (renderBlackBox libs imps inc bs bbCtx <*> pure 0))
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
@@ -37,6 +37,8 @@
 import qualified Data.HashMap.Strict                  as HashMapS
 import           Data.HashSet                         (HashSet)
 import qualified Data.HashSet                         as HashSet
+import qualified Data.Map                             as Map
+import           Data.Map                             (Map)
 import           Data.List
   (mapAccumL, nub, nubBy, intersperse, group, sort)
 import           Data.List.Extra                      ((<:>), equalLength, zipEqual)
@@ -46,6 +48,7 @@
 import qualified Data.Text.Lazy                       as T
 import qualified Data.Text                            as TextS
 import           Data.Text.Extra
+import           Data.Tuple                           (swap)
 
 #if MIN_VERSION_prettyprinter(1,7,0)
 import qualified Prettyprinter                        as PP
@@ -72,7 +75,7 @@
 import           Clash.Explicit.BlockRam.Internal     (unpackNats)
 import           Clash.Netlist.BlackBox.Types         (HdlSyn (..))
 import           Clash.Netlist.BlackBox.Util
-  (extractLiterals, renderBlackBox, renderFilePath)
+  (extractLiterals, renderBlackBox, addFilePath)
 import qualified Clash.Netlist.Id                     as Id
 import           Clash.Netlist.Types                  hiding (intWidth, usages, _usages)
 import           Clash.Netlist.Util
@@ -98,8 +101,12 @@
   , _libraries :: [T.Text]
   , _packages  :: [T.Text]
   , _includes  :: [(String,Doc)]
-  , _dataFiles      :: [(String,FilePath)]
-  -- ^ Files to be copied: (filename, old path)
+  , _dataFiles :: Map FilePath String
+  -- ^ Files to be copied: (path to file, file name). The file name stored in
+  -- the map might differ from the file name in the path, to prevent name
+  -- collisions.
+  , _includeDirs :: [FilePath]
+  -- ^ Import directories passed in with @-i@
   , _memoryDataFiles:: [(String,String)]
   -- ^ Files to be stored: (filename, contents). These files are generated
   -- during the execution of 'genNetlist'.
@@ -139,7 +146,8 @@
     , _libraries=[]
     , _packages=[]
     , _includes=[]
-    , _dataFiles=[]
+    , _dataFiles=mempty
+    , _includeDirs = opt_importPaths opts
     , _memoryDataFiles=[]
     , _idSeen=Id.emptyIdentifierSet (opt_escapedIds opts) (opt_lowerCaseBasicIds opts) VHDL
     , _tyPkgCtx=False
@@ -271,10 +279,11 @@
   addImports imps = packages %= (imps ++)
   addAndSetData f = do
     fs <- use dataFiles
-    let (fs',f') = renderFilePath fs f
+    iDirs <- use includeDirs
+    let (fs',f') = addFilePath iDirs fs f
     dataFiles .= fs'
     return f'
-  getDataFiles = use dataFiles
+  getDataFiles = map swap . Map.assocs <$> use dataFiles
   addMemoryDataFile f = memoryDataFiles %= (f:)
   getMemoryDataFiles = use memoryDataFiles
   ifThenElseExpr _ = False
@@ -1762,7 +1771,7 @@
   , [Literal _ (NumLit n), Literal _ i] <- extractLiterals bbCtx
   , Just k <- clogBase 2 n
   , let k' = max 1 k
-  = exprLit (Just (Unsigned k',k')) i
+  = exprLit (Just (Index n,k')) i
 
 expr_ _ (BlackBoxE pNm _ _ _ _ bbCtx _)
   | pNm == "Clash.Sized.Internal.Index.maxBound#"
@@ -1860,6 +1869,9 @@
     | i < 0                    -> "unsigned" <> parens ("std_logic_vector" <> parens ("to_signed" <> parens(integer i <> "," <> int n)))
     | i < 2^(31 :: Integer) -> "to_unsigned" <> parens (integer i <> "," <> int n)
     | otherwise -> "unsigned'" <> parens lit
+  Index n
+   | 0 <= i && i < n -> exprLit (Just (Unsigned sz, sz)) (NumLit i)  -- reuse Unsigned implementation above
+   | otherwise       -> hdlTypeErrValue hty
   Signed n
     | i < 2^(31 :: Integer) && i > (-2^(31 :: Integer)) -> "to_signed" <> parens (integer i <> "," <> int n)
     | otherwise -> "signed'" <> parens lit
diff --git a/src/Clash/Backend/Verilog.hs b/src/Clash/Backend/Verilog.hs
--- a/src/Clash/Backend/Verilog.hs
+++ b/src/Clash/Backend/Verilog.hs
@@ -45,6 +45,8 @@
 import qualified Data.HashMap.Strict                  as HashMap
 import           Data.HashSet                         (HashSet)
 import qualified Data.HashSet                         as HashSet
+import qualified Data.Map                             as Map
+import           Data.Map                             (Map)
 import           Data.Maybe                           (catMaybes, fromMaybe)
 import           Data.Monoid                          (Ap(Ap))
 import           Data.Monoid.Extra                    ()
@@ -58,6 +60,7 @@
 import qualified Data.Text.Lazy                       as Text
 import qualified Data.Text                            as TextS
 import           Data.Text.Prettyprint.Doc.Extra
+import           Data.Tuple                           (swap)
 import qualified System.FilePath
 import           GHC.Stack                            (HasCallStack)
 
@@ -76,13 +79,13 @@
 import           Clash.Explicit.BlockRam.Internal     (unpackNats)
 import           Clash.Netlist.BlackBox.Types         (HdlSyn)
 import           Clash.Netlist.BlackBox.Util
-  (extractLiterals, renderBlackBox, renderFilePath)
+  (extractLiterals, renderBlackBox, addFilePath)
 import qualified Clash.Netlist.Id                     as Id
 import           Clash.Netlist.Types as N             hiding (intWidth, usages, _usages)
 import           Clash.Netlist.Util
 import           Clash.Signal.Internal                (ActiveEdge (..))
 import           Clash.Util
-  (SrcSpan, noSrcSpan, curLoc, indexNote, makeCached)
+  (SrcSpan, clogBase, noSrcSpan, curLoc, indexNote, makeCached)
 
 -- | State for the 'Clash.Backend.Verilog.VerilogM' monad:
 data VerilogState =
@@ -94,8 +97,12 @@
     , _includes  :: [(String,Doc)]
     , _imports   :: HashSet Text.Text
     , _libraries :: HashSet Text.Text
-    , _dataFiles      :: [(String,FilePath)]
-    -- ^ Files to be copied: (filename, old path)
+    , _dataFiles :: Map FilePath String
+    -- ^ Files to be copied: (path to file, file name). The file name stored in
+    -- the map might differ from the file name in the path, to prevent name
+    -- collisions.
+    , _includeDirs :: [FilePath]
+    -- ^ Import directories passed in with @-i@
     , _memoryDataFiles:: [(String,String)]
     -- ^ Files to be stored: (filename, contents). These files are generated
     -- during the execution of 'genNetlist'.
@@ -126,7 +133,8 @@
     , _includes=[]
     , _imports=HashSet.empty
     , _libraries=HashSet.empty
-    , _dataFiles=[]
+    , _dataFiles=mempty
+    , _includeDirs = opt_importPaths opts
     , _memoryDataFiles=[]
     , _customConstrs=HashMap.empty
     , _intWidth=opt_intWidth opts
@@ -191,10 +199,11 @@
   addImports inps = imports %= (\s -> foldl' (flip HashSet.insert) s inps)
   addAndSetData f = do
     fs <- use dataFiles
-    let (fs',f') = renderFilePath fs f
+    iDirs <- use includeDirs
+    let (fs',f') = addFilePath iDirs fs f
     dataFiles .= fs'
     return f'
-  getDataFiles = use dataFiles
+  getDataFiles = map swap . Map.assocs <$> use dataFiles
   addMemoryDataFile f = memoryDataFiles %= (f:)
   getMemoryDataFiles = use memoryDataFiles
   ifThenElseExpr _ = True
@@ -1151,7 +1160,9 @@
 expr_ _ (BlackBoxE pNm _ _ _ _ bbCtx _)
   | pNm == "Clash.Sized.Internal.Index.fromInteger#"
   , [Literal _ (NumLit n), Literal _ i] <- extractLiterals bbCtx
-  = exprLit undefValue (Just (Index (fromInteger n),fromInteger n)) i
+  , Just k <- clogBase 2 n
+  , let k' = max 1 k
+  = exprLitV (Just (Index (fromInteger n),k')) i
 
 expr_ b (BlackBoxE _ libs imps inc bs bbCtx b') = do
   parenIf (b || b') (Ap (renderBlackBox libs imps inc bs bbCtx <*> pure 0))
@@ -1216,14 +1227,16 @@
 exprLitV :: Maybe (HWType,Size) -> Literal -> VerilogM Doc
 exprLitV = exprLit undefValue
 
-exprLit :: Lens' s (Maybe (Maybe Int)) -> Maybe (HWType,Size) -> Literal -> Ap (State s) Doc
+exprLit :: Backend s => Lens' s (Maybe (Maybe Int)) -> Maybe (HWType,Size) -> Literal -> Ap (State s) Doc
 exprLit _ Nothing (NumLit i) = integer i
 
 exprLit k (Just (hty,sz)) (NumLit i0) = case hty of
   Unsigned _
    | i < 0     -> string "-" <> int sz <> string "'d" <> integer (abs i)
    | otherwise -> int sz <> string "'d" <> integer i
-  Index _ -> int (typeSize hty) <> string "'d" <> integer i
+  Index n
+   | 0 <= i0 && i0 < n -> int (typeSize hty) <> string "'d" <> integer i0
+   | otherwise         -> hdlTypeErrValue hty
   Signed _
    | i < 0     -> string "-" <> int sz <> string "'sd" <> integer (abs i)
    | otherwise -> int sz <> string "'sd" <> integer i
diff --git a/src/Clash/Core/FreeVars.hs b/src/Clash/Core/FreeVars.hs
--- a/src/Clash/Core/FreeVars.hs
+++ b/src/Clash/Core/FreeVars.hs
@@ -29,11 +29,15 @@
   )
 where
 
+#if MIN_VERSION_ghc(9,8,4) || (MIN_VERSION_ghc(9,6,7) && !MIN_VERSION_ghc(9,8,0))
+#define UNIQUE_IS_WORD64
+#endif
+
 import qualified Control.Lens           as Lens
 import Control.Lens.Fold                (Fold)
 import Control.Lens.Getter              (Contravariant)
 import Data.Coerce
-#if MIN_VERSION_ghc(9,8,4)
+#ifdef UNIQUE_IS_WORD64
 import qualified GHC.Data.Word64Set     as IntSet
 #else
 import qualified Data.IntSet            as IntSet
@@ -86,7 +90,7 @@
   :: (Contravariant f, Applicative f)
   => (forall b . Var b -> Bool)
   -- ^ Predicate telling whether a variable is interesting
-#if MIN_VERSION_ghc(9,8,4)
+#ifdef UNIQUE_IS_WORD64
   -> IntSet.Word64Set
 #else
   -> IntSet.IntSet
diff --git a/src/Clash/Core/TermLiteral.hs b/src/Clash/Core/TermLiteral.hs
--- a/src/Clash/Core/TermLiteral.hs
+++ b/src/Clash/Core/TermLiteral.hs
@@ -48,7 +48,7 @@
 import           Clash.Core.Literal
 import           Clash.Core.Name                 (Name(..))
 import           Clash.Core.Pretty               (showPpr)
-import           Clash.Core.Term                 (Term(Literal, Data), collectArgs)
+import           Clash.Core.Term                 (Term(Literal, Data, Tick), collectArgs)
 import           Clash.Promoted.Nat
 import           Clash.Promoted.Nat.Unsafe
 import           Clash.Sized.Index               (Index)
@@ -127,6 +127,7 @@
   termToData t = Left t
 
 instance TermLiteral Integer where
+  termToData (Tick _ e) = termToData e
   termToData (Literal (IntegerLiteral n)) = Right n
   termToData (collectArgs -> (_, [Left (Literal (IntegerLiteral n))])) = Right n
   termToData t = Left t
@@ -136,6 +137,7 @@
   termToData t = Left t
 
 instance TermLiteral Natural where
+  termToData (Tick _ e) = termToData e
   termToData t@(Literal (NaturalLiteral n))
     | n < 0 = Left t
     | otherwise = Right (fromIntegral n)
@@ -151,6 +153,7 @@
 --
 instance TermLiteral (SNat n) where
   termToData = \case
+    Tick _ e                   -> termToData e
     Literal (NaturalLiteral n) -> Right (unsafeSNat n)
     t                          -> Left t
 
diff --git a/src/Clash/Core/VarEnv.hs b/src/Clash/Core/VarEnv.hs
--- a/src/Clash/Core/VarEnv.hs
+++ b/src/Clash/Core/VarEnv.hs
@@ -97,13 +97,17 @@
   )
 where
 
+#if MIN_VERSION_ghc(9,8,4) || (MIN_VERSION_ghc(9,6,7) && !MIN_VERSION_ghc(9,8,0))
+#define UNIQUE_IS_WORD64
+#endif
+
 import           Control.DeepSeq           (NFData)
 import           Data.Binary               (Binary)
 import           Data.Coerce               (coerce)
 import qualified Data.List                 as List
 import qualified Data.List.Extra           as List
 import           Data.Maybe                (fromMaybe)
-#if MIN_VERSION_ghc(9,8,4)
+#ifdef UNIQUE_IS_WORD64
 import           Data.Word                 (Word64)
 #endif
 
@@ -389,7 +393,7 @@
 -- * InScopeSet
 
 type Seed
-#if MIN_VERSION_ghc(9,8,4)
+#ifdef UNIQUE_IS_WORD64
   = Word64
 #else
   = Int
diff --git a/src/Clash/Data/UniqMap.hs b/src/Clash/Data/UniqMap.hs
--- a/src/Clash/Data/UniqMap.hs
+++ b/src/Clash/Data/UniqMap.hs
@@ -39,13 +39,17 @@
   , elems
   ) where
 
+#if MIN_VERSION_ghc(9,8,4) || (MIN_VERSION_ghc(9,6,7) && !MIN_VERSION_ghc(9,8,0))
+#define UNIQUE_IS_WORD64
+#endif
+
 import           Prelude hiding (elem, filter, lookup, notElem, null)
 
 import           Control.DeepSeq (NFData)
 import           Data.Binary (Binary (..))
 import           Data.Bifunctor (first)
 import           Data.Function (on)
-#if MIN_VERSION_ghc(9,8,4)
+#ifdef UNIQUE_IS_WORD64
 import           GHC.Data.Word64Map.Strict (Word64Map)
 import qualified GHC.Data.Word64Map.Strict as IntMap
 #else
@@ -71,7 +75,7 @@
 -- uniqueable and provide their own key, however a unique can be associated
 -- with any value.
 newtype UniqMap a
-#if MIN_VERSION_ghc(9,8,4)
+#ifdef UNIQUE_IS_WORD64
   = UniqMap { uniqMapToIntMap :: Word64Map a }
 #else
   = UniqMap { uniqMapToIntMap :: IntMap a }
@@ -85,7 +89,7 @@
     , Semigroup
     , Show
     )
-#if MIN_VERSION_ghc(9,8,4)
+#ifdef UNIQUE_IS_WORD64
 instance Binary a => Binary (UniqMap a) where
   put (UniqMap m) = put (IntMap.size m) <> mapM_ put (IntMap.toAscList m)
   get             = fmap (UniqMap . IntMap.fromDistinctAscList) get
diff --git a/src/Clash/Driver.hs b/src/Clash/Driver.hs
--- a/src/Clash/Driver.hs
+++ b/src/Clash/Driver.hs
@@ -27,7 +27,7 @@
 import           Control.DeepSeq
 import           Control.Exception                (throw, Exception)
 import qualified Control.Monad                    as Monad
-import           Control.Monad                    (unless, foldM, forM, filterM)
+import           Control.Monad                    (unless, foldM, forM)
 import           Control.Monad.Catch              (MonadMask, MonadThrow (throwM))
 import           Control.Monad.Extra              (whenM, ifM, unlessM)
 import           Control.Monad.IO.Class           (MonadIO)
@@ -476,7 +476,7 @@
       -- TODO: Data files should go into their own directory
       -- FIXME: Files can silently overwrite each other
       hdlDocDigests <- mapM (writeHDL hdlDir) hdlDocs
-      dataFilesDigests <- copyDataFiles (opt_importPaths opts) hdlDir dfiles
+      dataFilesDigests <- copyDataFiles hdlDir dfiles
       memoryFilesDigests <- writeMemoryDataFiles hdlDir mfiles
 
       let
@@ -1020,17 +1020,16 @@
   forM files $ \(fname, content) ->
     writeAndHash (dir </> fname) (ByteStringLazyChar8.pack content)
 
--- | Copy data files added with ~FILE
+-- | Copy data files added with ~FILE, assumes the files are canonicalized already.
+-- Throws an error on relative paths as sanity check.
 copyDataFiles
-  :: [FilePath]
-  -- ^ Import directories passed in with @-i@
-  -> FilePath
+  :: FilePath
   -- ^ Directory to copy to
   -> [(FilePath,FilePath)]
   -- ^ [(name of newly made file in HDL output dir, file to copy)]
   -> IO [ByteString]
   -- ^ SHA256 hashes of written files
-copyDataFiles idirs targetDir = mapM copyDataFile
+copyDataFiles targetDir = mapM copyDataFile
  where
   copyDataFile :: (FilePath, FilePath) -> IO ByteString
   copyDataFile (newName, toCopy)
@@ -1039,28 +1038,7 @@
         (doesFileExist toCopy)
         (copyAndHash toCopy (targetDir </> newName))
         (error [I.i|Could not find data file #{show toCopy}. Does it exist?|])
-    | otherwise = do
-      let candidates = map (</> toCopy) idirs
-      found <- filterM doesFileExist candidates
-      case found of
-        [] -> error [I.i|
-          Could not find data file #{show toCopy}. The following directories were
-          searched:
-
-            #{idirs}
-
-          You can add directories Clash will look in using `-i`.
-        |]
-        (_:_:_) -> error [I.i|
-          Multiple data files for #{show toCopy} found. The following candidates
-          were found:
-
-            #{found}
-
-          Please disambiguate data files.
-        |]
-        [c] ->
-          copyAndHash c (targetDir </> newName)
+    | otherwise = error [I.i|copyDataFiles received a relative path #{show toCopy}. This is a bug in Clash, please report it.|]
 
   copyAndHash src dst = do
     ifM
diff --git a/src/Clash/Netlist/BlackBox.hs b/src/Clash/Netlist/BlackBox.hs
--- a/src/Clash/Netlist/BlackBox.hs
+++ b/src/Clash/Netlist/BlackBox.hs
@@ -20,7 +20,13 @@
 {-# LANGUAGE RecordWildCards #-}
 {-# LANGUAGE TemplateHaskell #-}
 
-module Clash.Netlist.BlackBox where
+module Clash.Netlist.BlackBox
+    ( mkBlackBoxContext
+    , extractPrimWarnOrFail
+    , mkPrimitive
+    , prepareBlackBox
+    , isLiteral
+    ) where
 
 import           Control.Exception             (throw)
 import           Control.Lens                  ((%=))
diff --git a/src/Clash/Netlist/BlackBox/Parser.hs b/src/Clash/Netlist/BlackBox/Parser.hs
--- a/src/Clash/Netlist/BlackBox/Parser.hs
+++ b/src/Clash/Netlist/BlackBox/Parser.hs
@@ -150,8 +150,8 @@
 
 -- | Parse SigD
 pSigD :: Parser [Element]
-pSigD = some (pTagE <|> (Text (pack "[") <$ (pack <$> string "[\\"))
-                    <|> (Text (pack "]") <$ (pack <$> string "\\]"))
+pSigD = some (pTagE <|> (EscapedSymbol SquareBracketOpen <$ string "[\\")
+                    <|> (EscapedSymbol SquareBracketClose <$ string "\\]")
                     <|> (Text <$> (pack <$> some (satisfyRange '\000' '\90')))
                     <|> (Text <$> (pack <$> some (satisfyRange '\94' '\125'))))
 
diff --git a/src/Clash/Netlist/BlackBox/Types.hs b/src/Clash/Netlist/BlackBox/Types.hs
--- a/src/Clash/Netlist/BlackBox/Types.hs
+++ b/src/Clash/Netlist/BlackBox/Types.hs
@@ -19,6 +19,7 @@
  , BlackBoxTemplate
  , TemplateKind (..)
  , Element(..)
+ , EscapedSymbol(..)
  , Decl(..)
  , HdlSyn(..)
  , RenderVoid(..)
@@ -211,6 +212,12 @@
   | CtxName
   -- ^ The "context name", name set by `Clash.Magic.setName`, defaults to the
   -- name of the closest binder
+  | EscapedSymbol EscapedSymbol
+  -- ^ Used for "[\" and "\]", they'll be rendered as "[" and "]",
+  -- but pretty printed as "[\" and "\]".
+  deriving (Show, Generic, NFData, Binary, Eq, Hashable)
+
+data EscapedSymbol = SquareBracketOpen | SquareBracketClose
   deriving (Show, Generic, NFData, Binary, Eq, Hashable)
 
 -- | Component instantiation hole. First argument indicates which function argument
diff --git a/src/Clash/Netlist/BlackBox/Util.hs b/src/Clash/Netlist/BlackBox/Util.hs
--- a/src/Clash/Netlist/BlackBox/Util.hs
+++ b/src/Clash/Netlist/BlackBox/Util.hs
@@ -20,12 +20,28 @@
 {-# LANGUAGE RankNTypes #-}
 {-# LANGUAGE TemplateHaskell #-}
 
-module Clash.Netlist.BlackBox.Util where
+module Clash.Netlist.BlackBox.Util
+    ( renderTemplate
+    , walkElement
+    , verifyBlackBoxContext
+    , onBlackBox
+    , setSym
+    , extractLiterals
+    , renderBlackBox
+    , getUsedArguments
+    , canonicalizeDataFilePath
+    , addFilePath
+    , exprToString
+    , renderElem
+    , getDomainConf
+    , prettyBlackBox
+    ) where
 
 import           Control.Exception               (throw)
 import           Control.Lens
   (use, (%=), _1, _2, element, (^?))
-import           Control.Monad                   (forM, (<=<))
+import           Control.Monad                   (forM, (<=<), filterM)
+import           Control.Monad.Extra             (ifM)
 import           Control.Monad.State             (State, StateT (..), lift, gets)
 import           Data.Bitraversable              (bitraverse)
 import           Data.Bool                       (bool)
@@ -36,11 +52,17 @@
 import qualified Data.IntMap                     as IntMap
 import           Data.List                       (nub)
 import           Data.List.Extra                 (indexMaybe)
+import qualified Data.Map                        as Map
+import           Data.Map                        (Map)
 import           Data.Maybe                      (mapMaybe, maybeToList, fromJust)
 import           Data.Monoid                     (Ap(getAp))
+import qualified Data.Set                        as Set
+import           Data.Set                        (Set)
 import qualified Data.Text
 import           Data.Text.Lazy                  (Text)
 import qualified Data.Text.Lazy                  as Text
+import           System.Directory                (doesFileExist, canonicalizePath)
+import           System.IO.Unsafe                (unsafePerformIO)
 
 #if MIN_VERSION_prettyprinter(1,7,0)
 import qualified Prettyprinter                   as PP
@@ -51,7 +73,7 @@
 import           Data.Text.Prettyprint.Doc.Extra
 import           GHC.Stack                       (HasCallStack)
 import           System.FilePath                 (replaceBaseName, takeBaseName,
-                                                  takeFileName, (<.>))
+                                                  takeFileName, (<.>), isAbsolute, (</>))
 import           Text.Printf
 import           Text.Read                       (readEither)
 import           Text.Trifecta.Result            hiding (Err)
@@ -126,6 +148,7 @@
   DevNull _        -> Nothing
   SigD _ nM        -> nM
   CtxName          -> Nothing
+  EscapedSymbol _  -> Nothing
 
 -- | Determine if the number of normal\/literal\/function inputs of a blackbox
 -- context at least matches the number of argument that is expected by the
@@ -292,23 +315,85 @@
                   ++ "blackbox for " ++ bbnm
         )
 
-selectNewName
-    :: Foldable t
-    => t String
-    -- ^ Set of existing names
-    -> FilePath
-    -- ^ Name for new file (
-    -> String
+type FileName = FilePath
+
+-- | Canonicalizes a datafile path, keeping in mind that the path might be
+-- relative to one of the import directories passed in with @-i@.
+canonicalizeDataFilePath ::
+  -- | Import directories passed in with @-i@
+  [FilePath] ->
+  -- | File to canonicalize
+  FilePath ->
+  FilePath
+canonicalizeDataFilePath idirs toCanonicalize
+  | isAbsolute toCanonicalize = unsafePerformIO $
+    ifM
+      (doesFileExist toCanonicalize)
+      (canonicalizePath toCanonicalize)
+      (error [I.i|Could not find data file #{show toCanonicalize}. Does it exist?|])
+  | otherwise = unsafePerformIO $ do
+      let candidates = map (</> toCanonicalize) idirs
+      found <- filterM doesFileExist candidates
+      case found of
+        [] -> error [I.i|
+          Could not find data file #{show toCanonicalize}. The following directories were
+          searched:
+            #{idirs}
+        |]
+        (_:_:_) -> error [I.i|
+          Multiple data files for #{show toCanonicalize} found. The following candidates
+          were found:
+            #{found}
+          Please disambiguate data files.
+        |]
+        [c] ->
+          canonicalizePath c
+{-# NOINLINE canonicalizeDataFilePath #-} -- To contain unsafePerformIO
+
+-- | Select a new file name that doesn't collide with existing names. Might return
+-- the same name as given if there are no collisions.
+selectNewName ::
+  -- | Set of existing names
+  Set FileName ->
+  -- | Name for file
+  FileName ->
+  -- | Updated file name
+  FileName
 selectNewName as a
-  | elem a as = selectNewName as (replaceBaseName a (takeBaseName a ++ "_"))
+  | a `Set.member` as = selectNewName as (replaceBaseName a (takeBaseName a ++ "_"))
   | otherwise = a
 
-renderFilePath :: [(String,FilePath)] -> String -> ([(String,FilePath)],String)
-renderFilePath fs f = ((f'',f):fs, f'')
-  where
-    f'  = takeFileName f
-    f'' = selectNewName (map fst fs) f'
+-- | Add a data file to a collection of existing files. Typically used in the HDL
+-- backend's 'addAndSetData'.
+addFilePath ::
+  -- | Import directories passed in with @-i@
+  [FilePath] ->
+  -- | Map of existing file paths to file names. The file names are guaranteed
+  -- to be unique, as long as this function is used to add new file paths.
+  Map FilePath FileName ->
+  -- | New file path to add. The canonicalized version of this file path is stored
+  -- in the map. See 'canonicalizeFilePath'.
+  FilePath ->
+  -- | Updated map and filename. Note that the returned filename might be different
+  -- from the filename in the given filepath in case of naming collisions.
+  (Map FilePath FileName, FileName)
+addFilePath iDirs existing path =
+  case Map.lookup canonicalizedPath existing of
+    Just existingName ->
+      -- This path was already added, return existing map and name
+      (existing, existingName)
+    Nothing ->
+      -- Select a new name that doesn't collide with existing names
+      ( Map.insert canonicalizedPath newFileName existing
+      , newFileName
+      )
+ where
+  canonicalizedPath = canonicalizeDataFilePath iDirs path
 
+  allNames = Set.fromList (Map.elems existing)
+  fileName = takeFileName canonicalizedPath
+  newFileName = selectNewName allNames fileName
+
 -- | Render a blackbox given a certain context. Returns a filled out template
 -- and a list of 'hidden' inputs that must be added to the encompassing component.
 renderTemplate
@@ -403,7 +488,7 @@
     Just (templ0,_,libs,imps,inc,pCtx) -> do
       let b' = pCtx { bbResults = [(o,oTy)], bbInputs = bbInputs pCtx ++ is }
           layoutOptions = LayoutOptions (AvailablePerLine 120 0.4)
-          render = N.BBTemplate . parseFail . renderLazy . layoutPretty layoutOptions
+          render = N.BBTemplate . parseFail b' . renderLazy . layoutPretty layoutOptions
 
       templ1 <-
         case templ0 of
@@ -660,10 +745,15 @@
       Nothing -> error $ "Can't find domain " <> show dom <> ". Please report an issue at https://github.com/clash-lang/clash-compiler/issues."
       Just conf -> pure conf
 
-parseFail :: Text -> BlackBoxTemplate
-parseFail t = case runParse t of
+parseFail :: BlackBoxContext -> Text -> BlackBoxTemplate
+parseFail b t = case runParse t of
   Failure errInfo ->
-    error (show (_errDoc errInfo))
+    error $ unlines
+        [ "error while parsing blackbox: " <> Data.Text.unpack (bbName b)
+        , "in component " <> Data.Text.unpack (Id.toText $ bbCompName b)
+        , "error:"
+        , show (_errDoc errInfo)
+        ]
   Success templ -> templ
 
 idToExpr
@@ -904,6 +994,9 @@
     -> return (Id.toLazyText t)
   _ -> error "internal error"
 
+renderTag _ (EscapedSymbol sym) = case sym of
+  SquareBracketOpen  -> return "["
+  SquareBracketClose -> return "]"
 
 renderTag _ e = do e' <- getAp (prettyElem e)
                    error $ $(curLoc) ++ "Unable to evaluate: " ++ show e'
@@ -1108,6 +1201,9 @@
                                   <> brackets (string $ Text.concat bbname')
                                   <> brackets (string $ Text.concat source'))
 prettyElem CtxName = return "~CTXNAME"
+prettyElem (EscapedSymbol sym) = case sym of
+  SquareBracketOpen  -> return "[\\"
+  SquareBracketClose -> return "\\]"
 
 -- | Recursively walk @Element@, applying @f@ to each element in the tree.
 walkElement
@@ -1178,6 +1274,7 @@
         Repeat es1 es2 ->
           concatMap go es1 ++ concatMap go es2
         CtxName -> []
+        EscapedSymbol _ -> []
 
 -- | Determine variables used in an expression. Used for VHDL sensitivity list.
 -- Also see: https://github.com/clash-lang/clash-compiler/issues/365
@@ -1266,6 +1363,7 @@
         TypM _ -> Nothing
         Vars _ -> Nothing
         CtxName -> Nothing
+        EscapedSymbol _ -> Nothing
 
 onBlackBox
   :: (BlackBoxTemplate -> r)
diff --git a/src/Clash/Normalize/Transformations/Specialize.hs b/src/Clash/Normalize/Transformations/Specialize.hs
--- a/src/Clash/Normalize/Transformations/Specialize.hs
+++ b/src/Clash/Normalize/Transformations/Specialize.hs
@@ -463,11 +463,19 @@
                       -- binding @g'@ where both the body of @mealy@ and @g@
                       -- are inlined, meaning the state-transition-function
                       -- and the memory element will be in a single function.
+                      --
+                      -- Finally, we must make sure we do not inline the bodies
+                      -- of functions with a Synthesize annotation, as that would
+                      -- duplicate Clash compiler work. See also issue #3024
                       gTmM <- fmap (UniqMap.lookup g) $ Lens.use bindings
+                      let gBody = if g `elemVarSet` topEnts then
+                                    Nothing
+                                  else
+                                    fmap bindingTerm gTmM
                       return
                         ( g
                         , preferNoInline inl (maybe noUserInline bindingSpec gTmM)
-                        , maybe specArg (Left . (`mkApps` gArgs) . bindingTerm) gTmM
+                        , maybe specArg (Left . (`mkApps` gArgs)) gBody
                         )
                     else return (f,inl,specArg)
                 _ -> return (f,inl,specArg)
diff --git a/src/Clash/Primitives/Util.hs b/src/Clash/Primitives/Util.hs
--- a/src/Clash/Primitives/Util.hs
+++ b/src/Clash/Primitives/Util.hs
@@ -165,6 +165,7 @@
   -- ^ unresolved primitives found in annotations (in LoadModules and
   -- LoadInterfaceFiles)
   -> [(TS.Text, PrimitiveGuard ())]
+  -- ^ Primitive guards found in annotations
   -> [FilePath]
   -- ^ Directories to search for primitive definitions
   -> IO ResolvedPrimMap
diff --git a/src/Clash/Unique.hs b/src/Clash/Unique.hs
--- a/src/Clash/Unique.hs
+++ b/src/Clash/Unique.hs
@@ -17,8 +17,13 @@
   , fromGhcUnique
   ) where
 
+#if MIN_VERSION_ghc(9,8,4) || (MIN_VERSION_ghc(9,6,7) && !MIN_VERSION_ghc(9,8,0))
+#define UNIQUE_IS_WORD64
+#endif
+
 import Data.Word (Word64)
-#if MIN_VERSION_ghc(9,8,4)
+
+#ifdef UNIQUE_IS_WORD64
 import GHC.Word (Word64(W64#))
 import GHC.Exts (Word64#)
 #else
@@ -31,7 +36,7 @@
 import qualified Unique as GHC
 #endif
 
-#if MIN_VERSION_ghc(9,8,4)
+#ifdef UNIQUE_IS_WORD64
 type Unique = Word64
 type Unique# = Word64#
 
@@ -63,7 +68,7 @@
   getUnique = id
   setUnique = flip const
 
-#if !MIN_VERSION_ghc(9,8,4)
+#ifndef UNIQUE_IS_WORD64
 instance Uniquable Word64 where
   getUnique = fromIntegral
   setUnique _ = fromIntegral
diff --git a/src/Clash/Util.hs b/src/Clash/Util.hs
--- a/src/Clash/Util.hs
+++ b/src/Clash/Util.hs
@@ -1,7 +1,7 @@
 {-|
   Copyright   :  (C) 2012-2016, University of Twente
   License     :  BSD2 (see the file LICENSE)
-  Maintainer  :  Christiaan Baaij <christiaan.baaij@gmail.com>
+  Maintainer  :  QBayLogic B.V. <devops@qbaylogic.com>
 
   Assortment of utility function used in the Clash library
 -}
@@ -87,6 +87,10 @@
   show (ClashException _ s eM) = s ++ "\n" ++ maybe "" id eM
 
 instance Exception.Exception ClashException
+
+-- | Construct a string pattern match out of the given @TemplateHaskell@ name
+namePat :: TH.Name -> TH.Q TH.Pat
+namePat = return . TH.LitP . TH.StringL . show
 
 assertPanic
   :: String -> Int -> a
diff --git a/src/Clash/Util/Graph.hs b/src/Clash/Util/Graph.hs
--- a/src/Clash/Util/Graph.hs
+++ b/src/Clash/Util/Graph.hs
@@ -14,9 +14,13 @@
   , callGraphBindings
   ) where
 
+#if MIN_VERSION_ghc(9,8,4) || (MIN_VERSION_ghc(9,6,7) && !MIN_VERSION_ghc(9,8,0))
+#define UNIQUE_IS_WORD64
+#endif
+
 import           Data.Tuple            (swap)
 import           Data.Foldable         (foldlM)
-#if MIN_VERSION_ghc(9,8,4)
+#ifdef UNIQUE_IS_WORD64
 import qualified GHC.Data.Word64Map.Strict as IntMap
 import qualified GHC.Data.Word64Set        as IntSet
 #else
@@ -33,7 +37,7 @@
 import           Clash.Normalize.Util (callGraph)
 import           Clash.Unique (Unique)
 
-#if MIN_VERSION_ghc(9,8,4)
+#ifdef UNIQUE_IS_WORD64
 type IntMap = IntMap.Word64Map
 type IntSet = IntSet.Word64Set
 #endif
diff --git a/src/Data/Text/Prettyprint/Doc/Extra.hs b/src/Data/Text/Prettyprint/Doc/Extra.hs
--- a/src/Data/Text/Prettyprint/Doc/Extra.hs
+++ b/src/Data/Text/Prettyprint/Doc/Extra.hs
@@ -15,8 +15,8 @@
 
 import           Control.Applicative
 import           Data.String                           (IsString (..))
-import           Data.Text                             as T
-import           Data.Text.Lazy                        as LT
+import qualified Data.Text                             as T
+import qualified Data.Text.Lazy                        as LT
 
 #if MIN_VERSION_prettyprinter(1,7,0)
 import qualified Prettyprinter                         as PP
