clash-prelude-1.8.4: Clash: a functional hardware description language - Prelude library

Copyright | (C) 2022 QBayLogic B.V.
License | BSD2 (see the file LICENSE)
Maintainer | QBayLogic B.V. <devops@qbaylogic.com>
Safe Haskell | Safe
Language | Haskell2010

Extensions

- ScopedTypeVariables
- BangPatterns
- ViewPatterns
- DataKinds
- InstanceSigs
- StandaloneDeriving
- DeriveDataTypeable
- DeriveFunctor
- DeriveTraversable
- DeriveFoldable
- DeriveGeneric
- DefaultSignatures
- DeriveLift
- DerivingStrategies
- MagicHash
- KindSignatures
- PostfixOperators
- TupleSections
- TypeOperators
- ExplicitNamespaces
- ExplicitForAll
- BinaryLiterals
- TypeApplications

Clash.Prelude.BlockRam.Blob

Contents

- BlockRAMs initialized with a `MemBlob`
- Creating and inspecting `MemBlob`

Description

# Efficient bundling of initial RAM content with the compiled code

Leveraging Template Haskell, the initial content for the block RAM components in this module is stored alongside the compiled Haskell code. It covers use cases where passing the initial content as a `Vec` turns out to be problematically slow.

The data is stored efficiently, with very little overhead (worst-case 7%, often no overhead at all).

Unlike Clash.Prelude.BlockRam.File, Clash.Prelude.BlockRam.Blob generates practically the same HDL as Clash.Prelude.BlockRam and is compatible with all tools consuming the generated HDL.

Synopsis

- blockRamBlob :: forall (dom :: Domain) addr (m :: Nat) (n :: Nat). (HiddenClock dom, HiddenEnable dom, Enum addr, NFDataX addr) => MemBlob n m -> Signal dom addr -> Signal dom (Maybe (addr, BitVector m)) -> Signal dom (BitVector m)
- blockRamBlobPow2 :: forall (dom :: Domain) (m :: Nat) (n :: Nat). (HiddenClock dom, HiddenEnable dom, KnownNat n) => MemBlob (2 ^ n) m -> Signal dom (Unsigned n) -> Signal dom (Maybe (Unsigned n, BitVector m)) -> Signal dom (BitVector m)
- data MemBlob (n :: Nat) (m :: Nat)
- createMemBlob :: forall a f. (Foldable f, BitPack a) => String -> Maybe Bit -> f a -> DecsQ
- memBlobTH :: forall a f. (Foldable f, BitPack a) => Maybe Bit -> f a -> ExpQ
- unpackMemBlob :: forall (n :: Nat) (m :: Nat). MemBlob n m -> [BitVector m]

# BlockRAMs initialized with a `MemBlob`

blockRamBlob Source #

Arguments

:: forall (dom :: Domain) addr (m :: Nat) (n :: Nat). (HiddenClock dom, HiddenEnable dom, Enum addr, NFDataX addr) |
=> MemBlob n m | Initial content of the BRAM, also determines the size, `n`, of the BRAM NB: MUST be a constant
-> Signal dom addr | Read address `r`
-> Signal dom (Maybe (addr, BitVector m)) | (write address `w`, value to write)
-> Signal dom (BitVector m) | Value of the BRAM at address `r` from the previous clock cycle

Create a block RAM with space for `n` elements

- NB: Read value is delayed by 1 cycle
- NB: Initial output value is undefined, reading it will throw an `XException`

### See also:

- See Clash.Prelude.BlockRam for more information on how to use a block RAM.
- Use the adapter `readNew` for obtaining write-before-read semantics like this: ``readNew` (`blockRamBlob` content) rd wrM`.

blockRamBlobPow2 Source #

Arguments

:: forall (dom :: Domain) (m :: Nat) (n :: Nat). (HiddenClock dom, HiddenEnable dom, KnownNat n) |
=> MemBlob (2 ^ n) m | Initial content of the BRAM, also determines the size, 2^`n`, of the BRAM NB: MUST be a constant
-> Signal dom (Unsigned n) | Read address `r`
-> Signal dom (Maybe (Unsigned n, BitVector m)) | (write address `w`, value to write)
-> Signal dom (BitVector m) | Value of the BRAM at address `r` from the previous clock cycle

Create a block RAM with space for 2^`n` elements

- NB: Read value is delayed by 1 cycle
- NB: Initial output value is undefined, reading it will throw an `XException`

### See also:

- See Clash.Prelude.BlockRam for more information on how to use a block RAM.
- Use the adapter `readNew` for obtaining write-before-read semantics like this: ``readNew` (`blockRamBlobPow2` content) rd wrM`.

# Creating and inspecting `MemBlob`

data MemBlob (n :: Nat) (m :: Nat) Source #

Efficient storage of memory content

It holds `n` words of ``BitVector` m`.

#### Instances

Instances details

Show (MemBlob n m) Source # |
Instance details Defined in Clash.Explicit.BlockRam.Internal Methods showsPrec :: Int -> MemBlob n m -> ShowS Source # show :: MemBlob n m -> String Source # showList :: [MemBlob n m] -> ShowS Source #

createMemBlob Source #

Arguments

:: forall a f. (Foldable f, BitPack a) |
=> String | Name of the binding to generate
-> Maybe Bit | Value to map don't care bits to. `Nothing` means throwing an error on don't care bits.
-> f a | The content for the `MemBlob`
-> DecsQ |

Create a `MemBlob` binding from a list of values

Since this uses Template Haskell, nothing in the arguments given to `createMemBlob` can refer to something defined in the same module.

### Example

Expand

    createMemBlob "content" Nothing [15 :: Unsigned 8 .. 17]

    ram clk en = blockRamBlob clk en content

The `Maybe` datatype has don't care bits, where the actual value does not matter. But the bits need a defined value in the memory. Either 0 or 1 can be used, and both are valid representations of the data.

    >>> import qualified Prelude as P
    >>> let es = [ Nothing, Just (7 :: Unsigned 8), Just 8 ]
    >>> :{
    createMemBlob "content0" (Just 0) es
    createMemBlob "content1" (Just 1) es
    x = 1
    :}

    >>> let pr = mapM_ (putStrLn . show)
    >>> pr $ P.map pack es
    0b0_...._....
    0b1_0000_0111
    0b1_0000_1000
    >>> pr $ unpackMemBlob content0
    0b0_0000_0000
    0b1_0000_0111
    0b1_0000_1000
    >>> pr $ unpackMemBlob content1
    0b0_1111_1111
    0b1_0000_0111
    0b1_0000_1000

    >>> :{
    createMemBlob "contentN" Nothing es
    x = 1
    :}
    <interactive>:...: error:...
        packBVs: cannot convert don't care values. Please specify a mapping to a definite value.

# 297 "srcClashExplicitBlockRamBlob.hs" Note how we hinted to `clashi` that our multi-line command was a list of declarations by including a dummy declaration `x = 1`. Without this trick, `clashi` would expect an expression and the Template Haskell would not work.

memBlobTH Source #

Arguments

:: forall a f. (Foldable f, BitPack a) |
=> Maybe Bit | Value to map don't care bits to. `Nothing` means throwing an error on don't care bits.
-> f a | The content for the `MemBlob`
-> ExpQ |

Create a `MemBlob` from a list of values

Since this uses Template Haskell, nothing in the arguments given to `memBlobTH` can refer to something defined in the same module.

### Example

Expand

    ram clk en = blockRamBlob clk en $(memBlobTH Nothing [15 :: Unsigned 8 .. 17])

The `Maybe` datatype has don't care bits, where the actual value does not matter. But the bits need a defined value in the memory. Either 0 or 1 can be used, and both are valid representations of the data.

    >>> import qualified Prelude as P
    >>> let es = [ Nothing, Just (7 :: Unsigned 8), Just 8 ]
    >>> content0 = $(memBlobTH (Just 0) es)
    >>> content1 = $(memBlobTH (Just 1) es)
    >>> let pr = mapM_ (putStrLn . show)
    >>> pr $ P.map pack es
    0b0_...._....
    0b1_0000_0111
    0b1_0000_1000
    >>> pr $ unpackMemBlob content0
    0b0_0000_0000
    0b1_0000_0111
    0b1_0000_1000
    >>> pr $ unpackMemBlob content1
    0b0_1111_1111
    0b1_0000_0111
    0b1_0000_1000

    >>> $(memBlobTH Nothing es)
    <interactive>:...: error:...
        • packBVs: cannot convert don't care values. Please specify a mapping to a definite value.
        • In the untyped splice: $(memBlobTH Nothing es)

# 384 "srcClashExplicitBlockRamBlob.hs"

unpackMemBlob :: forall (n :: Nat) (m :: Nat). MemBlob n m -> [BitVector m] Source #

Convert a `MemBlob` back to a list

NB: Not synthesizable