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 +15/−0
- clash-lib.cabal +6/−6
- prims/commonverilog/Clash_Explicit_Testbench.primitives +9/−0
- prims/commonverilog/Clash_Signal_Internal.primitives +0/−8
- prims/systemverilog/Clash_Explicit_Testbench.primitives +31/−0
- prims/systemverilog/Clash_Signal_Internal.primitives +0/−31
- prims/verilog/Clash_Explicit_Testbench.primitives +34/−0
- prims/verilog/Clash_Signal_Internal.primitives +0/−34
- prims/vhdl/Clash_Explicit_Testbench.primitives +42/−0
- prims/vhdl/Clash_Signal_Internal.primitives +0/−39
- src/Clash/Backend/VHDL.hs +17/−7
- src/Clash/Core/DataCon.hs +1/−2
- src/Clash/Core/FreeVars.hs +2/−2
- src/Clash/Core/Subst.hs +81/−10
- src/Clash/Core/Term.hs +25/−9
- src/Clash/Core/Type.hs +11/−2
- src/Clash/Core/Type.hs-boot +0/−2
- src/Clash/Driver/Manifest.hs +4/−1
- src/Clash/Driver/Types.hs +38/−0
- src/Clash/Netlist.hs +1/−2
- src/Clash/Netlist/BlackBox/Types.hs +3/−3
- src/Clash/Netlist/Types.hs +3/−2
- src/Clash/Netlist/Types.hs-boot +2/−0
- src/Clash/Netlist/Util.hs +6/−4
- src/Clash/Normalize/Transformations.hs +30/−8
- src/Clash/Primitives/DSL.hs +22/−1
- src/Clash/Primitives/Types.hs +4/−4
- src/Clash/Rewrite/Types.hs +1/−2
- src/Clash/Rewrite/Util.hs +3/−3
- src/Clash/Util.hs +10/−5
- src/Data/Aeson/Extra.hs +1/−1
- src/Data/List/Extra.hs +8/−0
- src/GHC/SrcLoc/Extra.hs +6/−0
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