clash-protocols-0.1: src/Protocols/Experimental/Axi4/ReadAddress.hs
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -Wno-missing-fields #-}
{-# OPTIONS_GHC -fconstraint-solver-iterations=10 #-}
{- |
Defines ReadAddress channel of full AXI4 protocol with port names corresponding
to the AXI4 specification.
-}
module Protocols.Experimental.Axi4.ReadAddress (
M2S_ReadAddress (..),
S2M_ReadAddress (..),
Axi4ReadAddress,
-- * configuration
Axi4ReadAddressConfig (..),
KnownAxi4ReadAddressConfig,
ARKeepBurst,
ARKeepSize,
ARIdWidth,
ARAddrWidth,
ARKeepRegion,
ARKeepBurstLength,
ARKeepLock,
ARKeepCache,
ARKeepPermissions,
ARKeepQos,
-- * read address info
Axi4ReadAddressInfo (..),
axi4ReadAddrMsgToReadAddrInfo,
axi4ReadAddrMsgFromReadAddrInfo,
-- * helpers
forceResetSanity,
) where
-- base
import Control.DeepSeq (NFData)
import Data.Coerce
import Data.Kind (Type)
import GHC.Generics (Generic)
-- clash-prelude
import Clash.Prelude qualified as C
-- me
import Protocols.Experimental.Axi4.Common
import Protocols.Experimental.Simulate
import Protocols.Idle
import Protocols.Internal
-- | Configuration options for 'Axi4ReadAddress'.
data Axi4ReadAddressConfig = Axi4ReadAddressConfig
{ _arKeepBurst :: Bool
, _arKeepSize :: Bool
, _arIdWidth :: C.Nat
, _arAddrWidth :: C.Nat
, _arKeepRegion :: Bool
, _arKeepBurstLength :: Bool
, _arKeepLock :: Bool
, _arKeepCache :: Bool
, _arKeepPermissions :: Bool
, _arKeepQos :: Bool
}
{- | Grab '_arKeepBurst' from t'Axi4ReadAddressConfig' at the type level.
This boolean value determines whether to keep the '_arburst' field
in t'M2S_ReadAddress'.
-}
type family ARKeepBurst (conf :: Axi4ReadAddressConfig) where
ARKeepBurst ('Axi4ReadAddressConfig a _ _ _ _ _ _ _ _ _) = a
{- | Grab '_arKeepSize' from t'Axi4ReadAddressConfig' at the type level.
This boolean value determines whether to keep the '_arsize' field
in t'M2S_ReadAddress'.
-}
type family ARKeepSize (conf :: Axi4ReadAddressConfig) where
ARKeepSize ('Axi4ReadAddressConfig _ a _ _ _ _ _ _ _ _) = a
{- | Grab '_arIdWidth' from t'Axi4ReadAddressConfig' at the type level.
This nat value determines the size of the '_arid' field
in t'M2S_ReadAddress'.
-}
type family ARIdWidth (conf :: Axi4ReadAddressConfig) where
ARIdWidth ('Axi4ReadAddressConfig _ _ a _ _ _ _ _ _ _) = a
{- | Grab '_arAddrWidth' from t'Axi4ReadAddressConfig' at the type level.
This nat value determines the size of the '_araddr' field
in t'M2S_ReadAddress'.
-}
type family ARAddrWidth (conf :: Axi4ReadAddressConfig) where
ARAddrWidth ('Axi4ReadAddressConfig _ _ _ a _ _ _ _ _ _) = a
{- | Grab '_arKeepRegion' from t'Axi4ReadAddressConfig' at the type level.
This boolean value determines whether to keep the '_arregion' field
in t'M2S_ReadAddress'.
-}
type family ARKeepRegion (conf :: Axi4ReadAddressConfig) where
ARKeepRegion ('Axi4ReadAddressConfig _ _ _ _ a _ _ _ _ _) = a
{- | Grab '_arKeepBurstLength' from t'Axi4ReadAddressConfig' at the type level.
This boolean value determines whether to keep the '_arlen' field
in t'M2S_ReadAddress'.
-}
type family ARKeepBurstLength (conf :: Axi4ReadAddressConfig) where
ARKeepBurstLength ('Axi4ReadAddressConfig _ _ _ _ _ a _ _ _ _) = a
{- | Grab '_arKeepLock' from t'Axi4ReadAddressConfig' at the type level.
This boolean value determines whether to keep the '_arlock' field
in t'M2S_ReadAddress'.
-}
type family ARKeepLock (conf :: Axi4ReadAddressConfig) where
ARKeepLock ('Axi4ReadAddressConfig _ _ _ _ _ _ a _ _ _) = a
{- | Grab '_arKeepCache' from t'Axi4ReadAddressConfig' at the type level.
This boolean value determines whether to keep the '_arcache' field
in t'M2S_ReadAddress'.
-}
type family ARKeepCache (conf :: Axi4ReadAddressConfig) where
ARKeepCache ('Axi4ReadAddressConfig _ _ _ _ _ _ _ a _ _) = a
{- | Grab '_arKeepPermissions' from t'Axi4ReadAddressConfig' at the type level.
This boolean value determines whether to keep the '_arprot' field
in t'M2S_ReadAddress'.
-}
type family ARKeepPermissions (conf :: Axi4ReadAddressConfig) where
ARKeepPermissions ('Axi4ReadAddressConfig _ _ _ _ _ _ _ _ a _) = a
{- | Grab '_arKeepQos' from t'Axi4ReadAddressConfig' at the type level.
This boolean value determines whether to keep the '_arqos' field
in t'M2S_ReadAddress'.
-}
type family ARKeepQos (conf :: Axi4ReadAddressConfig) where
ARKeepQos ('Axi4ReadAddressConfig _ _ _ _ _ _ _ _ _ a) = a
-- | AXI4 Read Address channel protocol
data
Axi4ReadAddress
(dom :: C.Domain)
(conf :: Axi4ReadAddressConfig)
(userType :: Type)
instance Protocol (Axi4ReadAddress dom conf userType) where
type
Fwd (Axi4ReadAddress dom conf userType) =
C.Signal dom (M2S_ReadAddress conf userType)
type
Bwd (Axi4ReadAddress dom conf userType) =
C.Signal dom S2M_ReadAddress
instance Backpressure (Axi4ReadAddress dom conf userType) where
boolsToBwd _ = C.fromList_lazy . coerce
-- | See Table A2-5 "Read address channel signals"
data
M2S_ReadAddress
(conf :: Axi4ReadAddressConfig)
(userType :: Type)
= M2S_NoReadAddress
| M2S_ReadAddress
{ _arid :: C.BitVector (ARIdWidth conf)
-- ^ Read address id*
, _araddr :: C.BitVector (ARAddrWidth conf)
-- ^ Read address
, _arregion :: RegionType (ARKeepRegion conf)
-- ^ Read region*
, _arlen :: BurstLengthType (ARKeepBurstLength conf)
-- ^ Burst length*
, _arsize :: SizeType (ARKeepSize conf)
-- ^ Burst size*
, _arburst :: BurstType (ARKeepBurst conf)
-- ^ Burst type*
, _arlock :: LockType (ARKeepLock conf)
-- ^ Lock type*
, _arcache :: ArCacheType (ARKeepCache conf)
-- ^ Cache type* (has been renamed to modifiable in AXI spec)
, _arprot :: PermissionsType (ARKeepPermissions conf)
-- ^ Protection type
, _arqos :: QosType (ARKeepQos conf)
-- ^ QoS value
, _aruser :: userType
-- ^ User data
}
deriving (Generic)
deriving instance
(KnownAxi4ReadAddressConfig conf, C.NFDataX user) => C.NFDataX (M2S_ReadAddress conf user)
deriving instance
(KnownAxi4ReadAddressConfig conf, C.BitPack user) => C.BitPack (M2S_ReadAddress conf user)
deriving instance
(KnownAxi4ReadAddressConfig conf, Show userType) => Show (M2S_ReadAddress conf userType)
deriving instance
(KnownAxi4ReadAddressConfig conf, C.ShowX userType) =>
C.ShowX (M2S_ReadAddress conf userType)
deriving instance
(KnownAxi4ReadAddressConfig conf, Eq userType) => Eq (M2S_ReadAddress conf userType)
-- | See Table A2-5 "Read address channel signals"
newtype S2M_ReadAddress = S2M_ReadAddress
{_arready :: Bool}
deriving stock (Show, Generic, Eq)
deriving anyclass (C.ShowX, C.NFDataX, C.BitPack)
{- | Shorthand for a "well-behaved" read address config,
so that we don't need to write out a bunch of type constraints later.
Holds for every configuration; don't worry about implementing this class.
-}
type KnownAxi4ReadAddressConfig conf =
( KeepTypeClass (ARKeepBurst conf)
, KeepTypeClass (ARKeepSize conf)
, KeepTypeClass (ARKeepRegion conf)
, KeepTypeClass (ARKeepBurstLength conf)
, KeepTypeClass (ARKeepLock conf)
, KeepTypeClass (ARKeepCache conf)
, KeepTypeClass (ARKeepPermissions conf)
, KeepTypeClass (ARKeepQos conf)
, C.KnownNat (ARIdWidth conf)
, C.KnownNat (ARAddrWidth conf)
, C.ShowX (RegionType (ARKeepRegion conf))
, C.ShowX (BurstLengthType (ARKeepBurstLength conf))
, C.ShowX (SizeType (ARKeepSize conf))
, C.ShowX (BurstType (ARKeepBurst conf))
, C.ShowX (LockType (ARKeepLock conf))
, C.ShowX (ArCacheType (ARKeepCache conf))
, C.ShowX (PermissionsType (ARKeepPermissions conf))
, C.ShowX (QosType (ARKeepQos conf))
, Show (RegionType (ARKeepRegion conf))
, Show (BurstLengthType (ARKeepBurstLength conf))
, Show (SizeType (ARKeepSize conf))
, Show (BurstType (ARKeepBurst conf))
, Show (LockType (ARKeepLock conf))
, Show (ArCacheType (ARKeepCache conf))
, Show (PermissionsType (ARKeepPermissions conf))
, Show (QosType (ARKeepQos conf))
, C.NFDataX (RegionType (ARKeepRegion conf))
, C.NFDataX (BurstLengthType (ARKeepBurstLength conf))
, C.NFDataX (SizeType (ARKeepSize conf))
, C.NFDataX (BurstType (ARKeepBurst conf))
, C.NFDataX (LockType (ARKeepLock conf))
, C.NFDataX (ArCacheType (ARKeepCache conf))
, C.NFDataX (PermissionsType (ARKeepPermissions conf))
, C.NFDataX (QosType (ARKeepQos conf))
, C.BitPack (RegionType (ARKeepRegion conf))
, C.BitPack (BurstLengthType (ARKeepBurstLength conf))
, C.BitPack (SizeType (ARKeepSize conf))
, C.BitPack (BurstType (ARKeepBurst conf))
, C.BitPack (LockType (ARKeepLock conf))
, C.BitPack (ArCacheType (ARKeepCache conf))
, C.BitPack (PermissionsType (ARKeepPermissions conf))
, C.BitPack (QosType (ARKeepQos conf))
, NFData (RegionType (ARKeepRegion conf))
, NFData (BurstLengthType (ARKeepBurstLength conf))
, NFData (SizeType (ARKeepSize conf))
, NFData (BurstType (ARKeepBurst conf))
, NFData (LockType (ARKeepLock conf))
, NFData (ArCacheType (ARKeepCache conf))
, NFData (PermissionsType (ARKeepPermissions conf))
, NFData (QosType (ARKeepQos conf))
, Eq (RegionType (ARKeepRegion conf))
, Eq (BurstLengthType (ARKeepBurstLength conf))
, Eq (SizeType (ARKeepSize conf))
, Eq (BurstType (ARKeepBurst conf))
, Eq (LockType (ARKeepLock conf))
, Eq (ArCacheType (ARKeepCache conf))
, Eq (PermissionsType (ARKeepPermissions conf))
, Eq (QosType (ARKeepQos conf))
)
{- | Mainly for use in 'Protocols.DfConv.DfConv'.
Data carried along 'Axi4ReadAddress' channel which is put in control of
the user, rather than being managed by the 'Protocols.DfConv.DfConv' instances.
Matches up
one-to-one with the fields of t'M2S_ReadAddress' except for '_arlen',
'_arsize', and '_arburst'.
-}
data Axi4ReadAddressInfo (conf :: Axi4ReadAddressConfig) (userType :: Type) = Axi4ReadAddressInfo
{ _ariid :: C.BitVector (ARIdWidth conf)
-- ^ Id
, _ariaddr :: C.BitVector (ARAddrWidth conf)
-- ^ Address
, _ariregion :: RegionType (ARKeepRegion conf)
-- ^ Region
, _arilen :: BurstLengthType (ARKeepBurstLength conf)
-- ^ Burst length
, _arisize :: SizeType (ARKeepSize conf)
-- ^ Burst size
, _ariburst :: BurstType (ARKeepBurst conf)
-- ^ Burst type
, _arilock :: LockType (ARKeepLock conf)
-- ^ Lock type
, _aricache :: ArCacheType (ARKeepCache conf)
-- ^ Cache type
, _ariprot :: PermissionsType (ARKeepPermissions conf)
-- ^ Protection type
, _ariqos :: QosType (ARKeepQos conf)
-- ^ QoS value
, _ariuser :: userType
-- ^ User data
}
deriving (Generic)
deriving instance
( KnownAxi4ReadAddressConfig conf
, Show userType
) =>
Show (Axi4ReadAddressInfo conf userType)
deriving instance
( KnownAxi4ReadAddressConfig conf
, C.ShowX userType
) =>
C.ShowX (Axi4ReadAddressInfo conf userType)
deriving instance
( KnownAxi4ReadAddressConfig conf
, C.NFDataX userType
) =>
C.NFDataX (Axi4ReadAddressInfo conf userType)
deriving instance
( KnownAxi4ReadAddressConfig conf
, NFData userType
) =>
NFData (Axi4ReadAddressInfo conf userType)
deriving instance
( KnownAxi4ReadAddressConfig conf
, Eq userType
) =>
Eq (Axi4ReadAddressInfo conf userType)
-- | Convert t'M2S_ReadAddress' to t'Axi4ReadAddressInfo', dropping some info
axi4ReadAddrMsgToReadAddrInfo ::
M2S_ReadAddress conf userType ->
Axi4ReadAddressInfo conf userType
axi4ReadAddrMsgToReadAddrInfo M2S_NoReadAddress = C.errorX "Expected ReadAddress"
axi4ReadAddrMsgToReadAddrInfo M2S_ReadAddress{..} =
Axi4ReadAddressInfo
{ _ariid = _arid
, _ariaddr = _araddr
, _ariregion = _arregion
, _arilen = _arlen
, _arisize = _arsize
, _ariburst = _arburst
, _arilock = _arlock
, _aricache = _arcache
, _ariprot = _arprot
, _ariqos = _arqos
, _ariuser = _aruser
}
-- | Convert t'Axi4ReadAddressInfo' to t'M2S_ReadAddress', adding some info
axi4ReadAddrMsgFromReadAddrInfo ::
Axi4ReadAddressInfo conf userType -> M2S_ReadAddress conf userType
axi4ReadAddrMsgFromReadAddrInfo Axi4ReadAddressInfo{..} =
M2S_ReadAddress
{ _arid = _ariid
, _araddr = _ariaddr
, _arregion = _ariregion
, _arlen = _arilen
, _arsize = _arisize
, _arburst = _ariburst
, _arlock = _arilock
, _arcache = _aricache
, _arprot = _ariprot
, _arqos = _ariqos
, _aruser = _ariuser
}
instance IdleCircuit (Axi4ReadAddress dom conf userType) where
idleFwd _ = pure M2S_NoReadAddress
idleBwd _ = pure S2M_ReadAddress{_arready = False}
{- | Force a /nack/ on the backward channel and /no data/ on the forward
channel if reset is asserted.
-}
forceResetSanity ::
forall dom conf userType.
(C.KnownDomain dom, C.HiddenReset dom) =>
Circuit (Axi4ReadAddress dom conf userType) (Axi4ReadAddress dom conf userType)
forceResetSanity = forceResetSanityGeneric