{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE Trustworthy #-}
{-# OPTIONS_GHC -fplugin GHC.TypeLits.KnownNat.Solver #-}
{-# OPTIONS_HADDOCK show-extensions #-}
module Clash.Prelude.ROM
(
asyncRom
, asyncRomPow2
, rom
, romPow2
, asyncRom#
)
where
import Data.Array (listArray)
import Data.Array.Base (unsafeAt)
import GHC.Stack (withFrozenCallStack)
import GHC.TypeLits (KnownNat, type (^))
import Prelude hiding (length)
import Clash.Annotations.Primitive (hasBlackBox)
import qualified Clash.Explicit.ROM as E
import Clash.Signal
import Clash.Sized.Unsigned (Unsigned)
import Clash.Sized.Vector (Vec, length, toList)
import Clash.XException (NFDataX, errorX)
asyncRom
:: (KnownNat n, Enum addr)
=> Vec n a
-> addr
-> a
asyncRom :: Vec n a -> addr -> a
asyncRom = \Vec n a
content addr
rd -> Vec n a -> Int -> a
forall (n :: Nat) a. KnownNat n => Vec n a -> Int -> a
asyncRom# Vec n a
content (addr -> Int
forall a. Enum a => a -> Int
fromEnum addr
rd)
{-# INLINE asyncRom #-}
asyncRomPow2
:: KnownNat n
=> Vec (2^n) a
-> Unsigned n
-> a
asyncRomPow2 :: Vec (2 ^ n) a -> Unsigned n -> a
asyncRomPow2 = Vec (2 ^ n) a -> Unsigned n -> a
forall (n :: Nat) addr a.
(KnownNat n, Enum addr) =>
Vec n a -> addr -> a
asyncRom
{-# INLINE asyncRomPow2 #-}
asyncRom#
:: forall n a . KnownNat n
=> Vec n a
-> Int
-> a
asyncRom# :: Vec n a -> Int -> a
asyncRom# Vec n a
content = Int -> a
safeAt
where
szI :: Int
szI = Vec n a -> Int
forall (n :: Nat) a. KnownNat n => Vec n a -> Int
length Vec n a
content
arr :: Array Int a
arr = (Int, Int) -> [a] -> Array Int a
forall i e. Ix i => (i, i) -> [e] -> Array i e
listArray (Int
0,Int
szIInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) (Vec n a -> [a]
forall (n :: Nat) a. Vec n a -> [a]
toList Vec n a
content)
safeAt :: Int -> a
safeAt :: Int -> a
safeAt 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
Array Int a -> Int -> a
forall (a :: Type -> Type -> Type) e i.
(IArray a e, Ix i) =>
a i e -> Int -> e
unsafeAt Array Int a
arr Int
i
else
(HasCallStack => a) -> a
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack
(String -> a
forall a. HasCallStack => String -> a
errorX (String
"asyncRom: address " 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]
++
String
" not in range [0.." String -> String -> String
forall a. [a] -> [a] -> [a]
++ Int -> String
forall a. Show a => a -> String
show Int
szI String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
")"))
{-# NOINLINE asyncRom# #-}
{-# ANN asyncRom# hasBlackBox #-}
rom
:: forall dom n m a
. ( NFDataX a
, KnownNat n
, KnownNat m
, HiddenClock dom
, HiddenEnable dom )
=> Vec n a
-> Signal dom (Unsigned m)
-> Signal dom a
rom :: Vec n a -> Signal dom (Unsigned m) -> Signal dom a
rom = (Enable dom -> Vec n a -> Signal dom (Unsigned m) -> Signal dom a)
-> Vec n a -> Signal dom (Unsigned m) -> Signal dom a
forall (dom :: Domain) r.
HiddenEnable dom =>
(Enable dom -> r) -> r
hideEnable ((Clock dom
-> Enable dom
-> Vec n a
-> Signal dom (Unsigned m)
-> Signal dom a)
-> Enable dom -> Vec n a -> Signal dom (Unsigned m) -> Signal dom a
forall (dom :: Domain) r. HiddenClock dom => (Clock dom -> r) -> r
hideClock Clock dom
-> Enable dom -> Vec n a -> Signal dom (Unsigned m) -> Signal dom a
forall (dom :: Domain) (n :: Nat) a addr.
(KnownDomain dom, KnownNat n, NFDataX a, Enum addr) =>
Clock dom
-> Enable dom -> Vec n a -> Signal dom addr -> Signal dom a
E.rom)
{-# INLINE rom #-}
romPow2
:: forall dom n a
. ( KnownNat n
, NFDataX a
, HiddenClock dom
, HiddenEnable dom )
=> Vec (2^n) a
-> Signal dom (Unsigned n)
-> Signal dom a
romPow2 :: Vec (2 ^ n) a -> Signal dom (Unsigned n) -> Signal dom a
romPow2 = (Enable dom
-> Vec (2 ^ n) a -> Signal dom (Unsigned n) -> Signal dom a)
-> Vec (2 ^ n) a -> Signal dom (Unsigned n) -> Signal dom a
forall (dom :: Domain) r.
HiddenEnable dom =>
(Enable dom -> r) -> r
hideEnable ((Clock dom
-> Enable dom
-> Vec (2 ^ n) a
-> Signal dom (Unsigned n)
-> Signal dom a)
-> Enable dom
-> Vec (2 ^ n) a
-> Signal dom (Unsigned n)
-> Signal dom a
forall (dom :: Domain) r. HiddenClock dom => (Clock dom -> r) -> r
hideClock Clock dom
-> Enable dom
-> Vec (2 ^ n) a
-> Signal dom (Unsigned n)
-> Signal dom a
forall (dom :: Domain) (n :: Nat) a.
(KnownDomain dom, KnownNat n, NFDataX a) =>
Clock dom
-> Enable dom
-> Vec (2 ^ n) a
-> Signal dom (Unsigned n)
-> Signal dom a
E.romPow2)
{-# INLINE romPow2 #-}