packages feed

clash-lib 1.4.6 → 1.4.7

raw patch · 33 files changed

+416/−188 lines, 33 filesdep ~clash-preludedep ~ghc-bignumdep ~hashablePVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: clash-prelude, ghc-bignum, hashable, text, time

API changes (from Hackage documentation)

- Clash.Core.DataCon: instance Data.Hashable.Class.Hashable Clash.Core.DataCon.DataCon
- Clash.Core.Term: instance Data.Hashable.Class.Hashable Clash.Core.Term.CoreContext
- Clash.Core.Term: instance Data.Hashable.Class.Hashable Clash.Core.Term.Pat
- Clash.Core.Term: instance Data.Hashable.Class.Hashable Clash.Core.Term.PrimInfo
- Clash.Core.Term: instance Data.Hashable.Class.Hashable Clash.Core.Term.Term
- Clash.Core.Term: instance Data.Hashable.Class.Hashable Clash.Core.Term.TickInfo
- Clash.Core.Type: instance Data.Hashable.Class.Hashable Clash.Core.Type.Type
- Clash.Rewrite.Types: instance Data.Hashable.Class.Hashable Clash.Rewrite.Types.RewriteStep
+ Clash.Core.Subst: eqTerm :: Term -> Term -> Bool
+ Clash.Core.Subst: eqType :: Type -> Type -> Bool
+ Clash.Core.Subst: instance (TypeError ...) => Data.Hashable.Class.Hashable Clash.Core.Term.Term
+ Clash.Core.Subst: instance GHC.Classes.Ord Clash.Core.Term.TickInfo
+ Clash.Core.Term: instance GHC.Classes.Eq Clash.Core.Term.IsMultiPrim
+ Clash.Core.Term: instance GHC.Classes.Ord Clash.Core.Term.NameMod
+ Clash.Core.Term: stripAllTicks :: Term -> Term
+ Clash.Core.Type: instance (TypeError ...) => Data.Hashable.Class.Hashable Clash.Core.Type.Type
+ Clash.Driver.Types: instance GHC.Classes.Eq Clash.Driver.Types.ClashOpts
+ Clash.Driver.Types: instance GHC.Show.Show Clash.Driver.Types.SdcInfo
+ Clash.Netlist.BlackBox.Types: instance GHC.Classes.Eq Clash.Netlist.BlackBox.Types.Decl
+ Clash.Netlist.BlackBox.Types: instance GHC.Classes.Eq Clash.Netlist.BlackBox.Types.Element
+ Clash.Netlist.BlackBox.Types: instance GHC.Classes.Eq Clash.Netlist.BlackBox.Types.RenderVoid
+ Clash.Netlist.Types: instance GHC.Classes.Eq Clash.Netlist.Types.TopEntityT
+ Clash.Primitives.DSL: enableToBit :: (HasCallStack, Backend backend) => Text -> TExpr -> State (BlockState backend) TExpr
+ Clash.Primitives.Types: instance (GHC.Classes.Eq c, GHC.Classes.Eq a, GHC.Classes.Eq b, GHC.Classes.Eq d) => GHC.Classes.Eq (Clash.Primitives.Types.Primitive a b c d)
+ Clash.Primitives.Types: instance Data.Hashable.Class.Hashable Clash.Primitives.Types.TemplateSource
+ Clash.Primitives.Types: instance GHC.Classes.Eq Clash.Primitives.Types.TemplateFormat
+ Clash.Primitives.Types: instance GHC.Classes.Eq Clash.Primitives.Types.UsedArguments
- Clash.Netlist.Types: type HWMap = HashMap Type (Either String FilteredHWType)
+ Clash.Netlist.Types: type HWMap = Map Type (Either String FilteredHWType)
- Clash.Rewrite.Types: bindings :: forall extra_a3uKr. Lens' (RewriteState extra_a3uKr) BindingMap
+ Clash.Rewrite.Types: bindings :: forall extra_a3AFC. Lens' (RewriteState extra_a3AFC) BindingMap
- Clash.Rewrite.Types: curFun :: forall extra_a3uKr. Lens' (RewriteState extra_a3uKr) (Id, SrcSpan)
+ Clash.Rewrite.Types: curFun :: forall extra_a3AFC. Lens' (RewriteState extra_a3AFC) (Id, SrcSpan)
- Clash.Rewrite.Types: extra :: forall extra_a3uKr extra_a3uSR. Lens (RewriteState extra_a3uKr) (RewriteState extra_a3uSR) extra_a3uKr extra_a3uSR
+ Clash.Rewrite.Types: extra :: forall extra_a3AFC extra_a3ANj. Lens (RewriteState extra_a3AFC) (RewriteState extra_a3ANj) extra_a3AFC extra_a3ANj
- Clash.Rewrite.Types: globalHeap :: forall extra_a3uKr. Lens' (RewriteState extra_a3uKr) PrimHeap
+ Clash.Rewrite.Types: globalHeap :: forall extra_a3AFC. Lens' (RewriteState extra_a3AFC) PrimHeap
- Clash.Rewrite.Types: nameCounter :: forall extra_a3uKr. Lens' (RewriteState extra_a3uKr) Int
+ Clash.Rewrite.Types: nameCounter :: forall extra_a3AFC. Lens' (RewriteState extra_a3AFC) Int
- Clash.Rewrite.Types: transformCounter :: forall extra_a3uKr. Lens' (RewriteState extra_a3uKr) Int
+ Clash.Rewrite.Types: transformCounter :: forall extra_a3AFC. Lens' (RewriteState extra_a3AFC) Int
- Clash.Rewrite.Types: uniqSupply :: forall extra_a3uKr. Lens' (RewriteState extra_a3uKr) Supply
+ Clash.Rewrite.Types: uniqSupply :: forall extra_a3AFC. Lens' (RewriteState extra_a3AFC) Supply
- Clash.Rewrite.Types: workFreeBinders :: forall extra_a3uKr. Lens' (RewriteState extra_a3uKr) (VarEnv Bool)
+ Clash.Rewrite.Types: workFreeBinders :: forall extra_a3AFC. Lens' (RewriteState extra_a3AFC) (VarEnv Bool)

Files

CHANGELOG.md view
@@ -1,4 +1,19 @@ # Changelog for the Clash project+## 1.4.7 *Jan 30th 2022*+Fixed:+  * Clash now shows days in time strings for compile runs which take longer than a day [#1989](https://github.com/clash-lang/clash-compiler/compare/issue-1989).+  * Types defined in the package head are no longer qualified in the package body when rendering VHDL [#1996](https://github.com/clash-lang/clash-compiler/issues/1996).+  * `asyncRam` with different read and write clocks no longer produce the wrong results in Haskell simulation. [#2031](https://github.com/clash-lang/clash-compiler/pull/2031)+  * `Clash.Explicit.RAM.asyncRam#` Haskell simulation incorrectly treated an _undefined_ write enable as asserted. It now causes an _undefined_ value to be written instead. This problem did not propagate to the other `asyncRam` functions, where the same condition would simultaneously lead to an undefined write address, which would be handled correctly. This problem also only affects Haskell simulation, not the generated HDL. [#2031](https://github.com/clash-lang/clash-compiler/pull/2031)+  * `Clash.Explicit.BlockRam.blockRam#` and `Clash.Explicit.BlockRam.File.blockRamFile#` Haskell simulation incorrectly treated an _undefined_ write enable as asserted. It now causes an _undefined_ value to be written instead. This problem did not propagate to the other `blockRam` functions, where the same condition would simultaneously lead to an undefined write address, which would be handled correctly. This problem also only affects Haskell simulation, not the generated HDL.([#2054](https://github.com/clash-lang/clash-compiler/pull/2054))++Internal changes:+  * Removed instances of `Hashable Term` and `Hashable Type` [#1986](https://github.com/clash-lang/clash-compiler/pull/1986)+  * Added structural equality on `Term` (`Clash.Core.Subst.eqTerm`) and `Type` (`Clash.Core.Subst.eqType`)++Internal fixes:+  * Enable used to be a `Bool` in the Blackbox DSL, so we could use `boolToBit`. However it now has its own type in the DSL (`Enable domainName`), so we've added a new conversion function in order to convert it to a Bool.+  ## 1.4.6 *Oct 26th 2021* 
clash-lib.cabal view
@@ -1,6 +1,6 @@ Cabal-version:        2.2 Name:                 clash-lib-Version:              1.4.6+Version:              1.4.7 Synopsis:             Clash: a functional hardware description language - As a library Description:   Clash is a functional hardware description language that borrows both its@@ -144,7 +144,7 @@                       base16-bytestring       >= 0.1.1    && < 1.1,                       binary                  >= 0.8.5    && < 0.11,                       bytestring              >= 0.10.0.2 && < 0.12,-                      clash-prelude           == 1.4.6,+                      clash-prelude           == 1.4.7,                       concurrent-supply       >= 0.1.7    && < 0.2,                       containers              >= 0.5.0.0  && < 0.7,                       cryptohash-sha256       >= 0.11     && < 0.12,@@ -159,7 +159,7 @@                       filepath                >= 1.3.0.1  && < 1.5,                       ghc                     >= 8.4.0    && < 9.1,                       ghc-boot-th,-                      hashable                >= 1.2.1.0  && < 1.4,+                      hashable                >= 1.2.1.0  && < 1.5,                       haskell-src-meta        >= 0.8      && < 0.9,                       hint                    >= 0.7      && < 0.10,                       interpolate             >= 0.2.0    && < 1.0,@@ -175,9 +175,9 @@                       template-haskell        >= 2.8.0.0  && < 2.18,                       temporary               >= 1.2.1    && < 1.4,                       terminal-size           >= 0.3      && < 0.4,-                      text                    >= 1.2.2    && < 1.3,+                      text                    >= 1.2.2    && < 2.1,                       text-show               >= 3.7      && < 3.10,-                      time                    >= 1.4.0.1  && < 1.13,+                      time                    >= 1.4.0.1  && < 1.14,                       transformers            >= 0.5.2.0  && < 0.7,                       trifecta                >= 1.7.1.1  && < 2.2,                       utf8-string             >= 1.0.1    && < 1.1,@@ -186,7 +186,7 @@                       unordered-containers    >= 0.2.3.3  && < 0.3    if impl(ghc >= 9.0.0)-    build-depends:     ghc-bignum >=1.0 && <1.1+    build-depends:     ghc-bignum >=1.0 && <1.3   else     build-depends:     integer-gmp >=1.0 && <1.1 
+ prims/commonverilog/Clash_Explicit_Testbench.primitives view
@@ -0,0 +1,9 @@+[ { "BlackBox" :+    { "name" : "Clash.Explicit.Testbench.tbEnableGen"+    , "workInfo" : "Always"+    , "kind" : "Declaration"+    , "type" : "tbEnableGen :: Enable dom"+    , "template" : "assign ~RESULT = 1'b1;"+    }+  }+]
prims/commonverilog/Clash_Signal_Internal.primitives view
@@ -16,12 +16,4 @@     , "template" : "~ARG[0]"     }   }-, { "BlackBox" :-    { "name" : "Clash.Explicit.Testbench.tbEnableGen"-    , "workInfo" : "Always"-    , "kind" : "Declaration"-    , "type" : "tbEnableGen :: Enable dom"-    , "template" : "assign ~RESULT = 1'b1;"-    }-  } ]
prims/systemverilog/Clash_Explicit_Testbench.primitives view
@@ -57,4 +57,35 @@ // assertBitVector end"     }   }+, { "BlackBox" :+    { "name" : "Clash.Explicit.Testbench.tbClockGen"+    , "workInfo" : "Always"+    , "kind" : "Declaration"+    , "warning" : "Clash.Signal.Internal.tbClockGen is not synthesizable!"+    , "type" :+"tbClockGen+  :: KnownDomain dom     -- ARG[0]+  => Signal dom Bool      -- ARG[1]+  -> Clock dom"+    , "template" :+"// tbClockGen begin+// pragma translate_off+// 1 = 0.1ps+localparam ~GENSYM[half_period][0] = (~PERIOD[0]0 / 2);+always begin+  ~RESULT = ~IF~ACTIVEEDGE[Rising][0]~THEN 0 ~ELSE 1 ~FI;+  #30000 forever begin+    if (~ ~ARG[1]) begin+      $finish;+    end+    ~RESULT = ~ ~RESULT;+    #~SYM[0];+    ~RESULT = ~ ~RESULT;+    #~SYM[0];+  end+end+// pragma translate_on+// tbClockGen end"+    }+  } ]
prims/systemverilog/Clash_Signal_Internal.primitives view
@@ -109,37 +109,6 @@     }   } , { "BlackBox" :-    { "name" : "Clash.Explicit.Testbench.tbClockGen"-    , "workInfo" : "Always"-    , "kind" : "Declaration"-    , "warning" : "Clash.Signal.Internal.tbClockGen is not synthesizable!"-    , "type" :-"tbClockGen-  :: KnownDomain dom     -- ARG[0]-  => Signal dom Bool      -- ARG[1]-  -> Clock dom"-    , "template" :-"// tbClockGen begin-// pragma translate_off-// 1 = 0.1ps-localparam ~GENSYM[half_period][0] = (~PERIOD[0]0 / 2);-always begin-  ~RESULT = ~IF~ACTIVEEDGE[Rising][0]~THEN 0 ~ELSE 1 ~FI;-  #30000 forever begin-    if (~ ~ARG[1]) begin-      $finish;-    end-    ~RESULT = ~ ~RESULT;-    #~SYM[0];-    ~RESULT = ~ ~RESULT;-    #~SYM[0];-  end-end-// pragma translate_on-// tbClockGen end"-    }-  }-, { "BlackBox" :     { "name" : "Clash.Signal.Internal.resetGenN"     , "workInfo" : "Always"     , "kind" : "Declaration"
prims/verilog/Clash_Explicit_Testbench.primitives view
@@ -57,4 +57,38 @@ // assertBitVector end"     }   }+, { "BlackBox" :+    { "name" : "Clash.Explicit.Testbench.tbClockGen"+    , "workInfo"  : "Always"+    , "kind" : "Declaration"+    , "warning" : "Clash.Signal.Internal.tbClockGen is not synthesizable!"+    , "type" :+"tbClockGen+  :: KnownDomain dom     -- ARG[0]+  => Signal dom Bool      -- ARG[1]+  -> Clock dom"+    , "template" :+"// tbClockGen begin+// pragma translate_off+reg ~TYPO ~GENSYM[clk][0];+// 1 = 0.1ps+localparam ~GENSYM[half_period][1] = (~PERIOD[0]0 / 2);+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;+  #30000 forever begin+    if (~ ~ARG[1]) begin+      $finish;+    end+    ~SYM[0] = ~ ~SYM[0];+    #~SYM[1];+    ~SYM[0] = ~ ~SYM[0];+    #~SYM[1];+  end+end+assign ~RESULT = ~SYM[0];+// pragma translate_on+// tbClockGen end"+    }+  } ]
prims/verilog/Clash_Signal_Internal.primitives view
@@ -115,40 +115,6 @@     }   } , { "BlackBox" :-    { "name" : "Clash.Explicit.Testbench.tbClockGen"-    , "workInfo"  : "Always"-    , "kind" : "Declaration"-    , "warning" : "Clash.Signal.Internal.tbClockGen is not synthesizable!"-    , "type" :-"tbClockGen-  :: KnownDomain dom     -- ARG[0]-  => Signal dom Bool      -- ARG[1]-  -> Clock dom"-    , "template" :-"// tbClockGen begin-// pragma translate_off-reg ~TYPO ~GENSYM[clk][0];-// 1 = 0.1ps-localparam ~GENSYM[half_period][1] = (~PERIOD[0]0 / 2);-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;-  #30000 forever begin-    if (~ ~ARG[1]) begin-      $finish;-    end-    ~SYM[0] = ~ ~SYM[0];-    #~SYM[1];-    ~SYM[0] = ~ ~SYM[0];-    #~SYM[1];-  end-end-assign ~RESULT = ~SYM[0];-// pragma translate_on-// tbClockGen end"-    }-  }-, { "BlackBox" :     { "name"      : "Clash.Signal.Internal.resetGenN"     , "workInfo"  : "Always"     , "kind" : "Declaration"
prims/vhdl/Clash_Explicit_Testbench.primitives view
@@ -154,4 +154,46 @@ -- assertBitVector end"     }   }+, { "BlackBox" :+    { "name" : "Clash.Explicit.Testbench.tbClockGen"+    , "workInfo"  : "Always"+    , "kind" : "Declaration"+    , "warning" : "Clash.Signal.Internal.tbClockGen is not synthesizable!"+    , "type" :+"tbClockGen+  :: KnownDomain dom     -- ARG[0]+  => Signal dom Bool     -- ARG[1]+  -> Clock dom"+    , "comment" :+        "ModelSim and Vivado seem to round time values to an integer number of picoseconds.+        Use two half periods to prevent rounding errors from affecting the full period."+    , "template" :+"-- tbClockGen begin+-- pragma translate_off+~GENSYM[clkGen][0] : process is+  constant ~GENSYM[half_periodH][1] : time := ~PERIOD[0]000 fs / 2;+  constant ~GENSYM[half_periodL][2] : time := ~PERIOD[0]000 fs - ~SYM[1];+begin+  ~RESULT <= ~IF~ACTIVEEDGE[Rising][0]~THEN'0'~ELSE'1'~FI;+  wait for 3000 ps;+  while ~ARG[1] loop+    ~RESULT <= not ~RESULT;+    wait for ~SYM[1];+    ~RESULT <= not ~RESULT;+    wait for ~SYM[2];+  end loop;+  wait;+end process;+-- pragma translate_on+-- tbClockGen end"+    }+  }+, { "BlackBox" :+    { "name" : "Clash.Explicit.Testbench.tbEnableGen"+    , "workInfo" : "Always"+    , "kind" : "Declaration"+    , "type" : "tbEnableGen :: Enable dom"+    , "template" : "~RESULT <= true;"+    }+  } ]
prims/vhdl/Clash_Signal_Internal.primitives view
@@ -159,37 +159,6 @@     }   } , { "BlackBox" :-    { "name" : "Clash.Explicit.Testbench.tbClockGen"-    , "workInfo"  : "Always"-    , "kind" : "Declaration"-    , "warning" : "Clash.Signal.Internal.tbClockGen is not synthesizable!"-    , "type" :-"tbClockGen-  :: KnownDomain dom     -- ARG[0]-  => Signal dom Bool     -- ARG[1]-  -> Clock dom"-    , "template" :-"-- tbClockGen begin--- pragma translate_off-~GENSYM[clkGen][0] : process is-  constant ~GENSYM[half_periodH][1] : time := ~PERIOD[0]000 fs / 2;-  constant ~GENSYM[half_periodL][2] : time := ~PERIOD[0]000 fs - ~SYM[1];-begin-  ~RESULT <= ~IF~ACTIVEEDGE[Rising][0]~THEN'0'~ELSE'1'~FI;-  wait for 3000 ps;-  while ~ARG[1] loop-    ~RESULT <= not ~RESULT;-    wait for ~SYM[1];-    ~RESULT <= not ~RESULT;-    wait for ~SYM[2];-  end loop;-  wait;-end process;--- pragma translate_on--- tbClockGen end"-    }-  }-, { "BlackBox" :     { "name"      : "Clash.Signal.Internal.resetGenN"     , "workInfo"  : "Always"     , "kind" : "Declaration"@@ -219,14 +188,6 @@     , "type" : "unsafeToReset :: Signal dom Bool -> Reset dom"     , "template" : "~RESULT <= '1' when ~ARG[0] = true else '0';"-    }-  }-, { "BlackBox" :-    { "name" : "Clash.Explicit.Testbench.tbEnableGen"-    , "workInfo" : "Always"-    , "kind" : "Declaration"-    , "type" : "tbEnableGen :: Enable dom"-    , "template" : "~RESULT <= true;"     }   } ]
src/Clash/Backend/VHDL.hs view
@@ -94,6 +94,8 @@   -- ^ Files to be stored: (filename, contents). These files are generated   -- during the execution of 'genNetlist'.   , _idSeen    :: IdentifierSet+  , _tyPkgCtx :: Bool+  -- ^ Are we in the context of generating the @_types@ package?   , _intWidth  :: Int   -- ^ Int/Word/Integer bit-width   , _hdlsyn    :: HdlSyn@@ -121,6 +123,7 @@     , _dataFiles=[]     , _memoryDataFiles=[]     , _idSeen=Id.emptyIdentifierSet esc lw VHDL+    , _tyPkgCtx=False     , _intWidth=w     , _hdlsyn=hdlsyn_     , _undefValue=undefVal@@ -359,14 +362,15 @@ -- | Generate a VHDL package containing type definitions for the given HWTypes mkTyPackage_ :: ModName -> [HWType] -> VHDLM [(String,Doc)] mkTyPackage_ modName (map filterTransparent -> hwtys) = do-    { syn <- Mon hdlSyn+    { Mon (tyPkgCtx .= True)+    ; syn <- Mon hdlSyn     ; let usedTys     = concatMap mkUsedTys hwtys     ; let normTys0    = nub (map mkVecZ (hwtys ++ usedTys))     ; let sortedTys0  = topSortHWTys normTys0           packageDec  = vcat $ mapM tyDec (nubBy eqTypM sortedTys0)           (funDecs,funBodies) = unzip . mapMaybe (funDec syn) $ nubBy eqTypM (map normaliseType sortedTys0) -    ; (:[]) <$> (TextS.unpack (modName `TextS.append` "_types"),) <$>+    ; pkg <- (:[]) <$> (TextS.unpack (modName `TextS.append` "_types"),) <$>       "library IEEE;" <> line <>       "use IEEE.STD_LOGIC_1164.ALL;" <> line <>       "use IEEE.NUMERIC_STD.ALL;" <> line <> line <>@@ -375,6 +379,8 @@                     vcat (sequence funDecs)                   ) <> line <>       "end" <> semi <> packageBodyDec funBodies+    ; Mon (tyPkgCtx .= False)+    ; return pkg     }   where     packageBodyDec :: [VHDLM Doc] -> VHDLM Doc@@ -640,13 +646,13 @@   )  funDec _ t@(Product _ labels elTys) = Just-  ( "function" <+> "toSLV" <+> parens ("p :" <+> sizedQualTyName t) <+> "return std_logic_vector" <> semi <> line <>-    "function" <+> "fromSLV" <+> parens ("slv" <+> colon <+> "in" <+> "std_logic_vector") <+> "return" <+> sizedQualTyName t <> semi-  , "function" <+> "toSLV" <+> parens ("p :" <+> sizedQualTyName t) <+> "return std_logic_vector" <+> "is" <> line <>+  ( "function" <+> "toSLV" <+> parens ("p :" <+> sizedTyName t) <+> "return std_logic_vector" <> semi <> line <>+    "function" <+> "fromSLV" <+> parens ("slv" <+> colon <+> "in" <+> "std_logic_vector") <+> "return" <+> sizedTyName t <> semi+  , "function" <+> "toSLV" <+> parens ("p :" <+> sizedTyName t) <+> "return std_logic_vector" <+> "is" <> line <>     "begin" <> line <>     indent 2 ("return" <+> parens (hcat (punctuate " & " elTyToSLV)) <> semi) <> line <>     "end" <> semi <> line <>-    "function" <+> "fromSLV" <+> parens ("slv" <+> colon <+> "in" <+> "std_logic_vector") <+> "return" <+> sizedQualTyName t <+> "is" <> line <>+    "function" <+> "fromSLV" <+> parens ("slv" <+> colon <+> "in" <+> "std_logic_vector") <+> "return" <+> sizedTyName t <+> "is" <> line <>       "alias islv : std_logic_vector(0 to slv'length - 1) is slv;" <> line <>     "begin" <> line <>     indent 2 ("return" <+> parens (hcat (punctuate "," elTyFromSLV)) <> semi) <> line <>@@ -1001,8 +1007,12 @@    -- Custom types:   _ -> do+    pkgCtx <- Mon (use tyPkgCtx)     modName <- Mon (use modNm)-    pretty modName <> "_types." <> tyName hwty++    if pkgCtx+      then tyName hwty+      else pretty modName <> "_types." <> tyName hwty  -- | Generates a unique name for a given type. This action will cache its -- results, thus returning the same answer for the same @HWType@ argument.
src/Clash/Core/DataCon.hs view
@@ -22,7 +22,6 @@  import Control.DeepSeq                        (NFData(..)) import Data.Binary                            (Binary)-import Data.Hashable                          (Hashable) import qualified Data.Text                    as Text import GHC.Generics                           (Generic) @@ -53,7 +52,7 @@   -- ^ Argument types   , dcFieldLabels :: [Text.Text]   -- ^ Names of fields. Used when data constructor is referring to a record type.-  } deriving (Generic,NFData,Hashable,Binary)+  } deriving (Generic,NFData,Binary)  instance Show DataCon where   show = show . dcName
src/Clash/Core/FreeVars.hs view
@@ -83,7 +83,7 @@ -- set, its kind variables also aren´t; so in order to prevent collisions due to -- shadowing we close using an empty inScope set. ----- See also: https://git.haskell.org/ghc.git/commitdiff/503514b94f8dc7bd9eab5392206649aee45f140b+-- See also: https://gitlab.haskell.org/ghc/ghc/-/commit/503514b94f8dc7bd9eab5392206649aee45f140b typeFreeVars'   :: (Contravariant f, Applicative f)   => (forall b . Var b -> Bool)@@ -221,7 +221,7 @@ -- set, its type variables also aren´t; so in order to prevent collisions due to -- shadowing we close using an empty inScope set. ----- See also: https://git.haskell.org/ghc.git/commitdiff/503514b94f8dc7bd9eab5392206649aee45f140b+-- See also: https://gitlab.haskell.org/ghc/ghc/-/commit/503514b94f8dc7bd9eab5392206649aee45f140b termFreeVars'   :: (Contravariant f, Applicative f)   => (forall b . Var b -> Bool)
src/Clash/Core/Subst.hs view
@@ -10,6 +10,8 @@ {-# LANGUAGE CPP #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE StandaloneDeriving #-}+{-# LANGUAGE UndecidableInstances #-}  {-# OPTIONS_GHC -fno-warn-orphans #-} @@ -53,6 +55,9 @@     -- * Alpha equivalence   , aeqType   , aeqTerm+    -- * Structural equivalence+  , eqTerm+  , eqType   ) where @@ -64,9 +69,13 @@ import           Data.Text.Prettyprint.Doc #endif +import           Data.Hashable             (Hashable (hashWithSalt)) import qualified Data.List                 as List import qualified Data.List.Extra           as List import           Data.Ord                  (comparing)+import           GHC.SrcLoc.Extra          ()+import           GHC.TypeLits+  (TypeError, ErrorMessage (Text, (:<>:)))  import           Clash.Core.FreeVars   (noFreeVarsOfType, localFVsOfTerms, tyFVsOfTypes)@@ -819,12 +828,8 @@   go env (AppTy s1 t1) (AppTy s2 t2) =     go env s1 s2 `thenCompare` go env t1 t2   go _ (LitTy l1) (LitTy l2) = compare l1 l2-  go env (AnnType _ t1) (AnnType _ t2) =-    -- XXX: maybe ignore annotations, like we ignore ticks, i.e.-    ---    -- go env (AnnType t1) t2 = go env t1 t2-    -- go env t1 (AnnType t2) = go env t1 t2-    go env t1 t2+  go env (AnnType a1 t1) (AnnType a2 t2) =+    compare a1 a2 `thenCompare` go env t1 t2   go _ t1 t2 = compare (getRank t1) (getRank t2)    getRank :: Type -> Word@@ -835,6 +840,22 @@   getRank (AppTy {})    = 4   getRank (ForAllTy {}) = 5 +-- | Structural equality on 'Type'+eqType+  :: Type+  -> Type+  -> Bool+eqType = go+ where+  go (VarTy tv1) (VarTy tv2) = tv1 == tv2+  go (ConstTy c1) (ConstTy c2) = c1 == c2+  go (ForAllTy tv1 t1) (ForAllTy tv2 t2) =+    tv1 == tv2 && go (varType tv1) (varType tv2) && go t1 t2+  go (AppTy s1 t1) (AppTy s2 t2) = go s1 s2 && go t1 t2+  go (LitTy l1) (LitTy l2) = l1 == l2+  go (AnnType a1 t1) (AnnType a2 t2) = a1 == a2 && go t1 t2+  go _ _ = False+ -- | Alpha equality for terms aeqTerm   :: Term@@ -906,10 +927,8 @@     go env e1 e2 `thenCompare`     acmpType' env l1 l2 `thenCompare`     acmpType' env r1 r2-  -- Look through ticks for aeq-  go env (Tick _ e1) e2 = go env e1 e2-  go env e1 (Tick _ e2) = go env e1 e2-+  go env (Tick t1 e1) (Tick t2 e2) =+    compare t1 t2 `thenCompare` go env e1 e2   go _ e1 e2 = compare (getRank e1) (getRank e2)    goAlt env (DataPat c1 tvs1 ids1,e1) (DataPat c2 tvs2 ids2,e2) =@@ -938,6 +957,47 @@ thenCompare EQ rel = rel thenCompare rel _  = rel +-- | Structural equality on 'Term'+eqTerm :: Term -> Term -> Bool+eqTerm = go+ where+  go (Var id1) (Var id2) = id1 == id2+  go (Data dc1) (Data dc2) = dc1 == dc2+  go (Literal l1) (Literal l2) = l1 == l2+  go (Prim p1) (Prim p2) = primName p1 == primName p2+  go (Lam b1 e1) (Lam b2 e2) =+    b1 == b2 && eqType (varType b1) (varType b2) && go e1 e2+  go (TyLam b1 e1) (TyLam b2 e2) =+    b1 == b2 && eqType (varType b1) (varType b2) && go e1 e2+  go (App l1 r1) (App l2 r2) = go l1 l2 && go r1 r2+  go (TyApp l1 r1) (TyApp l2 r2) = go l1 l2 && eqType r1 r2+  go (Letrec bs1 e1) (Letrec bs2 e2) =+    go e1 e2 &&+    List.all2 goBind bs1 bs2+   where+    goBind (b1,r1) (b2,r2) =+      b1 == b2 &&+      -- We need to check the types of Rec bindings, because:+      --+      -- letrec (x : Bool) = x in X+      --+      -- is not structurally equivalent to+      --+      -- letrec (x : Int) = x in x+      eqType (varType b1) (varType b2) &&+      go r1 r2+  go (Case e1 _ a1) (Case e2 _ a2) =+    go e1 e2 &&+    List.all2 goAlt a1 a2+   where+    goAlt (p1,r1) (p2,r2) = p1 == p2 && go r1 r2+  go (Cast e1 l1 r1) (Cast e2 l2 r2) =+    go e1 e2 &&+    eqType l1 l2 &&+    eqType r1 r2+  go (Tick t1 e1) (Tick t2 e2) = t1 == t2 && go e1 e2+  go _ _ = False+ instance Eq Type where   (==) = aeqType @@ -947,5 +1007,16 @@ instance Eq Term where   (==) = aeqTerm +instance TypeError (+        'Text "A broken implementation of Hashable Term has been "+  ':<>: 'Text "removed in Clash 1.4.7. If this is an issue for you, please submit "+  ':<>: 'Text "an issue report at https://github.com/clash-lang/clash-compiler/issues."+  ) => Hashable Term where+    hashWithSalt = error "Term.hashWithSalt: unreachable"+++ instance Ord Term where   compare = acmpTerm++deriving instance Ord TickInfo
src/Clash/Core/Term.hs view
@@ -13,6 +13,7 @@ {-# LANGUAGE LambdaCase #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE UndecidableInstances #-}  module Clash.Core.Term   ( Term (..)@@ -33,6 +34,7 @@   , Alt   , TickInfo (..)   , stripTicks+  , stripAllTicks   , partitionTicks   , NameMod (..)   , PrimInfo (..)@@ -59,8 +61,8 @@ import qualified Data.DList                    as DList import Data.Either                             (lefts, rights) import Data.Foldable                           (foldl')-import Data.Maybe                              (catMaybes) import Data.Hashable                           (Hashable)+import Data.Maybe                              (catMaybes) import Data.List                               (nub, partition) import Data.Text                               (Text) import GHC.Generics@@ -77,7 +79,7 @@ import {-# SOURCE #-} Clash.Core.Subst         () -- instance Eq Type import {-# SOURCE #-} Clash.Core.Type          (Type) import Clash.Core.Var                          (Var(Id), Id, TyVar)-import Clash.Util                              (curLoc)+import Clash.Util                              (curLoc, second)  -- | Term representation in the CoreHW language: System F + LetRec + Case data Term@@ -94,7 +96,7 @@                                             -- alternatives, list of alternatives   | Cast    !Term !Type !Type               -- ^ Cast a term from one type to another   | Tick    !TickInfo !Term                 -- ^ Annotated term-  deriving (Show,Generic,NFData,Hashable,Binary)+  deriving (Show, Generic, NFData, Binary)  data TickInfo   = SrcSpan !SrcSpan@@ -107,7 +109,7 @@   | NoDeDup   -- ^ Do not deduplicate, i.e. /keep/, an expression inside a case-alternative;   -- do not try to share expressions between multiple branches.-  deriving (Eq,Show,Generic,NFData,Hashable,Binary)+  deriving (Eq, Show, Generic, NFData, Binary)  -- | Tag to indicate which instance/register name modifier was used data NameMod@@ -119,12 +121,12 @@   -- ^ @Clash.Magic.suffixNameP@   | SetName   -- ^ @Clash.Magic.setName@-  deriving (Eq,Show,Generic,NFData,Hashable,Binary)+  deriving (Eq,Ord,Show,Generic,NFData,Hashable,Binary)  data IsMultiPrim   = SingleResult   | MultiResult-  deriving (Show, Generic, NFData, Hashable, Binary)+  deriving (Show, Generic, NFData, Eq, Hashable, Binary)  data PrimInfo = PrimInfo   { primName :: !Text@@ -137,7 +139,7 @@   -- the variables it should assign its results to.   --   -- See: 'Clash.Normalize.Transformations.setupMultiResultPrim'-  } deriving (Show,Generic,NFData,Hashable,Binary)+  } deriving (Show, Generic, NFData, Binary)  data MultiPrimInfo = MultiPrimInfo   { mpi_primInfo :: PrimInfo@@ -171,7 +173,7 @@   -- ^ Literal pattern   | DefaultPat   -- ^ Default pattern-  deriving (Eq,Ord,Show,Generic,NFData,Hashable,Binary)+  deriving (Eq, Ord, Show, Generic, NFData, Binary)  type Alt = (Pat,Term) @@ -237,7 +239,7 @@   -- ^ Body of a Cast   | TickC TickInfo   -- ^ Body of a Tick-  deriving (Show, Generic, NFData, Hashable, Binary)+  deriving (Show, Generic, NFData, Binary)  -- | A list of @CoreContext@ describes the complete navigation path from the -- top-level to a specific sub-expression.@@ -282,6 +284,20 @@ stripTicks :: Term -> Term stripTicks (Tick _ e) = stripTicks e stripTicks e = e++-- | Like 'stripTicks' but removes all ticks from subexpressions.+stripAllTicks :: Term -> Term+stripAllTicks = go+ where+  go (Lam i x) = Lam i (go x)+  go (TyLam i x) = TyLam i (go x)+  go (App f x) = App (go f) (go x)+  go (TyApp f a) = TyApp (go f) a+  go (Letrec bs x) = Letrec (map (second go) bs) (go x)+  go (Case x ty alts) = Case (go x) ty (fmap go <$> alts)+  go (Cast x a b) = Cast (go x) a b+  go (Tick _ x) = go x+  go x = x  -- | Split a (Type)Application in the applied term and it arguments collectArgs :: Term -> (Term, [Either Term Type])
src/Clash/Core/Type.hs view
@@ -16,6 +16,7 @@ {-# LANGUAGE NamedFieldPuns #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE UndecidableInstances #-}  module Clash.Core.Type   ( Type (..)@@ -61,7 +62,7 @@ import           Control.DeepSeq        as DS import           Data.Binary            (Binary) import           Data.Coerce            (coerce)-import           Data.Hashable          (Hashable)+import           Data.Hashable          (Hashable (hashWithSalt)) import           Data.List              (foldl') import           Data.List.Extra        (splitAtList) import           Data.Maybe             (isJust, mapMaybe)@@ -69,6 +70,7 @@ import           GHC.Generics           (Generic(..)) import           GHC.Integer            (smallInteger) import           GHC.Integer.Logarithms (integerLogBase#)+import           GHC.TypeLits           (type TypeError, ErrorMessage(Text, (:<>:)))  -- GHC API #if MIN_VERSION_ghc(9,0,0)@@ -132,7 +134,14 @@   | AppTy    !Type !Type        -- ^ Type Application   | LitTy    !LitTy             -- ^ Type literal   | AnnType  [Attr'] !Type      -- ^ Annotated type, see Clash.Annotations.SynthesisAttributes-  deriving (Show,Generic,NFData,Hashable,Binary)+  deriving (Show, Generic, NFData, Binary)++instance TypeError (+        'Text "A broken implementation of Hashable Type has been "+  ':<>: 'Text "removed in Clash 1.4.7. If this is an issue for you, please submit "+  ':<>: 'Text "an issue report at https://github.com/clash-lang/clash-compiler/issues."+  ) => Hashable Type where+    hashWithSalt = error "Type.hashWithSalt: unreachable"  -- | An easier view on types data TypeView
src/Clash/Core/Type.hs-boot view
@@ -13,7 +13,6 @@  import Control.DeepSeq                  (NFData) import Data.Binary                      (Binary)-import Data.Hashable                    (Hashable) import GHC.Generics                     (Generic)  import                Clash.Core.Name@@ -28,7 +27,6 @@ instance Generic  Type instance Show     Type instance NFData   Type-instance Hashable Type instance Binary   Type  mkTyConTy :: TyConName -> Type
src/Clash/Driver/Manifest.hs view
@@ -19,6 +19,7 @@ import           Data.Aeson   (ToJSON(toJSON), FromJSON(parseJSON), KeyValue ((.=)), (.:), (.:?)) import           Data.Aeson.Types (Parser)+import qualified Data.Binary as Binary import qualified Data.ByteString.Base16 as Base16 import qualified Data.ByteString.Lazy as ByteStringLazy import           Data.ByteString (ByteString)@@ -378,7 +379,9 @@     , opt_hdlDir = Nothing     } -  topHash = hash+  -- TODO: Binary encoding does not account for alpha equivalence (nor should+  --       it?), so the cache behaves more pessimisticly than it could.+  topHash = hash $ Binary.encode     ( tops     , hashCompiledPrimMap primMap     , show clashModDate
src/Clash/Driver/Types.hs view
@@ -314,6 +314,44 @@ newtype SdcInfo = SdcInfo   { sdcClock :: [(Text, VDomainConfiguration)]   }+  deriving (Show)+++instance Eq ClashOpts where+  s0 == s1 =+    opt_inlineLimit s0 == opt_inlineLimit s1 &&+    opt_specLimit s0 == opt_specLimit s1 &&+    opt_inlineFunctionLimit s0 == opt_inlineFunctionLimit s1 &&+    opt_inlineConstantLimit s0 == opt_inlineConstantLimit s1 &&+    opt_evaluatorFuelLimit s0 == opt_evaluatorFuelLimit s1 &&+    opt_cachehdl s0 == opt_cachehdl s1 &&+    opt_clear s0 == opt_clear s1 &&+    opt_primWarn s0 == opt_primWarn s1 &&+    (opt_color s0 `eqOverridingBool` opt_color s1) &&+    opt_intWidth s0 == opt_intWidth s1 &&+    opt_hdlDir s0 == opt_hdlDir s1 &&+    opt_hdlSyn s0 == opt_hdlSyn s1 &&+    opt_errorExtra s0 == opt_errorExtra s1 &&+    opt_floatSupport s0 == opt_floatSupport s1 &&+    opt_importPaths s0 == opt_importPaths s1 &&+    opt_componentPrefix s0 == opt_componentPrefix s1 &&+    opt_newInlineStrat s0 == opt_newInlineStrat s1 &&+    opt_escapedIds s0 == opt_escapedIds s1 &&+    opt_lowerCaseBasicIds s0 == opt_lowerCaseBasicIds s1 &&+    opt_ultra s0 == opt_ultra s1 &&+    opt_forceUndefined s0 == opt_forceUndefined s1 &&+    opt_checkIDir s0 == opt_checkIDir s1 &&+    opt_aggressiveXOpt s0 == opt_aggressiveXOpt s1 &&+    opt_aggressiveXOptBB s0 == opt_aggressiveXOptBB s1 &&+    opt_inlineWFCacheLimit s0 == opt_inlineWFCacheLimit s1 &&+    opt_edalize s0 == opt_edalize s1++   where+    eqOverridingBool :: OverridingBool -> OverridingBool -> Bool+    eqOverridingBool Auto Auto = True+    eqOverridingBool Always Always = True+    eqOverridingBool Never Never = True+    eqOverridingBool _ _ = False  -- | Render an SDC file from an SdcInfo. -- The clock periods, waveforms, and targets are all hardcoded.
src/Clash/Netlist.hs view
@@ -30,7 +30,6 @@ import           Data.Char                        (ord) import           Data.Either                      (partitionEithers, rights) import           Data.Foldable                    (foldlM)-import qualified Data.HashMap.Strict              as HashMapS import qualified Data.HashMap.Lazy                as HashMap import           Data.List                        (elemIndex, partition, sortOn) import           Data.List.Extra                  (zipEqual)@@ -193,7 +192,7 @@         , _isTestBench=isTb         , _backEndITE=ite         , _backend=be-        , _htyCache=HashMapS.empty+        , _htyCache=mempty         }  -- | Generate names for all binders in "BindingMap", except for the ones already
src/Clash/Netlist/BlackBox/Types.hs view
@@ -48,7 +48,7 @@   -- ^ Render blackbox, even if result type is void   | NoRenderVoid   -- ^ Don't render blackbox result type is void. Default for all blackboxes.-  deriving (Show, Generic, NFData, Binary, Hashable, FromJSON)+  deriving (Show, Generic, NFData, Binary, Eq, Hashable, FromJSON)  data TemplateKind   = TDecl@@ -201,7 +201,7 @@   | CtxName   -- ^ The "context name", name set by `Clash.Magic.setName`, defaults to the   -- name of the closest binder-  deriving (Show, Generic, NFData, Binary, Hashable)+  deriving (Show, Generic, NFData, Binary, Eq, Hashable)  -- | Component instantiation hole. First argument indicates which function argument -- to instantiate. Third argument corresponds to output and input assignments,@@ -225,7 +225,7 @@       -- to zero. Haskell blackboxes can use this data type.       [(BlackBoxTemplate,BlackBoxTemplate)]       -- FIELD (name of signal, type of signal)-  deriving (Show, Generic, NFData, Binary, Hashable)+  deriving (Show, Generic, NFData, Binary, Eq, Hashable)  data HdlSyn = Vivado | Quartus | Other   deriving (Eq, Show, Read, Generic, NFData, Binary, Hashable)
src/Clash/Netlist/Types.hs view
@@ -53,6 +53,7 @@ import qualified Data.List                  as List import Data.IntMap                          (IntMap, empty) import Data.Map.Ordered                     (OMap)+import Data.Map                             (Map) import Data.Maybe                           (mapMaybe) import qualified Data.Set                   as Set import Data.Text                            (Text)@@ -99,7 +100,7 @@   -- ^ (Maybe) a topentity annotation   , topIsTestBench :: Bool   -- ^ Whether this entity is a test bench-  } deriving (Generic, Show)+  } deriving (Generic, Show, Eq)  -- | Same as "TopEntity", but with all port names that end up in HDL specified data ExpandedTopEntity a = ExpandedTopEntity@@ -132,7 +133,7 @@   deriving newtype (Functor, Monad, Applicative, MonadReader NetlistEnv,                     Strict.MonadState NetlistState, Strict.MonadIO, MonadFail) -type HWMap = HashMap Type (Either String FilteredHWType)+type HWMap = Map Type (Either String FilteredHWType)  -- | See 'is_freshCache' type FreshCache = HashMap Text (IntMap Word)
src/Clash/Netlist/Types.hs-boot view
@@ -30,3 +30,5 @@ data NetlistMonad a data PreserveCase = PreserveCase | ToLower instance Hashable PreserveCase+instance Eq PreserveCase+instance Show PreserveCase
src/Clash/Netlist/Util.hs view
@@ -45,6 +45,8 @@ import           Control.Applicative     (Alternative((<|>))) import           Data.List               (unzip4, partition) import qualified Data.List               as List+import qualified Data.Map                as Map+import           Data.Map                (Map) import           Data.Maybe   (catMaybes, fromMaybe, isNothing, mapMaybe, isJust, listToMaybe, maybeToList) import           Text.Printf             (printf)@@ -379,19 +381,19 @@   -- ^ Type to convert to HWType   -> State HWMap (Either String FilteredHWType) coreTypeToHWType builtInTranslation reprs m ty = do-  htyM <- HashMap.lookup ty <$> get+  htyM <- Map.lookup ty <$> get   case htyM of     Just hty -> return hty     _ -> do       hty0M <- builtInTranslation reprs m ty       hty1  <- go hty0M ty-      modify (HashMap.insert ty hty1)+      modify (Map.insert ty hty1)       return hty1  where   -- Try builtin translation; for now this is hardcoded to be the one in ghcTypeToHWType   go :: Maybe (Either String FilteredHWType)      -> Type-     -> State (HashMap Type (Either String FilteredHWType))+     -> State (Map Type (Either String FilteredHWType))               (Either String FilteredHWType)   go (Just hwtyE) _ = pure $ maybeConvertToCustomRepr reprs ty <$> hwtyE   -- Strip transparant types:@@ -655,7 +657,7 @@   -> Bool representableType builtInTranslation reprs stringRepresentable m =     either (const False) isRepresentable .-    flip evalState HashMap.empty .+    flip evalState mempty .     coreTypeToHWType' builtInTranslation reprs m   where     isRepresentable hty = case hty of
src/Clash/Normalize/Transformations.hs view
@@ -77,7 +77,6 @@ import           Data.Default import qualified Data.Either                 as Either import qualified Data.HashMap.Lazy           as HashMap-import qualified Data.HashMap.Strict         as HashMapS import           Data.List                   ((\\)) import qualified Data.List                   as List import qualified Data.List.Extra             as List@@ -516,8 +515,29 @@ {-# SCC inlineNonRepWorker #-}  +{-+NOTE: caseOneAlt before caseCon'++When you put a bang on a signal argument:+    f :: Signal d a -> _+    f !x = ...+GHC generates a case like:+    case x of+      _ :- _ -> ...++When this f is inlined in an:+    g = f (pure False)+And clash does its Signal d a ~ a thing we get:+    g = case False of+      _ :- _ -> ...+Because no pattern matches caseCon transforms this into+    g = undefined++By trying caseOneAlt first clash can instead drop the case+and use the body of the single alternative.+-} caseCon :: HasCallStack => NormRewrite-caseCon = apply "caseOneAlt" (const caseOneAlt) >-! caseCon'+caseCon = const caseOneAlt >-! caseCon'  -- | Specialize a Case-decomposition (replace by the RHS of an alternative) if -- the subject is (an application of) a DataCon; or if there is only a single@@ -676,7 +696,7 @@         let subjTy = termType tcm subj         tran <- Lens.view typeTranslator         reprs <- Lens.view customReprs-        case (`evalState` HashMapS.empty) (coreTypeToHWType tran reprs tcm subjTy) of+        case (`evalState` mempty) (coreTypeToHWType tran reprs tcm subjTy) of           Right (FilteredHWType (Void (Just hty)) _areVoids)             | hty `elem` [BitVector 0, Unsigned 0, Signed 0, Index 1]             -- If we know that the type of the subject is zero-bits wide and@@ -1359,10 +1379,12 @@ appPropFast ctx@(TransformContext is _) = \case   e@App {}     | let (fun,args,ticks) = collectArgsTicks e-    -> go is (deShadowTerm is fun) args ticks+    -> do (eN,hasChanged) <- listen (go is (deShadowTerm is fun) args ticks)+          if Monoid.getAny hasChanged then return eN else return e   e@TyApp {}     | let (fun,args,ticks) = collectArgsTicks e-    -> go is (deShadowTerm is fun) args ticks+    -> do (eN,hasChanged) <- listen (go is (deShadowTerm is fun) args ticks)+          if Monoid.getAny hasChanged then return eN else return e   e          -> return e  where   go :: InScopeSet -> Term -> [Either Term Type] -> [TickInfo]@@ -1935,7 +1957,7 @@     -- corresponding (sub)field from the target variable.     --     -- TODO: See [Note: Breaks on constants and predetermined equality]-    eqApp tcm v args (collectArgs . stripTicks -> (Var v',args'))+    eqApp tcm v args (collectArgs . stripAllTicks -> (Var v',args'))       | isGlobalId v'       , v == v'       , let args2 = Either.lefts args'@@ -1943,9 +1965,9 @@       = and (zipWith (eqArg tcm) args args2)     eqApp _ _ _ _ = False -    eqArg _ v1 v2@(stripTicks -> Var {})+    eqArg _ v1 v2@Var {}       = v1 == v2-    eqArg tcm v1 v2@(collectArgs . stripTicks -> (Data _, args'))+    eqArg tcm v1 v2@(collectArgs -> (Data _, args'))       | let t1 = normalizeType tcm (termType tcm v1)       , let t2 = normalizeType tcm (termType tcm v2)       , t1 == t2
src/Clash/Primitives/DSL.hs view
@@ -1,6 +1,7 @@ {-|   Copyright   :  (C) 2019, Myrtle Software Ltd.-                     2020, QBayLogic B.V.+                     2020-2021, QBayLogic B.V.+                     2021, Myrtle.ai   License     :  BSD2 (see the file LICENSE)   Maintainer  :  QBayLogic B.V. <devops@qbaylogic.com> @@ -56,6 +57,7 @@   -- ** Conversion   , toBV   , fromBV+  , enableToBit   , boolToBit   , boolFromBit   , boolFromBitVector@@ -370,6 +372,25 @@         ]     pure texp   tExpr -> error $ "boolToBit: Got \"" <> show tExpr <> "\" expected Bool"++-- | Convert an enable to a bit.+enableToBit+  :: (HasCallStack, Backend backend)+  => Text+  -- ^ Name hint for intermediate signal+  -> TExpr+  -> State (BlockState backend) TExpr+enableToBit bitName = \case+  TExpr ena@(Enable _) enableExpr -> do+    texp@(~(TExpr _ (Identifier uniqueBitName Nothing))) <- declare bitName Wire Bit+    addDeclaration $+      CondAssignment uniqueBitName Bit enableExpr ena+        -- Enable normalizes to Bool for all current backends+        [ (Just (BoolLit True), Literal Nothing (BitLit H))+        , (Nothing            , Literal Nothing (BitLit L))+        ]+    pure texp+  tExpr -> error $ "enableToBit: Got \"" <> show tExpr <> "\" expected Enable"  -- | Use to create an output `Bool` from a `Bit`. The expression given --   must be the identifier of the bool you wish to get assigned.
src/Clash/Primitives/Types.hs view
@@ -129,13 +129,13 @@   -- ^ Template source stored in file on filesystem   | TInline Text   -- ^ Template stored inline-  deriving (Show, Eq, Generic, NFData)+  deriving (Show, Eq, Hashable, Generic, NFData)   data TemplateFormat   = TTemplate   | THaskell-  deriving (Show, Generic, Hashable, NFData)+  deriving (Show, Generic, Eq, Hashable, NFData)  -- | Data type to indicate what arguments are in use by a BlackBox data UsedArguments@@ -143,7 +143,7 @@   -- ^ Only these are used   | IgnoredArguments [Int]   -- ^ All but these are used-  deriving (Show, Generic, Hashable, NFData, Binary)+  deriving (Show, Generic, Eq, Hashable, NFData, Binary)  -- | Externally defined primitive data Primitive a b c d@@ -229,7 +229,7 @@   , primSort :: !Text     -- ^ Additional information   }-  deriving (Show, Generic, NFData, Binary, Hashable, Functor)+  deriving (Show, Generic, NFData, Binary, Eq, Hashable, Functor)  instance FromJSON UnresolvedPrimitive where   parseJSON (Object v) =
src/Clash/Rewrite/Types.hs view
@@ -30,7 +30,6 @@ import Control.Monad.State.Strict            (State) import Control.Monad.Writer                  (MonadWriter (..)) import Data.Binary                           (Binary)-import Data.Hashable                         (Hashable) import Data.IntMap.Strict                    (IntMap) import Data.Monoid                           (Any) import qualified Data.Set                    as Set@@ -68,7 +67,7 @@   -- ^ Term before `apply`   , t_after  :: Term   -- ^ Term after `apply`-  } deriving (Show, Generic, NFData, Hashable, Binary)+  } deriving (Show, Generic, NFData, Binary)  -- | State of a rewriting session data RewriteState extra
src/Clash/Rewrite/Util.hs view
@@ -78,7 +78,7 @@ import           Clash.Core.Name import           Clash.Core.Pretty           (showPpr) import           Clash.Core.Subst-  (substTmEnv, aeqTerm, aeqType, extendIdSubst, mkSubst, substTm)+  (substTmEnv, aeqTerm, aeqType, extendIdSubst, mkSubst, substTm, eqTerm) import           Clash.Core.Term import           Clash.Core.TermInfo import           Clash.Core.TyCon            (TyConMap)@@ -269,7 +269,7 @@                      ]             ) (return ()) -  Monad.when (lvl >= DebugSilent && not hasChanged && not (exprOld `aeqTerm` exprNew)) $+  Monad.when (lvl >= DebugSilent && not hasChanged && not (exprOld `eqTerm` exprNew)) $     error $ $(curLoc) ++ "Expression changed without notice(" ++ name ++  "): before"                       ++ before ++ "\nafter:\n" ++ after @@ -768,7 +768,7 @@       specBndrs :: [Either Id TyVar]       specBndrs = map (Lens.over _Left (normalizeId tcm)) specBndrsIn       specAbs :: Either Term Type-      specAbs = either (Left . (`mkAbstraction` specBndrs)) (Right . id) specArg+      specAbs = either (Left . stripAllTicks . (`mkAbstraction` specBndrs)) (Right . id) specArg   -- Determine if 'f' has already been specialized on (a type-normalized) 'specArg'   specM <- Map.lookup (f,argLen,specAbs) <$> Lens.use (extra.specMapLbl)   case specM of
src/Clash/Util.hs view
@@ -276,15 +276,18 @@ pkgIdFromTypeable = tyConPackage . typeRepTyCon . typeOf  reportTimeDiff :: UTCTime -> UTCTime -> String-reportTimeDiff start end =-  Clock.formatTime Clock.defaultTimeLocale fmt+reportTimeDiff end start+  | diff >= Clock.nominalDay = show days <> "d" <> Clock.formatTime Clock.defaultTimeLocale fmt+    (Clock.UTCTime (toEnum 0) (fromRational (toRational hms)))+  | otherwise = Clock.formatTime Clock.defaultTimeLocale fmt     (Clock.UTCTime (toEnum 0) (fromRational (toRational diff)))  where-  diff = Clock.diffUTCTime start end+  diff = Clock.diffUTCTime end start+  (days,hms) = divMod @Integer (floor diff) (floor Clock.nominalDay)   fmt  | diff >= 3600-       = "%-Hh%-Mm%-S%03Qs"+       = "%-Hh%-Mm%-Ss"        | diff >= 60-       = "%-Mm%-S%03Qs"+       = "%-Mm%-Ss"        | otherwise        = "%-S%03Qs" @@ -302,6 +305,8 @@ --  * compiling files with clash --  * running output tests with runghc --  * compiling (local) Template/Blackbox functions with Hint+--+-- When changing this list please update docs/developing-hardware/language.rst wantedLanguageExtensions :: [LangExt.Extension] wantedLanguageExtensions =   [ LangExt.BinaryLiterals
src/Data/Aeson/Extra.hs view
@@ -49,7 +49,7 @@ -- | Aeson versions <1.5.0 accept unescaped newlines in JSON strings. This is in -- violation of RFC 7159. Aeson 1.5.0 fixes this bug. Unfortunately, "Clash -- JSON" files rely on the old behavior. This function replaces newlines (in--- stings) with their escaped variants.+-- strings) with their escaped variants. toSpecNewlines   :: ByteString   -> Either UnicodeException (LineMap, ByteString)
src/Data/List/Extra.hs view
@@ -11,6 +11,7 @@   , equalLength   , countEq   , zipEqual+  , all2    -- * From Control.Monad.Extra   , anyM@@ -85,6 +86,13 @@ equalLength [] [] = True equalLength (_:as) (_:bs) = equalLength as bs equalLength _ _ = False++-- | Like 'all', but the predicate operates over two lists. Asserts to 'False'+-- when the lists are of unequal length+all2 :: (a -> b -> Bool) -> [a] -> [b] -> Bool+all2 _ [] [] = True+all2 p (a:as) (b:bs) = p a b && all2 p as bs+all2 _ _ _ = False  -- | Return number of occurrences of an item in a list countEq
src/GHC/SrcLoc/Extra.hs view
@@ -33,6 +33,12 @@ import FastString                           (FastString (..), bytesFS, mkFastStringByteList) #endif ++#if MIN_VERSION_ghc(9,0,0)+deriving instance Ord SrcSpan+deriving instance Ord UnhelpfulSpanReason+#endif+ deriving instance Generic SrcSpan instance Hashable SrcSpan