clash-lib 1.8.5 → 1.10.0
raw patch · 77 files changed
+1341/−1309 lines, 77 filesdep +ghc-bootdep −integer-gmpdep ~aesondep ~basedep ~clash-preludePVP ok
version bump matches the API change (PVP)
Dependencies added: ghc-boot
Dependencies removed: integer-gmp
Dependency ranges changed: aeson, base, clash-prelude, containers, ghc, hashable, mtl, template-haskell, transformers, unordered-containers
API changes (from Hackage documentation)
- Clash.Driver: pprVerilatorShim :: Identifier -> Doc
- Clash.Driver: writeVerilatorShim :: FilePath -> Identifier -> [(FilePath, ByteString)] -> IO [(FilePath, ByteString)]
+ Clash.Core.Pretty: unsafeLookupEnvBool :: HasCallStack => String -> Bool -> Bool
+ Clash.Core.TysPrim: integerIsDc :: DataCon
+ Clash.Core.TysPrim: naturalNsDc :: DataCon
+ Clash.Driver.BrokenGhcs: All :: BrokenOn
+ Clash.Driver.BrokenGhcs: Ghc :: Int -> Int -> Int -> GhcVersion
+ Clash.Driver.BrokenGhcs: GhcRange :: GhcVersion -> GhcVersion -> GhcRange
+ Clash.Driver.BrokenGhcs: SomeOs :: OS -> BrokenOn
+ Clash.Driver.BrokenGhcs: Why :: String -> String -> String -> [(BrokenOn, GhcRange)] -> Why
+ Clash.Driver.BrokenGhcs: [brokenOn] :: Why -> [(BrokenOn, GhcRange)]
+ Clash.Driver.BrokenGhcs: [from] :: GhcRange -> GhcVersion
+ Clash.Driver.BrokenGhcs: [issue] :: Why -> String
+ Clash.Driver.BrokenGhcs: [major0] :: GhcVersion -> Int
+ Clash.Driver.BrokenGhcs: [major1] :: GhcVersion -> Int
+ Clash.Driver.BrokenGhcs: [patch] :: GhcVersion -> Int
+ Clash.Driver.BrokenGhcs: [solution] :: Why -> String
+ Clash.Driver.BrokenGhcs: [to] :: GhcRange -> GhcVersion
+ Clash.Driver.BrokenGhcs: [what] :: Why -> String
+ Clash.Driver.BrokenGhcs: assertWorking :: IO ()
+ Clash.Driver.BrokenGhcs: broken :: Maybe Why
+ Clash.Driver.BrokenGhcs: brokenGhcs :: [Why]
+ Clash.Driver.BrokenGhcs: data BrokenOn
+ Clash.Driver.BrokenGhcs: data GhcRange
+ Clash.Driver.BrokenGhcs: data GhcVersion
+ Clash.Driver.BrokenGhcs: data Why
+ Clash.Driver.BrokenGhcs: ghcInRange :: GhcVersion -> GhcRange -> Bool
+ Clash.Driver.BrokenGhcs: ghcMajor :: Int -> Int -> GhcRange
+ Clash.Driver.BrokenGhcs: ghcVersion :: GhcVersion
+ Clash.Driver.BrokenGhcs: instance GHC.Classes.Eq Clash.Driver.BrokenGhcs.GhcVersion
+ Clash.Driver.BrokenGhcs: instance GHC.Classes.Ord Clash.Driver.BrokenGhcs.GhcVersion
+ Clash.Driver.BrokenGhcs: matchBroken :: (BrokenOn, GhcRange) -> Bool
+ Clash.Driver.BrokenGhcs: matchOs :: BrokenOn -> Bool
+ Clash.Driver.BrokenGhcs: os :: OS
+ Clash.Driver.BrokenGhcs: whyPp :: Why -> String
+ Clash.Driver.Types: [opt_concurrentTopEntities] :: ClashOpts -> Bool
+ Clash.Driver.Types: [opt_ignoreBrokenGhcs] :: ClashOpts -> Bool
+ Clash.Netlist.BlackBox.Util: lookupFunctionInstantiation :: BlackBoxContext -> Int -> Int -> Either String (Either BlackBox (Identifier, [Declaration]), Usage, [BlackBoxTemplate], [BlackBoxTemplate], [((Text, Text), BlackBox)], BlackBoxContext)
+ Clash.Netlist.Types: fromSomeBackend :: (forall b. Backend b => b -> a) -> Getter SomeBackend a
+ Clash.Netlist.Types: onSomeBackend :: (forall b. Backend b => b -> a) -> SomeBackend -> a
+ Clash.Normalize.Transformations.Case: elimCaseBigNumInternals :: HasCallStack => NormRewrite
- Clash.Driver.Types: ClashOpts :: Bool -> Int -> Int -> Word -> Word -> Word -> DebugOpts -> Int -> Bool -> Bool -> Bool -> OverridingBool -> Int -> Maybe String -> HdlSyn -> Bool -> [FilePath] -> Maybe Text -> Bool -> Bool -> PreserveCase -> Bool -> Maybe (Maybe Int) -> Bool -> Bool -> Bool -> Word -> Bool -> Bool -> Period -> ClashOpts
+ Clash.Driver.Types: ClashOpts :: Bool -> Int -> Int -> Word -> Word -> Word -> DebugOpts -> Int -> Bool -> Bool -> Bool -> OverridingBool -> Int -> Maybe String -> HdlSyn -> Bool -> [FilePath] -> Maybe Text -> Bool -> Bool -> PreserveCase -> Bool -> Maybe (Maybe Int) -> Bool -> Bool -> Bool -> Word -> Bool -> Bool -> Period -> Bool -> Bool -> ClashOpts
- Clash.Netlist.Util: iteAlts :: HWType -> [Alt] -> Maybe (Term, Term)
+ Clash.Netlist.Util: iteAlts :: HWType -> NonEmpty Alt -> Maybe (Term, Term)
- Clash.Rewrite.Types: bindings :: forall extra_a4HGd. Lens' (RewriteState extra_a4HGd) BindingMap
+ Clash.Rewrite.Types: bindings :: forall extra_a4K1x. Lens' (RewriteState extra_a4K1x) BindingMap
- Clash.Rewrite.Types: curFun :: forall extra_a4HGd. Lens' (RewriteState extra_a4HGd) (Id, SrcSpan)
+ Clash.Rewrite.Types: curFun :: forall extra_a4K1x. Lens' (RewriteState extra_a4K1x) (Id, SrcSpan)
- Clash.Rewrite.Types: extra :: forall extra_a4HGd extra_a4HRw. Lens (RewriteState extra_a4HGd) (RewriteState extra_a4HRw) extra_a4HGd extra_a4HRw
+ Clash.Rewrite.Types: extra :: forall extra_a4K1x extra_a4KcQ. Lens (RewriteState extra_a4K1x) (RewriteState extra_a4KcQ) extra_a4K1x extra_a4KcQ
- Clash.Rewrite.Types: globalHeap :: forall extra_a4HGd. Lens' (RewriteState extra_a4HGd) PrimHeap
+ Clash.Rewrite.Types: globalHeap :: forall extra_a4K1x. Lens' (RewriteState extra_a4K1x) PrimHeap
- Clash.Rewrite.Types: nameCounter :: forall extra_a4HGd. Lens' (RewriteState extra_a4HGd) Int
+ Clash.Rewrite.Types: nameCounter :: forall extra_a4K1x. Lens' (RewriteState extra_a4K1x) Int
- Clash.Rewrite.Types: transformCounter :: forall extra_a4HGd. Lens' (RewriteState extra_a4HGd) Word
+ Clash.Rewrite.Types: transformCounter :: forall extra_a4K1x. Lens' (RewriteState extra_a4K1x) Word
- Clash.Rewrite.Types: transformCounters :: forall extra_a4HGd. Lens' (RewriteState extra_a4HGd) (HashMap Text Word)
+ Clash.Rewrite.Types: transformCounters :: forall extra_a4K1x. Lens' (RewriteState extra_a4K1x) (HashMap Text Word)
- Clash.Rewrite.Types: uniqSupply :: forall extra_a4HGd. Lens' (RewriteState extra_a4HGd) Supply
+ Clash.Rewrite.Types: uniqSupply :: forall extra_a4K1x. Lens' (RewriteState extra_a4K1x) Supply
- Clash.Rewrite.Types: workFreeBinders :: forall extra_a4HGd. Lens' (RewriteState extra_a4HGd) (VarEnv Bool)
+ Clash.Rewrite.Types: workFreeBinders :: forall extra_a4K1x. Lens' (RewriteState extra_a4K1x) (VarEnv Bool)
Files
- CHANGELOG.md +101/−1
- README.md +2/−2
- clash-lib.cabal +19/−22
- prims/commonverilog/Clash_Class_BitPack.primitives.yaml +120/−0
- prims/commonverilog/Clash_Intel_DDR.primitives.yaml +22/−19
- prims/commonverilog/Clash_Sized_Internal_Index.primitives.yaml +5/−5
- prims/commonverilog/GHC_Num_Integer.primitives.yaml +1/−1
- prims/commonverilog/GHC_Num_Natural.primitives.yaml +1/−1
- prims/systemverilog/Clash_Explicit_DDR.primitives.yaml +55/−52
- prims/systemverilog/Clash_Explicit_Testbench.primitives.yaml +6/−1
- prims/systemverilog/Clash_Intel_DDR.primitives.yaml +23/−20
- prims/systemverilog/Clash_Signal_Internal.primitives.yaml +6/−63
- prims/systemverilog/Clash_Xilinx_DDR.primitives.yaml +43/−36
- prims/verilog/Clash_Explicit_DDR.primitives.yaml +56/−53
- prims/verilog/Clash_Explicit_Testbench.primitives.yaml +6/−0
- prims/verilog/Clash_Intel_DDR.primitives.yaml +23/−20
- prims/verilog/Clash_Signal_Internal.primitives.yaml +6/−62
- prims/verilog/Clash_Sized_Vector.primitives.yaml +23/−18
- prims/verilog/Clash_Xilinx_DDR.primitives.yaml +43/−36
- prims/vhdl/Clash_Class_BitPack.primitives.yaml +120/−0
- prims/vhdl/Clash_Explicit_DDR.primitives.yaml +84/−81
- prims/vhdl/Clash_Intel_DDR.primitives.yaml +48/−42
- prims/vhdl/Clash_Sized_Internal_Index.primitives.yaml +5/−5
- prims/vhdl/Clash_Xilinx_DDR.primitives.yaml +43/−36
- src/Clash/Backend.hs +0/−4
- src/Clash/Backend/SystemVerilog.hs +6/−3
- src/Clash/Backend/VHDL.hs +0/−3
- src/Clash/Backend/Verilog.hs +7/−2
- src/Clash/Backend/Verilog/Time.hs +3/−0
- src/Clash/Core/EqSolver.hs +0/−6
- src/Clash/Core/HasType.hs +0/−2
- src/Clash/Core/Literal.hs +0/−2
- src/Clash/Core/Name.hs +0/−4
- src/Clash/Core/PartialEval/Monad.hs +0/−4
- src/Clash/Core/Pretty.hs +1/−6
- src/Clash/Core/Term.hs +0/−4
- src/Clash/Core/TermLiteral.hs +0/−4
- src/Clash/Core/TermLiteral/TH.hs +0/−14
- src/Clash/Core/Type.hs +0/−50
- src/Clash/Core/TysPrim.hs +32/−78
- src/Clash/Core/Util.hs +0/−8
- src/Clash/Data/UniqMap.hs +0/−4
- src/Clash/Driver.hs +12/−68
- src/Clash/Driver/Bool.hs +0/−6
- src/Clash/Driver/BrokenGhcs.hs +157/−0
- src/Clash/Driver/Manifest.hs +2/−1
- src/Clash/Driver/Types.hs +13/−8
- src/Clash/Netlist.hs +19/−33
- src/Clash/Netlist/BlackBox.hs +0/−9
- src/Clash/Netlist/BlackBox/Util.hs +53/−28
- src/Clash/Netlist/Types.hs +14/−9
- src/Clash/Netlist/Util.hs +5/−25
- src/Clash/Normalize.hs +5/−2
- src/Clash/Normalize/PrimitiveReductions.hs +22/−13
- src/Clash/Normalize/Strategy.hs +17/−4
- src/Clash/Normalize/Transformations/Case.hs +40/−20
- src/Clash/Normalize/Transformations/DEC.hs +0/−27
- src/Clash/Normalize/Transformations/Specialize.hs +48/−34
- src/Clash/Normalize/Util.hs +0/−4
- src/Clash/Primitives/DSL.hs +12/−5
- src/Clash/Primitives/GHC/Int.hs +0/−2
- src/Clash/Primitives/GHC/Word.hs +0/−2
- src/Clash/Primitives/Sized/ToInteger.hs +2/−42
- src/Clash/Primitives/Types.hs +0/−6
- src/Clash/Rewrite/Types.hs +1/−41
- src/Clash/Rewrite/Util.hs +9/−22
- src/Clash/Unique.hs +0/−4
- src/Clash/Util.hs +0/−15
- src/Clash/Util/Supply.hs +0/−6
- src/Data/Aeson/Extra.hs +0/−5
- src/Data/IntMap/Extra.hs +0/−36
- src/Data/List/Extra.hs +0/−4
- src/Data/Primitive/ByteArray/Extra.hs +0/−8
- src/GHC/BasicTypes/Extra.hs +0/−14
- src/GHC/SrcLoc/Extra.hs +0/−16
- tests/Clash/Tests/Core/FreeVars.hs +0/−4
- tools/v16-upgrade-primitives.hs +0/−12
CHANGELOG.md view
@@ -1,5 +1,105 @@ # Changelog for the Clash project +## 1.10.0 *Apr 23rd, 2026*++Release highlight:+* `Clash.Class.NumConvert`: Utilities for safely converting between various Clash number types [#2915](https://github.com/clash-lang/clash-compiler/pull/2915)++Added:+* Added GHC 9.12 support+* `Clash.Class.NumConvert`: Utilities for safely converting between various Clash number types [#2915](https://github.com/clash-lang/clash-compiler/pull/2915)+* Add `Clash.XException.ShowX` instance for `Foreign.C.Types.CUShort`. [#2397](https://github.com/clash-lang/clash-compiler/pull/2397)+* Introduced various new types to `Clash.Signal` to more easily represent time and its relation to your clock domain. New types: `Seconds`, `Milliseconds`, `Microseconds`, `Nanoseconds`, `Picoseconds`, `DomainToHz`, `HzToPeriod`, `PeriodToHz`, `PeriodToCycles`, `ClockDivider`. [#2734](https://github.com/clash-lang/clash-compiler/pull/2734)+* `Distributive` and `Representable` instances for `Vec`+* Resize functions `maybeResize` and `maybeTruncateB` to `Clash.Class.Resize`. Can be used to resize without loss of information. [#2779](https://github.com/clash-lang/clash-compiler/issues/2779)+* Alongside the existing Eq-like and Ord-like signal operators like `.==.` and `.<=.` etc., there are now new functions for comparing with constants: `.==`, `==.`, `./=`, `/=.`, `.<=`, `<=.`, `.>=`, `>=.`, `.>`, `>.`, `.<`, `<.`, `.&&`, `&&.`, `.||`, `||.`. These are useful for comparing signals with constants in a more readable way. For example, `a .==. pure True` can now be replaced with `a .== True`. [#2545](https://github.com/clash-lang/clash-compiler/pull/2545)+* instance `HasField f (Signal dom r) (Signal dom a)`. This means record dot accesses will be passed to the underlying type. For example, this will work:++ ```haskell+ data MyRecord = MyRecord { myField :: Int }++ a :: Signal dom MyRecord+ a = pure (MyRecord 3)++ b :: Signal dom Int+ b = a.myField+ ```+* `BitPack` instance for `Data.Proxy.Proxy`+* `apEn`, which is a `mux` that optionally applies an update function to a value. [#3029](https://github.com/clash-lang/clash-compiler/pull/3029)+* `regEnN`, which is a chain of `regEn`s. [#3029](https://github.com/clash-lang/clash-compiler/pull/3029)+* `Index 0` instances for `BitPack`, `Bits`, `Counter`, `FiniteBits`, `Parity`, and `SaturatingNum`. [#2784](https://github.com/clash-lang/clash-compiler/pull/2784)+* Zero-sized block RAM implementations for `blockRam1` and `blockRamU`. [#2784](https://github.com/clash-lang/clash-compiler/pull/2784)+* `Counter a => Counter (Vec 0 a)` instance. [#2784](https://github.com/clash-lang/clash-compiler/pull/2784)+* `SaturatingNum` and `Bounded` instances for `Signal dom a`. The `sat` family (`satAdd`, `satSucc`, ...) can now be used on `Signal`s and `{min,max}Bound` can be used to construct them [#2931](https://github.com/clash-lang/clash-compiler/issues/2931)+* `-fclash-no-concurrent-topentity-compilation` flag to disable concurrent compilation of top entities. This is mostly useful to get a consistent debug output.+* `SomeBoundedSNat` and Hedgehog generators [#3183](https://github.com/clash-lang/clash-compiler/pull/3183)+* `Eq`, `NFData`, `ShowX` and `BitPack` instances for `RamOp`.+* `smapWithBounds` extending `smap` via offering a proof witness for the upper bound of the vector size to the mapping function. [#2686](https://github.com/clash-lang/clash-compiler/pull/2686)+* The function `Clash.Explicit.DDR.ddrForwardClock`, which uses a DDR output primitive to forward a clock signal to a DDR-capable output pin. [#2876](https://github.com/clash-lang/clash-compiler/pull/2876)++Removed:+* Support for GHC versions 9.4 and older+* Newer Verilators (> v5) can deal with delay statements, hence removing the need for Clash specific workarounds. If you relied on Clash-generated Verilator shims, consider using `verilator --build --binary` instead.+* Experimental feature "multiple hidden domains" [#2750](https://github.com/clash-lang/clash-compiler/pull/2750)+* The deprecated module `Clash.Prelude.DataFlow` was removed. The `clash-protocols` package provides dataflow-based protocols and circuits. [#3181](https://github.com/clash-lang/clash-compiler/pull/3181)+* The deprecated functions `altpll` and `alteraPll` were removed from the `Clash.Intel.ClockGen` module. Clash 1.8 introduced the new functions `altpllSync`, `alteraPllSync`, `unsafeAltpll` and `unsafeAlteraPll`. A name for the IP instantiation, handled by the _name_ argument to `altpll` and `alteraPll`, can be provided with the `Clash.Magic.setName` function. [#3181](https://github.com/clash-lang/clash-compiler/pull/3181)++Changed:+* `dfold` now offers a proof witness for the upper bound of the vector size to the folding function. Note that this change may require additional type annotations, as solutions working in the past may complain with an untouchable type error now. [#2686](https://github.com/clash-lang/clash-compiler/pull/2686)+* You can now only create an `SDomainConfiguration` when the `period` of the domain is at least `1`. Pattern matching on an `SDomainConfiguration` bring the `1 <= period` into scope. This in turns enables the following code to typecheck:+ ```+ import Clash.Prelude+ import Data.Proxy++ f ::+ forall dom .+ KnownDomain dom =>+ Proxy dom ->+ SNat (PeriodToCycles dom (Milliseconds 1))+ f Proxy = case knownDomain @dom of+ SDomainConfiguration {} -> SNat+ ```+ where the `DivRU` in+ ```+ type PeriodToCycles (dom :: Domain) (period :: Nat) = period `DivRU` DomainPeriod dom+ ```+ requires that the `DomainPeriod dom` is at least `1`. [#2740](https://github.com/clash-lang/clash-compiler/pull/2740)+* `select` and `selectI` now use `<=` constraints instead of `CmpNat`. [#2873](https://github.com/clash-lang/clash-compiler/pull/2873)+* `ResetStrategy` now contains the reset function, to avoid dummy arguments on `NoClearOnReset` [#2849](https://github.com/clash-lang/clash-compiler/pull/2849)+* `Clash.Explicit.DDR`, `Clash.Intel.DDR` and `Clash.Xilinx.DDR`: [#2833](https://github.com/clash-lang/clash-compiler/pull/2833)+ - The constraints for the functions have been rewritten to use `DomainPeriod`, which makes them more readable and relaxes unnecessary constraints on the virtual DDR domain. The type-level variables for the domains have been renamed. `dom` is a real domain, `domDDR` is the virtual DDR domain.+ - The Xilinx and Intel primitives only support domains where the rising edge is the active edge. This is now enforced at the type level by adding a constraint.+ - The Xilinx and Intel primitives now directly support any data type that has a `BitPack` instance.+* Order of type arguments for functions in `clash-prelude-hedgehog` now follows _size_, _domain_, _monad_. [#2880](https://github.com/clash-lang/clash-compiler/pull/2880)+* The Clash Prelude now exports the `Default` class from the package `data-default` instead of from the now superseded `data-default-class`. If you import the `Default` class name or the `def` function from the `data-default-class` package _older than version 0.2_, or one of your dependencies does, you might get a bewildering error message. You might get the error "No instance for (Default T)" even though there appears to be such an instance. The best solution is to make sure all your packages and dependencies use the `data-default` package and not the `data-default-class` package. The next most obvious solution is to make sure `data-default-class` is of version 0.2 or higher, for instance by depending on it in your own package. If this creates a dependency conflict, another solution is to import the correct module. `Default` and `def` from `Clash.Prelude` or `Data.Default` are for the new `data-default` package. `Data.Default.Class` is for the `data-default-class` package. There are situations where this will still not be enough, but luckily the `Default` class is not used all that much. [#2891](https://github.com/clash-lang/clash-compiler/pull/2891)+* Changed implementation of `(+>>)` to no longer require `KnownNat`+* The `clash-prelude` package now uses `PolyKinds` by default, meaning all its type class instances are now more general than before. As an example, without `PolyKinds`, `BitPack (Proxy a)` would only be defined when `a :: Type`, with the extension it would be defined for any `a :: k`. After this change, some instances in user code might now overlap. [#2994](https://github.com/clash-lang/clash-compiler/pull/2994)+* When generating (System)Verilog, Clash now resets the default net type from none to the verilog default after the generated module. [#3005](https://github.com/clash-lang/clash-compiler/pull/3005)+* The content from the `Clash.Tutorial` module and from https://clash-lang.readthedocs.io/ has been split and moved to two new locations.+ 1. The actual tutorial parts has been moved to: https://docs.clash-lang.org/tutorial/+ 2. Parts that fit better in the clash compiler user guide have been moved to: https://docs.clash-lang.org/compiler-user-guide/++ Moving the documentation to these locations makes it easier to update their content as it is no longer needed to release a new version of the `clash-prelude` package for the publication of this content.+* Vector functions in Verilog now have indices consistent with the Vec inputs/outputs (before they were reversed). This is convenient when writing design constraints, which can now be referenced consistently like `imap[0],imap[1],..`. See [#3088](https://github.com/clash-lang/clash-compiler/issues/3088).++Fixed:+* Clash no longer gives `Dubious primitive instantiation warning` when using `unpack` [#2386](https://github.com/clash-lang/clash-compiler/issues/2386).+* Clash now generates more intuitive names for specialized binders. See [#2508](https://github.com/clash-lang/clash-compiler/issues/2508).+* `foldl` on `Vec` is now strict. See [this GitHub discussion](https://github.com/hasura/graphql-engine/pull/2933#discussion_r328821960) and [this blog post](https://well-typed.com/blog/90/) for more information. [#2482](https://github.com/clash-lang/clash-compiler/issues/2482)+* Type families that appear in GHC core types are now normalized before being translated into their Clash core equivalent. See [#3063](https://github.com/clash-lang/clash-compiler/issues/3063).+* Added an evaluator rule for `bigNatEq#` with compile-time constant arguments [#3084](https://github.com/clash-lang/clash-compiler/issues/3084)+* Reduce constants to NF before specialization [#3129](https://github.com/clash-lang/clash-compiler/issues/3129)+* `rotateL` and `rotateR` no longer error when used on `BitVector 0` [#2980](https://github.com/clash-lang/clash-compiler/issues/2980)+* Behavior of `shiftR` is now documented for `Unsigned`, `BitVector`, `Index`, and `Signed` [#2959](https://github.com/clash-lang/clash-compiler/issues/2959)+* Clash will no longer error if it finds the same data file more than once due to duplicate `-i` flags [#3141](https://github.com/clash-lang/clash-compiler/issues/3141)+* Higher order blackboxes not propagating usage metadata for generated results [#3147](https://github.com/clash-lang/clash-compiler/issues/3147)+* Run `caseCon` after post-normalization `inlineCleanup` [#3159](https://github.com/clash-lang/clash-compiler/issues/3159)+* Failure to generate binder assignments in very specific cases [#3185](https://github.com/clash-lang/clash-compiler/issues/3185)+* Clash won't create (invalid) netlist cases on Integer and Natural constructors anymore [#3157](https://github.com/clash-lang/clash-compiler/issues/3157)+* Post-normalization flattening could leave a `Just` constructor as the scrutinee of a `case` after simplifying tuple projections [#3204](https://github.com/clash-lang/clash-compiler/issues/3204)+* Clash no longer crashes on false positive free variable introduction in `reduceConst` and `constantSpec`. Fixes [#3206](https://github.com/clash-lang/clash-compiler/issues/3206).+* `negate` for `Num Bit` is now defined as the additive inverse, i.e., `negate = id`. [#2999](https://github.com/clash-lang/clash-compiler/issues/2999)+ ## 1.8.5 *Mar 24th, 2026* Added:@@ -358,7 +458,7 @@ * Don't overflow the range of VHDL's natural type in shift/rotate, leading to simulation issues. Shift now saturates to a 31-bit shift amount. For rotate, in simulation only, the rotate amount is modulo the word width of the rotated value [#1874](https://github.com/clash-lang/clash-compiler/pull/1874) * `shiftL` for Clash datatypes does not cause a crash anymore when running Clash code with a really large shift amount [#1874](https://github.com/clash-lang/clash-compiler/pull/1874) * VHDL generated for `Signed.fromInteger` now truncates, like the Clash simulation, when the result is smaller than the argument [#1874](https://github.com/clash-lang/clash-compiler/pull/1874)- * Clash now preserves boolean combinatorial logic better when generating HDL [#1881](https://github.com/clash-lang/clash-compiler/issues/1881)+ * Clash now preserves boolean combinational logic better when generating HDL [#1881](https://github.com/clash-lang/clash-compiler/issues/1881) * `valid` field of `TemplateFunction` is now checked for includes [#1945](https://github.com/clash-lang/clash-compiler/issues/1945) * Clash now generates clock generators that ensure that the amount of time between simulation start and the first active edge of the clock is equal to (/or longer than/) the period of the clock. The first active edges of the clocks do still occur simultaneously. [#2001](https://github.com/clash-lang/clash-compiler/issues/2001) * Expected values in assert become undefined when using `-fclash-compile-ultra` [#2040](https://github.com/clash-lang/clash-compiler/issues/2040)
README.md view
@@ -31,6 +31,6 @@ - [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))+- [Fosstodon: microblogging and community chat room](https://fosstodon.org/@ClashHDL)+- [Bluesky: microblogging and community chat room](https://bsky.app/profile/clash-lang.bsky.social) - [Github: issue tracker](https://github.com/clash-lang/clash-compiler/issues)
clash-lib.cabal view
@@ -1,6 +1,6 @@ Cabal-version: 2.2 Name: clash-lib-Version: 1.8.5+Version: 1.10.0 Synopsis: Clash: a functional hardware description language - As a library Description: Clash is a functional hardware description language that borrows both its@@ -54,6 +54,10 @@ 2017-2023, QBayLogic B.V., Google Inc. Category: Hardware Build-type: Simple+tested-with: GHC == 9.6.7,+ GHC == 9.8.4,+ GHC == 9.10.3,+ GHC == 9.12.4 Extra-source-files: README.md,@@ -140,19 +144,19 @@ RecordWildCards TemplateHaskell - Build-depends: aeson >= 0.6.2.0 && < 2.3,+ Build-depends: aeson >= 2.0.0.0 && < 2.3, attoparsec-aeson >= 2.1 && < 2.3, aeson-pretty >= 0.8 && < 0.9, ansi-terminal >= 0.8.0.0 && < 1.2, array, async >= 2.2.0 && < 2.3, attoparsec >= 0.10.4.0 && < 0.15,- base >= 4.11 && < 5,+ base >= 4.18 && < 5, base16-bytestring >= 0.1.1 && < 1.1, binary >= 0.8.5 && < 0.11, bytestring >= 0.10.0.2 && < 0.13,- clash-prelude == 1.8.5,- containers >= 0.5.0.0 && < 0.8,+ clash-prelude == 1.10.0,+ containers >= 0.6.7 && < 0.9, cryptohash-sha256 >= 0.11 && < 0.12, data-binary-ieee754 >= 0.4.4 && < 0.6, data-default >= 0.7 && < 0.9,@@ -162,41 +166,35 @@ exceptions >= 0.8.3 && < 0.11.0, extra >= 1.6.17 && < 1.9, filepath >= 1.3.0.1 && < 1.6,- ghc >= 8.6.0 && < 9.11,+ ghc >= 9.6.0 && < 9.13,+ ghc-boot, ghc-boot-th, ghc-prim,- hashable >= 1.2.1.0 && < 1.6,+ ghc-bignum >=1.0 && <1.4,+ hashable >= 1.4.1.0 && < 1.6, haskell-src-meta >= 0.8 && < 0.9, hint >= 0.7 && < 0.10, infinite-list ^>= 0.1, lens >= 4.10 && < 5.4,- mtl >= 2.1.2 && < 2.4,+ mtl >= 2.3.1 && < 2.4, ordered-containers >= 0.2 && < 0.3, prettyprinter >= 1.2.0.1 && < 1.8, prettyprinter-interp ^>= 0.2, pretty-show >= 1.9 && < 2.0, primitive >= 0.5.0.1 && < 1.0, string-interpolate ^>= 0.3,- template-haskell >= 2.8.0.0 && < 2.23,+ template-haskell >= 2.20.0.0 && < 2.24, temporary >= 1.2.1 && < 1.4, terminal-size >= 0.3 && < 0.4, text >= 1.2.2 && < 2.2, time >= 1.4.0.1 && < 1.15,- transformers >= 0.5.2.0 && < 0.7,+ transformers >= 0.6.1.0 && < 0.7, trifecta >= 1.7.1.1 && < 2.2, vector >= 0.11 && < 1.0, vector-binary-instances >= 0.2.3.5 && < 0.3,- unordered-containers >= 0.2.3.3 && < 0.3,+ unordered-containers >= 0.2.11 && < 0.3, yaml >= 0.11 && < 0.12, - if impl(ghc < 9.4.0)- build-depends:-- if impl(ghc >= 9.0.0)- build-depends: ghc-bignum >=1.0 && <1.4- else- build-depends: integer-gmp >=1.0 && <1.1- Autogen-Modules: Paths_clash_lib Exposed-modules: Clash.Annotations.BitRepresentation.ClashLib@@ -240,6 +238,7 @@ Clash.Driver Clash.Driver.Bool+ Clash.Driver.BrokenGhcs Clash.Driver.Manifest Clash.Driver.Types @@ -322,7 +321,6 @@ GHC.BasicTypes.Extra Other-Modules: Clash.Annotations.TopEntity.Extra- Data.IntMap.Extra Data.List.Extra Data.Map.Ordered.Extra Data.Monoid.Extra@@ -363,8 +361,7 @@ filepath GHC-Options: -Wall -Wcompat default-language: Haskell2010- if impl(ghc >= 9.2.0)- buildable: False+ buildable: False test-suite doctests
prims/commonverilog/Clash_Class_BitPack.primitives.yaml view
@@ -5,8 +5,128 @@ template: ~ARG[0] workInfo: Never - BlackBox:+ name: Clash.Class.BitPack.Internal.packInt8#+ kind: Expression+ type: 'packInt8# :: Int8 -> Bitvector 8'+ template: $unsigned(~ARG[0])+ workInfo: Never+- BlackBox:+ name: Clash.Class.BitPack.Internal.packInt16#+ kind: Expression+ type: 'packInt16# :: Int16 -> Bitvector 16'+ template: $unsigned(~ARG[0])+ workInfo: Never+- BlackBox:+ name: Clash.Class.BitPack.Internal.packInt32#+ kind: Expression+ type: 'packInt32# :: Int32 -> Bitvector 32'+ template: $unsigned(~ARG[0])+ workInfo: Never+- BlackBox:+ name: Clash.Class.BitPack.Internal.packInt64#+ kind: Expression+ type: 'packInt64# :: Int64 -> Bitvector 64'+ template: $unsigned(~ARG[0])+ workInfo: Never+- BlackBox:+ name: Clash.Class.BitPack.Internal.packWord#+ kind: Expression+ type: 'packWord# :: Word -> Bitvector WORD_SIZE_IN_BITS'+ template: ~ARG[0]+ workInfo: Never+- BlackBox:+ name: Clash.Class.BitPack.Internal.packWord8#+ kind: Expression+ type: 'packWord8# :: Word8 -> Bitvector 8'+ template: ~ARG[0]+ workInfo: Never+- BlackBox:+ name: Clash.Class.BitPack.Internal.packWord16#+ kind: Expression+ type: 'packWord16# :: Word16 -> Bitvector 16'+ template: ~ARG[0]+ workInfo: Never+- BlackBox:+ name: Clash.Class.BitPack.Internal.packWord32#+ kind: Expression+ type: 'packWord32# :: Word32 -> Bitvector 32'+ template: ~ARG[0]+ workInfo: Never+- BlackBox:+ name: Clash.Class.BitPack.Internal.packWord64#+ kind: Expression+ type: 'packWord64# :: Word64 -> Bitvector 64'+ template: ~ARG[0]+ workInfo: Never+- BlackBox:+ name: Clash.Class.BitPack.Internal.packCUShort#+ kind: Expression+ type: 'packCUShort# :: CUShort -> Bitvector 16'+ template: ~ARG[0]+ workInfo: Never+- BlackBox: name: Clash.Class.BitPack.Internal.unpackChar# kind: Expression type: 'unpackChar# :: BitVector 21 -> Char'+ template: ~ARG[0]+ workInfo: Never+- BlackBox:+ name: Clash.Class.BitPack.Internal.unpackInt8#+ kind: Expression+ type: 'unpackInt8# :: Bitvector 8 -> Int8'+ template: $signed(~ARG[0])+ workInfo: Never+- BlackBox:+ name: Clash.Class.BitPack.Internal.unpackInt16#+ kind: Expression+ type: 'unpackInt16# :: Bitvector 16 -> Int16'+ template: $signed(~ARG[0])+ workInfo: Never+- BlackBox:+ name: Clash.Class.BitPack.Internal.unpackInt32#+ kind: Expression+ type: 'unpackInt32# :: Bitvector 32 -> Int32'+ template: $signed(~ARG[0])+ workInfo: Never+- BlackBox:+ name: Clash.Class.BitPack.Internal.unpackInt64#+ kind: Expression+ type: 'unpackInt64# :: Bitvector 64 -> Int64'+ template: $signed(~ARG[0])+ workInfo: Never+- BlackBox:+ name: Clash.Class.BitPack.Internal.unpackWord#+ kind: Expression+ type: 'unpackWord# :: Bitvector WORD_SIZE_IN_BITS -> Word'+ template: ~ARG[0]+ workInfo: Never+- BlackBox:+ name: Clash.Class.BitPack.Internal.unpackWord8#+ kind: Expression+ type: 'unpackWord8# :: Bitvector 8 -> Word8'+ template: ~ARG[0]+ workInfo: Never+- BlackBox:+ name: Clash.Class.BitPack.Internal.unpackWord16#+ kind: Expression+ type: 'unpackWord16# :: Bitvector 16 -> Word16'+ template: ~ARG[0]+ workInfo: Never+- BlackBox:+ name: Clash.Class.BitPack.Internal.unpackWord32#+ kind: Expression+ type: 'unpackWord32# :: Bitvector 32 -> Word32'+ template: ~ARG[0]+ workInfo: Never+- BlackBox:+ name: Clash.Class.BitPack.Internal.unpackWord64#+ kind: Expression+ type: 'unpackWord64# :: Bitvector 64 -> Word64'+ template: ~ARG[0]+ workInfo: Never+- BlackBox:+ name: Clash.Class.BitPack.Internal.unpackCUShort#+ kind: Expression+ type: 'unpackCUShort# :: Bitvector 16 -> CUShort' template: ~ARG[0] workInfo: Never
prims/commonverilog/Clash_Intel_DDR.primitives.yaml view
@@ -5,23 +5,26 @@ - altera_mf type: |- altddioOut#- :: ( HasCallStack -- ARG[0]- , KnownConfi~ fast domf -- ARG[1]- , KnownConfi~ slow doms -- ARG[2]- , KnownNat m ) -- ARG[3]- => SSymbol deviceFamily -- ARG[4]- -> Clock slow -- ARG[5]- -> Reset slow -- ARG[6]- -> Enable slow -- ARG[7]- -> Signal slow (BitVector m) -- ARG[8]- -> Signal slow (BitVector m) -- ARG[9]- -> Signal fast (BitVector m)+ :: forall deviceFamily n dom domDDR+ . HasCallStack -- ARG[0]+ => KnownDomain dom -- ARG[1]+ => KnownDomain domDDR -- ARG[2]+ => DomPeriod ~ 2 * ... -- ARG[3]+ => DomEdge ~ Rising -- ARG[4]+ => KnownNat n -- ARG[5]+ => SSymbol deviceFamily -- ARG[6]+ -> Clock dom -- ARG[7]+ -> Reset dom -- ARG[8]+ -> Enable dom -- ARG[9]+ -> Signal dom (BitVector n) -- ARG[10]+ -> Signal dom (BitVector n) -- ARG[11]+ -> Signal domDDR (BitVector n) template: |- // altddioOut begin altddio_out #( .extend_oe_disable ("OFF"),- .intended_device_family (~LIT[4]),+ .intended_device_family (~LIT[6]), .invert_output ("OFF"), .lpm_hint ("UNUSED"), .lpm_type ("altddio_out"),@@ -29,15 +32,15 @@ .power_up_high ("OFF"), .width (~SIZE[~TYPO]) )- ~GENSYM[~COMPNAME_ALTDDIO_OUT][7] (~IF ~ISSYNC[2] ~THEN- .sclr (~ARG[6]),+ ~GENSYM[~COMPNAME_ALTDDIO_OUT][7] (~IF ~ISSYNC[1] ~THEN+ .sclr (~ARG[8]), .aclr (1'b0),~ELSE- .aclr (~ARG[6]),+ .aclr (~ARG[8]), .sclr (1'b0),~FI- .datain_h (~ARG[8]),- .datain_l (~ARG[9]),- .outclock (~ARG[5]),- .outclocken (~IF ~ISACTIVEENABLE[7] ~THEN ~ARG[7] ~ELSE 1'b1 ~FI),+ .datain_h (~ARG[10]),+ .datain_l (~ARG[11]),+ .outclock (~ARG[7]),+ .outclocken (~IF ~ISACTIVEENABLE[9] ~THEN ~ARG[9] ~ELSE 1'b1 ~FI), .dataout (~RESULT), .aset (1'b0), .sset (1'b0),
prims/commonverilog/Clash_Sized_Internal_Index.primitives.yaml view
@@ -1,16 +1,16 @@ - BlackBox: name: Clash.Sized.Internal.Index.pack# kind: Expression- type: 'pack# :: Index- n -> BitVector (CLog 2 n)'+ type: |-+ pack# :: Index n -> BitVector (CLogWZ 2 n 0) template: ~ARG[0] workInfo: Never - BlackBox: name: Clash.Sized.Internal.Index.unpack# kind: Expression- type: 'unpack# :: (KnownNat- n, 1 <= n) => BitVector (CLog 2 n) -> Index n'- template: ~ARG[2]+ type: |-+ unpack# :: KnownNat n => BitVector (CLogWZ 2 n 0) -> Index n+ template: ~ARG[1] workInfo: Never - BlackBox: name: Clash.Sized.Internal.Index.eq#
prims/commonverilog/GHC_Num_Integer.primitives.yaml view
@@ -111,7 +111,7 @@ kind: Expression type: 'integerGt# :: Integer -> Integer -> Int#'- template: '(~ARG[0] > ~ARG[1] ? ~SIZE[~TYPO]''sd1 : ~SIZE[~TYPO]''sd0'+ template: '(~ARG[0] > ~ARG[1]) ? ~SIZE[~TYPO]''sd1 : ~SIZE[~TYPO]''sd0' warning: 'GHC.Num.Integer.integerGt#: Integers are dynamically sized in simulation, but fixed-length after synthesis. Use carefully.' - BlackBox:
prims/commonverilog/GHC_Num_Natural.primitives.yaml view
@@ -74,7 +74,7 @@ kind: Expression type: 'naturalGt# :: Natural -> Natural -> Int#'- template: '(~ARG[0] > ~ARG[1] ? ~SIZE[~TYPO]''d1 : ~SIZE[~TYPO]''d0'+ template: '(~ARG[0] > ~ARG[1]) ? ~SIZE[~TYPO]''d1 : ~SIZE[~TYPO]''d0' warning: 'GHC.Num.Natural.naturalGt#: Naturals are dynamically sized in simulation, but fixed-length after synthesis. Use carefully.' - BlackBox:
prims/systemverilog/Clash_Explicit_DDR.primitives.yaml view
@@ -2,42 +2,43 @@ name: Clash.Explicit.DDR.ddrIn# kind: Declaration type: |-- ddrIn# :: forall a slow fast n pFast gated synchronous.- ( HasCallStack -- ARG[0]- , NFDataX a -- ARG[1]- , KnownConfi~ fast domf -- ARG[2]- , KnownConfi~ slow doms -- ARG[3]- => Clock slow -- ARG[4], clk- -> Reset slow -- ARG[5], rst- -> Enable slow -- ARG[6], en- -> a -- ARG[7]- -> a -- ARG[8]- -> a -- ARG[9]- -> Signal fast a -- ARG[10]- -> Signal slow (a,a)+ ddrIn# :: forall a dom domDDR+ . HasCallStack -- ARG[0]+ => NFDataX a -- ARG[1]+ => KnownDomain dom -- ARG[2]+ => KnownDomain domDDR -- ARG[3]+ => DomPeriod ~ 2 * ... -- ARG[4]+ => Clock dom -- ARG[5]+ -> Reset dom -- ARG[6]+ -> Enable dom -- ARG[7]+ -> a -- ARG[8]+ -> a -- ARG[9]+ -> a -- ARG[10]+ -> Signal domDDR a -- ARG[11]+ -> Signal dom (a,a) template: |- // ddrIn begin- ~SIGD[~GENSYM[data_Pos][1]][9];- ~SIGD[~GENSYM[data_Neg][2]][9];- ~SIGD[~GENSYM[data_Neg_Latch][3]][9];- always @(~IF~ACTIVEEDGE[Rising][2]~THENposedge~ELSEnegedge~FI ~ARG[4]~IF~ISSYNC[3]~THEN)~ELSE or ~IF~ISACTIVEHIGH[2]~THENposedge~ELSEnegedge~FI ~ARG[5])~FI begin : ~GENSYM[~COMPNAME_ddrIn_pos][6]- if (~IF~ISACTIVEHIGH[2]~THEN~ARG[5]~ELSE! ~ARG[5]~FI) begin- ~SYM[1] <= ~ARG[8];- end else ~IF ~ISACTIVEENABLE[6] ~THEN if (~ARG[6]) ~ELSE ~FI begin- ~SYM[1] <= ~ARG[10];+ ~SIGD[~GENSYM[data_Pos][1]][11];+ ~SIGD[~GENSYM[data_Neg][2]][11];+ ~SIGD[~GENSYM[data_Neg_Latch][3]][11];+ always @(~IF~ACTIVEEDGE[Rising][2]~THENposedge~ELSEnegedge~FI ~ARG[5]~IF~ISSYNC[2]~THEN)~ELSE or ~IF~ISACTIVEHIGH[2]~THENposedge~ELSEnegedge~FI ~ARG[6])~FI begin : ~GENSYM[~COMPNAME_ddrIn_pos][6]+ if (~IF~ISACTIVEHIGH[2]~THEN~ARG[6]~ELSE! ~ARG[6]~FI) begin+ ~SYM[1] <= ~ARG[9];+ end else ~IF ~ISACTIVEENABLE[7] ~THEN if (~ARG[7]) ~ELSE ~FI begin+ ~SYM[1] <= ~ARG[11]; end end- always @(~IF~ACTIVEEDGE[Rising][2]~THENnegedge~ELSEposedge~FI ~ARG[4]~IF~ISSYNC[3]~THEN)~ELSE or ~IF~ISACTIVEHIGH[2]~THENposedge~ELSEnegedge~FI ~ARG[5])~FI begin : ~GENSYM[~COMPNAME_ddrIn_neg][7]- if (~IF~ISACTIVEHIGH[2]~THEN~ARG[5]~ELSE! ~ARG[5]~FI) begin- ~SYM[2] <= ~ARG[9];- end else ~IF ~ISACTIVEENABLE[6] ~THEN if (~ARG[6]) ~ELSE ~FI begin+ always @(~IF~ACTIVEEDGE[Rising][2]~THENnegedge~ELSEposedge~FI ~ARG[5]~IF~ISSYNC[2]~THEN)~ELSE or ~IF~ISACTIVEHIGH[2]~THENposedge~ELSEnegedge~FI ~ARG[6])~FI begin : ~GENSYM[~COMPNAME_ddrIn_neg][7]+ if (~IF~ISACTIVEHIGH[2]~THEN~ARG[6]~ELSE! ~ARG[6]~FI) begin ~SYM[2] <= ~ARG[10];+ end else ~IF ~ISACTIVEENABLE[7] ~THEN if (~ARG[7]) ~ELSE ~FI begin+ ~SYM[2] <= ~ARG[11]; end end- always @(~IF~ACTIVEEDGE[Rising][2]~THENposedge~ELSEnegedge~FI ~ARG[4]~IF~ISSYNC[3]~THEN)~ELSE or ~IF~ISACTIVEHIGH[2]~THENposedge~ELSEnegedge~FI ~ARG[5])~FI begin : ~GENSYM[~COMPNAME_ddrIn_neg_latch][8]- if (~IF~ISACTIVEHIGH[2]~THEN~ARG[5]~ELSE! ~ARG[5]~FI) begin- ~SYM[3] <= ~ARG[7];- end else ~IF ~ISACTIVEENABLE[6] ~THEN if (~ARG[6]) ~ELSE ~FI begin+ always @(~IF~ACTIVEEDGE[Rising][2]~THENposedge~ELSEnegedge~FI ~ARG[5]~IF~ISSYNC[2]~THEN)~ELSE or ~IF~ISACTIVEHIGH[2]~THENposedge~ELSEnegedge~FI ~ARG[6])~FI begin : ~GENSYM[~COMPNAME_ddrIn_neg_latch][8]+ if (~IF~ISACTIVEHIGH[2]~THEN~ARG[6]~ELSE! ~ARG[6]~FI) begin+ ~SYM[3] <= ~ARG[8];+ end else ~IF ~ISACTIVEENABLE[7] ~THEN if (~ARG[7]) ~ELSE ~FI begin ~SYM[3] <= ~SYM[2]; end end@@ -49,38 +50,40 @@ kind: Declaration outputUsage: Blocking type: |-- ddrOut# :: ( HasCallStack -- ARG[0]- , NFDataX a -- ARG[1]- , KnownConfi~ fast domf -- ARG[2]- , KnownConfi~ slow doms -- ARG[3]- => Clock slow -- ARG[4]- -> Reset slow -- ARG[5]- -> Enable slow -- ARG[6]- -> a -- ARG[7]- -> Signal slow a -- ARG[8]- -> Signal slow a -- ARG[9]- -> Signal fast a+ ddrOut# :: forall a dom domDDR+ . HasCallStack -- ARG[0]+ => NFDataX a -- ARG[1]+ => KnownDomain dom -- ARG[2]+ => KnownDomain domDDR -- ARG[3]+ => DomPeriod ~ 2 * ... -- ARG[4]+ => Clock dom -- ARG[5]+ -> Reset dom -- ARG[6]+ -> Enable dom -- ARG[7]+ -> a -- ARG[8]+ -> Signal dom a -- ARG[9]+ -> Signal dom a -- ARG[10]+ -> Signal domDDR a template: |- // ddrOut begin- ~SIGD[~GENSYM[data_Pos][1]][7];- ~SIGD[~GENSYM[data_Neg][2]][7];- always @(~IF~ACTIVEEDGE[Rising][2]~THENposedge~ELSEnegedge~FI ~ARG[4]~IF~ISSYNC[3]~THEN)~ELSE or ~IF~ISACTIVEHIGH[2]~THENposedge~ELSEnegedge~FI ~ARG[5])~FI begin : ~GENSYM[~COMPNAME_ddrOut_pos][5]- if (~IF~ISACTIVEHIGH[2]~THEN~ARG[5]~ELSE! ~ARG[5]~FI) begin- ~SYM[1] <= ~ARG[7];- end else ~IF ~ISACTIVEENABLE[6] ~THEN if (~ARG[6]) ~ELSE ~FI begin+ ~SIGD[~GENSYM[data_Pos][1]][8];+ ~SIGD[~GENSYM[data_Neg][2]][8];+ always @(~IF~ACTIVEEDGE[Rising][2]~THENposedge~ELSEnegedge~FI ~ARG[5]~IF~ISSYNC[2]~THEN)~ELSE or ~IF~ISACTIVEHIGH[2]~THENposedge~ELSEnegedge~FI ~ARG[6])~FI begin : ~GENSYM[~COMPNAME_ddrOut_pos][5]+ if (~IF~ISACTIVEHIGH[2]~THEN~ARG[6]~ELSE! ~ARG[6]~FI) begin ~SYM[1] <= ~ARG[8];+ end else ~IF ~ISACTIVEENABLE[7] ~THEN if (~ARG[7]) ~ELSE ~FI begin+ ~SYM[1] <= ~ARG[9]; end end- always @(~IF~ACTIVEEDGE[Rising][2]~THENposedge~ELSEnegedge~FI ~ARG[4]~IF~ISSYNC[3]~THEN)~ELSE or ~IF~ISACTIVEHIGH[2]~THENposedge~ELSEnegedge~FI ~ARG[5])~FI begin : ~GENSYM[~COMPNAME_ddrOut_neg][6]- if (~IF~ISACTIVEHIGH[2]~THEN~ARG[5]~ELSE! ~ARG[5]~FI) begin- ~SYM[2] <= ~ARG[7];- end else ~IF ~ISACTIVEENABLE[6] ~THEN if (~ARG[6]) ~ELSE ~FI begin- ~SYM[2] <= ~ARG[9];+ always @(~IF~ACTIVEEDGE[Rising][2]~THENposedge~ELSEnegedge~FI ~ARG[5]~IF~ISSYNC[2]~THEN)~ELSE or ~IF~ISACTIVEHIGH[2]~THENposedge~ELSEnegedge~FI ~ARG[6])~FI begin : ~GENSYM[~COMPNAME_ddrOut_neg][6]+ if (~IF~ISACTIVEHIGH[2]~THEN~ARG[6]~ELSE! ~ARG[6]~FI) begin+ ~SYM[2] <= ~ARG[8];+ end else ~IF ~ISACTIVEENABLE[7] ~THEN if (~ARG[7]) ~ELSE ~FI begin+ ~SYM[2] <= ~ARG[10]; end end always @(*) begin- if (~ARG[4]) begin+ if (~ARG[5]) begin ~RESULT = ~IF~ACTIVEEDGE[Rising][2]~THEN~SYM[1]~ELSE~SYM[2]~FI; end else begin ~RESULT = ~IF~ACTIVEEDGE[Rising][2]~THEN~SYM[2]~ELSE~SYM[1]~FI;
prims/systemverilog/Clash_Explicit_Testbench.primitives.yaml view
@@ -17,6 +17,9 @@ always @(~IF~ACTIVEEDGE[Rising][0]~THENposedge~ELSEnegedge~FI ~ARG[3]) begin if (~ARG[6] !== ~ARG[7]) begin $display("@%0tns: %s, expected: %b, actual: %b", $time, ~LIT[5], ~TOBV[~ARG[7]][~TYP[7]], ~TOBV[~ARG[6]][~TYP[6]]);+ `ifdef VERILATOR+ $c("std::exit(1);");+ `endif $stop; end end@@ -47,10 +50,12 @@ always @(~IF~ACTIVEEDGE[Rising][0]~THENposedge~ELSEnegedge~FI ~ARG[2]) begin if (~SYM[1] !== ~SYM[2]) begin $display("@%0tns: %s, expected: %b, actual: %b", $time, ~LIT[4], ~TOBV[~ARG[6]][~TYP[6]], ~TOBV[~ARG[5]][~TYP[5]]);+ `ifdef VERILATOR+ $c("std::exit(1);");+ `endif $stop; end end // pragma translate_on assign ~RESULT = ~ARG[7]; // assertBitVector end-
prims/systemverilog/Clash_Intel_DDR.primitives.yaml view
@@ -5,38 +5,41 @@ - altera_mf type: |- altddioIn#- :: ( HasCallStack -- ARG[0]- , KnownConfi~ fast domf -- ARG[1]- , KnownConfi~ slow doms -- ARG[2]- , KnownNat m ) -- ARG[3]- => SSymbol deviceFamily -- ARG[4]- -> Clock slow -- ARG[5]- -> Reset slow -- ARG[6]- -> Enable slow -- ARG[7]- -> Signal fast (BitVector m) -- ARG[8]- -> Signal slow (BitVector m,BitVector m)+ :: forall deviceFamily n dom domDDR+ . HasCallStack -- ARG[0]+ => KnownDomain dom -- ARG[1]+ => KnownDomain domDDR -- ARG[2]+ => DomPeriod ~ 2 * ... -- ARG[3]+ => DomEdge ~ Rising -- ARG[4]+ => KnownNat n -- ARG[5]+ => SSymbol deviceFamily -- ARG[6]+ -> Clock dom -- ARG[7]+ -> Reset dom -- ARG[8]+ -> Enable dom -- ARG[9]+ -> Signal domDDR (BitVector n) -- ARG[10]+ -> Signal dom (BitVector n, BitVector n) template: |- // altddioIn begin- ~SIGD[~GENSYM[dataout_l][1]][8];- ~SIGD[~GENSYM[dataout_h][2]][8];+ ~SIGD[~GENSYM[dataout_l][1]][10];+ ~SIGD[~GENSYM[dataout_h][2]][10]; altddio_in #(- .intended_device_family (~LIT[4]),+ .intended_device_family (~LIT[6]), .invert_input_clocks ("OFF"), .lpm_hint ("UNUSED"), .lpm_type ("altddio_in"), .power_up_high ("OFF"),- .width (~SIZE[~TYP[8]])+ .width (~SIZE[~TYP[10]]) )- ~GENSYM[~COMPNAME_ALTDDIO_IN][7] (~IF ~ISSYNC[2] ~THEN- .sclr (~ARG[6]),+ ~GENSYM[~COMPNAME_ALTDDIO_IN][7] (~IF ~ISSYNC[1] ~THEN+ .sclr (~ARG[8]), .aclr (1'b0),~ELSE- .aclr (~ARG[6]),+ .aclr (~ARG[8]), .sclr (1'b0),~FI- .datain (~ARG[8]),- .inclock (~ARG[5]),- .inclocken (~IF ~ISACTIVEENABLE[7] ~THEN~ARG[7]~ELSE1'b1~FI),+ .datain (~ARG[10]),+ .inclock (~ARG[7]),+ .inclocken (~IF ~ISACTIVEENABLE[9] ~THEN~ARG[9]~ELSE1'b1~FI), .dataout_h (~SYM[2]), .dataout_l (~SYM[1]), .aset (1'b0),
prims/systemverilog/Clash_Signal_Internal.primitives.yaml view
@@ -100,10 +100,12 @@ localparam ~GENSYM[half_period][0] = (~PERIOD[0]0 / 2); always begin ~RESULT = ~IF~ACTIVEEDGE[Rising][0]~THEN 0 ~ELSE 1 ~FI;- `ifndef VERILATOR #~LONGESTPERIOD0 forever begin ~IF~ISACTIVEENABLE[1]~THEN if (~ ~ARG[1]) begin+ `ifdef VERILATOR+ $c("std::exit(0);");+ `endif $finish; end ~ELSE~FI@@ -112,40 +114,7 @@ ~RESULT = ~ ~RESULT; #~SYM[0]; end- `else- ~RESULT = $c("this->~GENSYM[tb_clock_gen][1](",~SYM[0],",~IF~ACTIVEEDGE[Rising][0]~THENtrue~ELSEfalse~FI,",(~ ~ARG[1]),")");- `endif end-- `ifdef VERILATOR- `systemc_interface- CData ~SYM[1](vluint32_t half_period, bool active_rising, bool result_rec) {- static vluint32_t init_wait = ~LONGESTPERIOD0;- static vluint32_t to_wait = 0;- static CData clock = active_rising ? 0 : 1;-- if(init_wait == 0) {- if(result_rec) {- std::exit(0);- }- else {- if(to_wait == 0) {- to_wait = half_period - 1;- clock = clock == 0 ? 1 : 0;- }- else {- to_wait = to_wait - 1;- }- }- }- else {- init_wait = init_wait - 1;- }-- return clock;- }- `verilog- `endif // pragma translate_on // tbClockGen end warning: Clash.Signal.Internal.tbClockGen is not synthesizable!@@ -170,6 +139,9 @@ #~LONGESTPERIOD0 forever begin ~IF~ISACTIVEENABLE[2]~THEN if (~ ~ARG[2]) begin+ `ifdef VERILATOR+ $c("std::exit(0);");+ `endif $finish; end ~ELSE~FI@@ -196,39 +168,10 @@ // resetGen begin // pragma translate_off localparam ~GENSYM[reset_period][0] = ~LONGESTPERIOD0 - 10 + (~LIT[2] * ~PERIOD[0]0);- `ifndef VERILATOR initial begin #1 ~RESULT = ~IF ~ISACTIVEHIGH[0] ~THEN 1 ~ELSE 0 ~FI; #~SYM[0] ~RESULT = ~IF ~ISACTIVEHIGH[0] ~THEN 0 ~ELSE 1 ~FI; end- `else- always begin- // The redundant (~RESULT | ~ ~RESULT) is needed to ensure that this is- // calculated in every cycle by verilator. Without it, the reset will stop- // being updated and will be stuck as asserted forever.- ~RESULT =- $c("this->~GENSYM[reset_gen][1](",~SYM[0],",~IF~ISACTIVEHIGH[0]~THENtrue~ELSEfalse~FI)") & (~RESULT | ~ ~RESULT);- end- `systemc_interface- CData ~SYM[1](vluint32_t reset_period, bool active_high) {- static vluint32_t to_wait = reset_period;- static CData reset = active_high ? 1 : 0;- static bool finished = false;-- if(!finished) {- if(to_wait == 0) {- reset = reset == 0 ? 1 : 0;- finished = true;- }- else {- to_wait = to_wait - 1;- }- }-- return reset;- }- `verilog- `endif // pragma translate_on // resetGen end warning: Clash.Signal.Internal.resetGenN can not be synthesized to hardware!
prims/systemverilog/Clash_Xilinx_DDR.primitives.yaml view
@@ -3,37 +3,40 @@ kind: Declaration type: |- iddr#- :: ( HasCallStack -- ARG[0]- , KnownConfi~ fast domf -- ARG[1]- , KnownConfi~ slow doms -- ARG[2]- , KnownNat m ) -- ARG[3]- -> Clock slow -- ARG[4]- -> Reset slow -- ARG[5]- -> Enable slow -- ARG[6]- -> Signal fast (BitVector m) -- ARG[7]- -> Signal slow (BitVector m,BitVector m)+ :: forall n dom domDDR+ . HasCallStack -- ARG[0]+ => KnownDomain dom -- ARG[1]+ => KnownDomain domDDR -- ARG[2]+ => DomPeriod ~ 2 * ... -- ARG[3]+ => DomEdge ~ Rising -- ARG[4]+ => KnownNat n -- ARG[5]+ => Clock dom -- ARG[6]+ -> Reset dom -- ARG[7]+ -> Enable dom -- ARG[8]+ -> Signal domDDR (BitVector n) -- ARG[9]+ -> Signal dom (BitVector n, BitVector n) template: |- // iddr begin- ~SIGD[~GENSYM[data_pos][1]][7];- ~SIGD[~GENSYM[data_neg][2]][7];- ~SIGD[~GENSYM[d][3]][7];- assign ~SYM[3] = ~ARG[7];+ ~SIGD[~GENSYM[data_pos][1]][9];+ ~SIGD[~GENSYM[data_neg][2]][9];+ ~SIGD[~GENSYM[d][3]][9];+ assign ~SYM[3] = ~ARG[9]; genvar ~GENSYM[i][8]; ~GENERATE- for (~SYM[8]=0; ~SYM[8] < ~SIZE[~TYP[7]]; ~SYM[8]=~SYM[8]+1) begin : ~GENSYM[ddri_array][7]+ for (~SYM[8]=0; ~SYM[8] < ~SIZE[~TYP[9]]; ~SYM[8]=~SYM[8]+1) begin : ~GENSYM[ddri_array][7] IDDR #( .DDR_CLK_EDGE("SAME_EDGE"), .INIT_Q1(1'b0), .INIT_Q2(1'b0),- .SRTYPE(~IF ~ISSYNC[2] ~THEN "SYNC" ~ELSE "ASYNC" ~FI)+ .SRTYPE(~IF ~ISSYNC[1] ~THEN "SYNC" ~ELSE "ASYNC" ~FI) ) ~GENSYM[~COMPNAME_IDDR][9] ( .Q1(~SYM[1][~SYM[8]]), .Q2(~SYM[2][~SYM[8]]),- .C(~ARG[4]),- .CE(~IF ~ISACTIVEENABLE[6] ~THEN ~ARG[6] ~ELSE 1'b1 ~FI),+ .C(~ARG[6]),+ .CE(~IF ~ISACTIVEENABLE[8] ~THEN ~ARG[8] ~ELSE 1'b1 ~FI), .D(~SYM[3][~SYM[8]]),- .R(~ARG[5]),+ .R(~ARG[7]), .S(1'b0) ); end@@ -46,38 +49,42 @@ kind: Declaration type: |- oddr#- :: ( KnownConfi~ fast domf -- ARG[0]- , KnownConfi~ slow doms -- ARG[1]- , KnownNat m ) -- ARG[2]- => Clock slow -- ARG[3]- -> Reset slow -- ARG[4]- -> Enable slow -- ARG[5]- -> Signal slow (BitVector m) -- ARG[6]- -> Signal slow (BitVector m) -- ARG[7]- -> Signal fast (BitVector m)+ :: forall n dom domDDR+ . HasCallStack -- ARG[0]+ => KnownDomain dom -- ARG[1]+ => KnownDomain domDDR -- ARG[2]+ => DomPeriod ~ 2 * ... -- ARG[3]+ => DomEdge ~ Rising -- ARG[4]+ => KnownNat n -- ARG[5]+ => Clock dom -- ARG[6]+ -> Reset dom -- ARG[7]+ -> Enable dom -- ARG[8]+ -> Signal dom (BitVector n) -- ARG[9]+ -> Signal dom (BitVector n) -- ARG[10]+ -> Signal domDDR (BitVector n) template: |- // oddr begin- ~SIGD[~GENSYM[data_pos][1]][7];- ~SIGD[~GENSYM[data_neg][2]][7];- ~SIGD[~GENSYM[q][3]][7];+ ~SIGD[~GENSYM[data_pos][1]][10];+ ~SIGD[~GENSYM[data_neg][2]][10];+ ~SIGD[~GENSYM[q][3]][10]; - assign ~SYM[1] = ~ARG[6];- assign ~SYM[2] = ~ARG[7];+ assign ~SYM[1] = ~ARG[9];+ assign ~SYM[2] = ~ARG[10]; genvar ~GENSYM[i][8]; ~GENERATE- for (~SYM[8]=0; ~SYM[8] < ~SIZE[~TYP[7]]; ~SYM[8]=~SYM[8]+1) begin : ~GENSYM[ddro_array][7]+ for (~SYM[8]=0; ~SYM[8] < ~SIZE[~TYP[10]]; ~SYM[8]=~SYM[8]+1) begin : ~GENSYM[ddro_array][7] ODDR #( .DDR_CLK_EDGE("SAME_EDGE"), .INIT(1'b0), .SRTYPE(~IF ~ISSYNC[1] ~THEN "SYNC" ~ELSE "ASYNC" ~FI) ) ~GENSYM[~COMPNAME_ODDR][9] ( .Q(~SYM[3][~SYM[8]]),- .C(~ARG[3]),- .CE(~IF ~ISACTIVEENABLE[5] ~THEN ~ARG[5] ~ELSE 1'b1 ~FI),+ .C(~ARG[6]),+ .CE(~IF ~ISACTIVEENABLE[8] ~THEN ~ARG[8] ~ELSE 1'b1 ~FI), .D1(~SYM[1][~SYM[8]]), .D2(~SYM[2][~SYM[8]]),- .R(~ARG[4]),+ .R(~ARG[7]), .S(1'b0) ); end
prims/verilog/Clash_Explicit_DDR.primitives.yaml view
@@ -2,42 +2,43 @@ name: Clash.Explicit.DDR.ddrIn# kind: Declaration type: |-- ddrIn# :: forall a slow fast n pFast gated synchronous.- ( HasCallStack -- ARG[0]- , NFDataX a -- ARG[1]- , KnownConfi~ fast domf -- ARG[2]- , KnownConfi~ slow doms -- ARG[3]- => Clock slow -- ARG[4]- -> Reset slow -- ARG[5]- -> Enable slow -- ARG[6]- -> a -- ARG[7]- -> a -- ARG[8]- -> a -- ARG[9]- -> Signal fast a -- ARG[10]- -> Signal slow (a,a)+ ddrIn# :: forall a dom domDDR+ . HasCallStack -- ARG[0]+ => NFDataX a -- ARG[1]+ => KnownDomain dom -- ARG[2]+ => KnownDomain domDDR -- ARG[3]+ => DomPeriod ~ 2 * ... -- ARG[4]+ => Clock dom -- ARG[5]+ -> Reset dom -- ARG[6]+ -> Enable dom -- ARG[7]+ -> a -- ARG[8]+ -> a -- ARG[9]+ -> a -- ARG[10]+ -> Signal domDDR a -- ARG[11]+ -> Signal dom (a,a) template: |- // ddrIn begin- reg ~SIGD[~GENSYM[data_Pos][1]][9];- reg ~SIGD[~GENSYM[data_Neg][2]][9];- reg ~SIGD[~GENSYM[data_Neg_Latch][3]][9];- always @(~IF~ACTIVEEDGE[Rising][2]~THENposedge~ELSEnegedge~FI ~ARG[4]~IF~ISSYNC[3]~THEN)~ELSE or ~IF~ISACTIVEHIGH[2]~THENposedge~ELSEnegedge~FI ~ARG[5])~FI begin : ~GENSYM[~COMPNAME_ddrIn_pos][6]- if (~IF~ISACTIVEHIGH[2]~THEN~ARG[5]~ELSE! ~ARG[5]~FI) begin- ~SYM[1] <= ~ARG[8];- end else ~IF ~ISACTIVEENABLE[6] ~THEN if (~ARG[6]) ~ELSE ~FI begin- ~SYM[1] <= ~ARG[10];+ reg ~SIGD[~GENSYM[data_Pos][1]][11];+ reg ~SIGD[~GENSYM[data_Neg][2]][11];+ reg ~SIGD[~GENSYM[data_Neg_Latch][3]][11];+ always @(~IF~ACTIVEEDGE[Rising][2]~THENposedge~ELSEnegedge~FI ~ARG[5]~IF~ISSYNC[2]~THEN)~ELSE or ~IF~ISACTIVEHIGH[2]~THENposedge~ELSEnegedge~FI ~ARG[6])~FI begin : ~GENSYM[~COMPNAME_ddrIn_pos][6]+ if (~IF~ISACTIVEHIGH[2]~THEN~ARG[6]~ELSE! ~ARG[6]~FI) begin+ ~SYM[1] <= ~ARG[9];+ end else ~IF ~ISACTIVEENABLE[7] ~THEN if (~ARG[7]) ~ELSE ~FI begin+ ~SYM[1] <= ~ARG[11]; end end- always @(~IF~ACTIVEEDGE[Rising][2]~THENnegedge~ELSEposedge~FI ~ARG[4]~IF~ISSYNC[3]~THEN)~ELSE or ~IF~ISACTIVEHIGH[2]~THENposedge~ELSEnegedge~FI ~ARG[5])~FI begin : ~GENSYM[~COMPNAME_ddrIn_neg][7]- if (~IF~ISACTIVEHIGH[2]~THEN~ARG[5]~ELSE! ~ARG[5]~FI) begin- ~SYM[2] <= ~ARG[9];- end else ~IF ~ISACTIVEENABLE[6] ~THEN if (~ARG[6]) ~ELSE ~FI begin+ always @(~IF~ACTIVEEDGE[Rising][2]~THENnegedge~ELSEposedge~FI ~ARG[5]~IF~ISSYNC[2]~THEN)~ELSE or ~IF~ISACTIVEHIGH[2]~THENposedge~ELSEnegedge~FI ~ARG[6])~FI begin : ~GENSYM[~COMPNAME_ddrIn_neg][7]+ if (~IF~ISACTIVEHIGH[2]~THEN~ARG[6]~ELSE! ~ARG[6]~FI) begin ~SYM[2] <= ~ARG[10];+ end else ~IF ~ISACTIVEENABLE[7] ~THEN if (~ARG[7]) ~ELSE ~FI begin+ ~SYM[2] <= ~ARG[11]; end end- always @(~IF~ACTIVEEDGE[Rising][2]~THENposedge~ELSEnegedge~FI ~ARG[4]~IF~ISSYNC[3]~THEN)~ELSE or ~IF~ISACTIVEHIGH[2]~THENposedge~ELSEnegedge~FI ~ARG[5])~FI begin : ~GENSYM[~COMPNAME_ddrIn_neg_latch][8]- if (~IF~ISACTIVEHIGH[2]~THEN~ARG[5]~ELSE! ~ARG[5]~FI) begin- ~SYM[3] <= ~ARG[7];- end else ~IF ~ISACTIVEENABLE[6] ~THEN if (~ARG[6]) ~ELSE ~FI begin+ always @(~IF~ACTIVEEDGE[Rising][2]~THENposedge~ELSEnegedge~FI ~ARG[5]~IF~ISSYNC[2]~THEN)~ELSE or ~IF~ISACTIVEHIGH[2]~THENposedge~ELSEnegedge~FI ~ARG[6])~FI begin : ~GENSYM[~COMPNAME_ddrIn_neg_latch][8]+ if (~IF~ISACTIVEHIGH[2]~THEN~ARG[6]~ELSE! ~ARG[6]~FI) begin+ ~SYM[3] <= ~ARG[8];+ end else ~IF ~ISACTIVEENABLE[7] ~THEN if (~ARG[7]) ~ELSE ~FI begin ~SYM[3] <= ~SYM[2]; end end@@ -48,45 +49,47 @@ name: Clash.Explicit.DDR.ddrOut# kind: Declaration type: |-- ddrOut# :: ( HasCallStack -- ARG[0]- , NFDataX a -- ARG[1]- , KnownConfi~ fast domf -- ARG[2]- , KnownConfi~ slow doms -- ARG[3]- => Clock slow -- ARG[4]- -> Reset slow -- ARG[5]- -> Enable slow -- ARG[6]- -> a -- ARG[7]- -> Signal slow a -- ARG[8]- -> Signal slow a -- ARG[9]- -> Signal fast a+ ddrOut# :: forall a dom domDDR+ . HasCallStack -- ARG[0]+ => NFDataX a -- ARG[1]+ => KnownDomain dom -- ARG[2]+ => KnownDomain domDDR -- ARG[3]+ => DomPeriod ~ 2 * ... -- ARG[4]+ => Clock dom -- ARG[5]+ -> Reset dom -- ARG[6]+ -> Enable dom -- ARG[7]+ -> a -- ARG[8]+ -> Signal dom a -- ARG[9]+ -> Signal dom a -- ARG[10]+ -> Signal domDDR a template: |- // ddrOut begin- reg ~SIGD[~GENSYM[data_Pos][1]][7];- reg ~SIGD[~GENSYM[data_Neg][2]][7];+ reg ~SIGD[~GENSYM[data_Pos][1]][8];+ reg ~SIGD[~GENSYM[data_Neg][2]][8]; ~IF ~VIVADO ~THENreg ~SIGDO[~GENSYM[ddrOut][3]];~ELSE~FI- always @(~IF~ACTIVEEDGE[Rising][2]~THENposedge~ELSEnegedge~FI ~ARG[4]~IF~ISSYNC[3]~THEN)~ELSE or ~IF~ISACTIVEHIGH[2]~THENposedge~ELSEnegedge~FI ~ARG[5])~FI begin : ~GENSYM[~COMPNAME_ddrOut_pos][5]- if (~IF~ISACTIVEHIGH[2]~THEN~ARG[5]~ELSE! ~ARG[5]~FI) begin- ~SYM[1] <= ~ARG[7];- end else ~IF ~ISACTIVEENABLE[6] ~THEN if (~ARG[6]) ~ELSE ~FI begin+ always @(~IF~ACTIVEEDGE[Rising][2]~THENposedge~ELSEnegedge~FI ~ARG[5]~IF~ISSYNC[2]~THEN)~ELSE or ~IF~ISACTIVEHIGH[2]~THENposedge~ELSEnegedge~FI ~ARG[6])~FI begin : ~GENSYM[~COMPNAME_ddrOut_pos][5]+ if (~IF~ISACTIVEHIGH[2]~THEN~ARG[6]~ELSE! ~ARG[6]~FI) begin ~SYM[1] <= ~ARG[8];+ end else ~IF ~ISACTIVEENABLE[7] ~THEN if (~ARG[7]) ~ELSE ~FI begin+ ~SYM[1] <= ~ARG[9]; end end- always @(~IF~ACTIVEEDGE[Rising][2]~THENposedge~ELSEnegedge~FI ~ARG[4]~IF~ISSYNC[3]~THEN)~ELSE or ~IF~ISACTIVEHIGH[2]~THENposedge~ELSEnegedge~FI ~ARG[5])~FI begin : ~GENSYM[~COMPNAME_ddrOut_neg][6]- if (~IF~ISACTIVEHIGH[2]~THEN~ARG[5]~ELSE! ~ARG[5]~FI) begin- ~SYM[2] <= ~ARG[7];- end else ~IF ~ISACTIVEENABLE[6] ~THEN if (~ARG[6]) ~ELSE ~FI begin- ~SYM[2] <= ~ARG[9];+ always @(~IF~ACTIVEEDGE[Rising][2]~THENposedge~ELSEnegedge~FI ~ARG[5]~IF~ISSYNC[2]~THEN)~ELSE or ~IF~ISACTIVEHIGH[2]~THENposedge~ELSEnegedge~FI ~ARG[6])~FI begin : ~GENSYM[~COMPNAME_ddrOut_neg][6]+ if (~IF~ISACTIVEHIGH[2]~THEN~ARG[6]~ELSE! ~ARG[6]~FI) begin+ ~SYM[2] <= ~ARG[8];+ end else ~IF ~ISACTIVEENABLE[7] ~THEN if (~ARG[7]) ~ELSE ~FI begin+ ~SYM[2] <= ~ARG[10]; end end ~IF ~VIVADO ~THENalways @(*) begin- if (~ARG[4]) begin+ if (~ARG[5]) begin ~SYM[3] = ~IF~ACTIVEEDGE[Rising][2]~THEN~SYM[1]~ELSE~SYM[2]~FI; end else begin ~SYM[3] = ~IF~ACTIVEEDGE[Rising][2]~THEN~SYM[2]~ELSE~SYM[1]~FI; end end assign ~RESULT = ~SYM[3];~ELSE- assign ~RESULT = ~ARG[4] ? ~IF~ACTIVEEDGE[Rising][2]~THEN~SYM[1] : ~SYM[2]~ELSE~SYM[2] : ~SYM[1]~FI;~FI+ assign ~RESULT = ~ARG[5] ? ~IF~ACTIVEEDGE[Rising][2]~THEN~SYM[1] : ~SYM[2]~ELSE~SYM[2] : ~SYM[1]~FI;~FI // ddrOut end
prims/verilog/Clash_Explicit_Testbench.primitives.yaml view
@@ -17,6 +17,9 @@ always @(~IF~ACTIVEEDGE[Rising][0]~THENposedge~ELSEnegedge~FI ~ARG[3]) begin if (~VAR[checked][6] !== ~VAR[expected][7]) begin $display("@%0tns: %s, expected: %b, actual: %b", $time, ~LIT[5], ~VAR[expected][7], ~VAR[checked][6]);+ `ifdef VERILATOR+ $c("std::exit(1);");+ `endif $finish; end end@@ -47,6 +50,9 @@ always @(~IF~ACTIVEEDGE[Rising][0]~THENposedge~ELSEnegedge~FI ~ARG[2]) begin if (~SYM[1] !== ~SYM[2]) begin $display("@%0tns: %s, expected: %b, actual: %b", $time, ~LIT[4], ~VAR[expected][6], ~VAR[checked][5]);+ `ifdef VERILATOR+ $c("std::exit(1);");+ `endif $finish; end end
prims/verilog/Clash_Intel_DDR.primitives.yaml view
@@ -5,38 +5,41 @@ - altera_mf type: |- altddioIn#- :: ( HasCallStack -- ARG[0]- , KnownConfi~ fast domf -- ARG[1]- , KnownConfi~ slow doms -- ARG[2]- , KnownNat m ) -- ARG[3]- => SSymbol deviceFamily -- ARG[4]- -> Clock slow -- ARG[5]- -> Reset slow -- ARG[6]- -> Enable slow -- ARG[7]- -> Signal fast (BitVector m) -- ARG[8]- -> Signal slow (BitVector m,BitVector m)+ :: forall deviceFamily n dom domDDR+ . HasCallStack -- ARG[0]+ => KnownDomain dom -- ARG[1]+ => KnownDomain domDDR -- ARG[2]+ => DomPeriod ~ 2 * ... -- ARG[3]+ => DomEdge ~ Rising -- ARG[4]+ => KnownNat n -- ARG[5]+ => SSymbol deviceFamily -- ARG[6]+ -> Clock dom -- ARG[7]+ -> Reset dom -- ARG[8]+ -> Enable dom -- ARG[9]+ -> Signal domDDR (BitVector n) -- ARG[10]+ -> Signal dom (BitVector n, BitVector n) template: |- // altddioIn begin- wire ~SIGD[~GENSYM[dataout_l][1]][8];- wire ~SIGD[~GENSYM[dataout_h][2]][8];+ wire ~SIGD[~GENSYM[dataout_l][1]][10];+ wire ~SIGD[~GENSYM[dataout_h][2]][10]; altddio_in #(- .intended_device_family (~LIT[4]),+ .intended_device_family (~LIT[6]), .invert_input_clocks ("OFF"), .lpm_hint ("UNUSED"), .lpm_type ("altddio_in"), .power_up_high ("OFF"),- .width (~SIZE[~TYP[8]])+ .width (~SIZE[~TYP[10]]) )- ~GENSYM[~COMPNAME_ALTDDIO_IN][7] (~IF ~ISSYNC[2] ~THEN- .sclr (~ARG[6]),+ ~GENSYM[~COMPNAME_ALTDDIO_IN][7] (~IF ~ISSYNC[1] ~THEN+ .sclr (~ARG[8]), .aclr (1'b0),~ELSE- .aclr (~ARG[6]),+ .aclr (~ARG[8]), .sclr (1'b0),~FI- .datain (~ARG[8]),- .inclock (~ARG[5]),- .inclocken (~IF ~ISACTIVEENABLE[7] ~THEN ~ARG[7] ~ELSE 1'b1 ~FI),+ .datain (~ARG[10]),+ .inclock (~ARG[7]),+ .inclocken (~IF ~ISACTIVEENABLE[9] ~THEN ~ARG[9] ~ELSE 1'b1 ~FI), .dataout_h (~SYM[2]), .dataout_l (~SYM[1]), .aset (1'b0),
prims/verilog/Clash_Signal_Internal.primitives.yaml view
@@ -101,10 +101,12 @@ always begin // Delay of 1 mitigates race conditions (https://github.com/steveicarus/iverilog/issues/160) #1 ~SYM[0] = ~IF~ACTIVEEDGE[Rising][0]~THEN 0 ~ELSE 1 ~FI;- `ifndef VERILATOR #~LONGESTPERIOD0 forever begin ~IF~ISACTIVEENABLE[1]~THEN if (~ ~ARG[1]) begin+ `ifdef VERILATOR+ $c("std::exit(0);");+ `endif $finish(0); end ~ELSE~FI@@ -113,41 +115,8 @@ ~SYM[0] = ~ ~SYM[0]; #~SYM[1]; end- `else- ~SYM[0] = $c("this->~GENSYM[tb_clock_gen][2](",~SYM[1],",~IF~ACTIVEEDGE[Rising][0]~THENtrue~ELSEfalse~FI,",(~ ~ARG[1]),")");- `endif end - `ifdef VERILATOR- `systemc_interface- CData ~SYM[2](vluint32_t half_period, bool active_rising, bool result_rec) {- static vluint32_t init_wait = ~LONGESTPERIOD0;- static vluint32_t to_wait = 0;- static CData clock = active_rising ? 0 : 1;-- if(init_wait == 0) {- if(result_rec) {- std::exit(0);- }- else {- if(to_wait == 0) {- to_wait = half_period - 1;- clock = clock == 0 ? 1 : 0;- }- else {- to_wait = to_wait - 1;- }- }- }- else {- init_wait = init_wait - 1;- }-- return clock;- }- `verilog- `endif- assign ~RESULT = ~SYM[0]; // pragma translate_on // tbClockGen end@@ -173,6 +142,9 @@ #~LONGESTPERIOD0 forever begin ~IF~ISACTIVEENABLE[2]~THEN if (~ ~ARG[2]) begin+ `ifdef VERILATOR+ $c("std::exit(0);");+ `endif $finish(0); end ~ELSE~FI@@ -201,38 +173,10 @@ // pragma translate_off reg ~TYPO ~GENSYM[rst][0]; localparam ~GENSYM[reset_period][1] = ~LONGESTPERIOD0 - 10 + (~LIT[2] * ~PERIOD[0]0);- `ifndef VERILATOR initial begin #1 ~SYM[0] = ~IF ~ISACTIVEHIGH[0] ~THEN 1 ~ELSE 0 ~FI; #~SYM[1] ~SYM[0] = ~IF ~ISACTIVEHIGH[0] ~THEN 0 ~ELSE 1 ~FI; end- `else- always begin- // The redundant (~SYM[0] | ~ ~SYM[0]) is needed to ensure that this is- // calculated in every cycle by verilator. Without it, the reset will stop- // being updated and will be stuck as asserted forever.- ~SYM[0] = $c("this->~GENSYM[reset_gen][2](",~SYM[1],",~IF~ISACTIVEHIGH[0]~THENtrue~ELSEfalse~FI)") & (~SYM[0] | ~ ~SYM[0]);- end- `systemc_interface- CData ~SYM[2](vluint32_t reset_period, bool active_high) {- static vluint32_t to_wait = reset_period;- static CData reset = active_high ? 1 : 0;- static bool finished = false;-- if(!finished) {- if(to_wait == 0) {- reset = reset == 0 ? 1 : 0;- finished = true;- }- else {- to_wait = to_wait - 1;- }- }-- return reset;- }- `verilog- `endif assign ~RESULT = ~SYM[0]; // pragma translate_on // resetGen end
prims/verilog/Clash_Sized_Vector.primitives.yaml view
@@ -86,15 +86,16 @@ // map begin genvar ~GENSYM[i][1]; ~GENERATE- for (~SYM[1]=0; ~SYM[1] < ~LENGTH[~TYPO]; ~SYM[1] = ~SYM[1] + 1) begin : ~GENSYM[map][2]~IF~SIZE[~TYP[1]]~THEN+ for (~SYM[1]=0; ~SYM[1] < ~LENGTH[~TYPO]; ~SYM[1] = ~SYM[1] + 1) begin : ~GENSYM[map][2]+ localparam ~GENSYM[vec_index][5] = ~MAXINDEX[~TYPO] - ~SYM[1];~IF~SIZE[~TYP[1]]~THEN wire ~TYPEL[~TYP[1]] ~GENSYM[map_in][3];- assign ~SYM[3] = ~VAR[vec][1][~SYM[1]*~SIZE[~TYPEL[~TYP[1]]]+:~SIZE[~TYPEL[~TYP[1]]]];~ELSE ~FI+ assign ~SYM[3] = ~VAR[vec][1][~SYM[5]*~SIZE[~TYPEL[~TYP[1]]]+:~SIZE[~TYPEL[~TYP[1]]]];~ELSE ~FI ~OUTPUTUSAGE[0] ~TYPEL[~TYPO] ~GENSYM[map_out][4]; ~INST 0 ~OUTPUT <= ~SYM[4]~ ~TYPEL[~TYPO]~ ~INPUT <= ~SYM[3]~ ~TYPEL[~TYP[1]]~ ~INST- assign ~RESULT[~SYM[1]*~SIZE[~TYPEL[~TYPO]]+:~SIZE[~TYPEL[~TYPO]]] = ~SYM[4];+ assign ~RESULT[~SYM[5]*~SIZE[~TYPEL[~TYPO]]+:~SIZE[~TYPEL[~TYPO]]] = ~SYM[4]; end ~ENDGENERATE // map end@@ -108,18 +109,19 @@ genvar ~GENSYM[i][1]; ~GENERATE for (~SYM[1]=0; ~SYM[1] < ~LENGTH[~TYPO]; ~SYM[1] = ~SYM[1] + 1) begin : ~GENSYM[imap][2]+ localparam ~GENSYM[vec_index][6] = ~MAXINDEX[~TYPO] - ~SYM[1]; wire [~SIZE[~INDEXTYPE[~LIT[0]]]-1: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+ assign ~SYM[4] = ~VAR[vec][2][~SYM[6]*~SIZE[~TYPEL[~TYP[2]]]+:~SIZE[~TYPEL[~TYP[2]]]];~ELSE ~FI ~OUTPUTUSAGE[1] ~TYPEL[~TYPO] ~GENSYM[map_out][5]; - assign ~SYM[3] = ~SIZE[~INDEXTYPE[~LIT[0]]]'d~MAXINDEX[~TYPO] - ~SYM[1][0+:~SIZE[~INDEXTYPE[~LIT[0]]]];+ assign ~SYM[3] = ~SYM[1][0+:~SIZE[~INDEXTYPE[~LIT[0]]]]; ~INST 1 ~OUTPUT <= ~SYM[5]~ ~TYPEL[~TYPO]~ ~INPUT <= ~SYM[3]~ ~INDEXTYPE[~LIT[0]]~ ~INPUT <= ~SYM[4]~ ~TYPEL[~TYP[2]]~ ~INST- assign ~RESULT[~SYM[1]*~SIZE[~TYPEL[~TYPO]]+:~SIZE[~TYPEL[~TYPO]]] = ~SYM[5];+ assign ~RESULT[~SYM[6]*~SIZE[~TYPEL[~TYPO]]+:~SIZE[~TYPEL[~TYPO]]] = ~SYM[5]; end ~ENDGENERATE // imap end@@ -129,25 +131,26 @@ kind: Declaration type: 'imap_go :: (Index n -> a -> b) -> Vec m a -> Index n -> Vec m b' template: |-- // imap begin+ // imap_go begin genvar ~GENSYM[i][1]; ~GENERATE- for (~SYM[1]=0; ~SYM[1] < ~LENGTH[~TYPO]; ~SYM[1] = ~SYM[1] + 1) begin : ~GENSYM[imap][2]+ for (~SYM[1]=0; ~SYM[1] < ~LENGTH[~TYPO]; ~SYM[1] = ~SYM[1] + 1) begin : ~GENSYM[imap_go][2]+ localparam ~GENSYM[vec_index][6] = ~MAXINDEX[~TYPO] - ~SYM[1]; 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+ assign ~SYM[4] = ~VAR[vec][1][~SYM[6]*~SIZE[~TYPEL[~TYP[1]]]+:~SIZE[~TYPEL[~TYP[1]]]];~ELSE ~FI ~OUTPUTUSAGE[0] ~TYPEL[~TYPO] ~GENSYM[map_out][5]; - assign ~SYM[3] = ~SIZE[~TYP[2]]'d~MAXINDEX[~TYPO] - ~SYM[1][0+:~SIZE[~TYP[2]]] + ~ARG[2];+ assign ~SYM[3] = ~SYM[1][0+:~SIZE[~TYP[2]]] + ~ARG[2]; ~INST 0 ~OUTPUT <= ~SYM[5]~ ~TYPEL[~TYPO]~ ~INPUT <= ~SYM[3]~ ~TYP[2]~ ~INPUT <= ~SYM[4]~ ~TYPEL[~TYP[1]]~ ~INST- assign ~RESULT[~SYM[1]*~SIZE[~TYPEL[~TYPO]]+:~SIZE[~TYPEL[~TYPO]]] = ~SYM[5];+ assign ~RESULT[~SYM[6]*~SIZE[~TYPEL[~TYPO]]+:~SIZE[~TYPEL[~TYPO]]] = ~SYM[5]; end ~ENDGENERATE- // imap end+ // imap_go end workInfo: Never - BlackBox: name: Clash.Sized.Vector.zipWith@@ -157,18 +160,19 @@ // zipWith start genvar ~GENSYM[i][2]; ~GENERATE- for (~SYM[2] = 0; ~SYM[2] < ~LENGTH[~TYPO]; ~SYM[2] = ~SYM[2] + 1) begin : ~GENSYM[zipWith][6]~IF~SIZE[~TYP[1]]~THEN+ for (~SYM[2] = 0; ~SYM[2] < ~LENGTH[~TYPO]; ~SYM[2] = ~SYM[2] + 1) begin : ~GENSYM[zipWith][6]+ localparam ~GENSYM[vec_index][7] = ~MAXINDEX[~TYPO] - ~SYM[2];~IF~SIZE[~TYP[1]]~THEN wire ~TYPEL[~TYP[1]] ~GENSYM[zipWith_in1][3];- assign ~SYM[3] = ~VAR[vec1][1][~SYM[2]*~SIZE[~TYPEL[~TYP[1]]]+:~SIZE[~TYPEL[~TYP[1]]]];~ELSE ~FI~IF~SIZE[~TYP[2]]~THEN+ assign ~SYM[3] = ~VAR[vec1][1][~SYM[7]*~SIZE[~TYPEL[~TYP[1]]]+:~SIZE[~TYPEL[~TYP[1]]]];~ELSE ~FI~IF~SIZE[~TYP[2]]~THEN wire ~TYPEL[~TYP[2]] ~GENSYM[zipWith_in2][4];- assign ~SYM[4] = ~VAR[vec2][2][~SYM[2]*~SIZE[~TYPEL[~TYP[2]]]+:~SIZE[~TYPEL[~TYP[2]]]];~ELSE ~FI- ~OUTPUTUSAGE[0] ~TYPEL[~TYPO] ~SYM[5];+ assign ~SYM[4] = ~VAR[vec2][2][~SYM[7]*~SIZE[~TYPEL[~TYP[2]]]+:~SIZE[~TYPEL[~TYP[2]]]];~ELSE ~FI+ ~OUTPUTUSAGE[0] ~TYPEL[~TYPO] ~GENSYM[zip_out][5]; ~INST 0 ~OUTPUT <= ~SYM[5]~ ~TYPEL[~TYPO]~ ~INPUT <= ~SYM[3]~ ~TYPEL[~TYP[1]]~ ~INPUT <= ~SYM[4]~ ~TYPEL[~TYP[2]]~ ~INST- assign ~RESULT[~SYM[2]*~SIZE[~TYPEL[~TYPO]]+:~SIZE[~TYPEL[~TYPO]]] = ~SYM[5];+ assign ~RESULT[~SYM[7]*~SIZE[~TYPEL[~TYPO]]+:~SIZE[~TYPEL[~TYPO]]] = ~SYM[5]; end ~ENDGENERATE // zipWith end@@ -185,8 +189,9 @@ genvar ~GENSYM[i][3]; ~GENERATE for (~SYM[3]=0; ~SYM[3] < ~LENGTH[~TYP[2]]; ~SYM[3]=~SYM[3]+1) begin : ~GENSYM[foldr][4]~IF~SIZE[~TYP[2]]~THEN+ localparam ~GENSYM[vec_index][8] = ~MAXINDEX[~TYP[2]] - ~SYM[3]; wire ~TYPEL[~TYP[2]] ~GENSYM[foldr_in1][5];- assign ~SYM[5] = ~VAR[xs][2][(~LENGTH[~TYP[2]]-1-~SYM[3])*~SIZE[~TYPEL[~TYP[2]]]+:~SIZE[~TYPEL[~TYP[2]]]];~ELSE ~FI+ assign ~SYM[5] = ~VAR[xs][2][(~SYM[8])*~SIZE[~TYPEL[~TYP[2]]]+:~SIZE[~TYPEL[~TYP[2]]]];~ELSE ~FI wire ~TYPO ~GENSYM[foldr_in2][6]; ~OUTPUTUSAGE[0] ~TYPO ~GENSYM[foldr_out][7];
prims/verilog/Clash_Xilinx_DDR.primitives.yaml view
@@ -3,37 +3,40 @@ kind: Declaration type: |- iddr#- :: ( HasCallStack -- ARG[0]- , KnownConfi~ fast domf -- ARG[1]- , KnownConfi~ slow doms -- ARG[2]- , KnownNat m ) -- ARG[3]- -> Clock slow -- ARG[4]- -> Reset slow -- ARG[5]- -> Enable slow -- ARG[6]- -> Signal fast (BitVector m) -- ARG[7]- -> Signal slow (BitVector m,BitVector m)+ :: forall n dom domDDR+ . HasCallStack -- ARG[0]+ => KnownDomain dom -- ARG[1]+ => KnownDomain domDDR -- ARG[2]+ => DomPeriod ~ 2 * ... -- ARG[3]+ => DomEdge ~ Rising -- ARG[4]+ => KnownNat n -- ARG[5]+ => Clock dom -- ARG[6]+ -> Reset dom -- ARG[7]+ -> Enable dom -- ARG[8]+ -> Signal domDDR (BitVector n) -- ARG[9]+ -> Signal dom (BitVector n, BitVector n) template: |- // iddr begin- 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];+ wire ~SIGD[~GENSYM[data_pos][1]][9];+ wire ~SIGD[~GENSYM[data_neg][2]][9];+ wire ~SIGD[~GENSYM[d][3]][9];+ assign ~SYM[3] = ~ARG[9]; genvar ~GENSYM[i][8]; ~GENERATE- for (~SYM[8]=0; ~SYM[8] < ~SIZE[~TYP[7]]; ~SYM[8]=~SYM[8]+1) begin : ~GENSYM[ddri_array][7]+ for (~SYM[8]=0; ~SYM[8] < ~SIZE[~TYP[9]]; ~SYM[8]=~SYM[8]+1) begin : ~GENSYM[ddri_array][7] IDDR #( .DDR_CLK_EDGE("SAME_EDGE"), .INIT_Q1(1'b0), .INIT_Q2(1'b0),- .SRTYPE(~IF ~ISSYNC[2] ~THEN "SYNC" ~ELSE "ASYNC" ~FI)+ .SRTYPE(~IF ~ISSYNC[1] ~THEN "SYNC" ~ELSE "ASYNC" ~FI) ) ~GENSYM[~COMPNAME_IDDR][9] ( .Q1(~SYM[1][~SYM[8]]), .Q2(~SYM[2][~SYM[8]]),- .C(~ARG[4]),- .CE(~IF ~ISACTIVEENABLE[6] ~THEN ~ARG[6] ~ELSE 1'b1 ~FI),+ .C(~ARG[6]),+ .CE(~IF ~ISACTIVEENABLE[8] ~THEN ~ARG[8] ~ELSE 1'b1 ~FI), .D(~SYM[3][~SYM[8]]),- .R(~ARG[5]),+ .R(~ARG[7]), .S(1'b0) ); end@@ -46,38 +49,42 @@ kind: Declaration type: |- oddr#- :: ( KnownConfi~ fast domf -- ARG[0]- , KnownConfi~ slow doms -- ARG[1]- , KnownNat m ) -- ARG[2]- => Clock slow -- ARG[3]- -> Reset slow -- ARG[4]- -> Enable slow -- ARG[5]- -> Signal slow (BitVector m) -- ARG[6]- -> Signal slow (BitVector m) -- ARG[7]- -> Signal fast (BitVector m)+ :: forall n dom domDDR+ . HasCallStack -- ARG[0]+ => KnownDomain dom -- ARG[1]+ => KnownDomain domDDR -- ARG[2]+ => DomPeriod ~ 2 * ... -- ARG[3]+ => DomEdge ~ Rising -- ARG[4]+ => KnownNat n -- ARG[5]+ => Clock dom -- ARG[6]+ -> Reset dom -- ARG[7]+ -> Enable dom -- ARG[8]+ -> Signal dom (BitVector n) -- ARG[9]+ -> Signal dom (BitVector n) -- ARG[10]+ -> Signal domDDR (BitVector n) template: |- // oddr begin- wire ~SIGD[~GENSYM[data_pos][1]][7];- wire ~SIGD[~GENSYM[data_neg][2]][7];- wire ~SIGD[~GENSYM[q][3]][7];+ wire ~SIGD[~GENSYM[data_pos][1]][10];+ wire ~SIGD[~GENSYM[data_neg][2]][10];+ wire ~SIGD[~GENSYM[q][3]][10]; - assign ~SYM[1] = ~ARG[6];- assign ~SYM[2] = ~ARG[7];+ assign ~SYM[1] = ~ARG[9];+ assign ~SYM[2] = ~ARG[10]; genvar ~GENSYM[i][8]; ~GENERATE- for (~SYM[8]=0; ~SYM[8] < ~SIZE[~TYP[7]]; ~SYM[8]=~SYM[8]+1) begin : ~GENSYM[ddro_array][7]+ for (~SYM[8]=0; ~SYM[8] < ~SIZE[~TYP[10]]; ~SYM[8]=~SYM[8]+1) begin : ~GENSYM[ddro_array][7] ODDR #( .DDR_CLK_EDGE("SAME_EDGE"), .INIT(1'b0), .SRTYPE(~IF ~ISSYNC[1] ~THEN "SYNC" ~ELSE "ASYNC" ~FI) ) ~GENSYM[~COMPNAME_ODDR][9] ( .Q(~SYM[3][~SYM[8]]),- .C(~ARG[3]),- .CE(~IF ~ISACTIVEENABLE[5] ~THEN ~ARG[5] ~ELSE 1'b1 ~FI),+ .C(~ARG[6]),+ .CE(~IF ~ISACTIVEENABLE[8] ~THEN ~ARG[8] ~ELSE 1'b1 ~FI), .D1(~SYM[1][~SYM[8]]), .D2(~SYM[2][~SYM[8]]),- .R(~ARG[4]),+ .R(~ARG[7]), .S(1'b0) ); end
prims/vhdl/Clash_Class_BitPack.primitives.yaml view
@@ -5,8 +5,128 @@ template: std_logic_vector(~ARG[0]) workInfo: Never - BlackBox:+ name: Clash.Class.BitPack.Internal.packInt8#+ kind: Expression+ type: 'packInt8# :: Int8 -> Bitvector 8'+ template: std_logic_vector(~ARG[0])+ workInfo: Never+- BlackBox:+ name: Clash.Class.BitPack.Internal.packInt16#+ kind: Expression+ type: 'packInt16# :: Int16 -> Bitvector 16'+ template: std_logic_vector(~ARG[0])+ workInfo: Never+- BlackBox:+ name: Clash.Class.BitPack.Internal.packInt32#+ kind: Expression+ type: 'packInt32# :: Int32 -> Bitvector 32'+ template: std_logic_vector(~ARG[0])+ workInfo: Never+- BlackBox:+ name: Clash.Class.BitPack.Internal.packInt64#+ kind: Expression+ type: 'packInt64# :: Int64 -> Bitvector 64'+ template: std_logic_vector(~ARG[0])+ workInfo: Never+- BlackBox:+ name: Clash.Class.BitPack.Internal.packWord#+ kind: Expression+ type: 'packWord# :: Word -> Bitvector WORD_SIZE_IN_BITS'+ template: std_logic_vector(~ARG[0])+ workInfo: Never+- BlackBox:+ name: Clash.Class.BitPack.Internal.packWord8#+ kind: Expression+ type: 'packWord8# :: Word8 -> Bitvector 8'+ template: std_logic_vector(~ARG[0])+ workInfo: Never+- BlackBox:+ name: Clash.Class.BitPack.Internal.packWord16#+ kind: Expression+ type: 'packWord16# :: Word16 -> Bitvector 16'+ template: std_logic_vector(~ARG[0])+ workInfo: Never+- BlackBox:+ name: Clash.Class.BitPack.Internal.packWord32#+ kind: Expression+ type: 'packWord32# :: Word32 -> Bitvector 32'+ template: std_logic_vector(~ARG[0])+ workInfo: Never+- BlackBox:+ name: Clash.Class.BitPack.Internal.packWord64#+ kind: Expression+ type: 'packWord64# :: Word64 -> Bitvector 64'+ template: std_logic_vector(~ARG[0])+ workInfo: Never+- BlackBox:+ name: Clash.Class.BitPack.Internal.packCUShort#+ kind: Expression+ type: 'packCUShort# :: CUShort -> Bitvector 16'+ 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+- BlackBox:+ name: Clash.Class.BitPack.Internal.unpackInt8#+ kind: Expression+ type: 'unpackInt8# :: Bitvector 8 -> Int8'+ template: signed(~ARG[0])+ workInfo: Never+- BlackBox:+ name: Clash.Class.BitPack.Internal.unpackInt16#+ kind: Expression+ type: 'unpackInt16# :: Bitvector 16 -> Int16'+ template: signed(~ARG[0])+ workInfo: Never+- BlackBox:+ name: Clash.Class.BitPack.Internal.unpackInt32#+ kind: Expression+ type: 'unpackInt32# :: Bitvector 32 -> Int32'+ template: signed(~ARG[0])+ workInfo: Never+- BlackBox:+ name: Clash.Class.BitPack.Internal.unpackInt64#+ kind: Expression+ type: 'unpackInt64# :: Bitvector 64 -> Int64'+ template: signed(~ARG[0])+ workInfo: Never+- BlackBox:+ name: Clash.Class.BitPack.Internal.unpackWord#+ kind: Expression+ type: 'unpackWord# :: Bitvector WORD_SIZE_IN_BITS -> Word'+ template: unsigned(~ARG[0])+ workInfo: Never+- BlackBox:+ name: Clash.Class.BitPack.Internal.unpackWord8#+ kind: Expression+ type: 'unpackWord8# :: Bitvector 8 -> Word8'+ template: unsigned(~ARG[0])+ workInfo: Never+- BlackBox:+ name: Clash.Class.BitPack.Internal.unpackWord16#+ kind: Expression+ type: 'unpackWord16# :: Bitvector 16 -> Word16'+ template: unsigned(~ARG[0])+ workInfo: Never+- BlackBox:+ name: Clash.Class.BitPack.Internal.unpackWord32#+ kind: Expression+ type: 'unpackWord32# :: Bitvector 32 -> Word32'+ template: unsigned(~ARG[0])+ workInfo: Never+- BlackBox:+ name: Clash.Class.BitPack.Internal.unpackWord64#+ kind: Expression+ type: 'unpackWord64# :: Bitvector 64 -> Word64'+ template: unsigned(~ARG[0])+ workInfo: Never+- BlackBox:+ name: Clash.Class.BitPack.Internal.unpackCUShort#+ kind: Expression+ type: 'unpackCUShort# :: Bitvector 16 -> CUShort' template: unsigned(~ARG[0]) workInfo: Never
prims/vhdl/Clash_Explicit_DDR.primitives.yaml view
@@ -2,57 +2,58 @@ name: Clash.Explicit.DDR.ddrIn# kind: Declaration type: |-- ddrIn# :: forall a slow fast n pFast enabled synchronous.- ( HasCallStack -- ARG[0]- , NFDataX a -- ARG[1]- , KnownConfi~ fast domf -- ARG[2]- , KnownConfi~ slow doms -- ARG[3]- => Clock slow -- ARG[4]- -> Reset slow -- ARG[5]- -> Enable slow -- ARG[6]- -> a -- ARG[7]- -> a -- ARG[8]- -> a -- ARG[9]- -> Signal fast a -- ARG[10]- -> Signal slow (a,a)+ ddrIn# :: forall a dom domDDR+ . HasCallStack -- ARG[0]+ => NFDataX a -- ARG[1]+ => KnownDomain dom -- ARG[2]+ => KnownDomain domDDR -- ARG[3]+ => DomPeriod ~ 2 * ... -- ARG[4]+ => Clock dom -- ARG[5]+ -> Reset dom -- ARG[6]+ -> Enable dom -- ARG[7]+ -> a -- ARG[8]+ -> a -- ARG[9]+ -> a -- ARG[10]+ -> Signal domDDR a -- ARG[11]+ -> Signal dom (a,a) template: |- -- ddrIn begin ~GENSYM[~COMPNAME_ddrIn][0] : block- signal ~GENSYM[data_Pos][1] : ~TYP[9];- signal ~GENSYM[data_Neg][2] : ~TYP[9];- signal ~GENSYM[data_Neg_Latch][3] : ~TYP[9];+ signal ~GENSYM[data_Pos][1] : ~TYP[11];+ signal ~GENSYM[data_Neg][2] : ~TYP[11];+ signal ~GENSYM[data_Neg_Latch][3] : ~TYP[11]; begin- ~IF ~ISSYNC[3] ~THEN+ ~IF ~ISSYNC[2] ~THEN -- sync -------------- ~GENSYM[~COMPNAME_ddrIn_pos][6] : process(~ARG[4])+ ~GENSYM[~COMPNAME_ddrIn_pos][6] : process(~ARG[5]) begin- if ~IF~ACTIVEEDGE[Rising][2]~THENrising_edge~ELSEfalling_edge~FI(~ARG[4]) then- if ~ARG[5] = ~IF~ISACTIVEHIGH[2]~THEN'1'~ELSE'0'~FI then- ~SYM[1] <= ~ARG[8];- els~IF ~ISACTIVEENABLE[6] ~THENif ~ARG[6] then~ELSEe~FI- ~SYM[1] <= ~ARG[10];+ if ~IF~ACTIVEEDGE[Rising][2]~THENrising_edge~ELSEfalling_edge~FI(~ARG[5]) then+ if ~ARG[6] = ~IF~ISACTIVEHIGH[2]~THEN'1'~ELSE'0'~FI then+ ~SYM[1] <= ~ARG[9];+ els~IF ~ISACTIVEENABLE[7] ~THENif ~ARG[7] then~ELSEe~FI+ ~SYM[1] <= ~ARG[11]; end if; end if; end process; - ~GENSYM[~COMPNAME_ddrIn_neg][7] : process(~ARG[4])+ ~GENSYM[~COMPNAME_ddrIn_neg][7] : process(~ARG[5]) begin- if ~IF~ACTIVEEDGE[Rising][2]~THENfalling_edge~ELSErising_edge~FI(~ARG[4]) then- if ~ARG[5] = ~IF~ISACTIVEHIGH[2]~THEN'1'~ELSE'0'~FI then- ~SYM[2] <= ~ARG[9];- els~IF ~ISACTIVEENABLE[6] ~THENif ~ARG[6] then~ELSEe~FI+ if ~IF~ACTIVEEDGE[Rising][2]~THENfalling_edge~ELSErising_edge~FI(~ARG[5]) then+ if ~ARG[6] = ~IF~ISACTIVEHIGH[2]~THEN'1'~ELSE'0'~FI then ~SYM[2] <= ~ARG[10];+ els~IF ~ISACTIVEENABLE[7] ~THENif ~ARG[7] then~ELSEe~FI+ ~SYM[2] <= ~ARG[11]; end if; end if; end process; - ~GENSYM[~COMPNAME_ddrIn_neg_latch][8] : process(~ARG[4])+ ~GENSYM[~COMPNAME_ddrIn_neg_latch][8] : process(~ARG[5]) begin- if ~IF~ACTIVEEDGE[Rising][2]~THENrising_edge~ELSEfalling_edge~FI(~ARG[4]) then- if ~ARG[5] = ~IF~ISACTIVEHIGH[2]~THEN'1'~ELSE'0'~FI then- ~SYM[3] <= ~ARG[7];- els~IF ~ISACTIVEENABLE[6] ~THENif ~ARG[6] then~ELSEe~FI+ if ~IF~ACTIVEEDGE[Rising][2]~THENrising_edge~ELSEfalling_edge~FI(~ARG[5]) then+ if ~ARG[6] = ~IF~ISACTIVEHIGH[2]~THEN'1'~ELSE'0'~FI then+ ~SYM[3] <= ~ARG[8];+ els~IF ~ISACTIVEENABLE[7] ~THENif ~ARG[7] then~ELSEe~FI ~SYM[3] <= ~SYM[2]; end if; end if;@@ -60,29 +61,29 @@ ~ELSE -- async --------------- ~SYM[6] : process(~ARG[4],~ARG[5])+ ~SYM[6] : process(~ARG[5],~ARG[6]) begin- if ~ARG[5] = ~IF~ISACTIVEHIGH[2]~THEN'1'~ELSE'0'~FI then- ~SYM[1] <= ~ARG[8];- 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[10];+ if ~ARG[6] = ~IF~ISACTIVEHIGH[2]~THEN'1'~ELSE'0'~FI then+ ~SYM[1] <= ~ARG[9];+ elsif ~IF ~ISACTIVEENABLE[7] ~THEN ~ARG[7] and ~ELSE ~FI ~IF~ACTIVEEDGE[Rising][2]~THENrising_edge~ELSEfalling_edge~FI(~ARG[5]) then+ ~SYM[1] <= ~ARG[11]; end if; end process; - ~SYM[7] : process(~ARG[4],~ARG[5])+ ~SYM[7] : process(~ARG[5],~ARG[6]) begin- if ~ARG[5] = ~IF~ISACTIVEHIGH[2]~THEN'1'~ELSE'0'~FI then- ~SYM[2] <= ~ARG[9];- elsif ~IF ~ISACTIVEENABLE[6] ~THEN ~ARG[6] and ~ELSE ~FI ~IF~ACTIVEEDGE[Rising][2]~THENfalling_edge~ELSErising_edge~FI(~ARG[4]) then+ if ~ARG[6] = ~IF~ISACTIVEHIGH[2]~THEN'1'~ELSE'0'~FI then ~SYM[2] <= ~ARG[10];+ elsif ~IF ~ISACTIVEENABLE[7] ~THEN ~ARG[7] and ~ELSE ~FI ~IF~ACTIVEEDGE[Rising][2]~THENfalling_edge~ELSErising_edge~FI(~ARG[5]) then+ ~SYM[2] <= ~ARG[11]; end if; end process; - ~SYM[8] : process(~ARG[4],~ARG[5])+ ~SYM[8] : process(~ARG[5],~ARG[6]) begin- if ~ARG[5] = ~IF~ISACTIVEHIGH[2]~THEN'1'~ELSE'0'~FI then- ~SYM[3] <= ~ARG[7];- elsif ~IF ~ISACTIVEENABLE[6] ~THEN ~ARG[6] and ~ELSE ~FI ~IF~ACTIVEEDGE[Rising][2]~THENrising_edge~ELSEfalling_edge~FI(~ARG[4]) then+ if ~ARG[6] = ~IF~ISACTIVEHIGH[2]~THEN'1'~ELSE'0'~FI then+ ~SYM[3] <= ~ARG[8];+ elsif ~IF ~ISACTIVEENABLE[7] ~THEN ~ARG[7] and ~ELSE ~FI ~IF~ACTIVEEDGE[Rising][2]~THENrising_edge~ELSEfalling_edge~FI(~ARG[5]) then ~SYM[3] <= ~SYM[2]; end if; end process;@@ -94,68 +95,70 @@ name: Clash.Explicit.DDR.ddrOut# kind: Declaration type: |-- ddrOut# :: ( HasCallStack -- ARG[0]- , NFDataX a -- ARG[1]- , KnownConfi~ fast domf -- ARG[2]- , KnownConfi~ slow doms -- ARG[3]- => Clock slow -- ARG[4]- -> Reset slow -- ARG[5]- -> Enable slow -- ARG[6]- -> a -- ARG[7]- -> Signal slow a -- ARG[8]- -> Signal slow a -- ARG[9]- -> Signal fast a+ ddrOut# :: forall a dom domDDR+ . HasCallStack -- ARG[0]+ => NFDataX a -- ARG[1]+ => KnownDomain dom -- ARG[2]+ => KnownDomain domDDR -- ARG[3]+ => DomPeriod ~ 2 * ... -- ARG[4]+ => Clock dom -- ARG[5]+ -> Reset dom -- ARG[6]+ -> Enable dom -- ARG[7]+ -> a -- ARG[8]+ -> Signal dom a -- ARG[9]+ -> Signal dom a -- ARG[10]+ -> Signal domDDR a template: |- -- ddrOut begin ~GENSYM[~COMPNAME_ddrOut][0] : block- signal ~GENSYM[data_Pos][1] : ~TYP[7];- signal ~GENSYM[data_Neg][2] : ~TYP[7];+ signal ~GENSYM[data_Pos][1] : ~TYP[8];+ signal ~GENSYM[data_Neg][2] : ~TYP[8]; begin- ~IF ~ISSYNC[3] ~THEN+ ~IF ~ISSYNC[2] ~THEN -- sync -------------- ~GENSYM[~COMPNAME_ddrOut_pos][5] : process(~ARG[4])+ ~GENSYM[~COMPNAME_ddrOut_pos][5] : process(~ARG[5]) begin- if ~IF~ACTIVEEDGE[Rising][2]~THENrising_edge~ELSEfalling_edge~FI(~ARG[4]) then- if ~ARG[5] = ~IF~ISACTIVEHIGH[2]~THEN'1'~ELSE'0'~FI then- ~SYM[1] <= ~ARG[7];- els~IF ~ISACTIVEENABLE[6] ~THENif ~ARG[6] then~ELSEe~FI+ if ~IF~ACTIVEEDGE[Rising][2]~THENrising_edge~ELSEfalling_edge~FI(~ARG[5]) then+ if ~ARG[6] = ~IF~ISACTIVEHIGH[2]~THEN'1'~ELSE'0'~FI then ~SYM[1] <= ~ARG[8];+ els~IF ~ISACTIVEENABLE[7] ~THENif ~ARG[7] then~ELSEe~FI+ ~SYM[1] <= ~ARG[9]; end if; end if; end process; - ~GENSYM[~COMPNAME_ddrOut_neg][6] : process(~ARG[4])+ ~GENSYM[~COMPNAME_ddrOut_neg][6] : process(~ARG[5]) begin- if ~IF~ACTIVEEDGE[Rising][2]~THENrising_edge~ELSEfalling_edge~FI(~ARG[4]) then- if ~ARG[5] = ~IF~ISACTIVEHIGH[2]~THEN'1'~ELSE'0'~FI then- ~SYM[2] <= ~ARG[7];- els~IF ~ISACTIVEENABLE[6] ~THENif ~ARG[6] then~ELSEe~FI- ~SYM[2] <= ~ARG[9];+ if ~IF~ACTIVEEDGE[Rising][2]~THENrising_edge~ELSEfalling_edge~FI(~ARG[5]) then+ if ~ARG[6] = ~IF~ISACTIVEHIGH[2]~THEN'1'~ELSE'0'~FI then+ ~SYM[2] <= ~ARG[8];+ els~IF ~ISACTIVEENABLE[7] ~THENif ~ARG[7] then~ELSEe~FI+ ~SYM[2] <= ~ARG[10]; end if; end if; end process; ~ELSE -- async --------------- ~SYM[5] : process(~ARG[4],~ARG[5]~VARS[8])+ ~SYM[5] : process(~ARG[5],~ARG[6]~VARS[9]) begin- if ~ARG[5] = ~IF~ISACTIVEHIGH[2]~THEN'1'~ELSE'0'~FI then- ~SYM[1] <= ~ARG[7];- elsif ~IF ~ISACTIVEENABLE[6] ~THEN ~ARG[6] and ~ELSE ~FI ~IF~ACTIVEEDGE[Rising][2]~THENrising_edge~ELSEfalling_edge~FI(~ARG[4]) then+ if ~ARG[6] = ~IF~ISACTIVEHIGH[2]~THEN'1'~ELSE'0'~FI then ~SYM[1] <= ~ARG[8];+ elsif ~IF ~ISACTIVEENABLE[7] ~THEN ~ARG[7] and ~ELSE ~FI ~IF~ACTIVEEDGE[Rising][2]~THENrising_edge~ELSEfalling_edge~FI(~ARG[5]) then+ ~SYM[1] <= ~ARG[9]; end if; end process; - ~SYM[6] : process(~ARG[4],~ARG[5]~VARS[9])+ ~SYM[6] : process(~ARG[5],~ARG[6]~VARS[10]) begin- if ~ARG[5] = ~IF~ISACTIVEHIGH[2]~THEN'1'~ELSE'0'~FI then- ~SYM[2] <= ~ARG[7];- 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];+ if ~ARG[6] = ~IF~ISACTIVEHIGH[2]~THEN'1'~ELSE'0'~FI then+ ~SYM[2] <= ~ARG[8];+ elsif ~IF ~ISACTIVEENABLE[7] ~THEN ~ARG[7] and ~ELSE ~FI ~IF~ACTIVEEDGE[Rising][2]~THENrising_edge~ELSEfalling_edge~FI(~ARG[5]) then+ ~SYM[2] <= ~ARG[10]; end if; end process; ~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;+ ~RESULT <= ~IF~ACTIVEEDGE[Rising][2]~THEN~SYM[1]~ELSE~SYM[2]~FI when (~ARG[5] = '1') else ~IF~ACTIVEEDGE[Rising][2]~THEN~SYM[2]~ELSE~SYM[1]~FI; end block; -- ddrOut end
prims/vhdl/Clash_Intel_DDR.primitives.yaml view
@@ -7,39 +7,42 @@ - altera_mf type: |- altddioIn#- :: ( HasCallStack -- ARG[0]- , KnownConfi~ fast domf -- ARG[1]- , KnownConfi~ slow doms -- ARG[2]- , KnownNat m ) -- ARG[3]- => SSymbol deviceFamily -- ARG[4]- -> Clock slow -- ARG[5]- -> Reset slow -- ARG[6]- -> Enable slow -- ARG[7]- -> Signal fast (BitVector m) -- ARG[8]- -> Signal slow (BitVector m,BitVector m)+ :: forall deviceFamily n dom domDDR+ . HasCallStack -- ARG[0]+ => KnownDomain dom -- ARG[1]+ => KnownDomain domDDR -- ARG[2]+ => DomPeriod ~ 2 * ... -- ARG[3]+ => DomEdge ~ Rising -- ARG[4]+ => KnownNat n -- ARG[5]+ => SSymbol deviceFamily -- ARG[6]+ -> Clock dom -- ARG[7]+ -> Reset dom -- ARG[8]+ -> Enable dom -- ARG[9]+ -> Signal domDDR (BitVector n) -- ARG[10]+ -> Signal dom (BitVector n, BitVector n) template: |- -- altddioIn begin ~GENSYM[~COMPNAME_ALTDDIO_IN][0] : block- signal ~GENSYM[dataout_l][1] : ~TYP[8];- signal ~GENSYM[dataout_h][2] : ~TYP[8];~IF ~ISACTIVEENABLE[7] ~THEN+ signal ~GENSYM[dataout_l][1] : ~TYP[10];+ signal ~GENSYM[dataout_h][2] : ~TYP[10];~IF ~ISACTIVEENABLE[9] ~THEN signal ~GENSYM[ce_logic][4]: std_logic;~ELSE ~FI- begin~IF ~ISACTIVEENABLE[7] ~THEN- ~SYM[4] <= '1' when (~ARG[7]) else '0';~ELSE ~FI+ begin~IF ~ISACTIVEENABLE[9] ~THEN+ ~SYM[4] <= '1' when (~ARG[9]) else '0';~ELSE ~FI ~GENSYM[~COMPNAME_ALTDDIO_IN][7] : ALTDDIO_IN GENERIC MAP (- intended_device_family => ~LIT[4],+ intended_device_family => ~LIT[6], invert_input_clocks => "OFF", lpm_hint => "UNUSED", lpm_type => "altddio_in", power_up_high => "OFF",- width => ~SIZE[~TYP[8]]+ width => ~SIZE[~TYP[10]] )- PORT MAP (~IF ~ISSYNC[6] ~THEN- sclr => ~ARG[6],~ELSE- aclr => ~ARG[6],~FI- datain => ~ARG[8],~IF ~ISACTIVEENABLE[7] ~THEN+ PORT MAP (~IF ~ISSYNC[1] ~THEN+ sclr => ~ARG[8],~ELSE+ aclr => ~ARG[8],~FI+ datain => ~ARG[10],~IF ~ISACTIVEENABLE[9] ~THEN inclocken => ~SYM[4],~ELSE ~FI- inclock => ~ARG[5],+ inclock => ~ARG[7], dataout_h => ~SYM[2], dataout_l => ~SYM[1] );@@ -55,27 +58,30 @@ - altera_mf type: |- altddioOut#- :: ( HasCallStack -- ARG[0]- , KnownConfi~ fast domf -- ARG[1]- , KnownConfi~ slow doms -- ARG[2]- , KnownNat m ) -- ARG[3]- => SSymbol deviceFamily -- ARG[4]- -> Clock slow -- ARG[5]- -> Reset slow -- ARG[6]- -> Enable slow -- ARG[7]- -> Signal slow (BitVector m) -- ARG[8]- -> Signal slow (BitVector m) -- ARG[9]- -> Signal fast (BitVector m)+ :: forall deviceFamily n dom domDDR+ . HasCallStack -- ARG[0]+ => KnownDomain dom -- ARG[1]+ => KnownDomain domDDR -- ARG[2]+ => DomPeriod ~ 2 * ... -- ARG[3]+ => DomEdge ~ Rising -- ARG[4]+ => KnownNat n -- ARG[5]+ => SSymbol deviceFamily -- ARG[6]+ -> Clock dom -- ARG[7]+ -> Reset dom -- ARG[8]+ -> Enable dom -- ARG[9]+ -> Signal dom (BitVector n) -- ARG[10]+ -> Signal dom (BitVector n) -- ARG[11]+ -> Signal domDDR (BitVector n) template: |- -- altddioOut begin- ~GENSYM[~COMPNAME_ALTDDIO_OUT][0] : block ~IF ~ISACTIVEENABLE[7] ~THEN+ ~GENSYM[~COMPNAME_ALTDDIO_OUT][0] : block ~IF ~ISACTIVEENABLE[9] ~THEN signal ~GENSYM[ce_logic][1] : std_logic; ~ELSE ~FI- begin~IF ~ISACTIVEENABLE[7] ~THEN- ~SYM[1] <= '1' when (~ARG[7]) else '0'; ~ELSE ~FI+ begin~IF ~ISACTIVEENABLE[9] ~THEN+ ~SYM[1] <= '1' when (~ARG[9]) else '0'; ~ELSE ~FI ~GENSYM[~COMPNAME_ALTDDIO_OUT][7] : ALTDDIO_OUT GENERIC MAP ( extend_oe_disable => "OFF",- intended_device_family => ~LIT[4],+ intended_device_family => ~LIT[6], invert_output => "OFF", lpm_hint => "UNUSED", lpm_type => "altddio_out",@@ -83,13 +89,13 @@ power_up_high => "OFF", width => ~SIZE[~TYPO] )- PORT MAP (~IF ~ISSYNC[2] ~THEN- sclr => ~ARG[6],~ELSE- aclr => ~ARG[6],~FI ~IF ~ISACTIVEENABLE[7] ~THEN+ PORT MAP (~IF ~ISSYNC[1] ~THEN+ sclr => ~ARG[8],~ELSE+ aclr => ~ARG[8],~FI ~IF ~ISACTIVEENABLE[9] ~THEN outclocken => ~SYM[1],~ELSE ~FI- outclock => ~ARG[5],- datain_h => ~ARG[8],- datain_l => ~ARG[9],+ outclock => ~ARG[7],+ datain_h => ~ARG[10],+ datain_l => ~ARG[11], dataout => ~RESULT ); end block;
prims/vhdl/Clash_Sized_Internal_Index.primitives.yaml view
@@ -1,16 +1,16 @@ - BlackBox: name: Clash.Sized.Internal.Index.pack# kind: Expression- type: 'pack# :: Index- n -> BitVector (CLog 2 n)'+ type: |-+ pack# :: Index n -> BitVector (CLogWZ 2 n 0) template: std_logic_vector(~ARG[0]) workInfo: Never - BlackBox: name: Clash.Sized.Internal.Index.unpack# kind: Expression- type: 'unpack# :: (KnownNat- n, 1 <= n) => BitVector (CLog 2 n) -> Index n'- template: unsigned(~ARG[2])+ type: |-+ unpack# :: KnownNat n => BitVector (CLogWZ 2 n 0) -> Index n+ template: unsigned(~ARG[1]) workInfo: Never - BlackBox: name: Clash.Sized.Internal.Index.eq#
prims/vhdl/Clash_Xilinx_DDR.primitives.yaml view
@@ -7,25 +7,28 @@ - UNISIM type: |- iddr#- :: ( HasCallStack -- ARG[0]- , KnownConfi~ fast domf -- ARG[1]- , KnownConfi~ slow doms -- ARG[2]- , KnownNat m ) -- ARG[3]- -> Clock slow -- ARG[4]- -> Reset slow -- ARG[5]- -> Enable slow -- ARG[6]- -> Signal fast (BitVector m) -- ARG[7]- -> Signal slow (BitVector m,BitVector m)+ :: forall n dom domDDR+ . HasCallStack -- ARG[0]+ => KnownDomain dom -- ARG[1]+ => KnownDomain domDDR -- ARG[2]+ => DomPeriod ~ 2 * ... -- ARG[3]+ => DomEdge ~ Rising -- ARG[4]+ => KnownNat n -- ARG[5]+ => Clock dom -- ARG[6]+ -> Reset dom -- ARG[7]+ -> Enable dom -- ARG[8]+ -> Signal domDDR (BitVector n) -- ARG[9]+ -> Signal dom (BitVector n, BitVector n) template: |- -- iddr begin ~GENSYM[~COMPNAME_IDDR][0] : block- 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[data_pos][1] : ~TYP[9];+ signal ~GENSYM[data_neg][2] : ~TYP[9];+ signal ~GENSYM[d][3] : ~TYP[9];~IF ~ISACTIVEENABLE[8] ~THEN signal ~GENSYM[ce_logic][4]: std_logic;~ELSE ~FI- begin~IF ~ISACTIVEENABLE[6] ~THEN- ~SYM[4] <= '1' when (~ARG[6]) else '0';~ELSE ~FI- ~SYM[3] <= ~ARG[7];+ begin~IF ~ISACTIVEENABLE[8] ~THEN+ ~SYM[4] <= '1' when (~ARG[8]) else '0';~ELSE ~FI+ ~SYM[3] <= ~ARG[9]; ~GENSYM[gen_iddr][7] : for ~GENSYM[i][8] in ~SYM[3]'range generate begin@@ -34,14 +37,14 @@ DDR_CLK_EDGE => "SAME_EDGE", INIT_Q1 => '0', INIT_Q2 => '0',- SRTYPE => ~IF ~ISSYNC[2] ~THEN "SYNC" ~ELSE "ASYNC" ~FI)+ SRTYPE => ~IF ~ISSYNC[1] ~THEN "SYNC" ~ELSE "ASYNC" ~FI) port map ( Q1 => ~SYM[1](~SYM[8]), -- 1-bit output for positive edge of clock Q2 => ~SYM[2](~SYM[8]), -- 1-bit output for negative edge of clock- C => ~ARG[4], -- 1-bit clock input- CE => ~IF ~ISACTIVEENABLE[6] ~THEN ~SYM[4] ~ELSE '1' ~FI, -- 1-bit clock enable input+ C => ~ARG[6], -- 1-bit clock input+ CE => ~IF ~ISACTIVEENABLE[8] ~THEN ~SYM[4] ~ELSE '1' ~FI, -- 1-bit clock enable input D => ~SYM[3](~SYM[8]), -- 1-bit DDR data input- R => ~ARG[5], -- 1-bit reset+ R => ~ARG[7], -- 1-bit reset S => '0' -- 1-bit set ); end generate;@@ -58,26 +61,30 @@ - UNISIM type: |- oddr#- :: ( KnownConfi~ fast domf -- ARG[0]- , KnownConfi~ slow doms -- ARG[1]- , KnownNat m ) -- ARG[2]- => Clock slow -- ARG[3]- -> Reset slow -- ARG[4]- -> Enable slow -- ARG[5]- -> Signal slow (BitVector m) -- ARG[6]- -> Signal slow (BitVector m) -- ARG[7]- -> Signal fast (BitVector m)+ :: forall n dom domDDR+ . HasCallStack -- ARG[0]+ => KnownDomain dom -- ARG[1]+ => KnownDomain domDDR -- ARG[2]+ => DomPeriod ~ 2 * ... -- ARG[3]+ => DomEdge ~ Rising -- ARG[4]+ => KnownNat n -- ARG[5]+ => Clock dom -- ARG[6]+ -> Reset dom -- ARG[7]+ -> Enable dom -- ARG[8]+ -> Signal dom (BitVector n) -- ARG[9]+ -> Signal dom (BitVector n) -- ARG[10]+ -> Signal domDDR (BitVector n) template: |- -- oddr begin ~GENSYM[~COMPNAME_ODDR][0] : block signal ~GENSYM[data_pos][1] : ~TYPO; signal ~GENSYM[data_neg][2] : ~TYPO;- signal ~GENSYM[q][3] : ~TYPO;~IF ~ISACTIVEENABLE[5] ~THEN+ signal ~GENSYM[q][3] : ~TYPO;~IF ~ISACTIVEENABLE[8] ~THEN signal ~GENSYM[ce_logic][4] : std_logic;~ELSE ~FI- begin~IF ~ISACTIVEENABLE[5] ~THEN- ~SYM[4] <= '1' when (~ARG[5]) else '0';~ELSE ~FI- ~SYM[1] <= ~ARG[6];- ~SYM[2] <= ~ARG[7];+ begin~IF ~ISACTIVEENABLE[8] ~THEN+ ~SYM[4] <= '1' when (~ARG[8]) else '0';~ELSE ~FI+ ~SYM[1] <= ~ARG[9];+ ~SYM[2] <= ~ARG[10]; ~GENSYM[gen_oddr][7] : for ~GENSYM[i][8] in ~SYM[3]'range generate begin@@ -88,11 +95,11 @@ 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- CE => ~IF ~ISACTIVEENABLE[5] ~THEN ~SYM[4] ~ELSE '1' ~FI, -- 1-bit clock enable input+ C => ~ARG[6], -- 1-bit clock input+ CE => ~IF ~ISACTIVEENABLE[8] ~THEN ~SYM[4] ~ELSE '1' ~FI, -- 1-bit clock enable input D1 => ~SYM[1](~SYM[8]), -- 1-bit data input (positive edge) D2 => ~SYM[2](~SYM[8]), -- 1-bit data input (negative edge)- R => ~ARG[4], -- 1-bit reset input+ R => ~ARG[7], -- 1-bit reset input S => '0' -- 1-bit set input ); end generate;
src/Clash/Backend.hs view
@@ -21,11 +21,7 @@ import Control.Monad.State (State) import Data.Text.Prettyprint.Doc.Extra (Doc) -#if MIN_VERSION_ghc(9,0,0) import GHC.Types.SrcLoc (SrcSpan)-#else-import SrcLoc (SrcSpan)-#endif import Clash.Driver.Types (ClashOpts) import {-# SOURCE #-} Clash.Netlist.Types
src/Clash/Backend/SystemVerilog.hs view
@@ -238,14 +238,17 @@ where cName = componentName c verilog = commentHeader <> line <>- nettype <> line <>+ nettypeNone <> line <> timescale <> line <>- module_ c+ module_ c <> line <>+ nettypeDefault+ commentHeader = "/* AUTOMATICALLY GENERATED SYSTEMVERILOG-2005 SOURCE CODE." <> line <> "** GENERATED BY CLASH " <> string (Text.pack clashVer) <> ". DO NOT MODIFY." <> line <> "*/"- nettype = "`default_nettype none"+ nettypeNone = "`default_nettype none"+ nettypeDefault = "`default_nettype wire" timescale = "`timescale 100fs/" <> string (Text.pack precision) precision = periodToString (opt_timescalePrecision opts)
src/Clash/Backend/VHDL.hs view
@@ -21,9 +21,6 @@ module Clash.Backend.VHDL (VHDLState) where import Control.Arrow (second)-#if !MIN_VERSION_base(4,18,0)-import Control.Applicative (liftA2)-#endif import Control.Lens hiding (Indexed, Empty) import Control.Monad (forM,join,zipWithM) import Control.Monad.State (State, StateT)
src/Clash/Backend/Verilog.hs view
@@ -234,7 +234,11 @@ usages .= usage setSrcSpan sp - v <- commentHeader <> line <> nettype <> line <> timescale <> line <> module_ c+ v <- commentHeader <> line <>+ nettypeNone <> line <>+ timescale <> line <>+ module_ c <> line <>+ nettypeDefault incs <- Ap $ use includes return ((TextS.unpack (Id.toText cName), v), incs) where@@ -243,7 +247,8 @@ = "/* AUTOMATICALLY GENERATED VERILOG-2001 SOURCE CODE." <> line <> "** GENERATED BY CLASH " <> string (Text.pack clashVer) <> ". DO NOT MODIFY." <> line <> "*/"- nettype = "`default_nettype none"+ nettypeNone = "`default_nettype none"+ nettypeDefault = "`default_nettype wire" timescale = "`timescale 100fs/" <> string (Text.pack precision) precision = periodToString (opt_timescalePrecision opts)
src/Clash/Backend/Verilog/Time.hs view
@@ -15,6 +15,9 @@ {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE TypeFamilies #-} +-- TryDomain instance+{-# OPTIONS_GHC -Wno-deprecations #-}+ module Clash.Backend.Verilog.Time where import Clash.Class.HasDomain.HasSingleDomain
src/Clash/Core/EqSolver.hs view
@@ -19,12 +19,8 @@ import Clash.Core.Var import Clash.Core.VarEnv (VarSet, elemVarSet, emptyVarSet, mkVarSet) import Clash.Unique (fromGhcUnique)-#if MIN_VERSION_ghc(9,0,0) import Clash.Core.DataCon (dcUniq) import GHC.Builtin.Names (unsafeReflDataConKey, eqPrimTyConKey, typeNatAddTyFamNameKey)-#else-import PrelNames (eqPrimTyConKey, typeNatAddTyFamNameKey)-#endif -- | Data type that indicates what kind of solution (if any) was found data TypeEqSolution@@ -139,12 +135,10 @@ :: TyConMap -> Pat -> Bool-#if MIN_VERSION_base(4,15,0) isAbsurdPat _tcm (DataPat dc _ _) -- unsafeCoerce is not absurd in the way intended by /isAbsurdPat/ | dcUniq dc == fromGhcUnique unsafeReflDataConKey = False-#endif isAbsurdPat tcm pat = any (isAbsurdEq tcm exts) (patEqs tcm pat) where
src/Clash/Core/HasType.hs view
@@ -67,14 +67,12 @@ CharLiteral _ -> charPrimTy Int64Literal _ -> int64PrimTy Word64Literal _ -> word64PrimTy-#if MIN_VERSION_ghc(8,8,0) Int8Literal _ -> int8PrimTy Int16Literal _ -> int16PrimTy Int32Literal _ -> int32PrimTy Word8Literal _ -> word8PrimTy Word16Literal _ -> word16PrimTy Word32Literal _ -> word32PrimTy-#endif NaturalLiteral _ -> naturalPrimTy ByteArrayLiteral _ -> byteArrayPrimTy
src/Clash/Core/Literal.hs view
@@ -51,14 +51,12 @@ | WordLiteral !Integer | Int64Literal !Integer | Word64Literal !Integer-#if MIN_VERSION_ghc(8,8,0) | Int8Literal !Integer | Int16Literal !Integer | Int32Literal !Integer | Word8Literal !Integer | Word16Literal !Integer | Word32Literal !Integer-#endif | StringLiteral !String | FloatLiteral !Word32 | DoubleLiteral !Word64
src/Clash/Core/Name.hs view
@@ -26,11 +26,7 @@ import GHC.BasicTypes.Extra () import GHC.Generics (Generic) import GHC.SrcLoc.Extra ()-#if MIN_VERSION_ghc(9,0,0) import GHC.Types.SrcLoc (SrcSpan, noSrcSpan)-#else-import SrcLoc (SrcSpan, noSrcSpan)-#endif import Clash.Unique
src/Clash/Core/PartialEval/Monad.hs view
@@ -63,10 +63,6 @@ import Control.Monad.Catch (MonadThrow, MonadCatch, MonadMask) import Control.Monad.IO.Class (MonadIO) -#if !MIN_VERSION_base(4,13,0)-import Control.Monad.Fail (MonadFail)-#endif- import Control.Monad.RWS.Strict (RWST, MonadReader, MonadState) import qualified Control.Monad.RWS.Strict as RWS import qualified Data.IntMap.Strict as IntMap
src/Clash/Core/Pretty.hs view
@@ -27,6 +27,7 @@ , tracePprId , tracePpr , fromPpr+ , unsafeLookupEnvBool ) where @@ -47,11 +48,7 @@ #endif import GHC.Show (showMultiLineString) import GHC.Stack (HasCallStack)-#if MIN_VERSION_ghc(9,0,0) import qualified GHC.Utils.Outputable as GHC-#else-import qualified Outputable as GHC-#endif import System.Environment (lookupEnv) import System.IO.Unsafe (unsafePerformIO) import Text.Read (readMaybe)@@ -371,14 +368,12 @@ Int64Literal i -> parensIf (i < 0) (pretty i <> "#64") WordLiteral w -> pretty w <> "##" Word64Literal w -> pretty w <> "##64"-#if MIN_VERSION_ghc(8,8,0) Int8Literal i -> parensIf (i < 0) (pretty i <> "#8") Int16Literal i -> parensIf (i < 0) (pretty i <> "#16") Int32Literal i -> parensIf (i < 0) (pretty i <> "#32") Word8Literal w -> pretty w <> "##8" Word16Literal w -> pretty w <> "##16" Word32Literal w -> pretty w <> "##32"-#endif FloatLiteral w -> pretty (wordToFloat w) <> "#" DoubleLiteral w -> pretty (wordToDouble w) <> "##" CharLiteral c -> pretty c <> "#"
src/Clash/Core/Term.hs view
@@ -71,11 +71,7 @@ import Data.List (nub, partition) import Data.Text (Text) import GHC.Generics-#if MIN_VERSION_ghc(9,0,0) import GHC.Types.SrcLoc (SrcSpan, leftmost_smallest)-#else-import SrcLoc (SrcSpan, leftmost_smallest)-#endif -- Internal Modules import Clash.Core.DataCon (DataCon)
src/Clash/Core/TermLiteral.hs view
@@ -32,11 +32,9 @@ import Data.Text (Text) import qualified Data.Text as Text import Data.Text.Extra (showt)-#if MIN_VERSION_ghc(9,4,0) import qualified Data.Text.Internal as Text import qualified Data.Text.Array as Text import qualified Data.Primitive.ByteArray as BA-#endif import Data.Typeable (Typeable, typeRep) import GHC.Natural import GHC.Stack@@ -101,12 +99,10 @@ instance TermLiteral Text where termToData (collectArgs -> (_, [Left (Literal (StringLiteral s))])) = Right (Text.pack s)-#if MIN_VERSION_ghc(9,4,0) termToData (collectArgs -> (_, [ Left (Literal (ByteArrayLiteral (BA.ByteArray ba))) , Left (Literal (IntLiteral off)) , Left (Literal (IntLiteral len))])) = Right (Text.Text (Text.ByteArray ba) (fromInteger off) (fromInteger len))-#endif termToData t = Left t instance KnownNat n => TermLiteral (Index n) where
src/Clash/Core/TermLiteral/TH.hs view
@@ -39,11 +39,7 @@ -- module Clash.Core.Subst cannot be linked; it is only available as a boot module import Clash.Core.Subst () -#if __GLASGOW_HASKELL__ >= 900 type CompatTyVarBndr = TyVarBndr ()-#else-type CompatTyVarBndr = TyVarBndr-#endif dcName' :: DataCon -> String dcName' = Text.unpack . nameOcc . dcName@@ -66,15 +62,9 @@ -- | Extracts variable names from a 'TyVarBndr'. typeVarName :: CompatTyVarBndr -> Q (Name, Maybe Type) typeVarName = \case-#if __GLASGOW_HASKELL__ >= 900 PlainTV typVarName () -> pure (typVarName, Nothing) KindedTV typVarName () StarT -> pure (typVarName, Nothing) KindedTV typVarName () kind -> pure (typVarName, Just kind)-#else- PlainTV typVarName -> pure (typVarName, Nothing)- KindedTV typVarName StarT -> pure (typVarName, Nothing)- KindedTV typVarName kind -> pure (typVarName, Just kind)-#endif -- | Derive a t'Clash.Core.TermLiteral.TermLiteral' instance for given type deriveTermLiteral :: Name -> Q [Dec]@@ -222,11 +212,7 @@ termName (ViewP (VarE 'collectArgs)-#if MIN_VERSION_template_haskell(2,18,0) (TupP [ ConP 'Data [] [ViewP (VarE 'dcName') (VarP nameName)]-#else- (TupP [ ConP 'Data [ViewP (VarE 'dcName') (VarP nameName)]-#endif , ViewP (VarE 'lefts) (if nArgs == 0 then WildP else VarP argsName)]))
src/Clash/Core/Type.hs view
@@ -73,22 +73,15 @@ import GHC.Integer (smallInteger) import GHC.Integer.Logarithms (integerLogBase#) import GHC.TypeLits (type TypeError, ErrorMessage(Text, (:<>:)))-#if MIN_VERSION_base(4,16,0) import GHC.Base (ord) import Data.Char (chr) import Data.Maybe (fromMaybe) import Data.Text.Extra (showt)-#endif -- GHC API-#if MIN_VERSION_ghc(9,0,0)-#if MIN_VERSION_ghc(9,2,0) import GHC.Builtin.Names (typeCharCmpTyFamNameKey, typeConsSymbolTyFamNameKey, typeUnconsSymbolTyFamNameKey, typeCharToNatTyFamNameKey, typeNatToCharTyFamNameKey)-#else-import GHC.Builtin.Names (typeNatLeqTyFamNameKey)-#endif import GHC.Builtin.Names (integerTyConKey, typeNatAddTyFamNameKey, typeNatExpTyFamNameKey, typeNatMulTyFamNameKey, typeNatSubTyFamNameKey,@@ -96,23 +89,6 @@ typeSymbolAppendFamNameKey, typeSymbolCmpTyFamNameKey, typeNatDivTyFamNameKey, typeNatModTyFamNameKey) import GHC.Types.SrcLoc (wiredInSrcSpan)-#else-#if __GLASGOW_HASKELL__ >= 808-import PrelNames- (ordLTDataConKey, ordEQDataConKey, ordGTDataConKey)-#else-import Unique (Unique)-import PrelNames- (ltDataConKey, eqDataConKey, gtDataConKey)-#endif-import PrelNames- (integerTyConKey, typeNatAddTyFamNameKey, typeNatExpTyFamNameKey,- typeNatLeqTyFamNameKey, typeNatMulTyFamNameKey, typeNatSubTyFamNameKey,- typeNatCmpTyFamNameKey,- typeSymbolAppendFamNameKey, typeSymbolCmpTyFamNameKey,- typeNatDivTyFamNameKey, typeNatModTyFamNameKey)-import SrcLoc (wiredInSrcSpan)-#endif -- Local imports import Clash.Annotations.SynthesisAttributes@@ -125,13 +101,6 @@ import Clash.Unique (fromGhcUnique) import Clash.Util -#if __GLASGOW_HASKELL__ <= 806-ordLTDataConKey, ordEQDataConKey, ordGTDataConKey :: Unique.Unique-ordLTDataConKey = ltDataConKey-ordEQDataConKey = eqDataConKey-ordGTDataConKey = gtDataConKey-#endif- varAttrs :: Var a -> [Attr Text] varAttrs t@(TyVar {}) = error $ $(curLoc) ++ "Unexpected argument: " ++ show t@@ -545,19 +514,6 @@ -> Just (LitTy (NumTy z)) _ -> Nothing -#if !MIN_VERSION_ghc(9,2,0)- | nameUniq tc == fromGhcUnique typeNatLeqTyFamNameKey- = case mapMaybe (litView tcm) tys of- [i1, i2]- | Just (FunTyCon {tyConKind = tck}) <- UniqMap.lookup tc tcm- , (_,tyView -> TyConApp boolTcNm []) <- splitFunTys tcm tck- , Just boolTc <- UniqMap.lookup boolTcNm tcm- -> let [falseTc,trueTc] = map (coerce . dcName) (tyConDataCons boolTc)- in if i1 <= i2 then Just (mkTyConApp trueTc [])- else Just (mkTyConApp falseTc [])- _ -> Nothing-#endif- | nameUniq tc == fromGhcUnique typeNatCmpTyFamNameKey -- "GHC.TypeNats.CmpNat" = case mapMaybe (litView tcm) tys of [i1, i2] ->@@ -584,7 +540,6 @@ (fromGhcUnique ordGTDataConKey) wiredInSrcSpan _ -> Nothing -#if MIN_VERSION_base(4,16,0) | nameUniq tc == fromGhcUnique typeCharCmpTyFamNameKey -- "GHC.TypeNats.CmpSymbol" = case mapMaybe (charLitView tcm) tys of [s1, s2] ->@@ -629,7 +584,6 @@ | nameUniq tc == fromGhcUnique typeNatToCharTyFamNameKey -- NatToChar , [n1] <- mapMaybe (litView tcm) tys = Just (LitTy (CharTy (chr (fromInteger n1))))-#endif | nameUniq tc == fromGhcUnique typeSymbolAppendFamNameKey -- GHC.TypeLits.AppendSymbol" = case mapMaybe (symLitView tcm) tys of@@ -692,7 +646,6 @@ -> Just (LitTy (NumTy (i1 `mod` i2))) _ -> Nothing -#if MIN_VERSION_base(4,11,0) | nameUniq tc == fromGhcUnique typeNatDivTyFamNameKey = case mapMaybe (litView tcm) tys of [i1, i2]@@ -706,7 +659,6 @@ | i2 > 0 -> Just (LitTy (NumTy (i1 `mod` i2))) _ -> Nothing-#endif | Just (FunTyCon {tyConSubst = tcSubst}) <- UniqMap.lookup tc tcm = let -- See [Note: Eager type families]@@ -736,12 +688,10 @@ symLitView m (reduceTypeFamily m -> Just ty') = symLitView m ty' symLitView _ _ = Nothing -#if MIN_VERSION_base(4,16,0) charLitView :: TyConMap -> Type -> Maybe Char charLitView _ (LitTy (CharTy c)) = Just c charLitView m (reduceTypeFamily m -> Just t) = charLitView m t charLitView _ _ = Nothing-#endif isIntegerTy :: Type -> Bool isIntegerTy (ConstTy (TyCon nm)) = nameUniq nm == fromGhcUnique integerTyConKey
src/Clash/Core/TysPrim.hs view
@@ -1,7 +1,7 @@ {-| Copyright : (C) 2012-2016, University of Twente, 2016 , Myrtle Software Ltd,- 2021-2024, QBayLogic B.V.+ 2021-2026, QBayLogic B.V. License : BSD2 (see the file LICENSE) Maintainer : QBayLogic B.V. <devops@qbaylogic.com> @@ -21,46 +21,34 @@ , integerPrimTy , charPrimTy , stringPrimTy-#if !MIN_VERSION_ghc(9,2,0)- , voidPrimTy-#endif , wordPrimTy , int64PrimTy , word64PrimTy-#if MIN_VERSION_ghc(8,8,0) , int8PrimTy , int16PrimTy , int32PrimTy , word8PrimTy , word16PrimTy , word32PrimTy-#endif , floatPrimTy , doublePrimTy , naturalPrimTy , byteArrayPrimTy , eqPrimTy , tysPrimMap+ , integerIsDc+ , naturalNsDc ) where --#if MIN_VERSION_ghc(9,0,0) import GHC.Builtin.Names-#else-import PrelNames-#endif -#if MIN_VERSION_ghc(8,8,0) import GHC.Base hiding (Type, TyCon) import Data.Text.Extra (showt)-#endif -#if MIN_VERSION_base(4,17,0) import Clash.Core.DataCon (DataCon(..), DcStrictness(..)) import GHC.Num.Integer (Integer(..)) import GHC.Num.Natural (Natural(..))-#endif import Clash.Core.Name import Clash.Core.TyCon@@ -73,12 +61,7 @@ liftedTypeKindTyConName, typeNatKindTyConName, typeSymbolKindTyConName :: TyConName liftedTypeKindTyConName = mkUnsafeSystemName "Type" (fromGhcUnique liftedTypeKindTyConKey)-#if MIN_VERSION_ghc(9,2,0) typeNatKindTyConName = naturalPrimTyConName-#else-typeNatKindTyConName = mkUnsafeSystemName "Nat"- (fromGhcUnique typeNatKindConNameKey)-#endif typeSymbolKindTyConName = mkUnsafeSystemName "Symbol" (fromGhcUnique typeSymbolKindConNameKey) @@ -97,47 +80,32 @@ wordPrimTyConName, int64PrimTyConName, word64PrimTyConName, floatPrimTyConName, doublePrimTyConName, naturalPrimTyConName, byteArrayPrimTyConName, eqPrimTyConName :: TyConName-intPrimTyConName = mkUnsafeSystemName "GHC.Prim.Int#"+intPrimTyConName = mkUnsafeSystemName (showt ''Int#) (fromGhcUnique intPrimTyConKey)-#if MIN_VERSION_base(4,15,0)-integerPrimTyConName = mkUnsafeSystemName "GHC.Num.Integer.Integer"- (fromGhcUnique integerTyConKey)-#else-integerPrimTyConName = mkUnsafeSystemName "GHC.Integer.Type.Integer"+integerPrimTyConName = mkUnsafeSystemName (showt ''Integer) (fromGhcUnique integerTyConKey)-#endif-stringPrimTyConName = mkUnsafeSystemName "GHC.Prim.Addr#"+stringPrimTyConName = mkUnsafeSystemName (showt ''Addr#) (fromGhcUnique addrPrimTyConKey)-charPrimTyConName = mkUnsafeSystemName "GHC.Prim.Char#"+charPrimTyConName = mkUnsafeSystemName (showt ''Char#) (fromGhcUnique charPrimTyConKey)-wordPrimTyConName = mkUnsafeSystemName "GHC.Prim.Word#"+wordPrimTyConName = mkUnsafeSystemName (showt ''Word#) (fromGhcUnique wordPrimTyConKey)-int64PrimTyConName = mkUnsafeSystemName "GHC.Prim.Int64#"+int64PrimTyConName = mkUnsafeSystemName (showt ''Int64#) (fromGhcUnique int64PrimTyConKey)-word64PrimTyConName = mkUnsafeSystemName "GHC.Prim.Word64#"+word64PrimTyConName = mkUnsafeSystemName (showt ''Word64#) (fromGhcUnique word64PrimTyConKey)-floatPrimTyConName = mkUnsafeSystemName "GHC.Prim.Float#"+floatPrimTyConName = mkUnsafeSystemName (showt ''Float#) (fromGhcUnique floatPrimTyConKey)-doublePrimTyConName = mkUnsafeSystemName "GHC.Prim.Double#"+doublePrimTyConName = mkUnsafeSystemName (showt ''Double#) (fromGhcUnique doublePrimTyConKey)-#if MIN_VERSION_base(4,15,0)-naturalPrimTyConName = mkUnsafeSystemName "GHC.Num.Natural.Natural"- (fromGhcUnique naturalTyConKey)-#else-naturalPrimTyConName = mkUnsafeSystemName "GHC.Natural.Natural"+naturalPrimTyConName = mkUnsafeSystemName (showt ''Natural) (fromGhcUnique naturalTyConKey)-#endif-byteArrayPrimTyConName = mkUnsafeSystemName "GHC.Prim.ByteArray#"+byteArrayPrimTyConName = mkUnsafeSystemName (showt ''ByteArray#) (fromGhcUnique byteArrayPrimTyConKey) eqPrimTyConName = mkUnsafeSystemName "GHC.Prim.~#" (fromGhcUnique eqPrimTyConKey) -#if !MIN_VERSION_ghc(9,2,0)-voidPrimTyConName :: TyConName-voidPrimTyConName = mkUnsafeSystemName "Void#" (fromGhcUnique voidPrimTyConKey)-#endif -#if MIN_VERSION_ghc(8,8,0) int8PrimTyConName, int16PrimTyConName, int32PrimTyConName, word8PrimTyConName, word16PrimTyConName, word32PrimTyConName :: TyConName int8PrimTyConName = mkUnsafeSystemName (showt ''Int8#)@@ -152,7 +120,6 @@ (fromGhcUnique word16PrimTyConKey) word32PrimTyConName = mkUnsafeSystemName (showt ''Word32#) (fromGhcUnique word32PrimTyConKey)-#endif liftedPrimTC :: TyConName -> TyCon@@ -163,7 +130,7 @@ int64PrimTc, word64PrimTc, floatPrimTc, doublePrimTc, naturalPrimTc, byteArrayPrimTc :: TyCon intPrimTc = liftedPrimTC intPrimTyConName-#if MIN_VERSION_base(4,17,0)+ -- While GHC might have dropped Integer and Natural literals, in Clash it is -- still nice to have them around. However, Integer and Natural are also no -- longer primitive types in GHC, but we still want to give the Integer and@@ -172,10 +139,9 @@ -- So instead of recording the primitive types, we record the algebraic types, -- i.e. the complete data type for Integer and Natural, data constructors and all. -integerPrimTc =- let- name = integerPrimTyConName- uniq = nameUniq name+integerIsDc, naturalNsDc :: DataCon+integerIsDc = isDc+ where isDcNm = mkUnsafeSystemName (showt 'IS) (fromGhcUnique integerISDataConKey) isDc = MkData { dcName = isDcNm@@ -188,6 +154,12 @@ , dcArgStrict = [Strict] , dcFieldLabels = [] }++integerPrimTc =+ let+ name = integerPrimTyConName+ uniq = nameUniq name+ isDc = integerIsDc ipDcNm = mkUnsafeSystemName (showt 'IP) (fromGhcUnique integerIPDataConKey) ipDc = MkData { dcName = ipDcNm@@ -216,10 +188,8 @@ in AlgTyCon uniq name liftedTypeKind 0 rhs False -naturalPrimTc =- let- name = naturalPrimTyConName- uniq = nameUniq name+naturalNsDc = nsDc+ where nsDcNm = mkUnsafeSystemName (showt 'NS) (fromGhcUnique naturalNSDataConKey) nsDc = MkData { dcName = nsDcNm@@ -232,6 +202,12 @@ , dcArgStrict = [Strict] , dcFieldLabels = [] }++naturalPrimTc =+ let+ name = naturalPrimTyConName+ uniq = nameUniq name+ nsDc = naturalNsDc nbDcNm = mkUnsafeSystemName (showt 'NB) (fromGhcUnique naturalNBDataConKey) nbDc = MkData { dcName = nbDcNm@@ -247,10 +223,6 @@ rhs = DataTyCon [nsDc,nbDc] in AlgTyCon uniq name liftedTypeKind 0 rhs False-#else-integerPrimTc = liftedPrimTC integerPrimTyConName-naturalPrimTc = liftedPrimTC naturalPrimTyConName-#endif charPrimTc = liftedPrimTC charPrimTyConName stringPrimTc = liftedPrimTC stringPrimTyConName wordPrimTc = liftedPrimTC wordPrimTyConName@@ -260,12 +232,7 @@ doublePrimTc = liftedPrimTC doublePrimTyConName byteArrayPrimTc = liftedPrimTC byteArrayPrimTyConName -#if !MIN_VERSION_ghc(9,2,0)-voidPrimTc :: TyCon-voidPrimTc = liftedPrimTC voidPrimTyConName-#endif -#if MIN_VERSION_ghc(8,8,0) int8PrimTc, int16PrimTc, int32PrimTc, word8PrimTc, word16PrimTc, word32PrimTc :: TyCon int8PrimTc = liftedPrimTC int8PrimTyConName@@ -274,7 +241,6 @@ word8PrimTc = liftedPrimTC word8PrimTyConName word16PrimTc = liftedPrimTC word16PrimTyConName word32PrimTc = liftedPrimTC word32PrimTyConName-#endif eqPrimTc :: TyCon eqPrimTc = PrimTyCon (nameUniq eqPrimTyConName) eqPrimTyConName ty 4@@ -305,12 +271,6 @@ byteArrayPrimTy = mkTyConTy byteArrayPrimTyConName eqPrimTy = mkTyConTy eqPrimTyConName -#if !MIN_VERSION_ghc(9,2,0)-voidPrimTy :: Type-voidPrimTy = mkTyConTy voidPrimTyConName-#endif--#if MIN_VERSION_ghc(8,8,0) int8PrimTy, int16PrimTy, int32PrimTy, word8PrimTy, word16PrimTy, word32PrimTy :: Type int8PrimTy = mkTyConTy int8PrimTyConName@@ -319,7 +279,6 @@ word8PrimTy = mkTyConTy word8PrimTyConName word16PrimTy = mkTyConTy word16PrimTyConName word32PrimTy = mkTyConTy word32PrimTyConName-#endif tysPrimMap :: TyConMap tysPrimMap = UniqMap.fromList@@ -330,20 +289,15 @@ , (integerPrimTyConName , integerPrimTc) , (charPrimTyConName , charPrimTc) , (stringPrimTyConName , stringPrimTc)-#if !MIN_VERSION_ghc(9,2,0)- , (voidPrimTyConName , voidPrimTc)-#endif , (wordPrimTyConName , wordPrimTc) , (int64PrimTyConName , int64PrimTc) , (word64PrimTyConName , word64PrimTc)-#if MIN_VERSION_ghc(8,8,0) , (int8PrimTyConName , int8PrimTc) , (int16PrimTyConName , int16PrimTc) , (int32PrimTyConName , int32PrimTc) , (word8PrimTyConName , word8PrimTc) , (word16PrimTyConName , word16PrimTc) , (word32PrimTyConName , word32PrimTc)-#endif , (floatPrimTyConName , floatPrimTc) , (doublePrimTyConName , doublePrimTc) , (naturalPrimTyConName , naturalPrimTc)
src/Clash/Core/Util.hs view
@@ -19,11 +19,7 @@ module Clash.Core.Util where import Control.Exception.Base (patError)-#if MIN_VERSION_base(4,16,0) import GHC.Prim.Panic (absentError)-#else-import Control.Exception.Base (absentError)-#endif import Control.Monad.Trans.Except (Except, throwE, runExcept) import Data.Bifunctor (first, second) import qualified Data.HashSet as HashSet@@ -41,11 +37,7 @@ (divZeroError, overflowError, ratioZeroDenominatorError, underflowError) import GHC.Stack (HasCallStack) -#if MIN_VERSION_ghc(9,0,0) import GHC.Builtin.Names (ipClassKey)-#else-import PrelNames (ipClassKey)-#endif import Clash.Core.DataCon import Clash.Core.EqSolver
src/Clash/Data/UniqMap.hs view
@@ -58,10 +58,6 @@ #endif import qualified Data.List as List (foldl') -#if !MIN_VERSION_containers(0,6,2)-import qualified Data.IntMap.Extra as IntMap-#endif- #if MIN_VERSION_prettyprinter(1,7,0) import Prettyprinter #else
src/Clash/Driver.hs view
@@ -60,11 +60,6 @@ import qualified Data.Text.Lazy as Text import Data.Text.Lazy.Encoding as Text import qualified Data.Text.Lazy.IO as Text-#if MIN_VERSION_prettyprinter(1,7,0)-import Prettyprinter (pretty)-#else-import Data.Text.Prettyprint.Doc (pretty)-#endif import Data.Text.Prettyprint.Doc.Extra (Doc, LayoutOptions (..), PageWidth (..) , layoutPretty, renderLazy) import qualified Data.Time.Clock as Clock@@ -85,15 +80,9 @@ import Text.Trifecta.Result (Result(Success, Failure), _errDoc) -#if MIN_VERSION_ghc(9,0,0) import GHC.Builtin.Names (eqTyConKey, ipClassKey) import GHC.Types.SrcLoc (SrcSpan)-#else-import PrelNames (eqTyConKey, ipClassKey)--import SrcLoc (SrcSpan)-#endif import GHC.BasicTypes.Extra () import Clash.Annotations.Primitive@@ -118,6 +107,7 @@ import Clash.Core.VarEnv (elemVarEnv, emptyVarEnv, lookupVarEnv, lookupVarEnv', mkVarEnv, lookupVarEnvDirectly, eltsVarEnv, VarEnv) import Clash.Debug (debugIsOn)+import qualified Clash.Driver.BrokenGhcs as BrokenGhcs import Clash.Driver.Types import Clash.Driver.Manifest (Manifest(..), readFreshManifest, UnexpectedModification, pprintUnexpectedModifications,@@ -327,6 +317,9 @@ let topEntities0 = designEntities design let opts = envOpts env + -- Detect "broken" GHCs and throw an error (unless silenced)+ unless (opt_ignoreBrokenGhcs opts) BrokenGhcs.assertWorking+ removeHistoryFile (dbg_historyFile (opt_debug opts)) unless (opt_cachehdl opts) $@@ -349,8 +342,13 @@ edamFiles <- newMVar HashMap.empty ioLock <- newMVar () - mapConcurrently_ (go compNames idSet edamFiles ioLock deps topEntityMap) tes+ let+ maybeMapConcurrently_+ | opt_concurrentTopEntities opts = mapConcurrently_+ | otherwise = mapM_ + maybeMapConcurrently_ (go compNames idSet edamFiles ioLock deps topEntityMap) tes+ time <- Clock.getCurrentTime let diff = reportTimeDiff time startTime putStrLn $ "Clash: Total compilation took " ++ diff@@ -416,14 +414,7 @@ then writeEdam hdlDir (topNm, varUniq topEntity) deps edamFiles fileNames else pure (edamFiles, fileNames) - -- If we are generating (System)Verilog, we could potentially verilate- -- the results. Clash can output a C++ shim for doing this automatically.- fileNames2 <-- case hdlFromBackend (Proxy @backend) of- VHDL -> pure fileNames1- _ -> writeVerilatorShim hdlDir topNm fileNames1-- writeManifest manPath manifest0{fileNames=fileNames2}+ writeManifest manPath manifest0{fileNames=fileNames1} topTime <- Clock.getCurrentTime let topDiff = reportTimeDiff topTime prevTime@@ -493,11 +484,6 @@ then writeEdam hdlDir (topNm, varUniq topEntity) deps edamFiles filesAndDigests0 else pure (edamFiles, filesAndDigests0) - filesAndDigests2 <-- case hdlFromBackend (Proxy @backend) of- VHDL -> pure filesAndDigests1- _ -> writeVerilatorShim hdlDir topNm filesAndDigests1- let depUniques = fromMaybe [] (HashMap.lookup (getUnique topEntity) deps) depBindings = mapMaybe (flip lookupVarEnvDirectly bindingsMap) depUniques@@ -506,7 +492,7 @@ manifest = mkManifest hdlState' domainConfs opts topComponent components depIds- filesAndDigests2 topHash+ filesAndDigests1 topHash writeManifest manPath manifest topTime <- hdlDocs `seq` Clock.getCurrentTime@@ -811,48 +797,6 @@ (error $ $(curLoc) ++ "Unknown synthesis domain: " ++ show dom) dom domainConfs--writeVerilatorShim- :: FilePath- -> Id.Identifier- -> [(FilePath, ByteString)]- -> IO [(FilePath, ByteString)]-writeVerilatorShim hdlDir topNm filesAndDigests = do- let file = Data.Text.unpack (Id.toText topNm) <> "_shim" <.> "cpp"- digest <- writeHDL hdlDir (file, pprVerilatorShim topNm)- pure ((file, digest) : filesAndDigests)---- | Create a shim for using verilator, which loads the entity and steps--- through simulation until finished.----pprVerilatorShim :: Id.Identifier -> Doc-pprVerilatorShim (Id.toText -> topNm) =- -- Extra newlines are aggressively inserted so the quasiquoter doesn't wrap- -- the outlines lines in the file. It doesn't matter for code inside main,- -- but is fatal for the #include directives.- pretty $ Data.Text.pack [I.i|- \#include <cstdlib>-- \#include <verilated.h>-- \#include "V#{topNm}.h"-- int main(int argc, char **argv) {- Verilated::commandArgs(argc, argv);-- V#{topNm} *top = new V#{topNm};-- while(!Verilated::gotFinish()) {- top->eval();- }-- top->final();-- delete top;-- return EXIT_SUCCESS;- }- |] writeEdam :: FilePath ->
src/Clash/Driver/Bool.hs view
@@ -12,13 +12,7 @@ import Data.Hashable (Hashable) import GHC.Generics (Generic) -#if MIN_VERSION_ghc(9,4,0) import qualified GHC.Data.Bool as Ghc-#elif MIN_VERSION_ghc(9,0,0)-import qualified GHC.Utils.Misc as Ghc-#else-import qualified Util as Ghc-#endif data OverridingBool = Auto | Never | Always deriving (Show, Read, Eq, Ord, Enum, Bounded, Hashable, Generic, NFData)
+ src/Clash/Driver/BrokenGhcs.hs view
@@ -0,0 +1,157 @@+{-|+Copyright : (C) 2024, Martijn Bastiaan+License : BSD2 (see the file LICENSE)+Maintainer : QBayLogic B.V. <devops@qbaylogic.com>++Utilities to detect and report GHC / operating system combinations that are+known to be buggy.+-}++{-# LANGUAGE CPP #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE NamedFieldPuns #-}+{-# LANGUAGE QuasiQuotes #-}++module Clash.Driver.BrokenGhcs where++import Data.Maybe (listToMaybe)+import Data.Version (Version(Version, versionBranch))+import GHC.Platform (OS(..))++import System.Info (fullCompilerVersion)++import qualified Clash.Util.Interpolate as I+import qualified System.Info++-- | Current OS. Currently only recognizes Linux, Windows, and macOS.+os :: OS+os = case System.Info.os of+ "darwin" -> OSDarwin+ "linux" -> OSLinux+ "mingw32" -> OSMinGW32+ _ -> OSUnknown++-- | What OS GHC is broken on (or all)+data BrokenOn = All | SomeOs OS++data GhcVersion = Ghc+ { major0 :: Int+ , major1 :: Int+ , patch :: Int+ }+ deriving (Eq, Ord)++data GhcRange = GhcRange+ { from :: GhcVersion+ -- ^ Start of range, inclusive+ , to :: GhcVersion+ -- ^ End of range, exclusive+ }++-- | Check if a 'GhcVersion' is within a 'GhcRange'+ghcInRange :: GhcVersion -> GhcRange -> Bool+ghcInRange ghc GhcRange{from, to} = from <= ghc && ghc < to++-- | Construct a range of all GHC versions matching a major version+ghcMajor :: Int -> Int -> GhcRange+ghcMajor major0 major1 = GhcRange+ { from=Ghc major0 major1 0+ , to=Ghc major0 (major1 + 1) 0+ }++data Why = Why+ { what :: String+ -- ^ What is broken+ , solution :: String+ -- ^ What can be done to work around or solve the issue+ , issue :: String+ -- ^ Link to issue+ , brokenOn :: [(BrokenOn, GhcRange)]+ -- ^ What operation systems are affected+ }++-- | Get current GHC version expressed as a triple. It probably does something+-- non-sensible on unreleased GHCs.+ghcVersion :: GhcVersion+ghcVersion = Ghc{major0, major1, patch}+ where+ (major0, major1, patch) =+ case fullCompilerVersion of+ Version{versionBranch} ->+ case versionBranch of+ [] -> (0, 0, 1)+ [a] -> (a, 0, 1)+ [a, b] -> (a, b, 1)+ [a, b, c] -> (a, b, c)+ (a:b:c:_) -> (a, b, c)++-- | Pretty print 'Why' into an error message+whyPp :: Why -> String+whyPp Why{what, solution, issue}= [I.i|+ Clash has known issues on #{major0}.#{major1}.#{patch} on your current+ OS. While not completely preventing the compiler from working, we recommend+ switching to another GHC version. Symptoms:++ #{what}++ Consider the following work around or solution:++ #{solution}++ More information can be found at:++ #{issue}++ If you want to ignore this message, pass the following flag to Clash:++ -fclash-ignore-broken-ghcs++ Alternatively, you can set the environment variable CLASH_IGNORE_BROKEN_GHCS+ to 'True'.+ |]+ where+ Ghc{major0, major1, patch} = ghcVersion++-- | Which GHCs are broken and why+brokenGhcs :: [Why]+brokenGhcs = [brokenClashCores, brokenTypeErrors, slowStarts]+ where+ brokenClashCores = Why+ { what = "GHC is known to fail compilation of libraries used by the Clash compiler test suite"+ , solution = "Upgrade to GHC 9.4 or downgrade to GHC 8.10"+ , issue = "<no link>"+ , brokenOn = [(SomeOs OSMinGW32, ghcMajor 9 0)]+ }++ brokenTypeErrors = Why+ { what = "Clash type error messages are indecipherable"+ , solution = "Upgrade to GHC 9.4 or downgrade to GHC 9.0"+ , issue = "<no link>"+ , brokenOn = [(All, ghcMajor 9 2)]+ }++ slowStarts = Why+ { what = "Clash starts really slowly from GHC 9.4.8 up to and including 9.6.2"+ , solution = "Upgrade to GHC 9.6.3 or newer, or downgrade to GHC 9.4.7"+ , issue = "https://github.com/clash-lang/clash-compiler/issues/2710"+ , brokenOn = [(All, GhcRange{from=Ghc 9 4 8, to=Ghc 9 6 3})]+ }++-- | Given a 'BrokenOn', determine whether current OS matches+matchOs :: BrokenOn -> Bool+matchOs All = True+matchOs (SomeOs brokenOs) = os == brokenOs++-- | Given a 'BrokenOn' and 'GhcVersion', determine whether it matches current OS and GHC+matchBroken :: (BrokenOn, GhcRange) -> Bool+matchBroken (brokenOs, brokenRange) = matchOs brokenOs && ghcInRange ghcVersion brokenRange++-- | Get first reason for GHC/OS being broken, if any+broken :: Maybe Why+broken = listToMaybe [why | why <- brokenGhcs, any matchBroken (brokenOn why)]++-- | Throw an error if current OS / GHC version is known to be buggy+assertWorking :: IO ()+assertWorking = case broken of+ Nothing -> pure ()+ Just why -> error (whyPp why)
src/Clash/Driver/Manifest.hs view
@@ -404,11 +404,12 @@ -- 2. Caching , opt_cachehdl = True - -- 3. Warnings+ -- 3. Warnings / errors , opt_primWarn = True , opt_color = Auto , opt_errorExtra = False , opt_checkIDir = True+ , opt_ignoreBrokenGhcs = False -- 4. Optional output , opt_edalize = False
src/Clash/Driver/Types.hs view
@@ -42,21 +42,14 @@ import GHC.Generics (Generic) -#if MIN_VERSION_ghc(9,4,0) import GHC.Types.Basic (InlineSpec) import GHC.Types.SrcLoc (SrcSpan)-#elif MIN_VERSION_ghc(9,0,0)-import GHC.Types.Basic (InlineSpec)-import GHC.Types.SrcLoc (SrcSpan)-#else-import BasicTypes (InlineSpec)-import SrcLoc (SrcSpan)-#endif import Clash.Annotations.BitRepresentation.Internal (CustomReprs) import Clash.Signal.Internal import Clash.Backend.Verilog.Time (Period(..), Unit(Fs))+import Clash.Core.Pretty (unsafeLookupEnvBool) import Clash.Core.Term (Term) import Clash.Core.TyCon (TyConMap, TyConName) import Clash.Core.Var (Id)@@ -403,6 +396,14 @@ , opt_timescalePrecision :: Period -- ^ Timescale precision set in Verilog files. E.g., setting this would sets -- the second part of @`timescale 100fs/100fs@.+ , opt_ignoreBrokenGhcs :: Bool+ -- ^ Don't error if we see a (potentially) broken GHC / platform combination.+ -- See the project's @README.md@ for more information.+ , opt_concurrentTopEntities :: Bool+ -- ^ Compile top entities concurrently. Disabling this is useful when+ -- investigating bugs, because it will make log output deterministic.+ --+ -- Command line flag: -fclash-no-concurrent-topentity-compilation } deriving (Show, Eq, NFData, Generic, Hashable) @@ -439,6 +440,10 @@ , opt_edalize = False , opt_renderEnums = True , opt_timescalePrecision = Period 100 Fs+ -- XXX: We probe environment variables until we've found a proper solution to+ -- https://github.com/clash-lang/clash-compiler/issues/2762.+ , opt_ignoreBrokenGhcs = unsafeLookupEnvBool "CLASH_IGNORE_BROKEN_GHCS" False+ , opt_concurrentTopEntities = True } -- | Synopsys Design Constraint (SDC) information for a component.
src/Clash/Netlist.hs view
@@ -44,13 +44,8 @@ import qualified Data.Text as StrictText import GHC.Stack (HasCallStack) -#if MIN_VERSION_ghc(9,0,0) import GHC.Utils.Outputable (ppr, showSDocUnsafe) import GHC.Types.SrcLoc (isGoodSrcSpan)-#else-import Outputable (ppr, showSDocUnsafe)-import SrcLoc (isGoodSrcSpan)-#endif import Clash.Annotations.Primitive (HDL) import Clash.Annotations.BitRepresentation.ClashLib@@ -71,6 +66,7 @@ import Clash.Core.Type (Type (..), coreView1, splitFunForallTy, splitCoreFunForallTy) import Clash.Core.TyCon (TyConMap)+import Clash.Core.TysPrim (integerPrimTy, naturalPrimTy) import Clash.Core.Util (splitShouldSplit) import Clash.Core.Var (Id, Var (..), isGlobalId) import Clash.Core.VarEnv@@ -273,7 +269,7 @@ -- HACK: Determine resulttype of this function by looking at its definition -- instead of looking at its last binder (which obscures any attributes -- [see: Clash.Annotations.SynthesisAttributes]).- ((args, binds, res{varType=varType1}))+ (args, binds, res{varType=varType1}) Left err -> throw (ClashException sp ($curLoc ++ err) Nothing) @@ -503,7 +499,8 @@ (_,sp) <- Lens.use curCompNm ite <- Lens.use backEndITE altHTy <- unsafeCoreTypeToHWTypeM' $(curLoc) altTy- case iteAlts scrutHTy (NE.toList alts0) of+ let e = Case scrut altTy (NE.toList alts0)+ case iteAlts scrutHTy alts0 of Just (altT,altF) | ite , Concurrent <- declType@@ -530,6 +527,10 @@ | otherwise -> do dstAssign <- contAssign dstId (IfThenElse scrutExpr altTExpr altFExpr) return $! scrutDecls ++ altTDecls ++ altFDecls ++ tickDecls ++ [dstAssign]+ _ | scrutTy == integerPrimTy+ -> throw (ClashException sp ($(curLoc) ++ "Can't create netlist for: case (_ :: Integer) of ...") (Just $ showPpr e))+ _ | scrutTy == naturalPrimTy+ -> throw (ClashException sp ($(curLoc) ++ "Can't create netlist for: case (_ :: Natural) of ...") (Just $ showPpr e)) _ -> do reprs <- Lens.view customReprs let alts1 = (reorderDefault . reorderCustom tcm reprs scrutTy) alts0@@ -564,14 +565,12 @@ LitPat (CharLiteral c) -> return (Just (NumLit . toInteger $ ord c), altExpr) LitPat (Int64Literal i) -> return (Just (NumLit i), altExpr) LitPat (Word64Literal w) -> return (Just (NumLit w), altExpr)-#if MIN_VERSION_base(4,16,0) LitPat (Int8Literal i) -> return (Just (NumLit i), altExpr) LitPat (Int16Literal i) -> return (Just (NumLit i), altExpr) LitPat (Int32Literal i) -> return (Just (NumLit i), altExpr) LitPat (Word8Literal w) -> return (Just (NumLit w), altExpr) LitPat (Word16Literal w) -> return (Just (NumLit w), altExpr) LitPat (Word32Literal w) -> return (Just (NumLit w), altExpr)-#endif LitPat (NaturalLiteral n) -> return (Just (NumLit n), altExpr) _ -> do (_,sp) <- Lens.use curCompNm@@ -849,6 +848,7 @@ let hwTyA = case hwTys of hwTy:_ -> hwTy _ -> error ("internal error: unable to extract sufficient hwTys from: " <> show bndr)+ let invalid kind = throw (ClashException sp ($(curLoc) ++ "Not in normal form: " ++ kind ++ "\n\n" ++ showPpr app) Nothing) case appF of Data dc -> mkDcApplication declType hwTys bndr dc tmArgs Prim pInfo -> mkPrimitive False bbEasD declType bndr pInfo args tickDecls@@ -858,9 +858,7 @@ return (Noop, []) else do return (Identifier (Id.unsafeFromCoreId f) Nothing, [])- | not (null tyArgs) ->- throw (ClashException sp ($(curLoc) ++ "Not in normal form: "- ++ "Var-application with Type arguments:\n\n" ++ showPpr app) Nothing)+ | not (null tyArgs) -> invalid "Var-application with type arguments" | otherwise -> do argNm <- Id.suffix (netlistId1 id Id.unsafeFromCoreId bndr) "fun_arg" decls <- mkFunApp declType argNm f tmArgs tickDecls@@ -881,12 +879,20 @@ -- This net was already declared in the call to mkSelection return ( Identifier argNm Nothing , NetDecl' Nothing argNm hwTyA Nothing:decls)+ Case _ _ [] -> invalid "No case alternatives\n\n" Letrec binders body -> do netDecls <- concatMapM mkNetDecl binders decls <- concatMapM (uncurry (mkDeclarations' declType)) binders (bodyE,bodyDecls) <- mkExpr bbEasD declType bndr (mkApps (mkTicks body ticks) args) return (bodyE,netDecls ++ decls ++ bodyDecls)- _ -> throw (ClashException sp ($(curLoc) ++ "Not in normal form: application of a Lambda-expression\n\n" ++ showPpr app) Nothing)+ Core.Literal _ -> invalid "application of literal"+ Let _ _ -> invalid "application of let"+ TyApp _ _ -> invalid "application of type application"+ Tick _ _ -> invalid "application of tick"+ Cast _ _ _ -> invalid "application of cast"+ Lam _ _ -> invalid "application of lambda"+ TyLam _ _ -> invalid "application of type lambda"+ App _ _ -> invalid "application of application" -- | Generate an expression that projects a field out of a data-constructor. --@@ -1092,42 +1098,22 @@ in return dc' Void {} -> return Noop Signed _-#if MIN_VERSION_base(4,15,0) | dcNm == "GHC.Num.Integer.IS"-#else- | dcNm == "GHC.Integer.Type.S#"-#endif , (a:_) <- argExprsFiltered -> pure a -- ByteArray# are non-translatable / void, except when they're literals-#if MIN_VERSION_base(4,15,0) | dcNm == "GHC.Num.Integer.IP"-#else- | dcNm == "GHC.Integer.Type.Jp#"-#endif , (a@(HW.Literal Nothing (NumLit _)):_) <- argExprs -> pure a-#if MIN_VERSION_base(4,15,0) | dcNm == "GHC.Num.Integer.IN"-#else- | dcNm == "GHC.Integer.Type.Jn#"-#endif -- ByteArray# are non-translatable / void, except when they're literals , (HW.Literal Nothing (NumLit i):_) <- argExprs -> pure (HW.Literal Nothing (NumLit (negate i))) Unsigned _-#if MIN_VERSION_base(4,15,0) | dcNm == "GHC.Num.Natural.NS"-#else- | dcNm == "GHC.Natural.NatS#"-#endif , (a:_) <- argExprsFiltered -> pure a-#if MIN_VERSION_base(4,15,0) | dcNm == "GHC.Num.Natural.NB"-#else- | dcNm == "GHC.Natural.NatJ#"-#endif -- ByteArray# are non-translatable / void, except when they're literals , (a@(HW.Literal Nothing (NumLit _)):_) <- argExprs -> pure a
src/Clash/Netlist/BlackBox.hs view
@@ -826,12 +826,7 @@ (mkLocalId (inferCoreTypeOf tcm e) (mkUnsafeSystemName "mealyres" 0)) in ([(u,e)], u)-#if __GLASGOW_HASKELL__ >= 900 args1 = args0-#else- -- Drop the 'State# World' argument- args1 = init args0-#endif -- Take into account that the state argument is split over multiple -- binders because it contained types that are not allowed to occur in -- a HDL aggregate type@@ -956,11 +951,7 @@ -- | Collect the sequential declarations for 'bindIO' collectBindIO :: NetlistId -> [Term] -> NetlistMonad (Expr,[Declaration])-#if __GLASGOW_HASKELL__ >= 900 collectBindIO dst (m:Lam x q@e:_) = do-#else-collectBindIO dst (m:Lam x q@(Lam _ e):_) = do-#endif tcm <- Lens.view tcCache (ds0,subst) <- collectAction tcm let qS = substTm "collectBindIO1" subst q
src/Clash/Netlist/BlackBox/Util.hs view
@@ -1,7 +1,7 @@ {-| Copyright : (C) 2012-2016, University of Twente, 2016-2017, Myrtle Software Ltd,- 2021-2023, QBayLogic B.V.+ 2021-2026, QBayLogic B.V. 2022 , LUMI GUIDE FIETSDETECTIE B.V. 2022 , Google Inc. License : BSD2 (see the file LICENSE)@@ -22,6 +22,7 @@ module Clash.Netlist.BlackBox.Util ( renderTemplate+ , lookupFunctionInstantiation , walkElement , verifyBlackBoxContext , onBlackBox@@ -46,6 +47,7 @@ import Data.Bitraversable (bitraverse) import Data.Bool (bool) import Data.Coerce (coerce)+import Data.Containers.ListUtils (nubOrd) import Data.Foldable (foldrM) import Data.Hashable (Hashable (..)) import qualified Data.HashMap.Strict as HashMap@@ -150,6 +152,41 @@ CtxName -> Nothing EscapedSymbol _ -> Nothing +lookupFunctionInstantiation+ :: BlackBoxContext+ -> Int+ -> Int+ -> Either+ String+ ( Either N.BlackBox (Id.Identifier, [Declaration])+ , N.Usage+ , [BlackBoxTemplate]+ , [BlackBoxTemplate]+ , [((Data.Text.Text, Data.Text.Text), N.BlackBox)]+ , BlackBoxContext+ )+lookupFunctionInstantiation bbCtx n subn =+ case IntMap.lookup n (bbFunctions bbCtx) of+ Nothing ->+ Left+ ( "Blackbox requested instantiation of function at argument "+ ++ show n+ ++ ", but BlackBoxContext did not contain one."+ )+ Just funcs ->+ case indexMaybe funcs subn of+ Nothing ->+ Left+ ( "Blackbox requested at least "+ ++ show (subn + 1)+ ++ " renders of function at argument "+ ++ show n+ ++ " but found only "+ ++ show (length funcs)+ )+ Just func ->+ Right func+ -- | 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 -- template.@@ -186,21 +223,14 @@ ++ "used ~CONST[" ++ show n ++ "], but was:\n\n" ++ show inp) _ -> Nothing Component (Decl n subn l') ->- case IntMap.lookup n (bbFunctions bbCtx) of- Just funcs ->- case indexMaybe funcs subn of- Nothing ->- Just ( "Blackbox requested at least " ++ show (subn+1)- ++ " renders of function at argument " ++ show n ++ " but "- ++ "found only " ++ show (length funcs) )- Just _ ->- orElses $- map- (verifyBlackBoxContext bbCtx . N.BBTemplate)- (concatTups l')- Nothing ->- Just ( "Blackbox requested instantiation of function at argument "- ++ show n ++ ", but BlackBoxContext did not contain one.")+ case lookupFunctionInstantiation bbCtx n subn of+ Left lookupErr ->+ Just lookupErr+ Right _ ->+ orElses $+ map+ (verifyBlackBoxContext bbCtx . N.BBTemplate)+ (concatTups l') _ -> case inputHole e of Nothing ->@@ -332,7 +362,7 @@ (canonicalizePath toCanonicalize) (error [I.i|Could not find data file #{show toCanonicalize}. Does it exist?|]) | otherwise = unsafePerformIO $ do- let candidates = map (</> toCanonicalize) idirs+ let candidates = map (</> toCanonicalize) (nubOrd idirs) found <- filterM doesFileExist candidates case found of [] -> error [I.i|@@ -481,11 +511,8 @@ (o,oTy,_) <- idToExpr <$> bitraverse (lineToIdentifier b) (return . lineToType b) l is <- mapM (fmap idToExpr . bitraverse (lineToIdentifier b) (return . lineToType b)) ls sp <- getSrcSpan- let func0 = IntMap.lookup n (bbFunctions b)- errr = concat [ "renderElem: not enough functions rendered? Needed "- , show (subN +1 ), " got only ", show (length (fromJust func0)) ]- case indexNote' errr subN <$> func0 of- Just (templ0,_,libs,imps,inc,pCtx) -> do+ case lookupFunctionInstantiation b n subN of+ Right (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 b' . renderLazy . layoutPretty layoutOptions@@ -524,12 +551,8 @@ , Data.Text.unpack (bbName b), ". Verification procedure " , "reported:\n\n" ++ err0 ] throw (ClashException sp ($(curLoc) ++ err1) Nothing)- Nothing ->- let err1 = concat [show n- , "'th argument isn't a function, only "- , show (IntMap.keys (bbFunctions b))- , "are."]- in throw (ClashException sp ($(curLoc) ++ err1) Nothing)+ Left err0 ->+ throw (ClashException sp ($(curLoc) ++ "renderElem: " ++ err0) Nothing) renderElem b (SigD e m) = do e' <- Text.concat <$> mapM (fmap ($ 0) . renderElem b) e@@ -897,7 +920,9 @@ renderTag b (MaxIndex e) = return . Text.pack . show . vecLen $ lineToType b [e] where vecLen (Vector n _) = n-1+ vecLen (Void (Just (Vector n _))) = n-1 vecLen (MemBlob n _) = n-1+ vecLen (Void (Just (MemBlob n _))) = n-1 vecLen thing = error $ $(curLoc) ++ "vecLen of a non-vector-like type: " ++ show thing
src/Clash/Netlist/Types.hs view
@@ -32,9 +32,6 @@ import Control.DeepSeq import qualified Control.Lens as Lens import Control.Lens (Lens', (.=))-#if !MIN_VERSION_base(4,13,0)-import Control.Monad.Fail (MonadFail)-#endif import Control.Monad.Reader (ReaderT, MonadReader) import qualified Control.Monad.State as Lazy (State) import qualified Control.Monad.State.Strict as Strict@@ -57,17 +54,15 @@ import qualified Data.Set as Set import Data.Text (Text) +#if __GLASGOW_HASKELL__ <= 910 import Data.Typeable (Typeable)+#endif import Data.Text.Prettyprint.Doc.Extra (Doc) import GHC.Generics (Generic) import GHC.Stack import Language.Haskell.TH.Syntax (Lift) -#if MIN_VERSION_ghc(9,0,0) import GHC.Types.SrcLoc (SrcSpan)-#else-import SrcLoc (SrcSpan)-#endif import Clash.Annotations.SynthesisAttributes(Attr) import Clash.Annotations.BitRepresentation (FieldAnn)@@ -80,7 +75,8 @@ import Clash.Core.Var (Id) import Clash.Core.TyCon (TyConMap) import Clash.Core.VarEnv (VarEnv)-import Clash.Driver.Types (BindingMap, ClashEnv(..), ClashOpts(..))+import Clash.Driver.Types+ (BindingMap, ClashEnv(..), ClashOpts(..)) import Clash.Netlist.BlackBox.Types (BlackBoxTemplate) import Clash.Primitives.Types (CompiledPrimMap) import Clash.Signal.Internal@@ -368,6 +364,12 @@ data SomeBackend where SomeBackend :: Backend backend => backend -> SomeBackend +onSomeBackend :: (forall b. Backend b => b -> a) -> SomeBackend -> a+onSomeBackend f (SomeBackend b) = f b++fromSomeBackend :: (forall b. Backend b => b -> a) -> Lens.Getter SomeBackend a+fromSomeBackend f = Lens.to (onSomeBackend f)+ type Comment = Text type Directive = Text @@ -828,7 +830,10 @@ | L -- ^ Low | U -- ^ Undefined | Z -- ^ High-impedance- deriving (Eq,Show,Typeable,Lift)+ deriving (Eq,Show,Lift)+#if __GLASGOW_HASKELL__ <= 910+ deriving Typeable+#endif toBit :: Integer -- ^ mask
src/Clash/Netlist/Util.hs view
@@ -2,7 +2,7 @@ Copyright : (C) 2012-2016, University of Twente, 2017 , Myrtle Software Ltd 2017-2018, Google Inc.- 2021-2024, QBayLogic B.V.+ 2021-2026, QBayLogic B.V. 2022 , Google Inc. License : BSD2 (see the file LICENSE) Maintainer : QBayLogic B.V. <devops@qbaylogic.com>@@ -14,9 +14,6 @@ {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE MagicHash #-}-#if !MIN_VERSION_ghc(8,8,0)-{-# LANGUAGE MonadFailDesugaring #-}-#endif {-# LANGUAGE MultiWayIf #-} {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE OverloadedStrings #-}@@ -50,6 +47,7 @@ import Control.Applicative (Alternative((<|>))) import Data.List (unzip4, partition) import qualified Data.List as List+import Data.List.NonEmpty (NonEmpty((:|))) import qualified Data.Map as Map import Data.Map (Map) import Data.Maybe@@ -62,23 +60,14 @@ import Data.Text.Lazy (toStrict) import Data.Text.Prettyprint.Doc.Extra -#if MIN_VERSION_base(4,15,0) import GHC.Num.Integer (Integer (..))-#else-import GHC.Integer.GMP.Internals (Integer (..), BigNat (..))-#endif import GHC.Stack (HasCallStack) import GHC.TypeLits (someNatVal) import GHC.TypeNats (SomeNat(..)) -#if MIN_VERSION_ghc(9,0,0) import GHC.Utils.Monad (zipWith3M) import GHC.Utils.Outputable (ppr, showSDocUnsafe)-#else-import MonadUtils (zipWith3M)-import Outputable (ppr, showSDocUnsafe)-#endif import Clash.Annotations.TopEntity (TopEntity(..), PortName(..), defSyn)@@ -133,11 +122,7 @@ import Clash.Util.Supply hmFindWithDefault :: (Eq k, Hashable k) => v -> k -> HashMap k v -> v-#if MIN_VERSION_unordered_containers(0,2,11) hmFindWithDefault = HashMap.findWithDefault-#else-hmFindWithDefault = HashMap.lookupDefault-#endif -- | Generate a simple port_name expression. See: --@@ -1838,8 +1823,9 @@ where freeVars = concatMap (Lens.toListOf typeFreeVars) (map coreTypeOf tms) -iteAlts :: HWType -> [Alt] -> Maybe (Term,Term)-iteAlts sHTy [(pat0,alt0),(pat1,alt1)] | validIteSTy sHTy = case pat0 of+-- | Attempt to make an if-then-else construction out of this Case+iteAlts :: HWType -> NonEmpty Alt -> Maybe (Term,Term)+iteAlts sHTy ((pat0,alt0) :| [(pat1,alt1)]) | validIteSTy sHTy = case pat0 of DataPat dc _ _ -> case dcTag dc of 2 -> Just (alt0,alt1) _ -> Just (alt1,alt0)@@ -2189,21 +2175,15 @@ C.WordLiteral w -> HW.Literal (Just (Unsigned iw,iw)) $ NumLit w C.Int64Literal i -> HW.Literal (Just (Signed 64,64)) $ NumLit i C.Word64Literal w -> HW.Literal (Just (Unsigned 64,64)) $ NumLit w-#if MIN_VERSION_ghc(8,8,0) C.Int8Literal i -> HW.Literal (Just (Signed 8,8)) $ NumLit i C.Int16Literal i -> HW.Literal (Just (Signed 16,16)) $ NumLit i C.Int32Literal i -> HW.Literal (Just (Signed 32,32)) $ NumLit i C.Word8Literal w -> HW.Literal (Just (Unsigned 8,8)) $ NumLit w C.Word16Literal w -> HW.Literal (Just (Unsigned 16,16)) $ NumLit w C.Word32Literal w -> HW.Literal (Just (Unsigned 32,32)) $ NumLit w-#endif C.CharLiteral c -> HW.Literal (Just (Unsigned 21,21)) . NumLit . toInteger $ ord c C.FloatLiteral w -> HW.Literal (Just (BitVector 32,32)) (NumLit $ toInteger w) C.DoubleLiteral w -> HW.Literal (Just (BitVector 64,64)) (NumLit $ toInteger w) C.NaturalLiteral n -> HW.Literal (Just (Unsigned iw,iw)) $ NumLit n-#if MIN_VERSION_base(4,15,0) C.ByteArrayLiteral (ByteArray ba) -> HW.Literal Nothing (NumLit (IP ba))-#else- C.ByteArrayLiteral (ByteArray ba) -> HW.Literal Nothing (NumLit (Jp# (BN# ba)))-#endif C.StringLiteral s -> HW.Literal Nothing $ StringLit s
src/Clash/Normalize.hs view
@@ -2,7 +2,7 @@ Copyright : (C) 2012-2016, University of Twente, 2016 , Myrtle Software Ltd, 2017 , Google Inc.,- 2021-2023, QBayLogic B.V.+ 2021-2026, QBayLogic B.V. License : BSD2 (see the file LICENSE) Maintainer : QBayLogic B.V. <devops@qbaylogic.com> @@ -399,7 +399,10 @@ -- Note that we do this as the very last step, after all constant propagation -- has been done to avoid #3036. topdownSucR (apply "collapseRHSNoops" collapseRHSNoops) >->- topdownSucR (apply "inlineCleanup" inlineCleanup)+ topdownSucR (apply "inlineCleanup" inlineCleanup) >->+ bottomupR (apply "caseCon" caseCon) >-> -- https://github.com/clash-lang/clash-compiler/issues/3159 / #3204+ bottomupR (apply "flattenLet" flattenLet) >-> -- https://github.com/clash-lang/clash-compiler/issues/3185+ topdownSucR (apply "topLet" topLet) goCheap c@(CLeaf (nm2,(Binding _ _ inl2 _ e _))) | isNoInline inl2 = (Nothing ,[c])
src/Clash/Normalize/PrimitiveReductions.hs view
@@ -43,7 +43,7 @@ import Control.Monad.Trans.Class (lift) import Control.Monad.Trans.Maybe (MaybeT (..)) import Data.Bifunctor (second)-import Data.List (mapAccumR)+import Data.List (mapAccumR, uncons) import Data.List.Extra (zipEqual) #if MIN_VERSION_base(4,20,0) import qualified Data.List.NonEmpty as NE hiding (unzip)@@ -56,30 +56,27 @@ import Data.Text.Extra (showt) import GHC.Stack (HasCallStack) -#if MIN_VERSION_ghc(9,0,0) import GHC.Builtin.Names (boolTyConKey, typeNatAddTyFamNameKey, typeNatMulTyFamNameKey, typeNatSubTyFamNameKey) import GHC.Types.SrcLoc (wiredInSrcSpan)-#else-import PrelNames- (boolTyConKey, typeNatAddTyFamNameKey, typeNatMulTyFamNameKey,- typeNatSubTyFamNameKey)-import SrcLoc (wiredInSrcSpan)-#endif import Clash.Core.DataCon (DataCon)+import Clash.Core.FreeVars (typeFreeVars) import Clash.Core.HasType+ import Clash.Core.Literal (Literal (..)) import Clash.Core.Name (nameOcc, Name(..), NameSort(User), mkUnsafeSystemName) import Clash.Core.Pretty (showPpr)+import Clash.Core.Subst (extendTvSubst, mkSubst, substTy) import Clash.Core.Term (IsMultiPrim (..), CoreContext (..), PrimInfo (..), Term (..), WorkInfo (..), Pat (..), collectTermIds, mkApps, PrimUnfolding(..)) import Clash.Core.Type (LitTy (..), Type (..), TypeView (..), coreView1, mkFunTy, mkTyConApp,+ normalizeType, splitFunForallTy, tyView) import Clash.Core.TyCon (TyConMap, TyConName, tyConDataCons, tyConName)@@ -735,22 +732,34 @@ (uniqs1,(vars,elems)) = second (second sconcat . NE.unzip) $ extractElems uniqs0 is1 consCon aTy 'D' n arg snatDc = Maybe.fromMaybe (error "reduceDFold: faild to build SNat") $ do- (_ltv:Right snTy:_,_) <- pure (splitFunForallTy (inferCoreTypeOf tcm fun))+ (_ltv:_rubp:Right snTy:_,_) <- pure (splitFunForallTy (inferCoreTypeOf tcm fun)) (TyConApp snatTcNm _) <- pure (tyView snTy) snatTc <- UniqMap.lookup snatTcNm tcm Maybe.listToMaybe (tyConDataCons snatTc)- lbody = doFold (buildSNat snatDc) (n-1) (NE.toList vars)+ ubp k = Maybe.fromMaybe+ (error "reduceDFold: failed to extract upper bound proof") $ do+ (_ltv:Right ubpT:_,_) <- pure (splitFunForallTy (inferCoreTypeOf tcm fun))+ -- toListOf does not de-duplicate, but we know that there is only+ -- one free variable in here, thus, taking the first element is fine+ (tvN, _) <- uncons $ Lens.toListOf typeFreeVars ubpT+ let subst = extendTvSubst (mkSubst is0) tvN (LitTy (NumTy k))+ let witness = normalizeType tcm (substTy subst ubpT)+ (TyConApp tupTcNm _) <- pure (tyView witness)+ witnessTc <- UniqMap.lookup tupTcNm tcm+ Maybe.listToMaybe (tyConDataCons witnessTc)+ lbody = doFold ubp (buildSNat snatDc) (n-1) (NE.toList vars) lb = Letrec (NE.init elems) lbody uniqSupply Lens..= uniqs1 changed lb go _ ty = error $ $(curLoc) ++ "reduceDFold: argument does not have a vector type: " ++ showPpr ty - doFold _ _ [] = start- doFold snDc k (x:xs) = mkApps fun+ doFold _ _ _ [] = start+ doFold ubp snDc k (x:xs) = mkApps fun [Right (LitTy (NumTy k))+ ,Left (Data (ubp k)) ,Left (snDc k) ,Left x- ,Left (doFold snDc (k-1) xs)+ ,Left (doFold ubp snDc (k-1) xs) ] -- | Replace an application of the @Clash.Sized.Vector.head@ primitive on
src/Clash/Normalize/Strategy.hs view
@@ -1,6 +1,6 @@ {-| Copyright : (C) 2012-2016, University of Twente,- (C) 2021, QBayLogic B.V.+ (C) 2021-2026, QBayLogic B.V. License : BSD2 (see the file LICENSE) Maintainer : QBayLogic B.V. <devops@qbaylogic.com> @@ -17,7 +17,7 @@ import Clash.Rewrite.Types import Clash.Rewrite.Util --- [Note: bottomup traversal evalConst]+-- [Note: bottomup traversal reduceConst] -- -- 2-May-2019: There is a bug in the evaluator where all data constructors are -- considered lazy, even though their declaration says they have strict fields.@@ -36,6 +36,7 @@ bindConst >-> letTL >-> evalConst >-!-> cse >-!-> cleanup >->+ elimCaseBigNum >-> -- see [Note] late elimCaseBigNum xOptim >-> rmDeadcode >-> cleanup >-> bindSimIO >-> recLetRec >-> splitArgs where@@ -46,9 +47,10 @@ rmUnusedExpr = bottomupR (apply "removeUnusedExpr" removeUnusedExpr) rmDeadcode = bottomupR (apply "deadcode" deadCode) bindConst = topdownR (apply "bindConstantVar" bindConstantVar)- -- See [Note] bottomup traversal evalConst:- evalConst = bottomupR (apply "evalConst" reduceConst)+ -- See [Note] bottomup traversal reduceConst:+ evalConst = bottomupR (apply "reduceConst" reduceConst) cse = topdownR (apply "CSE" simpleCSE)+ elimCaseBigNum = topdownR (apply "elimCaseBigNum" elimCaseBigNumInternals) xOptim = bottomupR (apply "xOptimize" xOptimize) cleanup = topdownR (apply "etaExpandSyn" etaExpandSyn) >-> topdownSucR (apply "inlineCleanup" inlineCleanup) !->@@ -135,6 +137,17 @@ , ("zeroWidthSpec", zeroWidthSpec) -- See Note [zeroWidthSpec enabling transformations] ]++{-+[Note] late elimCaseBigNum++elimCaseBigNum is placed fairly late in the pipeline, after any constant folding and after caseCon.+Because Naturals also hide inside SNat/Nat/KnownNats, and those can be bigger then 64bits.+But they're ultimately monomorphic and thus static and will be evaluated.+We just have to make sure that evaluation happens before we do elimCaseBigNum.++For an example of where this can happen see foldableSNat in tests/shouldwork/Issues/T3157_IntegerNaturalInternals.hs+-} {- Note [zeroWidthSpec enabling transformations]
src/Clash/Normalize/Transformations/Case.hs view
@@ -24,14 +24,11 @@ , caseLet , caseOneAlt , elimExistentials+ , elimCaseBigNumInternals ) where import Control.Exception.Base (patError)-#if MIN_VERSION_base(4,16,0) import GHC.Prim.Panic (absentError)-#else-import Control.Exception.Base (absentError)-#endif import qualified Control.Lens as Lens import Control.Monad.State.Strict (evalState) import Data.Bifunctor (second)@@ -44,11 +41,7 @@ import qualified Data.Text.Extra as Text (showt) import GHC.Stack (HasCallStack) -#if MIN_VERSION_base(4,15,0) import GHC.Num.Integer (Integer(..))-#else-import GHC.Integer.GMP.Internals (BigNat(..), Integer(..))-#endif import Clash.Sized.Internal.BitVector as BV (BitVector, eq#) import Clash.Sized.Internal.Index as I (Index, eq#)@@ -68,6 +61,7 @@ , collectTicks, mkApps, mkTicks, patIds, stripTicks, Bind(..)) import Clash.Core.TyCon (TyConMap) import Clash.Core.Type (LitTy(..), Type(..), TypeView(..), coreView1, tyView)+import Clash.Core.TysPrim (integerIsDc, naturalNsDc) import Clash.Core.Util (listToLets, mkInternalVar) import Clash.Core.VarEnv ( InScopeSet, elemVarSet, extendInScopeSet, extendInScopeSetList, mkVarSet@@ -388,11 +382,7 @@ else changed e | dcTag dc == 2 , l >= 2^(63::Int)-#if MIN_VERSION_base(4,15,0) = let !(IP ba) = l-#else- = let !(Jp# !(BN# ba)) = l-#endif ba' = BA.ByteArray ba fvs = Lens.foldMapOf freeLocalIds unitVarSet e bind = NonRec x (Literal (ByteArrayLiteral ba'))@@ -401,11 +391,7 @@ else changed e | dcTag dc == 3 , l < ((-2)^(63::Int))-#if MIN_VERSION_base(4,15,0) = let !(IN ba) = l-#else- = let !(Jn# !(BN# ba)) = l-#endif ba' = BA.ByteArray ba fvs = Lens.foldMapOf freeLocalIds unitVarSet e bind = NonRec x (Literal (ByteArrayLiteral ba'))@@ -434,11 +420,7 @@ else changed e | dcTag dc == 2 , l >= 2^(64::Int)-#if MIN_VERSION_base(4,15,0) = let !(IP ba) = l-#else- = let !(Jp# !(BN# ba)) = l-#endif ba' = BA.ByteArray ba fvs = Lens.foldMapOf freeLocalIds unitVarSet e bind = NonRec x (Literal (ByteArrayLiteral ba'))@@ -722,3 +704,41 @@ elimExistentials _ e = return e {-# SCC elimExistentials #-}++-- | This finds cases on Integers and Naturals and rewrites them+-- to remove the alternatives with bignums/bytearrays in them.+--+-- Natural and Integer are defined as:+-- @+-- data Natural = NS Word# | NB ByteArray#+-- data Integer = IS Int# | IP ByteArray# | IN ByteArray#+-- @+-- Both 'Natural' and 'Integer' have invariants stating that they will only use NB/IP/IN+-- when their values doesn't fit in NS/IS. And the code in base also makes use of that.+-- So we can be sure that small values, that are representable in HDL, are always encoded with NS/IS.+--+-- Because the NB/IP/IN don't/can't exist in HDL, this transformation looks for case with+-- patterns for NS/IS and just always picks those alternatives, and removes the other+-- alternatives.+--+-- This is as "safe" as the rest of the Natural/Integer handling that clash does in HDL,+-- because numbers bigger then Word/Int can't exist there anyway.+elimCaseBigNumInternals :: HasCallStack => NormRewrite+elimCaseBigNumInternals _ e@(Case scrut altsTy alts0@(_:_:_)) =+ go alts0+ where+ go [] = return e+ go ((pat,altE):alts) = case pat of+ DataPat dc [] [x] | (dc == integerIsDc || dc == naturalNsDc) ->+ if elemVarSet x fvs then+ -- field used, turn the case into a projection+ -- It seems this pattern never happens after ANF.+ changed (Case scrut altsTy [(DataPat dc [] [x],altE)])+ else+ -- field not used, eliminate the case completely+ changed altE+ _ -> go alts+ where+ fvs = Lens.foldMapOf freeLocalIds unitVarSet altE++elimCaseBigNumInternals _ e = return e
src/Clash/Normalize/Transformations/DEC.hs view
@@ -37,9 +37,6 @@ ( disjointExpressionConsolidation ) where -#if !MIN_VERSION_base(4,18,0)-import Control.Applicative (liftA2)-#endif import Control.Lens ((^.), _1) import qualified Control.Lens as Lens import qualified Control.Monad as Monad@@ -61,19 +58,9 @@ import GHC.Stack (HasCallStack) import qualified Language.Haskell.TH as TH -#if MIN_VERSION_ghc(9,6,0) import GHC.Core.Make (chunkify, mkChunkified)-#elif MIN_VERSION_ghc(8,10,0)-import GHC.Hs.Utils (chunkify, mkChunkified)-#else-import HsUtils (chunkify, mkChunkified)-#endif -#if MIN_VERSION_ghc(9,0,0) import GHC.Settings.Constants (mAX_TUPLE_SIZE)-#else-import Constants (mAX_TUPLE_SIZE)-#endif -- internal import Clash.Core.DataCon (DataCon)@@ -112,13 +99,7 @@ import qualified Clash.Sized.Internal.Unsigned import qualified GHC.Base import qualified GHC.Classes-#if MIN_VERSION_base(4,15,0) import qualified GHC.Num.Integer-#else--- interger-gmp primitives are defined in the hidden module GHC.Integer.Type,--- but exported from GHC.Integer-import qualified GHC.Integer as GHC.Integer.Type-#endif import qualified GHC.Prim -- | This transformation lifts applications of global binders out of@@ -763,19 +744,11 @@ ,('GHC.Base.modInt,lastNotPow2) ,('GHC.Classes.divInt#,lastNotPow2) ,('GHC.Classes.modInt#,lastNotPow2)-#if MIN_VERSION_base(4,15,0) ,('GHC.Num.Integer.integerMul,bothNotPow2) ,('GHC.Num.Integer.integerDiv,lastNotPow2) ,('GHC.Num.Integer.integerMod,lastNotPow2) ,('GHC.Num.Integer.integerQuot,lastNotPow2) ,('GHC.Num.Integer.integerRem,lastNotPow2)-#else- ,('GHC.Integer.Type.timesInteger,bothNotPow2)- ,('GHC.Integer.Type.divInteger,lastNotPow2)- ,('GHC.Integer.Type.modInteger,lastNotPow2)- ,('GHC.Integer.Type.quotInteger,lastNotPow2)- ,('GHC.Integer.Type.remInteger,lastNotPow2)-#endif ,('(GHC.Prim.*#),bothNotPow2) ,('GHC.Prim.quotInt#,lastNotPow2) ,('GHC.Prim.remInt#,lastNotPow2)
src/Clash/Normalize/Transformations/Specialize.hs view
@@ -2,7 +2,7 @@ Copyright : (C) 2012-2016, University of Twente, 2016-2017, Myrtle Software Ltd, 2017-2018, Google Inc.,- 2021-2023, QBayLogic B.V.+ 2021-2026, QBayLogic B.V. License : BSD2 (see the file LICENSE) Maintainer : QBayLogic B.V. <devops@qbaylogic.com> @@ -45,13 +45,10 @@ import qualified Data.Set.Ordered.Extra as OSet import qualified Data.Text as Text import qualified Data.Text.Extra as Text+import GHC.BasicTypes.Extra (isNoInline) import GHC.Stack (HasCallStack) -#if MIN_VERSION_ghc(9,0,0) import GHC.Types.Basic (InlineSpec (..))-#else-import BasicTypes (InlineSpec (..))-#endif import qualified Clash.Sized.Internal.BitVector as BV (BitVector, fromInteger#) import qualified Clash.Sized.Internal.Index as I (Index, fromInteger#)@@ -90,7 +87,7 @@ , typeTranslator, workFreeBinders, debugOpts, topEntities, specializationLimit) import Clash.Rewrite.Util ( mkBinderFor, mkDerivedName, mkFunction, mkTmBinderFor, setChanged, changed- , normalizeTermTypes, normalizeId)+ , normalizeTermTypes, normalizeId, whnfRW) import Clash.Rewrite.WorkFree (isWorkFree) import Clash.Normalize.Types ( NormRewrite, NormalizeSession, specialisationCache, specialisationHistory)@@ -293,9 +290,17 @@ = do specInfo<- constantSpecInfo ctx e2 if csrFoundConstant specInfo then let newBindings = csrNewBindings specInfo in- if null newBindings then- -- Whole of e2 is constant- specialize ctx (App e1 e2)+ if null newBindings then do+ -- Whole of e2 is constant, we reduce it here eagerly before specialization+ -- because we have observed long running compile times when having+ -- recursively defined constants, see:+ -- https://github.com/clash-lang/clash-compiler/issues/3129+ e2Red <- case collectArgs e2 of+ (Prim p0, _) -> whnfRW False ctx e2 $ \_ctx1 e2Red -> case e2Red of+ (collectArgs -> (Prim p1, _)) | primName p0 == primName p1 -> return e2+ _ -> changed e2Red+ _ -> return e2+ specialize ctx (App e1 e2Red) else do -- Parts of e2 are constant let is1 = extendInScopeSetList is0 (fst <$> csrNewBindings specInfo)@@ -332,10 +337,10 @@ If one of these had been specialized, the other two would hit that term in the specialization cache, saving Clash from having to re-do work which is in effect-the same. To preserve this behaviour, we use 'stripAllTicks' on the keys for+the same. To preserve this behavior, we use 'stripAllTicks' on the keys for the specialization cache. -TODO While this preserves the old behaviour, the old behaviour is likely not+TODO While this preserves the old behavior, the old behavior is likely not quite what we want. Using a value from the specialization cache may change the ticks present, which can affect naming / debugging information in generated HDL. We may also not want to look at ticks, as then the specialization cache will@@ -351,17 +356,11 @@ where enumInlineSpec :: InlineSpec -> Int enumInlineSpec = \case-#if MIN_VERSION_ghc(9,2,0) NoUserInlinePrag {} -> -1-#else- NoUserInline {} -> -1-#endif Inline {} -> 0 Inlinable {} -> 1 NoInline {} -> 2-#if MIN_VERSION_ghc(9,4,0) Opaque {} -> 3-#endif -- | Specialize an application on its argument specialize'@@ -449,21 +448,31 @@ args -- Determine name the resulting specialized function, and the -- form of the specialized-on argument- (fId,inl',specArg') <- case specArg of+ (newName, inl', specArg') <- case specArg of Left a@(collectArgsTicks -> (Var g,gArgs,_gTicks)) -> if isPolyFun tcm a then do -- In case we are specializing on an argument that is a- -- global function then we use that function's name as the- -- name of the specialized higher-order function.+ -- global function then we use that function's name as part+ -- of the name of the specialized higher-order function. -- Additionally, we will return the body of the global -- function, instead of a variable reference to the -- global function. --- -- This will turn things like @mealy g k@ into a new- -- binding @g'@ where both the body of @mealy@ and @g@+ -- This will turn things like @mealy g@ into a new+ -- binding 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. --+ -- The name of the new function depends on NOINLINE / OPAQUE+ -- annotations.+ --+ -- OPAQUE | Name for @f g@+ -- -----------|---------------+ -- f and g | f_g+ -- f | f+ -- g | g+ -- !f and !g | f_g+ -- -- 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@@ -473,15 +482,15 @@ else fmap bindingTerm gTmM return- ( g+ ( specializeName (inl, varName f) (bindingSpec <$> gTmM, varName g) , preferNoInline inl (maybe noUserInline bindingSpec gTmM) , maybe specArg (Left . (`mkApps` gArgs)) gBody )- else return (f,inl,specArg)- _ -> return (f,inl,specArg)+ else return (varName f, inl, specArg)+ _ -> return (varName f, inl, specArg) -- Create specialized functions let newBody = mkAbstraction (mkApps bodyTm (argVars ++ [specArg'])) (boundArgs ++ specBndrs)- newf <- mkFunction (varName fId) sp inl' newBody+ newf <- mkFunction newName sp inl' newBody -- Remember specialization (extra.specialisationHistory) %= UniqMap.insertWith (+) f 1 (extra.specialisationCache) %= Map.insert (f,argLen,specAbs) newf@@ -491,12 +500,21 @@ Nothing -> return e where noUserInline :: InlineSpec-#if MIN_VERSION_ghc(9,2,0) noUserInline = NoUserInlinePrag-#else- noUserInline = NoUserInline-#endif + specializeName :: (InlineSpec, Name Term) -> (Maybe InlineSpec, Name Term) -> Name Term+ specializeName (spec0, n0) (spec1, n1)+ | (ann0 && ann1) || (not ann0 && not ann1)+ = n0{nameOcc=nameOcc n0 <> "_" <> stripMods (nameOcc n1)}+ | ann0 = n0+ | otherwise = n1+ where+ ann0 = isNoInline spec0+ ann1 = fmap isNoInline spec1 == Just True++ stripMods :: Text.Text -> Text.Text+ stripMods = Text.takeWhileEnd (/= '.')+ collectBndrsMinusApps :: Term -> [Name a] collectBndrsMinusApps = reverse . go [] where@@ -522,11 +540,7 @@ -- Create a new function if an alpha-equivalent binder doesn't exist newf <- case UniqMap.elems existing of [] -> do (cf,sp) <- Lens.use curFun-#if MIN_VERSION_ghc(9,2,0) mkFunction (appendToName (varName cf) "_specF") sp NoUserInlinePrag newBody-#else- mkFunction (appendToName (varName cf) "_specF") sp NoUserInline newBody-#endif (b:_) -> return (bindingId b) -- Create specialized argument let newArg = Left $ mkApps (Var newf) specVars
src/Clash/Normalize/Util.hs view
@@ -46,11 +46,7 @@ import qualified Data.Text as Text import qualified Data.Text.Extra as Text -#if MIN_VERSION_ghc(9,0,0) import GHC.Builtin.Names (eqTyConKey)-#else-import PrelNames (eqTyConKey)-#endif import Clash.Annotations.Primitive (extractPrim) import Clash.Core.FreeVars
src/Clash/Primitives/DSL.hs view
@@ -1,6 +1,6 @@ {-| Copyright : (C) 2019, Myrtle Software Ltd.- 2020-2024, QBayLogic B.V.+ 2020-2026, QBayLogic B.V. 2021, Myrtle.ai 2022-2023, Google Inc License : BSD2 (see the file LICENSE)@@ -95,9 +95,8 @@ ) where import Control.Lens hiding (Indexed, assign)-#if MIN_VERSION_mtl(2,3,0)+import Control.Exception (throw) import Control.Monad (forM, forM_, zipWithM)-#endif import Control.Monad.State import Data.Default (Default(def)) import Data.IntMap (IntMap)@@ -119,13 +118,14 @@ import Clash.Backend hiding (Usage, fromBV, toBV) import Clash.Backend.VHDL (VHDLState) import Clash.Explicit.Signal (ResetPolarity(..), vResetPolarity)-import Clash.Netlist.BlackBox.Util (exprToString, getDomainConf, renderElem)+import Clash.Netlist.BlackBox.Util+ (exprToString, getDomainConf, lookupFunctionInstantiation, renderElem) import Clash.Netlist.BlackBox.Types (BlackBoxTemplate, Element(Component, Text), Decl(..)) import qualified Clash.Netlist.Id as Id import Clash.Netlist.Types hiding (Component, toBit) import Clash.Netlist.Util-import Clash.Util (clogBase)+import Clash.Util (ClashException(..), clogBase, curLoc) import qualified Data.String.Interpolate as I import qualified Language.Haskell.TH as TH import qualified Language.Haskell.TH.Syntax as TH@@ -837,6 +837,13 @@ resName <- declare' (ctxName <> "_" <> "ho" <> showt fPos <> "_" <> showt fSubPos <> "_res") resTy+ -- Pick the fSubPos-th HO instantiation (if present) and reuse its usage.+ sp <- zoom bsBackend getSrcSpan+ case lookupFunctionInstantiation bbCtx fPos fSubPos of+ Left err0 ->+ throw (ClashException sp ($(curLoc) ++ "instHO: " ++ err0) Nothing)+ Right (_, usage, _, _, _, _) ->+ declareUseOnce usage resName let res = ([Text (Id.toLazyText resName)], bbResTy) -- Render HO argument to plain text
src/Clash/Primitives/GHC/Int.hs view
@@ -29,11 +29,9 @@ \case IntegerLiteral i -> Just i IntLiteral i -> Just i-#if MIN_VERSION_ghc(8,8,0) Int8Literal i -> Just i Int16Literal i -> Just i Int32Literal i -> Just i-#endif Int64Literal i -> Just i _ -> Nothing
src/Clash/Primitives/GHC/Word.hs view
@@ -32,11 +32,9 @@ getWordLit = \case WordLiteral i -> Just i-#if MIN_VERSION_ghc(8,8,0) Word8Literal i -> Just i Word16Literal i -> Just i Word32Literal i -> Just i-#endif Word64Literal i -> Just i _ -> Nothing
src/Clash/Primitives/Sized/ToInteger.hs view
@@ -37,7 +37,7 @@ import qualified GHC.Utils.Outputable as Outputable import GHC.Types.Error (DiagnosticReason (WarningWithoutFlag)) import GHC.Types.SrcLoc (isGoodSrcSpan)-#elif MIN_VERSION_ghc(9,6,0)+#else import GHC.Utils.Error (DiagOpts(..), mkPlainDiagnostic, mkPlainMsgEnvelope, pprLocMsgEnvelopeDefault) import GHC.Utils.Outputable@@ -46,35 +46,6 @@ import qualified GHC.Utils.Outputable as Outputable import GHC.Types.Error (DiagnosticReason (WarningWithoutFlag)) import GHC.Types.SrcLoc (isGoodSrcSpan)-#elif MIN_VERSION_ghc(9,4,0)-import GHC.Utils.Error- (DiagOpts(..), mkPlainDiagnostic, mkPlainMsgEnvelope, pprLocMsgEnvelope)-import GHC.Utils.Outputable- (blankLine, empty, int, integer, showSDocUnsafe, text, ($$), ($+$), (<+>),- defaultSDocContext )-import qualified GHC.Utils.Outputable as Outputable-import GHC.Types.Error (DiagnosticReason (WarningWithoutFlag))-import GHC.Types.SrcLoc (isGoodSrcSpan)-#elif MIN_VERSION_ghc(9,2,0)-import GHC.Utils.Error (mkPlainWarnMsg, pprLocMsgEnvelope)-import GHC.Utils.Outputable- (blankLine, empty, int, integer, showSDocUnsafe, text, ($$), ($+$), (<+>))-import qualified GHC.Utils.Outputable as Outputable-import GHC.Types.SrcLoc (isGoodSrcSpan)-#elif MIN_VERSION_ghc(9,0,0)-import GHC.Driver.Session (unsafeGlobalDynFlags)-import GHC.Utils.Error (mkPlainWarnMsg, pprLocErrMsg)-import GHC.Utils.Outputable- (blankLine, empty, int, integer, showSDocUnsafe, text, ($$), ($+$), (<+>))-import qualified GHC.Utils.Outputable as Outputable-import GHC.Types.SrcLoc (isGoodSrcSpan)-#else-import DynFlags (unsafeGlobalDynFlags)-import ErrUtils (mkPlainWarnMsg, pprLocErrMsg)-import Outputable- (blankLine, empty, int, integer, showSDocUnsafe, text, ($$), ($+$), (<+>))-import qualified Outputable-import SrcLoc (isGoodSrcSpan) #endif import Clash.Annotations.Primitive (HDL (Verilog,VHDL))@@ -115,22 +86,11 @@ diag = mkPlainDiagnostic WarningWithoutFlag [] (warnMsg i1 iw $+$ blankLine $+$ srcInfo1) warnMsg1 = mkPlainMsgEnvelope opts sp diag warnMsg2 = pprLocMsgEnvelopeDefault warnMsg1-#elif MIN_VERSION_ghc(9,6,0)+#else opts = DiagOpts mempty mempty False False Nothing defaultSDocContext diag = mkPlainDiagnostic WarningWithoutFlag [] (warnMsg i1 iw $+$ blankLine $+$ srcInfo1) warnMsg1 = mkPlainMsgEnvelope opts sp diag warnMsg2 = pprLocMsgEnvelopeDefault warnMsg1-#elif MIN_VERSION_ghc(9,4,0)- opts = DiagOpts mempty mempty False False Nothing defaultSDocContext- diag = mkPlainDiagnostic WarningWithoutFlag [] (warnMsg i1 iw $+$ blankLine $+$ srcInfo1)- warnMsg1 = mkPlainMsgEnvelope opts sp diag- warnMsg2 = pprLocMsgEnvelope warnMsg1-#elif MIN_VERSION_ghc(9,2,0)- warnMsg1 = mkPlainWarnMsg sp (warnMsg i1 iw $+$ blankLine $+$ srcInfo1)- warnMsg2 = pprLocMsgEnvelope warnMsg1-#else- warnMsg1 = mkPlainWarnMsg unsafeGlobalDynFlags sp (warnMsg i1 iw $+$ blankLine $+$ srcInfo1)- warnMsg2 = pprLocErrMsg warnMsg1 #endif liftIO (hPutStrLn stderr (showSDocUnsafe warnMsg2))
src/Clash/Primitives/Types.hs view
@@ -56,9 +56,7 @@ import GHC.Stack (HasCallStack) import Text.Read (readMaybe) -#if MIN_VERSION_aeson(2,0,0) import qualified Data.Aeson.KeyMap as KeyMap-#endif -- | An unresolved primitive still contains pointers to files. type UnresolvedPrimitive = Primitive Text ((TemplateFormat,BlackBoxFunctionName),Maybe TemplateSource) (Maybe S.Text) (Maybe TemplateSource)@@ -238,11 +236,7 @@ instance FromJSON UnresolvedPrimitive where parseJSON (Object v) =-#if MIN_VERSION_aeson(2,0,0) case KeyMap.toList v of-#else- case H.toList v of-#endif [(conKey,Object conVal)] -> case conKey of "BlackBoxHaskell" -> do
src/Clash/Rewrite/Types.hs view
@@ -26,16 +26,11 @@ import qualified Control.Lens as Lens import Control.Monad.Fix (MonadFix) import Control.Monad.State.Strict (State)-#if MIN_VERSION_transformers(0,5,6) import Control.Monad.Reader (MonadReader (..)) import Control.Monad.State (MonadState (..)) import Control.Monad.Trans.RWS.CPS (RWST) import qualified Control.Monad.Trans.RWS.CPS as RWS import Control.Monad.Writer (MonadWriter (..))-#else-import Control.Monad.Trans.RWS.Strict (RWST)-import qualified Control.Monad.Trans.RWS.Strict as RWS-#endif import Data.Binary (Binary) import Data.HashMap.Strict (HashMap) import Data.IntMap.Strict (IntMap)@@ -174,14 +169,10 @@ , Functor , Monad , MonadFix- )-#if MIN_VERSION_transformers(0,5,6) && MIN_VERSION_mtl(2,3,0)- deriving newtype- ( MonadState (RewriteState extra)+ , MonadState (RewriteState extra) , MonadWriter Any , MonadReader RewriteEnv )-#endif -- | Run the computation in the RewriteMonad runR@@ -190,37 +181,6 @@ -> RewriteState extra -> IO (a, RewriteState extra, Any) runR m = RWS.runRWST (unR m)--#if MIN_VERSION_transformers(0,5,6) && !MIN_VERSION_mtl(2,3,0)--- For Control.Monad.Trans.RWS.Strict these are already defined, however the--- CPS version of RWS is not included in `mtl` yet.--instance MonadState (RewriteState extra) (RewriteMonad extra) where- get = R RWS.get- {-# INLINE get #-}- put = R . RWS.put- {-# INLINE put #-}- state = R . RWS.state- {-# INLINE state #-}--instance MonadWriter Any (RewriteMonad extra) where- writer = R . RWS.writer- {-# INLINE writer #-}- tell = R . RWS.tell- {-# INLINE tell #-}- listen = R . RWS.listen . unR- {-# INLINE listen #-}- pass = R . RWS.pass . unR- {-# INLINE pass #-}--instance MonadReader RewriteEnv (RewriteMonad extra) where- ask = R RWS.ask- {-# INLINE ask #-}- local f = R . RWS.local f . unR- {-# INLINE local #-}- reader = R . RWS.reader- {-# INLINE reader #-}-#endif instance MonadUnique (RewriteMonad extra) where getUniqueM = do
src/Clash/Rewrite/Util.hs view
@@ -30,11 +30,7 @@ import qualified Control.Lens as Lens import qualified Control.Monad as Monad import qualified Control.Monad.State.Strict as State-#if MIN_VERSION_transformers(0,5,6) import qualified Control.Monad.Trans.RWS.CPS as RWS-#else-import qualified Control.Monad.Trans.RWS.Strict as RWS-#endif import qualified Control.Monad.Writer as Writer import Data.Bifunctor (second) import Data.Coerce (coerce)@@ -55,11 +51,7 @@ import qualified Data.ByteString as BS import qualified Data.ByteString.Lazy as BL -#if MIN_VERSION_ghc(9,0,0) import GHC.Types.Basic (InlineSpec (..))-#else-import BasicTypes (InlineSpec (..))-#endif import Clash.Core.Evaluator.Types (PureHeap, whnf') import Clash.Core.FreeVars@@ -217,7 +209,7 @@ newFV = not (afterFV `Set.isSubsetOf` beforeFV) accidentalShadows = findAccidentialShadows exprNew -- see NOTE [Filter free variables]- allowNewFVsFromCtx = name == "caseCon"+ allowNewFVsFromCtx = name `elem` ["caseCon", "reduceConst", "constantSpec"] filterFVs | allowNewFVsFromCtx = Set.filter notInCtx | otherwise = id notInCtx v = notElemInScopeSet v (tfInScope ctx)@@ -273,15 +265,14 @@ after = showPpr exprNew -- NOTE [Filter free variables]--- Since [Give evaluator acces to inscope let-bindings #2571](https://github.com/clash-lang/clash-compiler/pull/2571)--- the evaluator can rewrite expressions using let bindings from the 'TransformContext',--- these bindings may reference other things bound in the context which weren't--- in the expression before, and in doing so introduces new free variables and--- fails this check for new free variables.--- To prevent this we filter out all variables from bound in the context.--- But only during a caseCon transformation, to not weaken this check unnecessarily.--+-- Since [Give evaluator access to in-scope let-bindings #2571](https://github.com/clash-lang/clash-compiler/pull/2571)+-- the evaluator can rewrite expressions using let bindings from its 'TransformContext'.+-- These bindings may reference other variables bound in the context which weren't+-- in the expression before. By just looking at the expression (i.e., not accounting+-- for the 'TransformContext'), it would therefore seem that free variables are+-- introduce which would subsequently fail the freevar check. To prevent this we+-- filter out all variables bound in the context, but only during a transformations+-- that call 'whnfRW'. -- | Perform a transformation on a Term runRewrite@@ -628,11 +619,7 @@ -- function at this moment for a reason! -- (termination, CSE and DEC oppertunities, -- ,etc.)-#if MIN_VERSION_ghc(9,2,0) (Binding newBodyId sp NoUserInlinePrag IsFun newBody r)-#else- (Binding newBodyId sp NoUserInline IsFun newBody r)-#endif -- Return the new binder return (var, newExpr) -- If it does, use the existing binder
src/Clash/Unique.hs view
@@ -30,11 +30,7 @@ import GHC.Int (Int(I#)) import GHC.Exts (Int#) #endif-#if MIN_VERSION_ghc(9,0,0) import qualified GHC.Types.Unique as GHC-#else-import qualified Unique as GHC-#endif #ifdef UNIQUE_IS_WORD64 type Unique = Word64
src/Clash/Util.hs view
@@ -18,9 +18,7 @@ ( module Clash.Util , SrcSpan , noSrcSpan-#if MIN_VERSION_transformers(0,6,0) , hoistMaybe-#endif ) where @@ -28,11 +26,7 @@ import Control.Lens import Control.Monad.State (MonadState,StateT) import qualified Control.Monad.State as State-#if MIN_VERSION_transformers(0,6,0) import Control.Monad.Trans.Maybe (hoistMaybe)-#else-import Control.Monad.Trans.Maybe (MaybeT (..))-#endif import Data.Hashable (Hashable) import Data.HashMap.Lazy (HashMap) import qualified Data.HashMap.Lazy as HashMapL@@ -61,11 +55,7 @@ import Type.Reflection (tyConPackage, typeRepTyCon, typeOf) import qualified Language.Haskell.TH as TH -#if MIN_VERSION_ghc(9,0,0) import GHC.Types.SrcLoc (SrcSpan, noSrcSpan)-#else-import SrcLoc (SrcSpan, noSrcSpan)-#endif import Clash.Data.UniqMap (UniqMap) import qualified Clash.Data.UniqMap as UniqMap@@ -347,8 +337,3 @@ thenCompare :: Ordering -> Ordering -> Ordering thenCompare EQ rel = rel thenCompare rel _ = rel--#if !MIN_VERSION_transformers(0,6,0)-hoistMaybe :: (Applicative m) => Maybe b -> MaybeT m b-hoistMaybe = MaybeT . pure-#endif
src/Clash/Util/Supply.hs view
@@ -1,7 +1,5 @@ {-# LANGUAGE MagicHash, UnboxedTuples, CPP, PatternSynonyms #-}-#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 702 {-# LANGUAGE Trustworthy #-}-#endif {-# OPTIONS_GHC -fno-full-laziness #-} {-# OPTIONS_GHC -Wno-incomplete-patterns #-} -----------------------------------------------------------------------------@@ -42,10 +40,6 @@ import Data.Hashable import Data.IORef-#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ < 710-import Data.Functor ((<$>))-import Data.Monoid-#endif import GHC.IO (unsafeDupablePerformIO, unsafePerformIO) import Clash.Unique (Unique, Unique#, pattern Unique#)
src/Data/Aeson/Extra.hs view
@@ -42,13 +42,8 @@ import qualified Clash.Util.Interpolate as I import Clash.Util (ClashException(..))-#if MIN_VERSION_ghc(9,0,0) import GHC.Types.SrcLoc (mkGeneralSrcSpan) import GHC.Data.FastString (mkFastString)-#else-import SrcLoc (mkGeneralSrcSpan)-import FastString (mkFastString)-#endif import GHC.Stack (HasCallStack) -- | See 'toSpecNewlines'. A line map maps "virtual" lines to a range of
− src/Data/IntMap/Extra.hs
@@ -1,36 +0,0 @@-{-# LANGUAGE CPP #-}--module Data.IntMap.Extra where--#if !MIN_VERSION_containers(0,6,2)-import Data.IntMap.Internal---- TODO We can remove this when support for GHC 8.6 is dropped.---- | /O(n+m)/. Check whether the key sets of two maps are disjoint--- (i.e. their 'intersection' is empty).------ > disjoint (fromList [(2,'a')]) (fromList [(1,()), (3,())]) == True--- > disjoint (fromList [(2,'a')]) (fromList [(1,'a'), (2,'b')]) == False--- > disjoint (fromList []) (fromList []) == True------ > disjoint a b == null (intersection a b)----disjoint :: IntMap a -> IntMap b -> Bool-disjoint Nil _ = True-disjoint _ Nil = True-disjoint (Tip kx _) ys = notMember kx ys-disjoint xs (Tip ky _) = notMember ky xs-disjoint t1@(Bin p1 m1 l1 r1) t2@(Bin p2 m2 l2 r2)- | shorter m1 m2 = disjoint1- | shorter m2 m1 = disjoint2- | p1 == p2 = disjoint l1 l2 && disjoint r1 r2- | otherwise = True- where- disjoint1 | nomatch p2 p1 m1 = True- | zero p2 m1 = disjoint l1 t2- | otherwise = disjoint r1 t2- disjoint2 | nomatch p1 p2 m2 = True- | zero p1 m2 = disjoint t1 l2- | otherwise = disjoint t1 r2-#endif
src/Data/List/Extra.hs view
@@ -26,10 +26,6 @@ import "extra" Data.List.Extra as NeilsExtra import "extra" Control.Monad.Extra (anyM, allM, orM, partitionM) -#if !MIN_VERSION_base(4,18,0)-import Control.Applicative (liftA2)-#endif- #if defined(DEBUG) import GHC.Stack (HasCallStack) #endif
src/Data/Primitive/ByteArray/Extra.hs view
@@ -18,14 +18,6 @@ -- In primitive < 0.8.0.0, its ByteArray is a distinct type from -- Data.Array.Byte.ByteArray (insofar as the latter even exists). #define DEFINE_HASHABLE_BYTEARRAY-#elif !MIN_VERSION_hashable(1,4,1)--- hashable < 1.4.1 doesn't define a Hashable ByteArray instance at all.-#define DEFINE_HASHABLE_BYTEARRAY-#elif !MIN_VERSION_hashable(1,4,2)--- hashable 1.4.1 defines hashable for the ByteArray added to base 4.17.-#if !MIN_VERSION_base(4,17,0)-#define DEFINE_HASHABLE_BYTEARRAY-#endif #endif #ifdef DEFINE_HASHABLE_BYTEARRAY
src/GHC/BasicTypes/Extra.hs view
@@ -10,18 +10,12 @@ module GHC.BasicTypes.Extra where -#if MIN_VERSION_ghc(9,0,0) import GHC.Types.Basic-#else-import BasicTypes-#endif import Control.DeepSeq import Data.Binary import GHC.Generics -#if MIN_VERSION_ghc(9,4,0) import GHC.Types.SourceText-#endif #if MIN_VERSION_ghc(9,8,0) import Data.ByteString@@ -41,29 +35,21 @@ get = unsafeCoerce (get :: Get ByteString) #endif -#if MIN_VERSION_ghc(9,4,0) deriving instance Generic SourceText #if !MIN_VERSION_ghc(9,8,0) instance NFData SourceText #endif instance Binary SourceText-#endif -- | Determine whether given 'InlineSpec' is NOINLINE or more strict (OPAQUE) isNoInline :: InlineSpec -> Bool isNoInline NoInline{} = True-#if MIN_VERSION_ghc(9,4,0) isNoInline Opaque{} = True-#endif isNoInline _ = False -- | Determine whether given 'InlineSpec' is OPAQUE. If this function is used on -- a GHC that does not support OPAQUE yet (<9.4), it will return 'True' if given -- 'InlineSpec' is NOINLINE instead. isOpaque :: InlineSpec -> Bool-#if MIN_VERSION_ghc(9,4,0) isOpaque Opaque{} = True-#else-isOpaque NoInline{} = True-#endif isOpaque _ = False
src/GHC/SrcLoc/Extra.hs view
@@ -13,7 +13,6 @@ import Data.Binary import Data.Hashable (Hashable (..)) import GHC.Generics-#if MIN_VERSION_ghc(9,0,0) import GHC.Types.SrcLoc (SrcSpan (..), RealSrcLoc, RealSrcSpan, BufSpan (..), BufPos (..), UnhelpfulSpanReason (..), mkRealSrcLoc, mkRealSrcSpan,@@ -21,24 +20,11 @@ srcLocFile, srcLocLine, srcLocCol, srcSpanFile, srcSpanStartLine, srcSpanEndLine, srcSpanStartCol, srcSpanEndCol) import GHC.Data.FastString (FastString (..), bytesFS, mkFastStringByteList)-#else-import SrcLoc- (SrcSpan (..), RealSrcLoc, RealSrcSpan,- mkRealSrcLoc, mkRealSrcSpan,- realSrcSpanStart, realSrcSpanEnd,- srcLocFile, srcLocLine, srcLocCol,- srcSpanFile, srcSpanStartLine, srcSpanEndLine, srcSpanStartCol, srcSpanEndCol)-import FastString (FastString (..), bytesFS, mkFastStringByteList)-#endif-#if MIN_VERSION_ghc(9,4,0) import qualified GHC.Data.Strict-#endif -#if MIN_VERSION_ghc(9,4,0) deriving instance Generic (GHC.Data.Strict.Maybe a) instance Hashable a => Hashable (GHC.Data.Strict.Maybe a) instance Binary a => Binary (GHC.Data.Strict.Maybe a)-#endif deriving instance Generic SrcSpan instance Hashable SrcSpan@@ -64,7 +50,6 @@ put str = put $ bytesFS str get = mkFastStringByteList <$> get -#if MIN_VERSION_ghc(9,0,0) deriving instance Generic BufPos instance Binary BufPos instance Hashable BufPos@@ -76,4 +61,3 @@ deriving instance Generic BufSpan instance Binary BufSpan instance Hashable BufSpan-#endif
tests/Clash/Tests/Core/FreeVars.hs view
@@ -3,11 +3,7 @@ module Clash.Tests.Core.FreeVars (tests) where -#if MIN_VERSION_ghc(9,0,0) import GHC.Types.SrcLoc (noSrcSpan)-#else-import SrcLoc (noSrcSpan)-#endif import qualified Control.Lens as Lens import Test.Tasty
tools/v16-upgrade-primitives.hs view
@@ -7,12 +7,10 @@ module Main where -#if MIN_VERSION_aeson(2,0,0) import qualified Data.Aeson.KeyMap as Aeson import Data.String (IsString) import qualified Data.Text.Lazy as LazyText import qualified Data.Text.Lazy.Encoding as LazyText-#endif import qualified Data.Aeson.Extra as AesonExtra import qualified Data.Aeson as Aeson@@ -70,7 +68,6 @@ we like them to be. And find-and-replace those temporary names back in the resulting ByteString. -}-#if MIN_VERSION_aeson(2,0,0) keySortingRenames :: IsString str => [(str,str)] keySortingRenames = [ ("name", "aaaa_really_should_be_name_but_renamed_to_get_the_sorting_we_like")@@ -94,15 +91,6 @@ LazyText.encodeUtf8 (foldl go (LazyText.decodeUtf8 inp) keySortingRenames) where go txt (orig,temp) = LazyText.replace temp orig txt-#else--- < aeson-2.0 stores keys in HashMaps, whose order we can't possibly predict.-removeTempKey :: ByteString -> ByteString-removeTempKey = id--customSortOutput:: Aeson.Value -> Aeson.Value-customSortOutput = id-#endif- main :: IO () main = do