{-# LANGUAGE GADTs #-}
{-# LANGUAGE Trustworthy #-}
{-# OPTIONS_GHC -fplugin GHC.TypeLits.KnownNat.Solver #-}
{-# OPTIONS_HADDOCK show-extensions #-}
{-# OPTIONS_GHC -fno-cpr-anal #-}
module Clash.Explicit.BlockRam
(
blockRam
, blockRamPow2
, blockRamU
, blockRam1
, ResetStrategy(..)
, readNew
, blockRam#
)
where
import Data.Maybe (isJust)
import qualified Data.Sequence as Seq
import GHC.Stack (HasCallStack, withFrozenCallStack)
import GHC.TypeLits (KnownNat, type (^), type (<=))
import Prelude hiding (length, replicate)
import Clash.Annotations.Primitive
(hasBlackBox)
import Clash.Class.Num (SaturationMode(SatBound), satSucc)
import Clash.Explicit.Signal (KnownDomain, Enable, register, fromEnable)
import Clash.Signal.Internal
(Clock(..), Reset, Signal (..), invertReset, (.&&.), mux)
import Clash.Promoted.Nat (SNat(..))
import Clash.Signal.Bundle (unbundle)
import Clash.Sized.Unsigned (Unsigned)
import Clash.Sized.Index (Index)
import Clash.Sized.Vector (Vec, replicate, toList, iterateI)
import qualified Clash.Sized.Vector as CV
import Clash.XException
(maybeIsX, seqX, NFDataX, deepErrorX, defaultSeqX, fromJustX)
blockRam
:: ( KnownDomain dom
, HasCallStack
, NFDataX a
, Enum addr )
=> Clock dom
-> Enable dom
-> Vec n a
-> Signal dom addr
-> Signal dom (Maybe (addr, a))
-> Signal dom a
blockRam :: Clock dom
-> Enable dom
-> Vec n a
-> Signal dom addr
-> Signal dom (Maybe (addr, a))
-> Signal dom a
blockRam = \clk :: Clock dom
clk gen :: Enable dom
gen content :: Vec n a
content rd :: Signal dom addr
rd wrM :: Signal dom (Maybe (addr, a))
wrM ->
let en :: Signal dom Bool
en = Maybe (addr, a) -> Bool
forall a. Maybe a -> Bool
isJust (Maybe (addr, a) -> Bool)
-> Signal dom (Maybe (addr, a)) -> Signal dom Bool
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Signal dom (Maybe (addr, a))
wrM
(wr :: Signal dom addr
wr,din :: Signal dom a
din) = Signal dom (addr, a) -> Unbundled dom (addr, a)
forall a (dom :: Domain).
Bundle a =>
Signal dom a -> Unbundled dom a
unbundle (Maybe (addr, a) -> (addr, a)
forall a. HasCallStack => Maybe a -> a
fromJustX (Maybe (addr, a) -> (addr, a))
-> Signal dom (Maybe (addr, a)) -> Signal dom (addr, a)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Signal dom (Maybe (addr, a))
wrM)
in (HasCallStack => Signal dom a) -> Signal dom a
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack
(Clock dom
-> Enable dom
-> Vec n a
-> Signal dom Int
-> Signal dom Bool
-> Signal dom Int
-> Signal dom a
-> Signal dom a
forall (dom :: Domain) a (n :: Nat).
(KnownDomain dom, HasCallStack, NFDataX a) =>
Clock dom
-> Enable dom
-> Vec n a
-> Signal dom Int
-> Signal dom Bool
-> Signal dom Int
-> Signal dom a
-> Signal dom a
blockRam# Clock dom
clk Enable dom
gen Vec n a
content (addr -> Int
forall a. Enum a => a -> Int
fromEnum (addr -> Int) -> Signal dom addr -> Signal dom Int
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Signal dom addr
rd) Signal dom Bool
en (addr -> Int
forall a. Enum a => a -> Int
fromEnum (addr -> Int) -> Signal dom addr -> Signal dom Int
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Signal dom addr
wr) Signal dom a
din)
{-# INLINE blockRam #-}
blockRamPow2
:: ( KnownDomain dom
, HasCallStack
, NFDataX a
, KnownNat n )
=> Clock dom
-> Enable dom
-> Vec (2^n) a
-> Signal dom (Unsigned n)
-> Signal dom (Maybe (Unsigned n, a))
-> Signal dom a
blockRamPow2 :: Clock dom
-> Enable dom
-> Vec (2 ^ n) a
-> Signal dom (Unsigned n)
-> Signal dom (Maybe (Unsigned n, a))
-> Signal dom a
blockRamPow2 = \clk :: Clock dom
clk en :: Enable dom
en cnt :: Vec (2 ^ n) a
cnt rd :: Signal dom (Unsigned n)
rd wrM :: Signal dom (Maybe (Unsigned n, a))
wrM -> (HasCallStack => Signal dom a) -> Signal dom a
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack
(Clock dom
-> Enable dom
-> Vec (2 ^ n) a
-> Signal dom (Unsigned n)
-> Signal dom (Maybe (Unsigned n, a))
-> Signal dom a
forall (dom :: Domain) a addr (n :: Nat).
(KnownDomain dom, HasCallStack, NFDataX a, Enum addr) =>
Clock dom
-> Enable dom
-> Vec n a
-> Signal dom addr
-> Signal dom (Maybe (addr, a))
-> Signal dom a
blockRam Clock dom
clk Enable dom
en Vec (2 ^ n) a
cnt Signal dom (Unsigned n)
rd Signal dom (Maybe (Unsigned n, a))
wrM)
{-# INLINE blockRamPow2 #-}
data ResetStrategy (r :: Bool) where
ClearOnReset :: ResetStrategy 'True
NoClearOnReset :: ResetStrategy 'False
blockRamU
:: forall n dom a r addr
. ( KnownDomain dom
, HasCallStack
, NFDataX a
, Enum addr
, 1 <= n )
=> Clock dom
-> Reset dom
-> Enable dom
-> ResetStrategy r
-> SNat n
-> (Index n -> a)
-> Signal dom addr
-> Signal dom (Maybe (addr, a))
-> Signal dom a
blockRamU :: Clock dom
-> Reset dom
-> Enable dom
-> ResetStrategy r
-> SNat n
-> (Index n -> a)
-> Signal dom addr
-> Signal dom (Maybe (addr, a))
-> Signal dom a
blockRamU clk :: Clock dom
clk rst0 :: Reset dom
rst0 en :: Enable dom
en rstStrategy :: ResetStrategy r
rstStrategy n :: SNat n
n@SNat n
SNat initF :: Index n -> a
initF rd0 :: Signal dom addr
rd0 mw0 :: Signal dom (Maybe (addr, a))
mw0 =
case ResetStrategy r
rstStrategy of
ClearOnReset ->
Clock dom
-> Enable dom
-> SNat n
-> Signal dom Int
-> Signal dom Bool
-> Signal dom Int
-> Signal dom a
-> Signal dom a
forall (n :: Nat) (dom :: Domain) a.
(KnownDomain dom, HasCallStack, NFDataX a) =>
Clock dom
-> Enable dom
-> SNat n
-> Signal dom Int
-> Signal dom Bool
-> Signal dom Int
-> Signal dom a
-> Signal dom a
blockRamU# Clock dom
clk Enable dom
en SNat n
n Signal dom Int
rd1 Signal dom Bool
we1 Signal dom Int
wa1 Signal dom a
w1
NoClearOnReset ->
Clock dom
-> Enable dom
-> SNat n
-> Signal dom Int
-> Signal dom Bool
-> Signal dom Int
-> Signal dom a
-> Signal dom a
forall (n :: Nat) (dom :: Domain) a.
(KnownDomain dom, HasCallStack, NFDataX a) =>
Clock dom
-> Enable dom
-> SNat n
-> Signal dom Int
-> Signal dom Bool
-> Signal dom Int
-> Signal dom a
-> Signal dom a
blockRamU# Clock dom
clk Enable dom
en SNat n
n
(addr -> Int
forall a. Enum a => a -> Int
fromEnum (addr -> Int) -> Signal dom addr -> Signal dom Int
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Signal dom addr
rd0)
Signal dom Bool
we0
(addr -> Int
forall a. Enum a => a -> Int
fromEnum (addr -> Int) -> Signal dom addr -> Signal dom Int
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Signal dom addr
wa0)
Signal dom a
w0
where
rstBool :: Signal dom Bool
rstBool = Clock dom
-> Reset dom
-> Enable dom
-> Bool
-> Signal dom Bool
-> Signal dom Bool
forall (dom :: Domain) a.
(KnownDomain dom, NFDataX a) =>
Clock dom
-> Reset dom -> Enable dom -> a -> Signal dom a -> Signal dom a
register Clock dom
clk Reset dom
rst0 Enable dom
en Bool
True (Bool -> Signal dom Bool
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure Bool
False)
rstInv :: Reset dom
rstInv = Reset dom -> Reset dom
forall (dom :: Domain). Reset dom -> Reset dom
invertReset Reset dom
rst0
waCounter :: Signal dom (Index n)
waCounter :: Signal dom (Index n)
waCounter = Clock dom
-> Reset dom
-> Enable dom
-> Index n
-> Signal dom (Index n)
-> Signal dom (Index n)
forall (dom :: Domain) a.
(KnownDomain dom, NFDataX a) =>
Clock dom
-> Reset dom -> Enable dom -> a -> Signal dom a -> Signal dom a
register Clock dom
clk Reset dom
rstInv Enable dom
en 0 (SaturationMode -> Index n -> Index n
forall a. SaturatingNum a => SaturationMode -> a -> a
satSucc SaturationMode
SatBound (Index n -> Index n)
-> Signal dom (Index n) -> Signal dom (Index n)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Signal dom (Index n)
waCounter)
wa0 :: Signal dom addr
wa0 = (addr, a) -> addr
forall a b. (a, b) -> a
fst ((addr, a) -> addr)
-> (Maybe (addr, a) -> (addr, a)) -> Maybe (addr, a) -> addr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe (addr, a) -> (addr, a)
forall a. HasCallStack => Maybe a -> a
fromJustX (Maybe (addr, a) -> addr)
-> Signal dom (Maybe (addr, a)) -> Signal dom addr
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Signal dom (Maybe (addr, a))
mw0
w0 :: Signal dom a
w0 = (addr, a) -> a
forall a b. (a, b) -> b
snd ((addr, a) -> a)
-> (Maybe (addr, a) -> (addr, a)) -> Maybe (addr, a) -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe (addr, a) -> (addr, a)
forall a. HasCallStack => Maybe a -> a
fromJustX (Maybe (addr, a) -> a)
-> Signal dom (Maybe (addr, a)) -> Signal dom a
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Signal dom (Maybe (addr, a))
mw0
we0 :: Signal dom Bool
we0 = Maybe (addr, a) -> Bool
forall a. Maybe a -> Bool
isJust (Maybe (addr, a) -> Bool)
-> Signal dom (Maybe (addr, a)) -> Signal dom Bool
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Signal dom (Maybe (addr, a))
mw0
rd1 :: Signal dom Int
rd1 = Signal dom Bool
-> Signal dom Int -> Signal dom Int -> Signal dom Int
forall (f :: Type -> Type) a.
Applicative f =>
f Bool -> f a -> f a -> f a
mux Signal dom Bool
rstBool 0 (addr -> Int
forall a. Enum a => a -> Int
fromEnum (addr -> Int) -> Signal dom addr -> Signal dom Int
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Signal dom addr
rd0)
we1 :: Signal dom Bool
we1 = Signal dom Bool
-> Signal dom Bool -> Signal dom Bool -> Signal dom Bool
forall (f :: Type -> Type) a.
Applicative f =>
f Bool -> f a -> f a -> f a
mux Signal dom Bool
rstBool (Bool -> Signal dom Bool
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure Bool
True) Signal dom Bool
we0
wa1 :: Signal dom Int
wa1 = Signal dom Bool
-> Signal dom Int -> Signal dom Int -> Signal dom Int
forall (f :: Type -> Type) a.
Applicative f =>
f Bool -> f a -> f a -> f a
mux Signal dom Bool
rstBool (Integer -> Int
forall a. Num a => Integer -> a
fromInteger (Integer -> Int) -> (Index n -> Integer) -> Index n -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Index n -> Integer
forall a. Integral a => a -> Integer
toInteger (Index n -> Int) -> Signal dom (Index n) -> Signal dom Int
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Signal dom (Index n)
waCounter) (addr -> Int
forall a. Enum a => a -> Int
fromEnum (addr -> Int) -> Signal dom addr -> Signal dom Int
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Signal dom addr
wa0)
w1 :: Signal dom a
w1 = Signal dom Bool -> Signal dom a -> Signal dom a -> Signal dom a
forall (f :: Type -> Type) a.
Applicative f =>
f Bool -> f a -> f a -> f a
mux Signal dom Bool
rstBool (Index n -> a
initF (Index n -> a) -> Signal dom (Index n) -> Signal dom a
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Signal dom (Index n)
waCounter) Signal dom a
w0
blockRamU#
:: forall n dom a
. ( KnownDomain dom
, HasCallStack
, NFDataX a )
=> Clock dom
-> Enable dom
-> SNat n
-> Signal dom Int
-> Signal dom Bool
-> Signal dom Int
-> Signal dom a
-> Signal dom a
blockRamU# :: Clock dom
-> Enable dom
-> SNat n
-> Signal dom Int
-> Signal dom Bool
-> Signal dom Int
-> Signal dom a
-> Signal dom a
blockRamU# clk :: Clock dom
clk en :: Enable dom
en SNat =
Clock dom
-> Enable dom
-> Vec n a
-> Signal dom Int
-> Signal dom Bool
-> Signal dom Int
-> Signal dom a
-> Signal dom a
forall (dom :: Domain) a (n :: Nat).
(KnownDomain dom, HasCallStack, NFDataX a) =>
Clock dom
-> Enable dom
-> Vec n a
-> Signal dom Int
-> Signal dom Bool
-> Signal dom Int
-> Signal dom a
-> Signal dom a
blockRam#
Clock dom
clk
Enable dom
en
((Int -> a) -> Vec n Int -> Vec n a
forall a b (n :: Nat). (a -> b) -> Vec n a -> Vec n b
CV.map
(\i :: Int
i -> String -> a
forall a. (NFDataX a, HasCallStack) => String -> a
deepErrorX (String -> a) -> String -> a
forall a b. (a -> b) -> a -> b
$ "Initial value at index " String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
i String -> String -> String
forall a. [a] -> [a] -> [a]
++ " undefined.")
((Int -> Int) -> Int -> Vec n Int
forall (n :: Nat) a. KnownNat n => (a -> a) -> a -> Vec n a
iterateI @n Int -> Int
forall a. Enum a => a -> a
succ (0 :: Int)))
{-# NOINLINE blockRamU# #-}
{-# ANN blockRamU# hasBlackBox #-}
blockRam1
:: forall n dom a r addr
. ( KnownDomain dom
, HasCallStack
, NFDataX a
, Enum addr
, 1 <= n )
=> Clock dom
-> Reset dom
-> Enable dom
-> ResetStrategy r
-> SNat n
-> a
-> Signal dom addr
-> Signal dom (Maybe (addr, a))
-> Signal dom a
blockRam1 :: Clock dom
-> Reset dom
-> Enable dom
-> ResetStrategy r
-> SNat n
-> a
-> Signal dom addr
-> Signal dom (Maybe (addr, a))
-> Signal dom a
blockRam1 clk :: Clock dom
clk rst0 :: Reset dom
rst0 en :: Enable dom
en rstStrategy :: ResetStrategy r
rstStrategy n :: SNat n
n@SNat n
SNat a :: a
a rd0 :: Signal dom addr
rd0 mw0 :: Signal dom (Maybe (addr, a))
mw0 =
case ResetStrategy r
rstStrategy of
ClearOnReset ->
Clock dom
-> Enable dom
-> SNat n
-> a
-> Signal dom Int
-> Signal dom Bool
-> Signal dom Int
-> Signal dom a
-> Signal dom a
forall (n :: Nat) (dom :: Domain) a.
(KnownDomain dom, HasCallStack, NFDataX a) =>
Clock dom
-> Enable dom
-> SNat n
-> a
-> Signal dom Int
-> Signal dom Bool
-> Signal dom Int
-> Signal dom a
-> Signal dom a
blockRam1# Clock dom
clk Enable dom
en SNat n
n a
a Signal dom Int
rd1 Signal dom Bool
we1 Signal dom Int
wa1 Signal dom a
w1
NoClearOnReset ->
Clock dom
-> Enable dom
-> SNat n
-> a
-> Signal dom Int
-> Signal dom Bool
-> Signal dom Int
-> Signal dom a
-> Signal dom a
forall (n :: Nat) (dom :: Domain) a.
(KnownDomain dom, HasCallStack, NFDataX a) =>
Clock dom
-> Enable dom
-> SNat n
-> a
-> Signal dom Int
-> Signal dom Bool
-> Signal dom Int
-> Signal dom a
-> Signal dom a
blockRam1# Clock dom
clk Enable dom
en SNat n
n a
a
(addr -> Int
forall a. Enum a => a -> Int
fromEnum (addr -> Int) -> Signal dom addr -> Signal dom Int
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Signal dom addr
rd0)
Signal dom Bool
we0
(addr -> Int
forall a. Enum a => a -> Int
fromEnum (addr -> Int) -> Signal dom addr -> Signal dom Int
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Signal dom addr
wa0)
Signal dom a
w0
where
rstBool :: Signal dom Bool
rstBool = Clock dom
-> Reset dom
-> Enable dom
-> Bool
-> Signal dom Bool
-> Signal dom Bool
forall (dom :: Domain) a.
(KnownDomain dom, NFDataX a) =>
Clock dom
-> Reset dom -> Enable dom -> a -> Signal dom a -> Signal dom a
register Clock dom
clk Reset dom
rst0 Enable dom
en Bool
True (Bool -> Signal dom Bool
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure Bool
False)
rstInv :: Reset dom
rstInv = Reset dom -> Reset dom
forall (dom :: Domain). Reset dom -> Reset dom
invertReset Reset dom
rst0
waCounter :: Signal dom (Index n)
waCounter :: Signal dom (Index n)
waCounter = Clock dom
-> Reset dom
-> Enable dom
-> Index n
-> Signal dom (Index n)
-> Signal dom (Index n)
forall (dom :: Domain) a.
(KnownDomain dom, NFDataX a) =>
Clock dom
-> Reset dom -> Enable dom -> a -> Signal dom a -> Signal dom a
register Clock dom
clk Reset dom
rstInv Enable dom
en 0 (SaturationMode -> Index n -> Index n
forall a. SaturatingNum a => SaturationMode -> a -> a
satSucc SaturationMode
SatBound (Index n -> Index n)
-> Signal dom (Index n) -> Signal dom (Index n)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Signal dom (Index n)
waCounter)
wa0 :: Signal dom addr
wa0 = (addr, a) -> addr
forall a b. (a, b) -> a
fst ((addr, a) -> addr)
-> (Maybe (addr, a) -> (addr, a)) -> Maybe (addr, a) -> addr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe (addr, a) -> (addr, a)
forall a. HasCallStack => Maybe a -> a
fromJustX (Maybe (addr, a) -> addr)
-> Signal dom (Maybe (addr, a)) -> Signal dom addr
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Signal dom (Maybe (addr, a))
mw0
w0 :: Signal dom a
w0 = (addr, a) -> a
forall a b. (a, b) -> b
snd ((addr, a) -> a)
-> (Maybe (addr, a) -> (addr, a)) -> Maybe (addr, a) -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe (addr, a) -> (addr, a)
forall a. HasCallStack => Maybe a -> a
fromJustX (Maybe (addr, a) -> a)
-> Signal dom (Maybe (addr, a)) -> Signal dom a
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Signal dom (Maybe (addr, a))
mw0
we0 :: Signal dom Bool
we0 = Maybe (addr, a) -> Bool
forall a. Maybe a -> Bool
isJust (Maybe (addr, a) -> Bool)
-> Signal dom (Maybe (addr, a)) -> Signal dom Bool
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Signal dom (Maybe (addr, a))
mw0
rd1 :: Signal dom Int
rd1 = Signal dom Bool
-> Signal dom Int -> Signal dom Int -> Signal dom Int
forall (f :: Type -> Type) a.
Applicative f =>
f Bool -> f a -> f a -> f a
mux Signal dom Bool
rstBool 0 (addr -> Int
forall a. Enum a => a -> Int
fromEnum (addr -> Int) -> Signal dom addr -> Signal dom Int
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Signal dom addr
rd0)
we1 :: Signal dom Bool
we1 = Signal dom Bool
-> Signal dom Bool -> Signal dom Bool -> Signal dom Bool
forall (f :: Type -> Type) a.
Applicative f =>
f Bool -> f a -> f a -> f a
mux Signal dom Bool
rstBool (Bool -> Signal dom Bool
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure Bool
True) Signal dom Bool
we0
wa1 :: Signal dom Int
wa1 = Signal dom Bool
-> Signal dom Int -> Signal dom Int -> Signal dom Int
forall (f :: Type -> Type) a.
Applicative f =>
f Bool -> f a -> f a -> f a
mux Signal dom Bool
rstBool (Integer -> Int
forall a. Num a => Integer -> a
fromInteger (Integer -> Int) -> (Index n -> Integer) -> Index n -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Index n -> Integer
forall a. Integral a => a -> Integer
toInteger (Index n -> Int) -> Signal dom (Index n) -> Signal dom Int
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Signal dom (Index n)
waCounter) (addr -> Int
forall a. Enum a => a -> Int
fromEnum (addr -> Int) -> Signal dom addr -> Signal dom Int
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Signal dom addr
wa0)
w1 :: Signal dom a
w1 = Signal dom Bool -> Signal dom a -> Signal dom a -> Signal dom a
forall (f :: Type -> Type) a.
Applicative f =>
f Bool -> f a -> f a -> f a
mux Signal dom Bool
rstBool (a -> Signal dom a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure a
a) Signal dom a
w0
blockRam1#
:: forall n dom a
. ( KnownDomain dom
, HasCallStack
, NFDataX a )
=> Clock dom
-> Enable dom
-> SNat n
-> a
-> Signal dom Int
-> Signal dom Bool
-> Signal dom Int
-> Signal dom a
-> Signal dom a
blockRam1# :: Clock dom
-> Enable dom
-> SNat n
-> a
-> Signal dom Int
-> Signal dom Bool
-> Signal dom Int
-> Signal dom a
-> Signal dom a
blockRam1# clk :: Clock dom
clk en :: Enable dom
en n :: SNat n
n a :: a
a =
Clock dom
-> Enable dom
-> Vec n a
-> Signal dom Int
-> Signal dom Bool
-> Signal dom Int
-> Signal dom a
-> Signal dom a
forall (dom :: Domain) a (n :: Nat).
(KnownDomain dom, HasCallStack, NFDataX a) =>
Clock dom
-> Enable dom
-> Vec n a
-> Signal dom Int
-> Signal dom Bool
-> Signal dom Int
-> Signal dom a
-> Signal dom a
blockRam# Clock dom
clk Enable dom
en (SNat n -> a -> Vec n a
forall (n :: Nat) a. SNat n -> a -> Vec n a
replicate SNat n
n a
a)
{-# NOINLINE blockRam1# #-}
{-# ANN blockRam1# hasBlackBox #-}
blockRam#
:: ( KnownDomain dom
, HasCallStack
, NFDataX a )
=> Clock dom
-> Enable dom
-> Vec n a
-> Signal dom Int
-> Signal dom Bool
-> Signal dom Int
-> Signal dom a
-> Signal dom a
blockRam# :: Clock dom
-> Enable dom
-> Vec n a
-> Signal dom Int
-> Signal dom Bool
-> Signal dom Int
-> Signal dom a
-> Signal dom a
blockRam# (Clock _) gen :: Enable dom
gen content :: Vec n a
content rd :: Signal dom Int
rd wen :: Signal dom Bool
wen =
Seq a
-> a
-> Signal dom Bool
-> Signal dom Int
-> Signal dom Bool
-> Signal dom Int
-> Signal dom a
-> Signal dom a
forall t a (dom :: Domain) (dom :: Domain) (dom :: Domain)
(dom :: Domain) (dom :: Domain) (dom :: Domain).
(NFDataX t, Enum a) =>
Seq t
-> t
-> Signal dom Bool
-> Signal dom Int
-> Signal dom Bool
-> Signal dom a
-> Signal dom t
-> Signal dom t
go
([a] -> Seq a
forall a. [a] -> Seq a
Seq.fromList (Vec n a -> [a]
forall (n :: Nat) a. Vec n a -> [a]
toList Vec n a
content))
((HasCallStack => a) -> a
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack (String -> a
forall a. (NFDataX a, HasCallStack) => String -> a
deepErrorX "blockRam: intial value undefined"))
(Enable dom -> Signal dom Bool
forall (dom :: Domain). Enable dom -> Signal dom Bool
fromEnable Enable dom
gen)
Signal dom Int
rd
(Enable dom -> Signal dom Bool
forall (dom :: Domain). Enable dom -> Signal dom Bool
fromEnable Enable dom
gen Signal dom Bool -> Signal dom Bool -> Signal dom Bool
forall (f :: Type -> Type).
Applicative f =>
f Bool -> f Bool -> f Bool
.&&. Signal dom Bool
wen)
where
go :: Seq t
-> t
-> Signal dom Bool
-> Signal dom Int
-> Signal dom Bool
-> Signal dom a
-> Signal dom t
-> Signal dom t
go !Seq t
ram o :: t
o ret :: Signal dom Bool
ret@(~(re :: Bool
re :- res :: Signal dom Bool
res)) rt :: Signal dom Int
rt@(~(r :: Int
r :- rs :: Signal dom Int
rs)) et :: Signal dom Bool
et@(~(e :: Bool
e :- en :: Signal dom Bool
en)) wt :: Signal dom a
wt@(~(w :: a
w :- wr :: Signal dom a
wr)) dt :: Signal dom t
dt@(~(d :: t
d :- din :: Signal dom t
din)) =
let ram' :: Seq t
ram' = t
d t -> Seq t -> Seq t
forall a b. NFDataX a => a -> b -> b
`defaultSeqX` Seq t -> Bool -> Int -> t -> Seq t
forall a. Seq a -> Bool -> Int -> a -> Seq a
upd Seq t
ram Bool
e (a -> Int
forall a. Enum a => a -> Int
fromEnum a
w) t
d
o' :: t
o' = if Bool
re then Seq t
ram Seq t -> Int -> t
forall a. Seq a -> Int -> a
`Seq.index` Int
r else t
o
in t
o t -> Signal dom t -> Signal dom t
forall a b. a -> b -> b
`seqX` t
o t -> Signal dom t -> Signal dom t
forall (dom :: Domain) a. a -> Signal dom a -> Signal dom a
:- (Signal dom Bool
ret Signal dom Bool -> Signal dom t -> Signal dom t
forall a b. a -> b -> b
`seq` Signal dom Int
rt Signal dom Int -> Signal dom t -> Signal dom t
forall a b. a -> b -> b
`seq` Signal dom Bool
et Signal dom Bool -> Signal dom t -> Signal dom t
forall a b. a -> b -> b
`seq` Signal dom a
wt Signal dom a -> Signal dom t -> Signal dom t
forall a b. a -> b -> b
`seq` Signal dom t
dt Signal dom t -> Signal dom t -> Signal dom t
forall a b. a -> b -> b
`seq` Seq t
-> t
-> Signal dom Bool
-> Signal dom Int
-> Signal dom Bool
-> Signal dom a
-> Signal dom t
-> Signal dom t
go Seq t
ram' t
o' Signal dom Bool
res Signal dom Int
rs Signal dom Bool
en Signal dom a
wr Signal dom t
din)
upd :: Seq a -> Bool -> Int -> a -> Seq a
upd ram :: Seq a
ram we :: Bool
we waddr :: Int
waddr d :: a
d = case Bool -> Maybe Bool
forall a. a -> Maybe a
maybeIsX Bool
we of
Nothing -> case Int -> Maybe Int
forall a. a -> Maybe a
maybeIsX Int
waddr of
Nothing -> (a -> a) -> Seq a -> Seq a
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap (a -> a -> a
forall a b. a -> b -> a
const (Int -> a -> a
forall a b. a -> b -> b
seq Int
waddr a
d)) Seq a
ram
Just wa :: Int
wa -> Int -> a -> Seq a -> Seq a
forall a. Int -> a -> Seq a -> Seq a
Seq.update Int
wa a
d Seq a
ram
Just True -> case Int -> Maybe Int
forall a. a -> Maybe a
maybeIsX Int
waddr of
Nothing -> (a -> a) -> Seq a -> Seq a
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
fmap (a -> a -> a
forall a b. a -> b -> a
const (Int -> a -> a
forall a b. a -> b -> b
seq Int
waddr a
d)) Seq a
ram
Just wa :: Int
wa -> Int -> a -> Seq a -> Seq a
forall a. Int -> a -> Seq a -> Seq a
Seq.update Int
wa a
d Seq a
ram
_ -> Seq a
ram
{-# ANN blockRam# hasBlackBox #-}
{-# NOINLINE blockRam# #-}
readNew
:: ( KnownDomain dom
, NFDataX a
, Eq addr )
=> Clock dom
-> Reset dom
-> Enable dom
-> (Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a)
-> Signal dom addr
-> Signal dom (Maybe (addr, a))
-> Signal dom a
readNew :: Clock dom
-> Reset dom
-> Enable dom
-> (Signal dom addr
-> Signal dom (Maybe (addr, a)) -> Signal dom a)
-> Signal dom addr
-> Signal dom (Maybe (addr, a))
-> Signal dom a
readNew clk :: Clock dom
clk rst :: Reset dom
rst en :: Enable dom
en ram :: Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
ram rdAddr :: Signal dom addr
rdAddr wrM :: Signal dom (Maybe (addr, a))
wrM = Signal dom Bool -> Signal dom a -> Signal dom a -> Signal dom a
forall (f :: Type -> Type) a.
Applicative f =>
f Bool -> f a -> f a -> f a
mux Signal dom Bool
wasSame Signal dom a
wasWritten (Signal dom a -> Signal dom a) -> Signal dom a -> Signal dom a
forall a b. (a -> b) -> a -> b
$ Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
ram Signal dom addr
rdAddr Signal dom (Maybe (addr, a))
wrM
where readNewT :: a -> Maybe (a, b) -> (Bool, b)
readNewT rd :: a
rd (Just (wr :: a
wr, wrdata :: b
wrdata)) = (a
wr a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
rd, b
wrdata)
readNewT _ Nothing = (Bool
False , b
forall a. HasCallStack => a
undefined)
(wasSame :: Signal dom Bool
wasSame,wasWritten :: Signal dom a
wasWritten) =
Signal dom (Bool, a) -> Unbundled dom (Bool, a)
forall a (dom :: Domain).
Bundle a =>
Signal dom a -> Unbundled dom a
unbundle (Clock dom
-> Reset dom
-> Enable dom
-> (Bool, a)
-> Signal dom (Bool, a)
-> Signal dom (Bool, a)
forall (dom :: Domain) a.
(KnownDomain dom, NFDataX a) =>
Clock dom
-> Reset dom -> Enable dom -> a -> Signal dom a -> Signal dom a
register Clock dom
clk Reset dom
rst Enable dom
en (Bool
False, a
forall a. HasCallStack => a
undefined)
(addr -> Maybe (addr, a) -> (Bool, a)
forall a b. Eq a => a -> Maybe (a, b) -> (Bool, b)
readNewT (addr -> Maybe (addr, a) -> (Bool, a))
-> Signal dom addr -> Signal dom (Maybe (addr, a) -> (Bool, a))
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Signal dom addr
rdAddr Signal dom (Maybe (addr, a) -> (Bool, a))
-> Signal dom (Maybe (addr, a)) -> Signal dom (Bool, a)
forall (f :: Type -> Type) a b.
Applicative f =>
f (a -> b) -> f a -> f b
<*> Signal dom (Maybe (addr, a))
wrM))