{-# LANGUAGE CPP #-}
{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskellQuotes #-}
{-# LANGUAGE Trustworthy #-}
{-# OPTIONS_GHC -fplugin GHC.TypeLits.KnownNat.Solver #-}
{-# OPTIONS_HADDOCK show-extensions #-}
{-# OPTIONS_GHC -fno-do-lambda-eta-expansion #-}
{-# OPTIONS_GHC -fno-cpr-anal #-}
module Clash.Explicit.BlockRam
(
blockRam
, blockRamPow2
, blockRamU
, blockRam1
, ResetStrategy(..)
, readNew
, trueDualPortBlockRam
, RamOp(..)
, blockRam#
, blockRamU#
, blockRam1#
, trueDualPortBlockRam#
)
where
import Clash.HaskellPrelude
import Control.Exception (catch, throw)
import Control.Monad (forM_)
import Control.Monad.ST (ST, runST)
import Control.Monad.ST.Unsafe (unsafeInterleaveST, unsafeIOToST, unsafeSTToIO)
import Data.Array.MArray (newListArray)
import Data.List.Infinite (Infinite(..), (...))
import Data.Maybe (isJust)
import Data.Sequence (Seq)
import Data.String.Interpolate (__i)
import GHC.Arr (STArray, unsafeReadSTArray, unsafeWriteSTArray)
import GHC.Generics (Generic)
import GHC.Stack (HasCallStack, withFrozenCallStack)
import GHC.TypeLits (KnownNat, type (^), type (<=))
import Unsafe.Coerce (unsafeCoerce)
import Clash.Annotations.Primitive
(Primitive(InlineYamlPrimitive), HDL(..), hasBlackBox)
import Clash.Class.AutoReg (AutoReg(autoReg))
import Clash.Class.BitPack (bitToBool, msb)
import Clash.Class.Num (SaturationMode(SatBound), satSucc)
import Clash.Explicit.BlockRam.Model (TdpbramModelConfig(..), tdpbramModel)
import Clash.Explicit.Signal (KnownDomain, Enable, register, fromEnable, andEnable)
import Clash.Promoted.Nat (SNat(..))
import Clash.Signal.Bundle (unbundle)
import Clash.Signal.Internal
(Clock(..), Reset, Signal (..), invertReset, (.&&.), mux)
import Clash.Sized.BitVector (BitVector)
import Clash.Sized.Index (Index)
import Clash.Sized.Unsigned (Unsigned)
import Clash.Sized.Vector (Vec, replicate, iterateI)
import Clash.XException
(maybeIsX, NFDataX(deepErrorX), defaultSeqX, fromJustX, undefined,
XException (..), seqX, errorX)
import Clash.XException.MaybeX (MaybeX(..), andX)
import qualified Data.Sequence as Seq
import qualified Data.List as L
import qualified Clash.Sized.Vector as CV
blockRam
:: ( KnownDomain dom
, HasCallStack
, NFDataX a
, Enum addr
, NFDataX 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 = \Clock dom
clk Enable dom
gen Vec n a
content Signal dom addr
rd 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
(Signal dom addr
wr,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, NFDataX a) => 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 = \Clock dom
clk Enable dom
en Vec (2 ^ n) a
cnt Signal dom (Unsigned n)
rd 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,
NFDataX 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
, NFDataX 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 Clock dom
clk Reset dom
rst0 Enable dom
en ResetStrategy r
rstStrategy n :: SNat n
n@SNat n
SNat Index n -> a
initF Signal dom addr
rd0 Signal dom (Maybe (addr, a))
mw0 =
case ResetStrategy r
rstStrategy of
ResetStrategy r
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
ResetStrategy r
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). KnownDomain dom => 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 Index n
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, NFDataX a) => 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, NFDataX a) => 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 Signal dom Int
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# Clock dom
clk Enable dom
en SNat n
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
(\Int
i -> String -> a
forall a. (NFDataX a, HasCallStack) => String -> a
deepErrorX (String -> a) -> String -> a
forall a b. (a -> b) -> a -> b
$ String
"Initial value at index " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Int -> String
forall a. Show a => a -> String
show Int
i String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
" 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 (Int
0 :: Int)))
{-# CLASH_OPAQUE blockRamU# #-}
{-# ANN blockRamU# hasBlackBox #-}
blockRam1
:: forall n dom a r addr
. ( KnownDomain dom
, HasCallStack
, NFDataX a
, Enum addr
, NFDataX 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 Clock dom
clk Reset dom
rst0 Enable dom
en ResetStrategy r
rstStrategy n :: SNat n
n@SNat n
SNat a
a Signal dom addr
rd0 Signal dom (Maybe (addr, a))
mw0 =
case ResetStrategy r
rstStrategy of
ResetStrategy r
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
ResetStrategy r
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). KnownDomain dom => 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 Index n
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, NFDataX a) => 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, NFDataX a) => 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 Signal dom Int
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# Clock dom
clk Enable dom
en SNat n
n 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)
{-# CLASH_OPAQUE blockRam1# #-}
{-# ANN blockRam1# hasBlackBox #-}
blockRam#
:: forall dom a n
. ( 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 SSymbol dom
_ Maybe (Signal dom Femtoseconds)
Nothing) Enable dom
gen Vec n a
content = \Signal dom Int
rd Signal dom Bool
wen Signal dom Int
waS Signal dom a
wd -> (forall s. ST s (Signal dom a)) -> Signal dom a
forall a. (forall s. ST s a) -> a
runST ((forall s. ST s (Signal dom a)) -> Signal dom a)
-> (forall s. ST s (Signal dom a)) -> Signal dom a
forall a b. (a -> b) -> a -> b
$ do
STArray s Int a
ramStart <- (Int, Int) -> [a] -> ST s (STArray s Int a)
forall (a :: Type -> Type -> Type) e (m :: Type -> Type) i.
(MArray a e m, Ix i) =>
(i, i) -> [e] -> m (a i e)
newListArray (Int
0,Int
szIInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) [a]
contentL
STArray s Int a
-> a
-> Signal dom Bool
-> Signal dom Int
-> Signal dom Bool
-> Signal dom Int
-> Signal dom a
-> ST s (Signal dom a)
forall s.
STArray s Int a
-> a
-> Signal dom Bool
-> Signal dom Int
-> Signal dom Bool
-> Signal dom Int
-> Signal dom a
-> ST s (Signal dom a)
go
STArray s Int a
ramStart
((HasCallStack => a) -> a
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack (String -> a
forall a. (NFDataX a, HasCallStack) => String -> a
deepErrorX String
"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)
Signal dom Int
waS
Signal dom a
wd
where
contentL :: [a]
contentL = Vec n a -> [a]
forall a b. a -> b
unsafeCoerce Vec n a
content :: [a]
szI :: Int
szI = [a] -> Int
forall (t :: Type -> Type) a. Foldable t => t a -> Int
L.length [a]
contentL
go :: STArray s Int a -> a -> Signal dom Bool -> Signal dom Int
-> Signal dom Bool -> Signal dom Int -> Signal dom a
-> ST s (Signal dom a)
go :: STArray s Int a
-> a
-> Signal dom Bool
-> Signal dom Int
-> Signal dom Bool
-> Signal dom Int
-> Signal dom a
-> ST s (Signal dom a)
go !STArray s Int a
ram a
o ret :: Signal dom Bool
ret@(~(Bool
re :- Signal dom Bool
res)) rt :: Signal dom Int
rt@(~(Int
r :- Signal dom Int
rs)) et :: Signal dom Bool
et@(~(Bool
e :- Signal dom Bool
en)) wt :: Signal dom Int
wt@(~(Int
w :- Signal dom Int
wr)) dt :: Signal dom a
dt@(~(a
d :- Signal dom a
din)) = do
a
o a -> ST s (Signal dom a) -> ST s (Signal dom a)
forall a b. a -> b -> b
`seqX` (a
o a -> Signal dom a -> Signal dom a
forall (dom :: Domain) a. a -> Signal dom a -> Signal dom a
:-) (Signal dom a -> Signal dom a)
-> ST s (Signal dom a) -> ST s (Signal dom a)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> (Signal dom Bool
ret Signal dom Bool -> ST s (Signal dom a) -> ST s (Signal dom a)
`seq` Signal dom Int
rt Signal dom Int -> ST s (Signal dom a) -> ST s (Signal dom a)
`seq` Signal dom Bool
et Signal dom Bool -> ST s (Signal dom a) -> ST s (Signal dom a)
`seq` Signal dom Int
wt Signal dom Int -> ST s (Signal dom a) -> ST s (Signal dom a)
`seq` Signal dom a
dt Signal dom a -> ST s (Signal dom a) -> ST s (Signal dom a)
`seq`
ST s (Signal dom a) -> ST s (Signal dom a)
forall s a. ST s a -> ST s a
unsafeInterleaveST
(do a
o' <- IO a -> ST s a
forall a s. IO a -> ST s a
unsafeIOToST
(IO a -> (XException -> IO a) -> IO a
forall e a. Exception e => IO a -> (e -> IO a) -> IO a
catch (if Bool
re then ST s a -> IO a
forall s a. ST s a -> IO a
unsafeSTToIO (STArray s Int a
ram STArray s Int a -> Int -> ST s a
forall s. HasCallStack => STArray s Int a -> Int -> ST s a
`safeAt` Int
r) else a -> IO a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure a
o)
(\err :: XException
err@XException {} -> a -> IO a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (XException -> a
forall a e. Exception e => e -> a
throw XException
err)))
a
d a -> ST s () -> ST s ()
forall a b. NFDataX a => a -> b -> b
`defaultSeqX` STArray s Int a -> Bool -> Int -> a -> ST s ()
forall s. STArray s Int a -> Bool -> Int -> a -> ST s ()
upd STArray s Int a
ram Bool
e (Int -> Int
forall a. Enum a => a -> Int
fromEnum Int
w) a
d
STArray s Int a
-> a
-> Signal dom Bool
-> Signal dom Int
-> Signal dom Bool
-> Signal dom Int
-> Signal dom a
-> ST s (Signal dom a)
forall s.
STArray s Int a
-> a
-> Signal dom Bool
-> Signal dom Int
-> Signal dom Bool
-> Signal dom Int
-> Signal dom a
-> ST s (Signal dom a)
go STArray s Int a
ram a
o' Signal dom Bool
res Signal dom Int
rs Signal dom Bool
en Signal dom Int
wr Signal dom a
din))
upd :: STArray s Int a -> Bool -> Int -> a -> ST s ()
upd :: STArray s Int a -> Bool -> Int -> a -> ST s ()
upd STArray s Int a
ram Bool
we Int
waddr a
d = case Bool -> Maybe Bool
forall a. a -> Maybe a
maybeIsX Bool
we of
Maybe Bool
Nothing -> case Int -> Maybe Int
forall a. a -> Maybe a
maybeIsX Int
waddr of
Maybe Int
Nothing ->
[Int] -> (Int -> ST s ()) -> ST s ()
forall (t :: Type -> Type) (m :: Type -> Type) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [Int
0..(Int
szIInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)] (\Int
i -> STArray s Int a -> Int -> a -> ST s ()
forall s i e. STArray s i e -> Int -> e -> ST s ()
unsafeWriteSTArray STArray s Int a
ram Int
i (Int -> a -> a
seq Int
waddr a
d))
Just Int
wa ->
Int -> a -> STArray s Int a -> ST s ()
forall s. HasCallStack => Int -> a -> STArray s Int a -> ST s ()
safeUpdate Int
wa (Bool -> a -> a
seq Bool
we a
d) STArray s Int a
ram
Just Bool
True -> case Int -> Maybe Int
forall a. a -> Maybe a
maybeIsX Int
waddr of
Maybe Int
Nothing ->
[Int] -> (Int -> ST s ()) -> ST s ()
forall (t :: Type -> Type) (m :: Type -> Type) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [Int
0..(Int
szIInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)] (\Int
i -> STArray s Int a -> Int -> a -> ST s ()
forall s i e. STArray s i e -> Int -> e -> ST s ()
unsafeWriteSTArray STArray s Int a
ram Int
i (Int -> a -> a
seq Int
waddr a
d))
Just Int
wa -> Int -> a -> STArray s Int a -> ST s ()
forall s. HasCallStack => Int -> a -> STArray s Int a -> ST s ()
safeUpdate Int
wa a
d STArray s Int a
ram
Maybe Bool
_ -> () -> ST s ()
forall (m :: Type -> Type) a. Monad m => a -> m a
return ()
safeAt :: HasCallStack => STArray s Int a -> Int -> ST s a
safeAt :: STArray s Int a -> Int -> ST s a
safeAt STArray s Int a
s Int
i =
if (Int
0 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
i) Bool -> Bool -> Bool
&& (Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
szI) then
STArray s Int a -> Int -> ST s a
forall s i e. STArray s i e -> Int -> ST s e
unsafeReadSTArray STArray s Int a
s Int
i
else a -> ST s a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (a -> ST s a) -> a -> ST s a
forall a b. (a -> b) -> a -> b
$
(HasCallStack => a) -> a
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack
(String -> a
forall a. (NFDataX a, HasCallStack) => String -> a
deepErrorX (String
"blockRam: read address " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Int -> String
forall a. Show a => a -> String
show Int
i String -> String -> String
forall a. Semigroup a => a -> a -> a
<>
String
" not in range [0.." String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Int -> String
forall a. Show a => a -> String
show Int
szI String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
")"))
{-# INLINE safeAt #-}
safeUpdate :: HasCallStack => Int -> a -> STArray s Int a -> ST s ()
safeUpdate :: Int -> a -> STArray s Int a -> ST s ()
safeUpdate Int
i a
a STArray s Int a
s =
if (Int
0 Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
<= Int
i) Bool -> Bool -> Bool
&& (Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
szI) then
STArray s Int a -> Int -> a -> ST s ()
forall s i e. STArray s i e -> Int -> e -> ST s ()
unsafeWriteSTArray STArray s Int a
s Int
i a
a
else
let d :: a
d = (HasCallStack => a) -> a
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack
(String -> a
forall a. (NFDataX a, HasCallStack) => String -> a
deepErrorX (String
"blockRam: write address " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Int -> String
forall a. Show a => a -> String
show Int
i String -> String -> String
forall a. Semigroup a => a -> a -> a
<>
String
" not in range [0.." String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Int -> String
forall a. Show a => a -> String
show Int
szI String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
")"))
in [Int] -> (Int -> ST s ()) -> ST s ()
forall (t :: Type -> Type) (m :: Type -> Type) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [Int
0..(Int
szIInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1)] (\Int
j -> STArray s Int a -> Int -> a -> ST s ()
forall s i e. STArray s i e -> Int -> e -> ST s ()
unsafeWriteSTArray STArray s Int a
s Int
j a
d)
{-# INLINE safeUpdate #-}
blockRam# Clock dom
_ Enable dom
_ Vec n a
_ = String
-> Signal dom Int
-> Signal dom Bool
-> Signal dom Int
-> Signal dom a
-> Signal dom a
forall a. HasCallStack => String -> a
error String
"blockRam#: dynamic clocks not supported"
{-# ANN blockRam# hasBlackBox #-}
{-# CLASH_OPAQUE 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 Clock dom
clk Reset dom
rst Enable dom
en Signal dom addr -> Signal dom (Maybe (addr, a)) -> Signal dom a
ram Signal dom addr
rdAddr 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 a
rd (Just (a
wr, b
wrdata)) = (a
wr a -> a -> Bool
forall a. Eq a => a -> a -> Bool
== a
rd, b
wrdata)
readNewT a
_ Maybe (a, b)
Nothing = (Bool
False , b
forall a. HasCallStack => a
undefined)
(Signal dom Bool
wasSame,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))
data RamOp n a
= RamRead (Index n)
| RamWrite (Index n) a
| RamNoOp
deriving ((forall x. RamOp n a -> Rep (RamOp n a) x)
-> (forall x. Rep (RamOp n a) x -> RamOp n a)
-> Generic (RamOp n a)
forall x. Rep (RamOp n a) x -> RamOp n a
forall x. RamOp n a -> Rep (RamOp n a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (n :: Nat) a x. Rep (RamOp n a) x -> RamOp n a
forall (n :: Nat) a x. RamOp n a -> Rep (RamOp n a) x
$cto :: forall (n :: Nat) a x. Rep (RamOp n a) x -> RamOp n a
$cfrom :: forall (n :: Nat) a x. RamOp n a -> Rep (RamOp n a) x
Generic, HasCallStack => String -> RamOp n a
RamOp n a -> Bool
RamOp n a -> ()
RamOp n a -> RamOp n a
(HasCallStack => String -> RamOp n a)
-> (RamOp n a -> Bool)
-> (RamOp n a -> RamOp n a)
-> (RamOp n a -> ())
-> NFDataX (RamOp n a)
forall a.
(HasCallStack => String -> a)
-> (a -> Bool) -> (a -> a) -> (a -> ()) -> NFDataX a
forall (n :: Nat) a.
(NFDataX a, HasCallStack) =>
String -> RamOp n a
forall (n :: Nat) a. NFDataX a => RamOp n a -> Bool
forall (n :: Nat) a. NFDataX a => RamOp n a -> ()
forall (n :: Nat) a. NFDataX a => RamOp n a -> RamOp n a
rnfX :: RamOp n a -> ()
$crnfX :: forall (n :: Nat) a. NFDataX a => RamOp n a -> ()
ensureSpine :: RamOp n a -> RamOp n a
$censureSpine :: forall (n :: Nat) a. NFDataX a => RamOp n a -> RamOp n a
hasUndefined :: RamOp n a -> Bool
$chasUndefined :: forall (n :: Nat) a. NFDataX a => RamOp n a -> Bool
deepErrorX :: String -> RamOp n a
$cdeepErrorX :: forall (n :: Nat) a.
(NFDataX a, HasCallStack) =>
String -> RamOp n a
NFDataX, Int -> RamOp n a -> String -> String
[RamOp n a] -> String -> String
RamOp n a -> String
(Int -> RamOp n a -> String -> String)
-> (RamOp n a -> String)
-> ([RamOp n a] -> String -> String)
-> Show (RamOp n a)
forall a.
(Int -> a -> String -> String)
-> (a -> String) -> ([a] -> String -> String) -> Show a
forall (n :: Nat) a. Show a => Int -> RamOp n a -> String -> String
forall (n :: Nat) a. Show a => [RamOp n a] -> String -> String
forall (n :: Nat) a. Show a => RamOp n a -> String
showList :: [RamOp n a] -> String -> String
$cshowList :: forall (n :: Nat) a. Show a => [RamOp n a] -> String -> String
show :: RamOp n a -> String
$cshow :: forall (n :: Nat) a. Show a => RamOp n a -> String
showsPrec :: Int -> RamOp n a -> String -> String
$cshowsPrec :: forall (n :: Nat) a. Show a => Int -> RamOp n a -> String -> String
Show)
instance (AutoReg a, KnownNat n) => AutoReg (RamOp n a) where
autoReg :: Clock dom
-> Reset dom
-> Enable dom
-> RamOp n a
-> Signal dom (RamOp n a)
-> Signal dom (RamOp n a)
autoReg Clock dom
clk Reset dom
rst Enable dom
en RamOp n a
initVal Signal dom (RamOp n a)
input =
BitVector 2 -> Index n -> a -> RamOp n a
forall a a (n :: Nat).
(Eq a, Num a, NFDataX a) =>
a -> Index n -> a -> RamOp n a
createRamOp (BitVector 2 -> Index n -> a -> RamOp n a)
-> Signal dom (BitVector 2)
-> Signal dom (Index n -> a -> RamOp n a)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Signal dom (BitVector 2)
tagR Signal dom (Index n -> a -> RamOp n a)
-> Signal dom (Index n) -> Signal dom (a -> RamOp n a)
forall (f :: Type -> Type) a b.
Applicative f =>
f (a -> b) -> f a -> f b
<*> Signal dom (Index n)
valAddr Signal dom (a -> RamOp n a)
-> Signal dom a -> Signal dom (RamOp n a)
forall (f :: Type -> Type) a b.
Applicative f =>
f (a -> b) -> f a -> f b
<*> Signal dom a
valValue
where
tag :: Signal dom (BitVector 2)
tag = RamOp n a -> BitVector 2
forall (n :: Nat) a. RamOp n a -> BitVector 2
toTag (RamOp n a -> BitVector 2)
-> Signal dom (RamOp n a) -> Signal dom (BitVector 2)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Signal dom (RamOp n a)
input
toTag :: RamOp n a -> BitVector 2
toTag RamOp n a
op = case RamOp n a
op of
RamOp n a
RamNoOp -> BitVector 2
0b00 :: BitVector 2
RamRead{} -> BitVector 2
0b01
RamWrite{} -> BitVector 2
0b10
tagInit :: BitVector 2
tagInit = RamOp n a -> BitVector 2
forall (n :: Nat) a. RamOp n a -> BitVector 2
toTag RamOp n a
initVal
tagR :: Signal dom (BitVector 2)
tagR = Clock dom
-> Reset dom
-> Enable dom
-> BitVector 2
-> Signal dom (BitVector 2)
-> Signal dom (BitVector 2)
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 BitVector 2
tagInit Signal dom (BitVector 2)
tag
toAddr :: RamOp n a -> Index n
toAddr RamOp n a
op = case RamOp n a
op of
RamOp n a
RamNoOp -> String -> Index n
forall a. (NFDataX a, HasCallStack) => String -> a
deepErrorX String
"autoReg'.ramOpAddr"
RamRead Index n
addr -> Index n
addr
RamWrite Index n
addr a
_ -> Index n
addr
toValue :: RamOp n p -> p
toValue RamOp n p
op = case RamOp n p
op of
RamWrite Index n
_ p
a -> p
a
RamOp n p
_ -> String -> p
forall a. (NFDataX a, HasCallStack) => String -> a
deepErrorX String
"autoReg'.ramOpValue"
opAddr :: Signal dom (Index n)
opAddr = RamOp n a -> Index n
forall (n :: Nat) a. RamOp n a -> Index n
toAddr (RamOp n a -> Index n)
-> Signal dom (RamOp n a) -> Signal dom (Index n)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Signal dom (RamOp n a)
input
opValue :: Signal dom a
opValue = RamOp n a -> a
forall p (n :: Nat). NFDataX p => RamOp n p -> p
toValue (RamOp n a -> a) -> Signal dom (RamOp n a) -> Signal dom a
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Signal dom (RamOp n a)
input
addrInit :: Index n
addrInit = RamOp n a -> Index n
forall (n :: Nat) a. RamOp n a -> Index n
toAddr RamOp n a
initVal
valInit :: a
valInit = RamOp n a -> a
forall p (n :: Nat). NFDataX p => RamOp n p -> p
toValue RamOp n a
initVal
valAddr :: Signal dom (Index n)
valAddr = Clock dom
-> Reset dom
-> Enable dom
-> Index n
-> Signal dom (Index n)
-> Signal dom (Index n)
forall a (dom :: Domain).
(AutoReg a, HasCallStack, KnownDomain dom) =>
Clock dom
-> Reset dom -> Enable dom -> a -> Signal dom a -> Signal dom a
autoReg Clock dom
clk Reset dom
rst (Enable dom -> Signal dom Bool -> Enable dom
forall (dom :: Domain). Enable dom -> Signal dom Bool -> Enable dom
andEnable Enable dom
en ((BitVector 2 -> BitVector 2 -> Bool
forall a. Eq a => a -> a -> Bool
/=BitVector 2
0) (BitVector 2 -> Bool)
-> Signal dom (BitVector 2) -> Signal dom Bool
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Signal dom (BitVector 2)
tag)) Index n
addrInit Signal dom (Index n)
opAddr
valValue :: Signal dom a
valValue = Clock dom
-> Reset dom -> Enable dom -> a -> Signal dom a -> Signal dom a
forall a (dom :: Domain).
(AutoReg a, HasCallStack, KnownDomain dom) =>
Clock dom
-> Reset dom -> Enable dom -> a -> Signal dom a -> Signal dom a
autoReg Clock dom
clk Reset dom
rst (Enable dom -> Signal dom Bool -> Enable dom
forall (dom :: Domain). Enable dom -> Signal dom Bool -> Enable dom
andEnable Enable dom
en (Bit -> Bool
bitToBool (Bit -> Bool) -> (BitVector 2 -> Bit) -> BitVector 2 -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. BitVector 2 -> Bit
forall a. BitPack a => a -> Bit
msb (BitVector 2 -> Bool)
-> Signal dom (BitVector 2) -> Signal dom Bool
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Signal dom (BitVector 2)
tag)) a
valInit Signal dom a
opValue
createRamOp :: a -> Index n -> a -> RamOp n a
createRamOp a
t Index n
addr a
val = case a
t of
a
0b00 -> RamOp n a
forall (n :: Nat) a. RamOp n a
RamNoOp
a
0b01 -> Index n -> RamOp n a
forall (n :: Nat) a. Index n -> RamOp n a
RamRead Index n
addr
a
0b10 -> Index n -> a -> RamOp n a
forall (n :: Nat) a. Index n -> a -> RamOp n a
RamWrite Index n
addr a
val
a
_ -> String -> RamOp n a
forall a. (NFDataX a, HasCallStack) => String -> a
deepErrorX String
"autoReg'.createRamOp: impossible"
{-# INLINE autoReg #-}
ramOpAddr :: RamOp n a -> Index n
ramOpAddr :: RamOp n a -> Index n
ramOpAddr (RamRead Index n
addr) = Index n
addr
ramOpAddr (RamWrite Index n
addr a
_) = Index n
addr
ramOpAddr RamOp n a
RamNoOp = String -> Index n
forall a. HasCallStack => String -> a
errorX String
"Address for No operation undefined"
isRamWrite :: RamOp n a -> Bool
isRamWrite :: RamOp n a -> Bool
isRamWrite (RamWrite {}) = Bool
True
isRamWrite RamOp n a
_ = Bool
False
ramOpWriteVal :: RamOp n a -> Maybe a
ramOpWriteVal :: RamOp n a -> Maybe a
ramOpWriteVal (RamWrite Index n
_ a
val) = a -> Maybe a
forall a. a -> Maybe a
Just a
val
ramOpWriteVal RamOp n a
_ = Maybe a
forall a. Maybe a
Nothing
isOp :: RamOp n a -> Bool
isOp :: RamOp n a -> Bool
isOp RamOp n a
RamNoOp = Bool
False
isOp RamOp n a
_ = Bool
True
trueDualPortBlockRam ::
forall nAddrs domA domB a .
( HasCallStack
, KnownNat nAddrs
, KnownDomain domA
, KnownDomain domB
, NFDataX a
)
=> Clock domA
-> Clock domB
-> Signal domA (RamOp nAddrs a)
-> Signal domB (RamOp nAddrs a)
-> (Signal domA a, Signal domB a)
{-# INLINE trueDualPortBlockRam #-}
trueDualPortBlockRam :: Clock domA
-> Clock domB
-> Signal domA (RamOp nAddrs a)
-> Signal domB (RamOp nAddrs a)
-> (Signal domA a, Signal domB a)
trueDualPortBlockRam = \Clock domA
clkA Clock domB
clkB Signal domA (RamOp nAddrs a)
opA Signal domB (RamOp nAddrs a)
opB ->
Clock domA
-> Signal domA Bool
-> Signal domA Bool
-> Signal domA (Index nAddrs)
-> Signal domA a
-> Clock domB
-> Signal domB Bool
-> Signal domB Bool
-> Signal domB (Index nAddrs)
-> Signal domB a
-> (Signal domA a, Signal domB a)
forall (nAddrs :: Nat) (domA :: Domain) (domB :: Domain) a.
(HasCallStack, KnownNat nAddrs, KnownDomain domA, KnownDomain domB,
NFDataX a) =>
Clock domA
-> Signal domA Bool
-> Signal domA Bool
-> Signal domA (Index nAddrs)
-> Signal domA a
-> Clock domB
-> Signal domB Bool
-> Signal domB Bool
-> Signal domB (Index nAddrs)
-> Signal domB a
-> (Signal domA a, Signal domB a)
trueDualPortBlockRamWrapper
Clock domA
clkA (RamOp nAddrs a -> Bool
forall (n :: Nat) a. RamOp n a -> Bool
isOp (RamOp nAddrs a -> Bool)
-> Signal domA (RamOp nAddrs a) -> Signal domA Bool
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Signal domA (RamOp nAddrs a)
opA) (RamOp nAddrs a -> Bool
forall (n :: Nat) a. RamOp n a -> Bool
isRamWrite (RamOp nAddrs a -> Bool)
-> Signal domA (RamOp nAddrs a) -> Signal domA Bool
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Signal domA (RamOp nAddrs a)
opA) (RamOp nAddrs a -> Index nAddrs
forall (n :: Nat) a. RamOp n a -> Index n
ramOpAddr (RamOp nAddrs a -> Index nAddrs)
-> Signal domA (RamOp nAddrs a) -> Signal domA (Index nAddrs)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Signal domA (RamOp nAddrs a)
opA) (Maybe a -> a
forall a. (HasCallStack, NFDataX a) => Maybe a -> a
fromJustX (Maybe a -> a)
-> (RamOp nAddrs a -> Maybe a) -> RamOp nAddrs a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RamOp nAddrs a -> Maybe a
forall (n :: Nat) a. RamOp n a -> Maybe a
ramOpWriteVal (RamOp nAddrs a -> a)
-> Signal domA (RamOp nAddrs a) -> Signal domA a
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Signal domA (RamOp nAddrs a)
opA)
Clock domB
clkB (RamOp nAddrs a -> Bool
forall (n :: Nat) a. RamOp n a -> Bool
isOp (RamOp nAddrs a -> Bool)
-> Signal domB (RamOp nAddrs a) -> Signal domB Bool
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Signal domB (RamOp nAddrs a)
opB) (RamOp nAddrs a -> Bool
forall (n :: Nat) a. RamOp n a -> Bool
isRamWrite (RamOp nAddrs a -> Bool)
-> Signal domB (RamOp nAddrs a) -> Signal domB Bool
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Signal domB (RamOp nAddrs a)
opB) (RamOp nAddrs a -> Index nAddrs
forall (n :: Nat) a. RamOp n a -> Index n
ramOpAddr (RamOp nAddrs a -> Index nAddrs)
-> Signal domB (RamOp nAddrs a) -> Signal domB (Index nAddrs)
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Signal domB (RamOp nAddrs a)
opB) (Maybe a -> a
forall a. (HasCallStack, NFDataX a) => Maybe a -> a
fromJustX (Maybe a -> a)
-> (RamOp nAddrs a -> Maybe a) -> RamOp nAddrs a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RamOp nAddrs a -> Maybe a
forall (n :: Nat) a. RamOp n a -> Maybe a
ramOpWriteVal (RamOp nAddrs a -> a)
-> Signal domB (RamOp nAddrs a) -> Signal domB a
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Signal domB (RamOp nAddrs a)
opB)
trueDualPortBlockRamWrapper :: Clock domA
-> Signal domA Bool
-> Signal domA Bool
-> Signal domA (Index nAddrs)
-> Signal domA a
-> Clock domB
-> Signal domB Bool
-> Signal domB Bool
-> Signal domB (Index nAddrs)
-> Signal domB a
-> (Signal domA a, Signal domB a)
trueDualPortBlockRamWrapper Clock domA
clkA Signal domA Bool
enA Signal domA Bool
weA Signal domA (Index nAddrs)
addrA Signal domA a
datA Clock domB
clkB Signal domB Bool
enB Signal domB Bool
weB Signal domB (Index nAddrs)
addrB Signal domB a
datB =
Clock domA
-> Signal domA Bool
-> Signal domA Bool
-> Signal domA (Index nAddrs)
-> Signal domA a
-> Clock domB
-> Signal domB Bool
-> Signal domB Bool
-> Signal domB (Index nAddrs)
-> Signal domB a
-> (Signal domA a, Signal domB a)
forall (nAddrs :: Nat) (domA :: Domain) (domB :: Domain) a.
(HasCallStack, KnownNat nAddrs, KnownDomain domA, KnownDomain domB,
NFDataX a) =>
Clock domA
-> Signal domA Bool
-> Signal domA Bool
-> Signal domA (Index nAddrs)
-> Signal domA a
-> Clock domB
-> Signal domB Bool
-> Signal domB Bool
-> Signal domB (Index nAddrs)
-> Signal domB a
-> (Signal domA a, Signal domB a)
trueDualPortBlockRam# Clock domA
clkA Signal domA Bool
enA Signal domA Bool
weA Signal domA (Index nAddrs)
addrA Signal domA a
datA Clock domB
clkB Signal domB Bool
enB Signal domB Bool
weB Signal domB (Index nAddrs)
addrB Signal domB a
datB
{-# CLASH_OPAQUE trueDualPortBlockRamWrapper #-}
{-# CLASH_OPAQUE trueDualPortBlockRam# #-}
{-# ANN trueDualPortBlockRam# hasBlackBox #-}
{-# ANN trueDualPortBlockRam# (
let
bbName = show 'trueDualPortBlockRam#
_hasCallStack
:< knownNatAddrs
:< _knownDomainA
:< _knownDomainB
:< _nfdataX
:< clockA
:< enaA
:< wenaA
:< addrA
:< datA
:< clockB
:< enaB
:< wenaB
:< addrB
:< datB
:< _ = ((0 :: Int)...)
symBlockName
:< symDoutA
:< symDoutB
:< _ = ((0 :: Int)...)
in InlineYamlPrimitive [VHDL] [__i|
BlackBox:
name: "#{bbName}"
kind: Declaration
template: |-
-- trueDualPortBlockRam begin
~GENSYM[~RESULT_trueDualPortBlockRam][#{symBlockName}] : block
-- Shared memory
type mem_type is array ( ~LIT[#{knownNatAddrs}]-1 downto 0 ) of ~TYP[#{datA}];
shared variable mem : mem_type;
signal ~GENSYM[a_dout][#{symDoutA}] : ~TYP[#{datA}];
signal ~GENSYM[b_dout][#{symDoutB}] : ~TYP[#{datB}];
begin
-- Port A
process(~ARG[#{clockA}])
begin
if(rising_edge(~ARG[#{clockA}])) then
if(~ARG[#{enaA}]) then
if(~ARG[#{wenaA}]) then
mem(~IF~SIZE[~TYP[#{addrA}]]~THENto_integer(~ARG[#{addrA}])~ELSE0~FI) := ~ARG[#{datA}];
end if;
~SYM[#{symDoutA}] <= mem(~IF~SIZE[~TYP[#{addrA}]]~THENto_integer(~ARG[#{addrA}])~ELSE0~FI);
end if;
end if;
end process;
-- Port B
process(~ARG[#{clockB}])
begin
if(rising_edge(~ARG[#{clockB}])) then
if(~ARG[#{enaB}]) then
if(~ARG[#{wenaB}]) then
mem(~IF~SIZE[~TYP[#{addrB}]]~THENto_integer(~ARG[#{addrB}])~ELSE0~FI) := ~ARG[#{datB}];
end if;
~SYM[#{symDoutB}] <= mem(~IF~SIZE[~TYP[#{addrB}]]~THENto_integer(~ARG[#{addrB}])~ELSE0~FI);
end if;
end if;
end process;
~RESULT <= (~SYM[#{symDoutA}], ~SYM[#{symDoutB}]);
end block;
-- end trueDualPortBlockRam
|]) #-}
{-# ANN trueDualPortBlockRam# (
let
bbName = show 'trueDualPortBlockRam#
_hasCallStack
:< knownNatAddrs
:< knownDomainA
:< knownDomainB
:< _nfdataX
:< clockA
:< enaA
:< wenaA
:< addrA
:< datA
:< clockB
:< enaB
:< wenaB
:< addrB
:< datB
:< _ = ((0 :: Int)...)
symMem
:< symDoutA
:< symDoutB
:< _ = ((0 :: Int)...)
in InlineYamlPrimitive [SystemVerilog] [__i|
BlackBox:
name: "#{bbName}"
kind: Declaration
template: |-
// trueDualPortBlockRam begin
// Shared memory
logic [~SIZE[~TYP[#{datA}]]-1:0] ~GENSYM[mem][#{symMem}] [~LIT[#{knownNatAddrs}]-1:0];
~SIGD[~GENSYM[a_dout][#{symDoutA}]][#{datA}];
~SIGD[~GENSYM[b_dout][#{symDoutB}]][#{datB}];
// Port A
always @(~IF~ACTIVEEDGE[Rising][#{knownDomainA}]~THENposedge~ELSEnegedge~FI ~ARG[#{clockA}]) begin
if(~ARG[#{enaA}]) begin
~SYM[#{symDoutA}] <= ~SYM[#{symMem}][~IF~SIZE[~TYP[#{addrA}]]~THEN~ARG[#{addrA}]~ELSE0~FI];
if(~ARG[#{wenaA}]) begin
~SYM[#{symDoutA}] <= ~ARG[#{datA}];
~SYM[#{symMem}][~IF~SIZE[~TYP[#{addrA}]]~THEN~ARG[#{addrA}]~ELSE0~FI] <= ~ARG[#{datA}];
end
end
end
// Port B
always @(~IF~ACTIVEEDGE[Rising][#{knownDomainB}]~THENposedge~ELSEnegedge~FI ~ARG[#{clockB}]) begin
if(~ARG[#{enaB}]) begin
~SYM[#{symDoutB}] <= ~SYM[#{symMem}][~IF~SIZE[~TYP[#{addrB}]]~THEN~ARG[#{addrB}]~ELSE0~FI];
if(~ARG[#{wenaB}]) begin
~SYM[#{symDoutB}] <= ~ARG[#{datB}];
~SYM[#{symMem}][~IF~SIZE[~TYP[#{addrB}]]~THEN~ARG[#{addrB}]~ELSE0~FI] <= ~ARG[#{datB}];
end
end
end
assign ~RESULT = {~SYM[#{symDoutA}], ~SYM[#{symDoutB}]};
// end trueDualPortBlockRam
|]) #-}
{-# ANN trueDualPortBlockRam# (
let
bbName = show 'trueDualPortBlockRam#
_hasCallStack
:< knownNatAddrs
:< knownDomainA
:< knownDomainB
:< _nfdataX
:< clockA
:< enaA
:< wenaA
:< addrA
:< datA
:< clockB
:< enaB
:< wenaB
:< addrB
:< datB
:< _ = ((0 :: Int)...)
symMem
:< symDoutA
:< symDoutB
:< _ = ((0 :: Int)...)
in InlineYamlPrimitive [Verilog] [__i|
BlackBox:
name: "#{bbName}"
kind: Declaration
template: |-
// trueDualPortBlockRam begin
// Shared memory
reg [~SIZE[~TYP[#{datA}]]-1:0] ~GENSYM[mem][#{symMem}] [~LIT[#{knownNatAddrs}]-1:0];
reg ~SIGD[~GENSYM[a_dout][#{symDoutA}]][#{datA}];
reg ~SIGD[~GENSYM[b_dout][#{symDoutB}]][#{datB}];
// Port A
always @(~IF~ACTIVEEDGE[Rising][#{knownDomainA}]~THENposedge~ELSEnegedge~FI ~ARG[#{clockA}]) begin
if(~ARG[#{enaA}]) begin
~SYM[#{symDoutA}] <= ~SYM[#{symMem}][~IF~SIZE[~TYP[#{addrA}]]~THEN~ARG[#{addrA}]~ELSE0~FI];
if(~ARG[#{wenaA}]) begin
~SYM[#{symDoutA}] <= ~ARG[#{datA}];
~SYM[#{symMem}][~IF~SIZE[~TYP[#{addrA}]]~THEN~ARG[#{addrA}]~ELSE0~FI] <= ~ARG[#{datA}];
end
end
end
// Port B
always @(~IF~ACTIVEEDGE[Rising][#{knownDomainB}]~THENposedge~ELSEnegedge~FI ~ARG[#{clockB}]) begin
if(~ARG[#{enaB}]) begin
~SYM[#{symDoutB}] <= ~SYM[#{symMem}][~IF~SIZE[~TYP[#{addrB}]]~THEN~ARG[#{addrB}]~ELSE0~FI];
if(~ARG[#{wenaB}]) begin
~SYM[#{symDoutB}] <= ~ARG[#{datB}];
~SYM[#{symMem}][~IF~SIZE[~TYP[#{addrB}]]~THEN~ARG[#{addrB}]~ELSE0~FI] <= ~ARG[#{datB}];
end
end
end
assign ~RESULT = {~SYM[#{symDoutA}], ~SYM[#{symDoutB}]};
// end trueDualPortBlockRam
|]) #-}
trueDualPortBlockRam#, trueDualPortBlockRamWrapper ::
forall nAddrs domA domB a .
( HasCallStack
, KnownNat nAddrs
, KnownDomain domA
, KnownDomain domB
, NFDataX a
) =>
Clock domA ->
Signal domA Bool ->
Signal domA Bool ->
Signal domA (Index nAddrs) ->
Signal domA a ->
Clock domB ->
Signal domB Bool ->
Signal domB Bool ->
Signal domB (Index nAddrs) ->
Signal domB a ->
(Signal domA a, Signal domB a)
trueDualPortBlockRam# :: Clock domA
-> Signal domA Bool
-> Signal domA Bool
-> Signal domA (Index nAddrs)
-> Signal domA a
-> Clock domB
-> Signal domB Bool
-> Signal domB Bool
-> Signal domB (Index nAddrs)
-> Signal domB a
-> (Signal domA a, Signal domB a)
trueDualPortBlockRam# Clock domA
clkA Signal domA Bool
enA Signal domA Bool
weA Signal domA (Index nAddrs)
addrA Signal domA a
datA Clock domB
clkB Signal domB Bool
enB Signal domB Bool
weB Signal domB (Index nAddrs)
addrB Signal domB a
datB =
TdpbramModelConfig Bool a
-> Clock domA
-> Signal domA Bool
-> Signal domA (Index nAddrs)
-> Signal domA Bool
-> Signal domA a
-> Clock domB
-> Signal domB Bool
-> Signal domB (Index nAddrs)
-> Signal domB Bool
-> Signal domB a
-> (Signal domA a, Signal domB a)
forall (nAddrs :: Nat) (domA :: Domain) (domB :: Domain) a
writeEnable.
(HasCallStack, KnownNat nAddrs, KnownDomain domA, KnownDomain domB,
NFDataX a) =>
TdpbramModelConfig writeEnable a
-> Clock domA
-> Signal domA Bool
-> Signal domA (Index nAddrs)
-> Signal domA writeEnable
-> Signal domA a
-> Clock domB
-> Signal domB Bool
-> Signal domB (Index nAddrs)
-> Signal domB writeEnable
-> Signal domB a
-> (Signal domA a, Signal domB a)
tdpbramModel
TdpbramModelConfig :: forall writeEnable a.
(MaybeX writeEnable -> MaybeX Bool)
-> (MaybeX Bool -> MaybeX writeEnable -> MaybeX writeEnable)
-> (Int -> MaybeX writeEnable -> a -> Seq a -> Seq a)
-> TdpbramModelConfig writeEnable a
TdpbramModelConfig
{ tdpIsActiveWriteEnable :: MaybeX Bool -> MaybeX Bool
tdpIsActiveWriteEnable = MaybeX Bool -> MaybeX Bool
forall a. a -> a
id
, tdpMergeWriteEnable :: MaybeX Bool -> MaybeX Bool -> MaybeX Bool
tdpMergeWriteEnable = MaybeX Bool -> MaybeX Bool -> MaybeX Bool
andX
, tdpUpdateRam :: Int -> MaybeX Bool -> a -> Seq a -> Seq a
tdpUpdateRam = Int -> MaybeX Bool -> a -> Seq a -> Seq a
updateRam }
Clock domA
clkA Signal domA Bool
enA Signal domA (Index nAddrs)
addrA Signal domA Bool
weA Signal domA a
datA
Clock domB
clkB Signal domB Bool
enB Signal domB (Index nAddrs)
addrB Signal domB Bool
weB Signal domB a
datB
where
updateRam :: Int -> MaybeX Bool -> a -> Seq a -> Seq a
updateRam :: Int -> MaybeX Bool -> a -> Seq a -> Seq a
updateRam Int
addr MaybeX Bool
writeEnable a
dat Seq a
mem =
case MaybeX Bool
writeEnable of
IsDefined Bool
False -> Seq a
mem
IsDefined Bool
True -> Int -> a -> Seq a -> Seq a
forall a. Int -> a -> Seq a -> Seq a
Seq.update Int
addr a
dat Seq a
mem
IsX String
msg -> Int -> a -> Seq a -> Seq a
forall a. Int -> a -> Seq a -> Seq a
Seq.update Int
addr a
dat (Seq a -> Seq a) -> Seq a -> Seq a
forall a b. (a -> b) -> a -> b
$ String -> Seq a
forall a. (NFDataX a, HasCallStack) => String -> a
deepErrorX (String -> Seq a) -> String -> Seq a
forall a b. (a -> b) -> a -> b
$
String
"Write enable unknown; position" String -> String -> String
forall a. Semigroup a => a -> a -> a
<> Int -> String
forall a. Show a => a -> String
show Int
addr String -> String -> String
forall a. Semigroup a => a -> a -> a
<>
String
"\nWrite enable error message: " String -> String -> String
forall a. Semigroup a => a -> a -> a
<> String
msg