Skip to content

Commit

Permalink
Merge pull request #159 from clash-lang/undefined
Browse files Browse the repository at this point in the history
 Create values with undefined elements
  • Loading branch information
christiaanb authored Jun 14, 2018
2 parents d1637ba + 3cf6359 commit ebf3d69
Show file tree
Hide file tree
Showing 29 changed files with 250 additions and 83 deletions.
1 change: 1 addition & 0 deletions clash-prelude.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ Library
base >= 4.8.0.0 && < 5,
bifunctors >= 5.4.0 && < 6.0,
constraints >= 0.8 && < 1.0,
containers >= 0.4.0 && < 0.6,
data-binary-ieee754 >= 0.4.4 && < 0.6,
data-default >= 0.5.3 && < 0.8,
integer-gmp >= 0.5.1.0 && < 1.1,
Expand Down
4 changes: 3 additions & 1 deletion src/Clash/Examples.hs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Licence : Creative Commons 4.0 (CC BY 4.0) (http://creativecommons.org/license

{-# LANGUAGE NoImplicitPrelude, CPP, TemplateHaskell, DataKinds, BinaryLiterals,
FlexibleContexts, GADTs, TypeOperators, TypeApplications,
RecordWildCards #-}
RecordWildCards, DeriveAnyClass #-}
{-# OPTIONS_GHC -fno-warn-unused-imports #-}
{-# OPTIONS_GHC -fno-warn-unused-binds #-}
{-# OPTIONS_GHC -fno-warn-type-defaults #-}
Expand Down Expand Up @@ -172,6 +172,7 @@ data RxReg
, _rx_d2 :: Bit
, _rx_busy :: Bool
}
deriving Undefined

makeLenses ''RxReg

Expand All @@ -183,6 +184,7 @@ data TxReg
, _tx_out :: Bit
, _tx_cnt :: Unsigned 4
}
deriving Undefined

makeLenses ''TxReg

Expand Down
10 changes: 5 additions & 5 deletions src/Clash/Explicit/BlockRam.hs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ We start with the definition of the Instructions, Register names and machine
codes:
@
{\-\# LANGUAGE RecordWildCards, TupleSections \#-\}
{\-\# LANGUAGE RecordWildCards, TupleSections, DeriveAnyClass \#-\}
module CPU where
import Clash.Explicit.Prelude
Expand Down Expand Up @@ -403,12 +403,12 @@ import Clash.Signal.Internal
import Clash.Signal.Bundle (unbundle)
import Clash.Sized.Unsigned (Unsigned)
import Clash.Sized.Vector (Vec, toList)
import Clash.XException (errorX, maybeX, seqX)
import Clash.XException (Undefined, errorX, maybeX, seqX)

{- $setup
>>> import Clash.Explicit.Prelude as C
>>> import qualified Data.List as L
>>> :set -XDataKinds -XRecordWildCards -XTupleSections
>>> :set -XDataKinds -XRecordWildCards -XTupleSections -XDeriveAnyClass
>>> type InstrAddr = Unsigned 8
>>> type MemAddr = Unsigned 5
>>> type Value = Signed 8
Expand All @@ -421,7 +421,7 @@ data Reg
| RegC
| RegD
| RegE
deriving (Eq,Show,Enum)
deriving (Eq,Show,Enum,Undefined)
:}
>>> :{
Expand Down Expand Up @@ -786,7 +786,7 @@ blockRam# clk content rd wen = case clockEnable clk of

-- | Create read-after-write blockRAM from a read-before-write one
readNew
:: Eq addr
:: (Eq addr, Undefined a)
=> Reset domain synchronous
-> Clock domain gated
-> (Signal domain addr -> Signal domain (Maybe (addr, a)) -> Signal domain a)
Expand Down
2 changes: 2 additions & 0 deletions src/Clash/Explicit/DDR.hs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ ddrIn# (GatedClock _ _ ena) (Async rst) i0 i1 i2 =
--
-- Produces a DDR output signal from a normal signal of pairs of input.
ddrOut :: ( HasCallStack
, Undefined a
, fast ~ 'Dom n pFast
, slow ~ 'Dom n (2*pFast))
=> Clock slow gated -- ^ clock
Expand All @@ -139,6 +140,7 @@ ddrOut clk rst i0 = uncurry (withFrozenCallStack $ ddrOut# clk rst i0) . unbundl


ddrOut# :: ( HasCallStack
, Undefined a
, fast ~ 'Dom n pFast
, slow ~ 'Dom n (2*pFast))
=> Clock slow gated
Expand Down
6 changes: 4 additions & 2 deletions src/Clash/Explicit/Mealy.hs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ module Clash.Explicit.Mealy
where

import Clash.Explicit.Signal (Bundle (..), Clock, Reset, Signal, register)
import Clash.XException (Undefined)

{- $setup
>>> :set -XDataKinds -XTypeApplications
Expand Down Expand Up @@ -75,7 +76,8 @@ let macT s (x,y) = (s',s)
-- s1 = 'mealy' clk rst mac 0 ('bundle' (a,x))
-- s2 = 'mealy' clk rst mac 0 ('bundle' (b,y))
-- @
mealy :: Clock dom gated -- ^ 'Clock' to synchronize to
mealy :: Undefined s
=> Clock dom gated -- ^ 'Clock' to synchronize to
-> Reset dom synchronous
-> (s -> i -> (s,o)) -- ^ Transfer function in mealy machine form:
-- @state -> input -> (newstate,output)@
Expand Down Expand Up @@ -115,7 +117,7 @@ mealy clk rst f iS =
-- (i1,b1) = 'mealyB' clk rst f 0 (a,b)
-- (i2,b2) = 'mealyB' clk rst f 3 (i1,c)
-- @
mealyB :: (Bundle i, Bundle o)
mealyB :: (Bundle i, Bundle o, Undefined s)
=> Clock dom gated
-> Reset dom synchronous
-> (s -> i -> (s,o)) -- ^ Transfer function in mealy machine form:
Expand Down
11 changes: 7 additions & 4 deletions src/Clash/Explicit/Moore.hs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ module Clash.Explicit.Moore
where

import Clash.Explicit.Signal (Bundle (..), Clock, Reset, Signal, register)
import Clash.XException (Undefined)

{- $setup
>>> :set -XDataKinds -XTypeApplications
Expand Down Expand Up @@ -69,7 +70,8 @@ import Clash.Explicit.Signal (Bundle (..), Clock, Reset, Signal, register)
-- s2 = 'moore' clk rst mac id 0 ('bundle' (b,y))
-- @
moore
:: Clock domain gated -- ^ 'Clock' to synchronize to
:: Undefined s
=> Clock domain gated -- ^ 'Clock' to synchronize to
-> Reset domain synchronous
-> (s -> i -> s) -- ^ Transfer function in moore machine form:
-- @state -> input -> newstate@
Expand All @@ -88,7 +90,8 @@ moore clk rst ft fo iS =
-- | Create a synchronous function from a combinational function describing
-- a moore machine without any output logic
medvedev
:: Clock domain gated
:: Undefined s
=> Clock domain gated
-> Reset domain synchronous
-> (s -> i -> s)
-> s
Expand Down Expand Up @@ -124,7 +127,7 @@ medvedev clk rst tr st = moore clk rst tr id st
-- (i2,b2) = 'mooreB' clk rst t o 3 (i1,c)
-- @
mooreB
:: (Bundle i, Bundle o)
:: (Bundle i, Bundle o, Undefined s)
=> Clock domain gated
-> Reset domain synchronous
-> (s -> i -> s) -- ^ Transfer function in moore machine form:
Expand All @@ -140,7 +143,7 @@ mooreB clk rst ft fo iS i = unbundle (moore clk rst ft fo iS (bundle i))

-- | A version of 'medvedev' that does automatic 'Bundle'ing
medvedevB
:: (Bundle i, Bundle s)
:: (Bundle i, Bundle s, Undefined s)
=> Clock domain gated
-> Reset domain synchronous
-> (s -> i -> s)
Expand Down
4 changes: 2 additions & 2 deletions src/Clash/Explicit/Prelude.hs
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ import Clash.XException
-- [<1,0,0,0>,<2,1,0,0>,<3,2,1,0>,<4,3,2,1>,<5,4,3,2>...
-- ...
window
:: (KnownNat n, Default a)
:: (KnownNat n, Default a, Undefined a)
=> Clock domain gated
-- ^ Clock to which the incoming signal is synchronized
-> Reset domain synchronous
Expand All @@ -205,7 +205,7 @@ window clk rst x = res
-- [<0,0,0>,<1,0,0>,<2,1,0>,<3,2,1>,<4,3,2>...
-- ...
windowD
:: (KnownNat n, Default a)
:: (KnownNat n, Default a, Undefined a)
=> Clock domain gated
-- ^ Clock to which the incoming signal is synchronized
-> Reset domain synchronous
Expand Down
6 changes: 3 additions & 3 deletions src/Clash/Explicit/Prelude/Safe.hs
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ import Clash.XException
-- [(8,8),(1,1),(2,2),(3,3)...
-- ...
registerB
:: Bundle a
:: (Bundle a, Undefined a)
=> Clock domain gated
-> Reset domain synchronous
-> a
Expand All @@ -172,7 +172,7 @@ registerB clk rst i = unbundle Prelude.. register clk rst i Prelude.. bundle

-- | Give a pulse when the 'Signal' goes from 'minBound' to 'maxBound'
isRising
:: (Bounded a, Eq a)
:: (Bounded a, Eq a, Undefined a)
=> Clock domain gated
-> Reset domain synchronous
-> a -- ^ Starting value
Expand All @@ -186,7 +186,7 @@ isRising clk rst is s = liftA2 edgeDetect prev s

-- | Give a pulse when the 'Signal' goes from 'maxBound' to 'minBound'
isFalling
:: (Bounded a, Eq a)
:: (Bounded a, Eq a, Undefined a)
=> Clock domain gated
-> Reset domain synchronous
-> a -- ^ Starting value
Expand Down
28 changes: 19 additions & 9 deletions src/Clash/Explicit/ROM.hs
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ ROMs
-}

{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE TypeOperators #-}

{-# LANGUAGE Safe #-}
{-# LANGUAGE Trustworthy #-}

{-# OPTIONS_GHC -fplugin GHC.TypeLits.KnownNat.Solver #-}
{-# OPTIONS_HADDOCK show-extensions #-}
Expand All @@ -26,18 +27,14 @@ module Clash.Explicit.ROM
where

import Data.Array ((!),listArray)
import GHC.Stack (withFrozenCallStack)
import GHC.TypeLits (KnownNat, type (^))
import Prelude hiding (length)

-- import Clash.Signal (Signal)
-- import Clash.Signal.Explicit (Signal', SClock, systemClockGen)
import Clash.Explicit.Signal (Clock, Signal, delay)

import Clash.Signal.Internal (Clock (..), Signal (..))
import Clash.Sized.Unsigned (Unsigned)
-- import Clash.Signal.Explicit (register')
import Clash.Sized.Vector (Vec, length, toList)
-- import Clash.XException (errorX)

import Clash.XException (errorX, seqX)

-- | A ROM with a synchronous read port, with space for 2^@n@ elements
--
Expand Down Expand Up @@ -90,8 +87,21 @@ rom#
-> Signal domain Int -- ^ Read address @rd@
-> Signal domain a
-- ^ The value of the ROM at address @rd@ from the previous clock cycle
rom# clk content rd = delay clk ((arr !) <$> rd)
rom# clk content rd = go clk ((arr !) <$> rd)
where
szI = length content
arr = listArray (0,szI-1) (toList content)

go :: Clock domain gated
-> Signal domain a
-> Signal domain a
go Clock {} =
\s -> withFrozenCallStack (errorX "rom: initial value undefined") :- s

go (GatedClock _ _ en) =
go' (withFrozenCallStack (errorX "rom: initial value undefined")) en

go' o (e :- es) as@(~(x :- xs)) =
-- See [Note: register strictness annotations]
o `seqX` o :- (as `seq` if e then go' x es xs else go' o es xs)
{-# NOINLINE rom# #-}
11 changes: 7 additions & 4 deletions src/Clash/Explicit/Signal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,8 @@ import GHC.Stack (HasCallStack, withFrozenCallStack)
import Clash.Signal.Internal
import Clash.Signal.Bundle (Bundle (..))

import Clash.XException (Undefined)

{- $setup
>>> :set -XDataKinds -XTypeApplications
>>> import Clash.Explicit.Prelude
Expand Down Expand Up @@ -457,7 +459,7 @@ repSchedule high low = take low $ repSchedule' low high 1
-- >>> printX (sampleN 3 (delay systemClockGen (fromList [1,2,3,4])))
-- [X,1,2]
delay
:: HasCallStack
:: (HasCallStack, Undefined a)
=> Clock domain gated
-- ^ Clock
-> Signal domain a
Expand All @@ -471,7 +473,7 @@ delay = \clk i -> withFrozenCallStack (delay# clk i)
-- >>> sampleN 3 (register systemClockGen systemResetGen 8 (fromList [1,2,3,4]))
-- [8,1,2]
register
:: HasCallStack
:: (HasCallStack, Undefined a)
=> Clock domain gated
-- ^ clock
-> Reset domain synchronous
Expand Down Expand Up @@ -507,7 +509,7 @@ register = \clk rst initial i -> withFrozenCallStack
-- >>> sampleN 8 (count systemClockGen systemResetGen)
-- [0,0,1,1,2,2,3,3]
regMaybe
:: HasCallStack
:: (HasCallStack, Undefined a)
=> Clock domain gated
-- ^ Clock
-> Reset domain synchronous
Expand Down Expand Up @@ -536,7 +538,8 @@ regMaybe = \clk rst initial iM -> withFrozenCallStack
-- >>> sampleN 8 (count systemClockGen systemResetGen)
-- [0,0,1,1,2,2,3,3]
regEn
:: Clock domain clk
:: Undefined a
=> Clock domain clk
-- ^ Clock
-> Reset domain synchronous
-- ^ Reset (active-high), 'regEn' outputs the reset value when the
Expand Down
5 changes: 3 additions & 2 deletions src/Clash/Explicit/Signal/Delayed.hs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import Clash.Sized.Vector
import Clash.Explicit.Signal
(Clock, Domain, Reset, Signal, register, fromList, fromList_lazy, bundle,
unbundle)
import Clash.XException (Undefined)

{- $setup
>>> :set -XDataKinds
Expand Down Expand Up @@ -124,7 +125,7 @@ dfromList_lazy = coerce . fromList_lazy
-- [0,0,0,1,2,3]
delayed
:: forall domain gated synchronous a n d
. KnownNat d
. (KnownNat d, Undefined a)
=> Clock domain gated
-> Reset domain synchronous
-> Vec d a
Expand All @@ -151,7 +152,7 @@ delayed clk rst m ds = coerce (delaySignal (coerce ds))
-- >>> sampleN 6 (delay2 systemClockGen systemResetGen (dfromList [1..]))
-- [0,0,1,2,3,4]
delayedI
:: (Default a, KnownNat d)
:: (Default a, KnownNat d, Undefined a)
=> Clock domain gated
-> Reset domain synchronous
-> DSignal domain n a
Expand Down
4 changes: 3 additions & 1 deletion src/Clash/Explicit/Synchronizer.hs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ import Clash.Promoted.Nat (SNat (..), pow2SNat)
import Clash.Promoted.Nat.Literals (d0)
import Clash.Signal (mux)
import Clash.Sized.BitVector (BitVector, (++#))
import Clash.XException (Undefined)

-- * Dual flip-flop synchronizer

Expand All @@ -86,7 +87,8 @@ import Clash.Sized.BitVector (BitVector, (++#))
-- If you want to have /safe/ __word__-synchronisation use
-- 'asyncFIFOSynchronizer'.
dualFlipFlopSynchronizer
:: Clock domain1 gated1
:: Undefined a
=> Clock domain1 gated1
-- ^ 'Clock' to which the incoming data is synchronised
-> Clock domain2 gated2
-- ^ 'Clock' to which the outgoing data is synchronised
Expand Down
4 changes: 2 additions & 2 deletions src/Clash/Prelude.hs
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ It instead exports the identically named functions defined in terms of
-- [<1,0,0,0>,<2,1,0,0>,<3,2,1,0>,<4,3,2,1>,<5,4,3,2>...
-- ...
window
:: (KnownNat n, Default a, HiddenClockReset domain gated synchronous)
:: (KnownNat n, Default a, Undefined a, HiddenClockReset domain gated synchronous)
=> Signal domain a -- ^ Signal to create a window over
-> Vec (n + 1) (Signal domain a) -- ^ Window of at least size 1
window = hideClockReset E.window
Expand All @@ -213,7 +213,7 @@ window = hideClockReset E.window
-- [<0,0,0>,<1,0,0>,<2,1,0>,<3,2,1>,<4,3,2>...
-- ...
windowD
:: (KnownNat n, Default a, HiddenClockReset domain gated synchronous)
:: (KnownNat n, Default a, Undefined a, HiddenClockReset domain gated synchronous)
=> Signal domain a -- ^ Signal to create a window over
-> Vec (n + 1) (Signal domain a) -- ^ Window of at least size 1
windowD = hideClockReset E.windowD
Expand Down
Loading

0 comments on commit ebf3d69

Please sign in to comment.