From 873ba12fa448c8e4dbaeee624cc8bad24b0fa51e Mon Sep 17 00:00:00 2001 From: Leon Schoorl Date: Thu, 30 Nov 2023 14:55:43 +0100 Subject: [PATCH 1/2] Change Signal.fromList's tail from errorX to error By making the undefined tail of a signal created with fromList into an error instead of errorX, this makes it clear when you're trying use a signal without enough input data. A problem with the errorX was that in certain circumstances it can be turned into a signal full of XException. That can turn into a signal full of undefined BitVectors. And when that is used as the basis for the expected values of a outputVerifierBitVector you end up with a testbench that reports everything is fine for some (possibly big) part of the test. Also add HasCallStack to Signal.fromList to help with tracing this error. --- clash-prelude/src/Clash/Explicit/Prelude.hs | 2 +- clash-prelude/src/Clash/Prelude.hs | 4 ++-- clash-prelude/src/Clash/Prelude/Moore.hs | 2 +- clash-prelude/src/Clash/Signal/Internal.hs | 8 ++++---- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/clash-prelude/src/Clash/Explicit/Prelude.hs b/clash-prelude/src/Clash/Explicit/Prelude.hs index 997918ecce..2e53219025 100644 --- a/clash-prelude/src/Clash/Explicit/Prelude.hs +++ b/clash-prelude/src/Clash/Explicit/Prelude.hs @@ -263,7 +263,7 @@ window clk rst en x = res -- @ -- -- >>> simulateB (windowD3 systemClockGen resetGen enableGen) [1::Int,1,2,3,4] :: [Vec 3 Int] --- [0 :> 0 :> 0 :> Nil,0 :> 0 :> 0 :> Nil,1 :> 0 :> 0 :> Nil,2 :> 1 :> 0 :> Nil,3 :> 2 :> 1 :> Nil,4 :> 3 :> 2 :> Nil,... +-- [0 :> 0 :> 0 :> Nil,0 :> 0 :> 0 :> Nil,1 :> 0 :> 0 :> Nil,2 :> 1 :> 0 :> Nil,3 :> 2 :> 1 :> Nil,4 :> 3 :> 2 :> Nil... -- ... windowD :: ( KnownNat n diff --git a/clash-prelude/src/Clash/Prelude.hs b/clash-prelude/src/Clash/Prelude.hs index 7ca69664f0..c29b270c9e 100644 --- a/clash-prelude/src/Clash/Prelude.hs +++ b/clash-prelude/src/Clash/Prelude.hs @@ -244,7 +244,7 @@ functions a type class called 'Clash.Class.Parity.Parity' is available at -- > window4 = window -- -- >>> simulateB @System window4 [1::Int,2,3,4,5] :: [Vec 4 Int] --- [1 :> 0 :> 0 :> 0 :> Nil,2 :> 1 :> 0 :> 0 :> Nil,3 :> 2 :> 1 :> 0 :> Nil,4 :> 3 :> 2 :> 1 :> Nil,5 :> 4 :> 3 :> 2 :> Nil,... +-- [1 :> 0 :> 0 :> 0 :> Nil,2 :> 1 :> 0 :> 0 :> Nil,3 :> 2 :> 1 :> 0 :> Nil,4 :> 3 :> 2 :> 1 :> Nil,5 :> 4 :> 3 :> 2 :> Nil... -- ... window :: ( HiddenClockResetEnable dom @@ -267,7 +267,7 @@ window = hideClockResetEnable E.window -- > windowD3 = windowD -- -- >>> simulateB @System windowD3 [1::Int,2,3,4] :: [Vec 3 Int] --- [0 :> 0 :> 0 :> Nil,1 :> 0 :> 0 :> Nil,2 :> 1 :> 0 :> Nil,3 :> 2 :> 1 :> Nil,4 :> 3 :> 2 :> Nil,... +-- [0 :> 0 :> 0 :> Nil,1 :> 0 :> 0 :> Nil,2 :> 1 :> 0 :> Nil,3 :> 2 :> 1 :> Nil,4 :> 3 :> 2 :> Nil... -- ... windowD :: ( HiddenClockResetEnable dom diff --git a/clash-prelude/src/Clash/Prelude/Moore.hs b/clash-prelude/src/Clash/Prelude/Moore.hs index fc9f154047..4e3f9e1304 100644 --- a/clash-prelude/src/Clash/Prelude/Moore.hs +++ b/clash-prelude/src/Clash/Prelude/Moore.hs @@ -61,7 +61,7 @@ let macT s (x,y) = x * y + s -- @ -- -- >>> simulate @System mac [(0,0),(1,1),(2,2),(3,3),(4,4)] --- [0,0,1,5,14,30,... +-- [0,0,1,5,14,30... -- ... -- -- Synchronous sequential functions can be composed just like their diff --git a/clash-prelude/src/Clash/Signal/Internal.hs b/clash-prelude/src/Clash/Signal/Internal.hs index 868ce8f632..d9644164ba 100644 --- a/clash-prelude/src/Clash/Signal/Internal.hs +++ b/clash-prelude/src/Clash/Signal/Internal.hs @@ -204,7 +204,7 @@ import Clash.NamedTypes import Clash.Promoted.Nat (SNat (..), snatToNum, snatToNatural) import Clash.Promoted.Symbol (SSymbol (..), ssymbolToString) import Clash.XException - (NFDataX(..), errorX, isX, deepseqX, defaultSeqX, seqX) + (NFDataX(..), isX, deepseqX, defaultSeqX, seqX) {- $setup >>> :set -XDataKinds @@ -1689,8 +1689,8 @@ sampleN n = take n . sample -- [1,2] -- -- __NB__: This function is not synthesizable -fromList :: NFDataX a => [a] -> Signal dom a -fromList = Prelude.foldr (\a b -> deepseqX a (a :- b)) (errorX "finite list") +fromList :: (HasCallStack,NFDataX a) => [a] -> Signal dom a +fromList = Prelude.foldr (\a b -> deepseqX a (a :- b)) (error "finite list") -- * Simulation functions (not synthesizable) @@ -1748,7 +1748,7 @@ sampleN_lazy n = take n . sample_lazy -- [1,2] -- -- __NB__: This function is not synthesizable -fromList_lazy :: [a] -> Signal dom a +fromList_lazy :: HasCallStack => [a] -> Signal dom a fromList_lazy = Prelude.foldr (:-) (error "finite list") -- * Simulation functions (not synthesizable) From f6b6891997828dbecd299937a47f774081b050af Mon Sep 17 00:00:00 2001 From: Leon Schoorl Date: Fri, 1 Dec 2023 14:31:34 +0100 Subject: [PATCH 2/2] Change Signal.fromList's tail to pure (error "..") After the provided list runs out, the tail of the signal is an infinite signal filled with error calls. This makes sure that a simulation that happens to not use the values in this signal can still make progress. --- clash-prelude/src/Clash/Signal/Internal.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/clash-prelude/src/Clash/Signal/Internal.hs b/clash-prelude/src/Clash/Signal/Internal.hs index d9644164ba..728aa0b5d3 100644 --- a/clash-prelude/src/Clash/Signal/Internal.hs +++ b/clash-prelude/src/Clash/Signal/Internal.hs @@ -1690,7 +1690,7 @@ sampleN n = take n . sample -- -- __NB__: This function is not synthesizable fromList :: (HasCallStack,NFDataX a) => [a] -> Signal dom a -fromList = Prelude.foldr (\a b -> deepseqX a (a :- b)) (error "finite list") +fromList = Prelude.foldr (\a b -> deepseqX a (a :- b)) (pure $ error "finite list") -- * Simulation functions (not synthesizable) @@ -1749,7 +1749,7 @@ sampleN_lazy n = take n . sample_lazy -- -- __NB__: This function is not synthesizable fromList_lazy :: HasCallStack => [a] -> Signal dom a -fromList_lazy = Prelude.foldr (:-) (error "finite list") +fromList_lazy = Prelude.foldr (:-) (pure $ error "finite list") -- * Simulation functions (not synthesizable)