{-# LANGUAGE CPP #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE PatternSynonyms #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE ViewPatterns #-}
module Clash.Primitives.DSL
(
BlackBoxHaskellOpts(..)
, blackBoxHaskell
, BlockState (..)
, TExpr(..)
, addDeclaration
, assign
, compInBlock
, declaration
, declarationReturn
, declare
, declareN
, instDecl
, instHO
, viaAnnotatedSignal
, bvLit
, LitHDL (..)
, pattern High
, pattern Low
, constructProduct
, tuple
, vec
, tInputs
, tResults
, getStr
, getBool
, getVec
, exprToInteger
, tExprToInteger
, deconstructProduct
, untuple
, unvec
, deconstructMaybe
, bitCoerce
, toBV
, toBvWithAttrs
, fromBV
, enableToBit
, boolToBit
, boolFromBit
, boolFromBitVector
, unsignedFromBitVector
, boolFromBits
, unsafeToActiveHigh
, unsafeToActiveLow
, andExpr
, notExpr
, pureToBV
, pureToBVResized
, open
, clog2
, litTExpr
, toIdentifier
, tySize
) where
import Control.Lens hiding (Indexed, assign)
#if MIN_VERSION_mtl(2,3,0)
import Control.Monad (forM, forM_, zipWithM)
#endif
import Control.Monad.State
import Data.Default (Default(def))
import Data.IntMap (IntMap)
import qualified Data.IntMap as IntMap
import Data.List (intersperse)
import Data.List.Extra (zipEqual)
import Data.Maybe (fromMaybe)
import Data.Monoid (Ap(getAp))
import Data.Semigroup hiding (Product)
import Data.String
import Data.Text (Text)
import qualified Data.Text as Text
import Data.Text.Extra (showt)
import Data.Text.Prettyprint.Doc.Extra
import GHC.Stack (HasCallStack)
import Clash.Annotations.Primitive (HDL (..), Primitive (..))
import Clash.Annotations.SynthesisAttributes (Attr)
import Clash.Backend hiding (Usage, fromBV, toBV)
import Clash.Backend.VHDL (VHDLState)
import Clash.Explicit.Signal (ResetPolarity(..), vResetPolarity)
import Clash.Netlist.BlackBox.Util (exprToString, getDomainConf, renderElem)
import Clash.Netlist.BlackBox.Types
(BlackBoxTemplate, Element(Component, Text), Decl(..))
import qualified Clash.Netlist.Id as Id
import Clash.Netlist.Types hiding (Component, toBit)
import Clash.Netlist.Util
import Clash.Util (clogBase)
import qualified Data.String.Interpolate as I
import qualified Language.Haskell.TH as TH
import qualified Language.Haskell.TH.Syntax as TH
import Prelude
data BlackBoxHaskellOpts = BlackBoxHaskellOpts
{
BlackBoxHaskellOpts -> [Int]
bo_ignoredArguments :: [Int]
, BlackBoxHaskellOpts -> [HDL]
bo_supportedHdls :: [HDL]
, BlackBoxHaskellOpts -> Bool
bo_multiResult :: Bool
}
instance Default BlackBoxHaskellOpts where
def :: BlackBoxHaskellOpts
def = BlackBoxHaskellOpts
{ bo_ignoredArguments :: [Int]
bo_ignoredArguments = []
, bo_supportedHdls :: [HDL]
bo_supportedHdls = [HDL
forall a. Bounded a => a
minBound..HDL
forall a. Bounded a => a
maxBound]
, bo_multiResult :: Bool
bo_multiResult = Bool
False
}
blackBoxHaskell
:: TH.Name
-> TH.Name
-> BlackBoxHaskellOpts
-> Primitive
blackBoxHaskell :: Name -> Name -> BlackBoxHaskellOpts -> Primitive
blackBoxHaskell Name
bb Name
tf BlackBoxHaskellOpts{Bool
[Int]
[HDL]
bo_ignoredArguments :: BlackBoxHaskellOpts -> [Int]
bo_supportedHdls :: BlackBoxHaskellOpts -> [HDL]
bo_multiResult :: BlackBoxHaskellOpts -> Bool
bo_ignoredArguments :: [Int]
bo_supportedHdls :: [HDL]
bo_multiResult :: Bool
..} =
[HDL] -> String -> Primitive
InlineYamlPrimitive [HDL]
bo_supportedHdls [I.__i|
BlackBoxHaskell:
name: #{bb}
templateFunction: #{tf}
ignoredArguments : #{bo_ignoredArguments}
multiResult : #{toYamlBool bo_multiResult}
|]
where
toYamlBool :: Bool -> String
toYamlBool :: Bool -> String
toYamlBool Bool
True = String
"true"
toYamlBool Bool
False = String
"false"
data BlockState backend = BlockState
{ forall backend. BlockState backend -> [Declaration]
_bsDeclarations :: [Declaration]
, forall backend. BlockState backend -> IntMap Int
_bsHigherOrderCalls :: IntMap Int
, forall backend. BlockState backend -> backend
_bsBackend :: backend
}
makeLenses ''BlockState
instance Backend backend => HasIdentifierSet (BlockState backend) where
identifierSet :: Lens' (BlockState backend) IdentifierSet
identifierSet :: Lens' (BlockState backend) IdentifierSet
identifierSet = (backend -> f backend)
-> BlockState backend -> f (BlockState backend)
forall backend backend (f :: Type -> Type).
Functor f =>
(backend -> f backend)
-> BlockState backend -> f (BlockState backend)
bsBackend ((backend -> f backend)
-> BlockState backend -> f (BlockState backend))
-> ((IdentifierSet -> f IdentifierSet) -> backend -> f backend)
-> (IdentifierSet -> f IdentifierSet)
-> BlockState backend
-> f (BlockState backend)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (IdentifierSet -> f IdentifierSet) -> backend -> f backend
forall s. HasIdentifierSet s => Lens' s IdentifierSet
Lens' backend IdentifierSet
identifierSet
instance HasUsageMap backend => HasUsageMap (BlockState backend) where
usageMap :: Lens' (BlockState backend) UsageMap
usageMap = (backend -> f backend)
-> BlockState backend -> f (BlockState backend)
forall backend backend (f :: Type -> Type).
Functor f =>
(backend -> f backend)
-> BlockState backend -> f (BlockState backend)
bsBackend((backend -> f backend)
-> BlockState backend -> f (BlockState backend))
-> ((UsageMap -> f UsageMap) -> backend -> f backend)
-> (UsageMap -> f UsageMap)
-> BlockState backend
-> f (BlockState backend)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(UsageMap -> f UsageMap) -> backend -> f backend
forall s. HasUsageMap s => Lens' s UsageMap
Lens' backend UsageMap
usageMap
liftToBlockState
:: forall backend a. Backend backend
=> State backend a -> State (BlockState backend) a
liftToBlockState :: forall backend a.
Backend backend =>
State backend a -> State (BlockState backend) a
liftToBlockState (StateT backend -> Identity (a, backend)
f) = (BlockState backend -> Identity (a, BlockState backend))
-> StateT (BlockState backend) Identity a
forall s (m :: Type -> Type) a. (s -> m (a, s)) -> StateT s m a
StateT BlockState backend -> Identity (a, BlockState backend)
g
where
g :: BlockState backend -> Identity (a, BlockState backend)
g :: BlockState backend -> Identity (a, BlockState backend)
g BlockState backend
sbsIn = do
let sIn :: backend
sIn = BlockState backend -> backend
forall backend. BlockState backend -> backend
_bsBackend BlockState backend
sbsIn
(res,sOut) <- backend -> Identity (a, backend)
f backend
sIn
pure (res, sbsIn{_bsBackend = sOut})
data TExpr = TExpr
{ TExpr -> HWType
ety :: HWType
, TExpr -> Expr
eex :: Expr
} deriving Int -> TExpr -> ShowS
[TExpr] -> ShowS
TExpr -> String
(Int -> TExpr -> ShowS)
-> (TExpr -> String) -> ([TExpr] -> ShowS) -> Show TExpr
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> TExpr -> ShowS
showsPrec :: Int -> TExpr -> ShowS
$cshow :: TExpr -> String
show :: TExpr -> String
$cshowList :: [TExpr] -> ShowS
showList :: [TExpr] -> ShowS
Show
makeLenses ''TExpr
declarationReturn
:: Backend backend
=> BlackBoxContext
-> Text.Text
-> State (BlockState backend) [TExpr]
-> State backend Doc
declarationReturn :: forall backend.
Backend backend =>
BlackBoxContext
-> Text -> State (BlockState backend) [TExpr] -> State backend Doc
declarationReturn BlackBoxContext
bbCtx Text
blockName State (BlockState backend) [TExpr]
blockBuilder =
Text -> State (BlockState backend) () -> State backend Doc
forall backend.
Backend backend =>
Text -> State (BlockState backend) () -> State backend Doc
declaration Text
blockName (State (BlockState backend) () -> State backend Doc)
-> State (BlockState backend) () -> State backend Doc
forall a b. (a -> b) -> a -> b
$ do
res <- State (BlockState backend) [TExpr]
blockBuilder
forM_ (zip (bbResults bbCtx) res) $ \((Expr, HWType)
rNm, TExpr
r) -> case (Expr, HWType)
rNm of
(Identifier Identifier
resultNm Maybe Modifier
Nothing, HWType
_) ->
Declaration -> State (BlockState backend) ()
forall backend. Declaration -> State (BlockState backend) ()
addDeclaration (Identifier -> Usage -> Expr -> Declaration
Assignment Identifier
resultNm Usage
Cont (TExpr -> Expr
eex TExpr
r))
(Expr
t,HWType
_) -> String -> State (BlockState backend) ()
forall a. HasCallStack => String -> a
error (String
"declarationReturn expected an Identifier, but got: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Expr -> String
forall a. Show a => a -> String
show Expr
t)
emptyBlockState :: backend -> BlockState backend
emptyBlockState :: forall backend. backend -> BlockState backend
emptyBlockState backend
bck = BlockState
{ _bsDeclarations :: [Declaration]
_bsDeclarations = []
, _bsHigherOrderCalls :: IntMap Int
_bsHigherOrderCalls = IntMap Int
forall a. IntMap a
IntMap.empty
, _bsBackend :: backend
_bsBackend = backend
bck
}
declaration
:: Backend backend
=> Text.Text
-> State (BlockState backend) ()
-> State backend Doc
declaration :: forall backend.
Backend backend =>
Text -> State (BlockState backend) () -> State backend Doc
declaration Text
blockName State (BlockState backend) ()
c = do
backend0 <- StateT backend Identity backend
forall s (m :: Type -> Type). MonadState s m => m s
get
let initState = backend -> BlockState backend
forall backend. backend -> BlockState backend
emptyBlockState backend
backend0
(BlockState {..}) = execState c initState
put _bsBackend
blockNameUnique <- Id.makeBasic blockName
getAp $ blockDecl blockNameUnique (reverse _bsDeclarations)
addDeclaration :: Declaration -> State (BlockState backend) ()
addDeclaration :: forall backend. Declaration -> State (BlockState backend) ()
addDeclaration Declaration
dec = ([Declaration] -> Identity [Declaration])
-> BlockState backend -> Identity (BlockState backend)
forall backend (f :: Type -> Type).
Functor f =>
([Declaration] -> f [Declaration])
-> BlockState backend -> f (BlockState backend)
bsDeclarations (([Declaration] -> Identity [Declaration])
-> BlockState backend -> Identity (BlockState backend))
-> ([Declaration] -> [Declaration])
-> StateT (BlockState backend) Identity ()
forall s (m :: Type -> Type) a b.
MonadState s m =>
ASetter s s a b -> (a -> b) -> m ()
%= Declaration -> [Declaration] -> [Declaration]
forall s a. Cons s s a a => a -> s -> s
cons Declaration
dec
declare'
:: Backend backend
=> Text
-> HWType
-> State (BlockState backend) Identifier
declare' :: forall backend.
Backend backend =>
Text -> HWType -> State (BlockState backend) Identifier
declare' Text
decName HWType
ty = do
uniqueName <- Text -> StateT (BlockState backend) Identity Identifier
forall (m :: Type -> Type).
(HasCallStack, IdentifierSetMonad m) =>
Text -> m Identifier
Id.makeBasic Text
decName
addDeclaration (NetDecl' Nothing uniqueName ty Nothing)
pure uniqueName
declare
:: Backend backend
=> Text
-> HWType
-> State (BlockState backend) TExpr
declare :: forall backend.
Backend backend =>
Text -> HWType -> State (BlockState backend) TExpr
declare Text
decName HWType
ty = do
uniqueName <- Text -> HWType -> State (BlockState backend) Identifier
forall backend.
Backend backend =>
Text -> HWType -> State (BlockState backend) Identifier
declare' Text
decName HWType
ty
pure (TExpr ty (Identifier uniqueName Nothing))
declareN
:: Backend backend
=> Text
-> [HWType]
-> State (BlockState backend) [TExpr]
declareN :: forall backend.
Backend backend =>
Text -> [HWType] -> State (BlockState backend) [TExpr]
declareN Text
decName [HWType]
tys = do
firstName <- Text -> StateT (BlockState backend) Identity Identifier
forall (m :: Type -> Type).
(HasCallStack, IdentifierSetMonad m) =>
Text -> m Identifier
Id.makeBasic Text
decName
nextNames <- Id.nextN (length tys - 1) firstName
let uniqueNames = Identifier
firstName Identifier -> [Identifier] -> [Identifier]
forall a. a -> [a] -> [a]
: [Identifier]
nextNames
zipWithM
(\Identifier
uniqueName HWType
ty -> do
Declaration -> State (BlockState backend) ()
forall backend. Declaration -> State (BlockState backend) ()
addDeclaration (Declaration -> State (BlockState backend) ())
-> Declaration -> State (BlockState backend) ()
forall a b. (a -> b) -> a -> b
$ Maybe Text -> Identifier -> HWType -> Maybe Expr -> Declaration
NetDecl' Maybe Text
forall a. Maybe a
Nothing Identifier
uniqueName HWType
ty Maybe Expr
forall a. Maybe a
Nothing
TExpr -> StateT (BlockState backend) Identity TExpr
forall a. a -> StateT (BlockState backend) Identity a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (TExpr -> StateT (BlockState backend) Identity TExpr)
-> TExpr -> StateT (BlockState backend) Identity TExpr
forall a b. (a -> b) -> a -> b
$ HWType -> Expr -> TExpr
TExpr HWType
ty (Identifier -> Maybe Modifier -> Expr
Identifier Identifier
uniqueName Maybe Modifier
forall a. Maybe a
Nothing)
) uniqueNames tys
assign
:: Backend backend
=> Text
-> TExpr
-> State (BlockState backend) TExpr
assign :: forall backend.
Backend backend =>
Text -> TExpr -> State (BlockState backend) TExpr
assign Text
aName (TExpr HWType
ty Expr
aExpr) = do
texp <- Text -> HWType -> State (BlockState backend) TExpr
forall backend.
Backend backend =>
Text -> HWType -> State (BlockState backend) TExpr
declare Text
aName HWType
ty
let uniqueName = case TExpr
texp of
TExpr HWType
_ (Identifier Identifier
x Maybe Modifier
Nothing) -> Identifier
x
TExpr
t' -> String -> Identifier
forall a. HasCallStack => String -> a
error (String
"assign expected an Identifier, but got: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> TExpr -> String
forall a. Show a => a -> String
show TExpr
t')
addDeclaration (Assignment uniqueName Cont aExpr)
pure texp
unvec
:: (HasCallStack, Backend backend)
=> Text
-> TExpr
-> State (BlockState backend) [TExpr]
unvec :: forall backend.
(HasCallStack, Backend backend) =>
Text -> TExpr -> State (BlockState backend) [TExpr]
unvec Text
vName v :: TExpr
v@(TExpr -> HWType
ety -> Vector Int
vSize HWType
eType) = do
texp <- Text -> TExpr -> State (BlockState backend) TExpr
forall backend.
Backend backend =>
Text -> TExpr -> State (BlockState backend) TExpr
toIdentifier Text
vName TExpr
v
let vUniqueName = case TExpr
texp of
TExpr HWType
_ (Identifier Identifier
x Maybe Modifier
Nothing) -> Identifier
x
TExpr
t' -> String -> Identifier
forall a. HasCallStack => String -> a
error (String
"unvec expected an Identifier, but got: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> TExpr -> String
forall a. Show a => a -> String
show TExpr
t')
let vIndex Int
i = Identifier -> Maybe Modifier -> Expr
Identifier Identifier
vUniqueName (Modifier -> Maybe Modifier
forall a. a -> Maybe a
Just ((HWType, Int, Int) -> Modifier
Indexed (TExpr -> HWType
ety TExpr
v, Int
10, Int
i)))
pure (map (TExpr eType . vIndex) [0..vSize-1])
unvec Text
_ TExpr
e = String -> StateT (BlockState backend) Identity [TExpr]
forall a. HasCallStack => String -> a
error (String -> StateT (BlockState backend) Identity [TExpr])
-> String -> StateT (BlockState backend) Identity [TExpr]
forall a b. (a -> b) -> a -> b
$ String
"unvec: cannot be called on non-vector: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> HWType -> String
forall a. Show a => a -> String
show (TExpr -> HWType
ety TExpr
e)
deconstructMaybe ::
(HasCallStack, Backend backend) =>
TExpr ->
(Text, Text) ->
State (BlockState backend) (TExpr, TExpr)
deconstructMaybe :: forall backend.
(HasCallStack, Backend backend) =>
TExpr -> (Text, Text) -> State (BlockState backend) (TExpr, TExpr)
deconstructMaybe e :: TExpr
e@TExpr{HWType
ety :: TExpr -> HWType
ety :: HWType
ety} (Text
bitName, Text
contentName)
| SP Text
tyName [(Text
_nothing, []),(Text
_just, [HWType
aTy])] <- HWType
ety
, Text
tyName Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== String -> Text
forall a. IsString a => String -> a
fromString (Name -> String
forall a. Show a => a -> String
show ''Maybe)
= do
eBv <- Text -> TExpr -> State (BlockState backend) TExpr
forall backend.
Backend backend =>
Text -> TExpr -> State (BlockState backend) TExpr
toBV (Text
bitName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_and_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
contentName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_bv") TExpr
e
eId <- toIdentifier' (bitName <> "_and_" <> contentName) eBv
let eSize = HWType -> Int
typeSize HWType
ety
bitExpr <- fromBV bitName Bit TExpr
{ eex = Identifier eId (Just (Sliced (BitVector eSize, eSize - 1, eSize - 1)))
, ety = BitVector 1
}
contentExpr <- fromBV contentName aTy TExpr
{ eex = Identifier eId (Just (Sliced (BitVector eSize, eSize - 1 - 1, 0)))
, ety = BitVector (eSize - 1)
}
pure (bitExpr, contentExpr)
deconstructMaybe TExpr
e (Text, Text)
_ =
String -> StateT (BlockState backend) Identity (TExpr, TExpr)
forall a. HasCallStack => String -> a
error (String -> StateT (BlockState backend) Identity (TExpr, TExpr))
-> String -> StateT (BlockState backend) Identity (TExpr, TExpr)
forall a b. (a -> b) -> a -> b
$ String
"deconstructMaybe: cannot be called on non-Maybe: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> HWType -> String
forall a. Show a => a -> String
show (TExpr -> HWType
ety TExpr
e)
deconstructProduct
:: (HasCallStack, Backend backend)
=> TExpr
-> [Text]
-> State (BlockState backend) [TExpr]
deconstructProduct :: forall backend.
(HasCallStack, Backend backend) =>
TExpr -> [Text] -> State (BlockState backend) [TExpr]
deconstructProduct (TExpr ty :: HWType
ty@(Product Text
_ Maybe [Text]
_ [HWType]
fieldTys) (Identifier Identifier
resName Maybe Modifier
Nothing)) [Text]
nameHints =
[(Int, Text, HWType)]
-> ((Int, Text, HWType)
-> StateT (BlockState backend) Identity TExpr)
-> StateT (BlockState backend) Identity [TExpr]
forall (t :: Type -> Type) (m :: Type -> Type) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM ([Int] -> [Text] -> [HWType] -> [(Int, Text, HWType)]
forall a b c. [a] -> [b] -> [c] -> [(a, b, c)]
zip3 [Int
0..] [Text]
nameHints [HWType]
fieldTys) (((Int, Text, HWType)
-> StateT (BlockState backend) Identity TExpr)
-> StateT (BlockState backend) Identity [TExpr])
-> ((Int, Text, HWType)
-> StateT (BlockState backend) Identity TExpr)
-> StateT (BlockState backend) Identity [TExpr]
forall a b. (a -> b) -> a -> b
$ \(Int
fieldIndex, Text
nameHint, HWType
fieldTy) ->
Text -> TExpr -> StateT (BlockState backend) Identity TExpr
forall backend.
Backend backend =>
Text -> TExpr -> State (BlockState backend) TExpr
assign Text
nameHint (TExpr -> StateT (BlockState backend) Identity TExpr)
-> TExpr -> StateT (BlockState backend) Identity TExpr
forall a b. (a -> b) -> a -> b
$
HWType -> Expr -> TExpr
TExpr HWType
fieldTy (Identifier -> Maybe Modifier -> Expr
Identifier Identifier
resName (Modifier -> Maybe Modifier
forall a. a -> Maybe a
Just ((HWType, Int, Int) -> Modifier
Indexed (HWType
ty, Int
0, Int
fieldIndex))))
deconstructProduct t0 :: TExpr
t0@(TExpr (Product {}) Expr
_) [Text]
nameHints = do
t1 <- Text -> TExpr -> StateT (BlockState backend) Identity TExpr
forall backend.
Backend backend =>
Text -> TExpr -> State (BlockState backend) TExpr
toIdentifier Text
"product" TExpr
t0
deconstructProduct t1 nameHints
deconstructProduct TExpr
e [Text]
i =
String -> StateT (BlockState backend) Identity [TExpr]
forall a. HasCallStack => String -> a
error (String -> StateT (BlockState backend) Identity [TExpr])
-> String -> StateT (BlockState backend) Identity [TExpr]
forall a b. (a -> b) -> a -> b
$ String
"deconstructProduct: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> TExpr -> String
forall a. Show a => a -> String
show TExpr
e String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
" " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> [Text] -> String
forall a. Show a => a -> String
show [Text]
i
untuple
:: (HasCallStack, Backend backend)
=> TExpr
-> [Text]
-> State (BlockState backend) [TExpr]
untuple :: forall backend.
(HasCallStack, Backend backend) =>
TExpr -> [Text] -> State (BlockState backend) [TExpr]
untuple = TExpr -> [Text] -> State (BlockState backend) [TExpr]
forall backend.
(HasCallStack, Backend backend) =>
TExpr -> [Text] -> State (BlockState backend) [TExpr]
deconstructProduct
pattern High :: TExpr
pattern $mHigh :: forall {r}. TExpr -> ((# #) -> r) -> ((# #) -> r) -> r
$bHigh :: TExpr
High <- TExpr Bit (Literal _ (BitLit H))
where High = HWType -> Expr -> TExpr
TExpr HWType
Bit (Maybe (HWType, Int) -> Literal -> Expr
Literal ((HWType, Int) -> Maybe (HWType, Int)
forall a. a -> Maybe a
Just (HWType
Bit,Int
1)) (Bit -> Literal
BitLit Bit
H))
pattern Low :: TExpr
pattern $mLow :: forall {r}. TExpr -> ((# #) -> r) -> ((# #) -> r) -> r
$bLow :: TExpr
Low <- TExpr Bit (Literal _ (BitLit L))
where Low = HWType -> Expr -> TExpr
TExpr HWType
Bit (Maybe (HWType, Int) -> Literal -> Expr
Literal ((HWType, Int) -> Maybe (HWType, Int)
forall a. a -> Maybe a
Just (HWType
Bit,Int
1)) (Bit -> Literal
BitLit Bit
L))
pattern T :: TExpr
pattern $mT :: forall {r}. TExpr -> ((# #) -> r) -> ((# #) -> r) -> r
$bT :: TExpr
T <- TExpr Bool (Literal _ (BoolLit True))
where T = HWType -> Expr -> TExpr
TExpr HWType
Bool (Maybe (HWType, Int) -> Literal -> Expr
Literal ((HWType, Int) -> Maybe (HWType, Int)
forall a. a -> Maybe a
Just (HWType
Bool,Int
1)) (Bool -> Literal
BoolLit Bool
True))
pattern F :: TExpr
pattern $mF :: forall {r}. TExpr -> ((# #) -> r) -> ((# #) -> r) -> r
$bF :: TExpr
F <- TExpr Bool (Literal _ (BoolLit False))
where F = HWType -> Expr -> TExpr
TExpr HWType
Bool (Maybe (HWType, Int) -> Literal -> Expr
Literal ((HWType, Int) -> Maybe (HWType, Int)
forall a. a -> Maybe a
Just (HWType
Bool,Int
1)) (Bool -> Literal
BoolLit Bool
False))
bvLit
:: Int
-> Integer
-> TExpr
bvLit :: Int -> Integer -> TExpr
bvLit Int
sz Integer
n =
HWType -> Expr -> TExpr
TExpr
(Int -> HWType
BitVector Int
sz)
(Maybe (HWType, Int) -> Literal -> Expr
Literal ((HWType, Int) -> Maybe (HWType, Int)
forall a. a -> Maybe a
Just (Int -> HWType
BitVector Int
sz, Int
sz)) (Integer -> Integer -> Literal
BitVecLit Integer
0 Integer
n))
boolToBit
:: (HasCallStack, Backend backend)
=> Text
-> TExpr
-> State (BlockState backend) TExpr
boolToBit :: forall backend.
(HasCallStack, Backend backend) =>
Text -> TExpr -> State (BlockState backend) TExpr
boolToBit Text
bitName = \case
TExpr
T -> TExpr -> State (BlockState backend) TExpr
forall a. a -> StateT (BlockState backend) Identity a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure TExpr
High
TExpr
F -> TExpr -> State (BlockState backend) TExpr
forall a. a -> StateT (BlockState backend) Identity a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure TExpr
Low
TExpr HWType
Bool Expr
boolExpr -> do
texp <- Text -> HWType -> State (BlockState backend) TExpr
forall backend.
Backend backend =>
Text -> HWType -> State (BlockState backend) TExpr
declare Text
bitName HWType
Bit
let uniqueBitName = case TExpr
texp of
TExpr HWType
_ (Identifier Identifier
x Maybe Modifier
Nothing) -> Identifier
x
TExpr
t' -> String -> Identifier
forall a. HasCallStack => String -> a
error (String
"boolFromBit expected an Identifier, but got: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> TExpr -> String
forall a. Show a => a -> String
show TExpr
t')
addDeclaration $
CondAssignment uniqueBitName Bit boolExpr Bool
[ (Just (BoolLit True), Literal Nothing (BitLit H))
, (Nothing , Literal Nothing (BitLit L))
]
declareUseOnce (Proc NonBlocking) uniqueBitName
pure texp
TExpr
tExpr -> String -> State (BlockState backend) TExpr
forall a. HasCallStack => String -> a
error (String -> State (BlockState backend) TExpr)
-> String -> State (BlockState backend) TExpr
forall a b. (a -> b) -> a -> b
$ String
"boolToBit: Got \"" String -> ShowS
forall a. Semigroup a => a -> a -> a
<> TExpr -> String
forall a. Show a => a -> String
show TExpr
tExpr String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
"\" expected Bool"
enableToBit
:: (HasCallStack, Backend backend)
=> Text
-> TExpr
-> State (BlockState backend) TExpr
enableToBit :: forall backend.
(HasCallStack, Backend backend) =>
Text -> TExpr -> State (BlockState backend) TExpr
enableToBit Text
bitName = \case
TExpr ena :: HWType
ena@(Enable Text
_) Expr
enableExpr -> do
texp <- Text -> HWType -> State (BlockState backend) TExpr
forall backend.
Backend backend =>
Text -> HWType -> State (BlockState backend) TExpr
declare Text
bitName HWType
Bit
let uniqueBitName = case TExpr
texp of
TExpr HWType
_ (Identifier Identifier
x Maybe Modifier
Nothing) -> Identifier
x
TExpr
t' -> String -> Identifier
forall a. HasCallStack => String -> a
error (String
"boolFromBit expected an Identifier, but got: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> TExpr -> String
forall a. Show a => a -> String
show TExpr
t')
addDeclaration $
CondAssignment uniqueBitName Bit enableExpr ena
[ (Just (BoolLit True), Literal Nothing (BitLit H))
, (Nothing , Literal Nothing (BitLit L))
]
declareUseOnce (Proc NonBlocking) uniqueBitName
pure texp
TExpr
tExpr -> String -> State (BlockState backend) TExpr
forall a. HasCallStack => String -> a
error (String -> State (BlockState backend) TExpr)
-> String -> State (BlockState backend) TExpr
forall a b. (a -> b) -> a -> b
$ String
"enableToBit: Got \"" String -> ShowS
forall a. Semigroup a => a -> a -> a
<> TExpr -> String
forall a. Show a => a -> String
show TExpr
tExpr String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
"\" expected Enable"
boolFromBit
:: (HasCallStack, Backend backend)
=> Text
-> TExpr
-> State (BlockState backend) TExpr
boolFromBit :: forall backend.
(HasCallStack, Backend backend) =>
Text -> TExpr -> State (BlockState backend) TExpr
boolFromBit Text
boolName = \case
TExpr
High -> TExpr -> State (BlockState backend) TExpr
forall a. a -> StateT (BlockState backend) Identity a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure TExpr
T
TExpr
Low -> TExpr -> State (BlockState backend) TExpr
forall a. a -> StateT (BlockState backend) Identity a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure TExpr
F
TExpr HWType
Bit Expr
bitExpr -> do
texp <- Text -> HWType -> State (BlockState backend) TExpr
forall backend.
Backend backend =>
Text -> HWType -> State (BlockState backend) TExpr
declare Text
boolName HWType
Bool
let uniqueBoolName = case TExpr
texp of
TExpr HWType
_ (Identifier Identifier
x Maybe Modifier
Nothing) -> Identifier
x
TExpr
t' -> String -> Identifier
forall a. HasCallStack => String -> a
error (String
"boolFromBit expected an Identifier, but got: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> TExpr -> String
forall a. Show a => a -> String
show TExpr
t')
addDeclaration $
CondAssignment uniqueBoolName Bool bitExpr Bit
[ (Just (BitLit H), Literal Nothing (BoolLit True))
, (Nothing , Literal Nothing (BoolLit False))
]
declareUseOnce (Proc NonBlocking) uniqueBoolName
pure texp
TExpr
tExpr -> String -> State (BlockState backend) TExpr
forall a. HasCallStack => String -> a
error (String -> State (BlockState backend) TExpr)
-> String -> State (BlockState backend) TExpr
forall a b. (a -> b) -> a -> b
$ String
"boolFromBit: Got \"" String -> ShowS
forall a. Semigroup a => a -> a -> a
<> TExpr -> String
forall a. Show a => a -> String
show TExpr
tExpr String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
"\" expected Bit"
boolFromBitVector
:: Size
-> Text
-> TExpr
-> State (BlockState VHDLState) TExpr
boolFromBitVector :: Int -> Text -> TExpr -> State (BlockState VHDLState) TExpr
boolFromBitVector Int
n =
HWType
-> HWType
-> (Text -> Text)
-> Text
-> TExpr
-> State (BlockState VHDLState) TExpr
forall backend.
(HasCallStack, Backend backend) =>
HWType
-> HWType
-> (Text -> Text)
-> Text
-> TExpr
-> State (BlockState backend) TExpr
outputCoerce (Int -> HWType
BitVector Int
n) HWType
Bool (\Text
i -> Text
"unsigned(" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
i Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
") > 0")
unsignedFromBitVector ::
(HasCallStack, Backend backend) =>
Text ->
TExpr ->
State (BlockState backend) TExpr
unsignedFromBitVector :: forall backend.
(HasCallStack, Backend backend) =>
Text -> TExpr -> State (BlockState backend) TExpr
unsignedFromBitVector Text
nameHint e :: TExpr
e@TExpr{ety :: TExpr -> HWType
ety=BitVector Int
n} =
Text -> HWType -> TExpr -> State (BlockState backend) TExpr
forall backend.
(HasCallStack, Backend backend) =>
Text -> HWType -> TExpr -> State (BlockState backend) TExpr
fromBV Text
nameHint (Int -> HWType
Unsigned Int
n) TExpr
e
unsignedFromBitVector Text
_nameHint TExpr{HWType
ety :: TExpr -> HWType
ety :: HWType
ety} =
String -> State (BlockState backend) TExpr
forall a. HasCallStack => String -> a
error (String -> State (BlockState backend) TExpr)
-> String -> State (BlockState backend) TExpr
forall a b. (a -> b) -> a -> b
$ String
"unsignedFromBitVector: Expected BitVector, got: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> HWType -> String
forall a. Show a => a -> String
show HWType
ety
boolFromBits
:: [Text]
-> TExpr
-> State (BlockState VHDLState) [TExpr]
boolFromBits :: [Text] -> TExpr -> State (BlockState VHDLState) [TExpr]
boolFromBits [Text]
inNames = [HWType]
-> HWType
-> ([Text] -> Text)
-> [Text]
-> TExpr
-> State (BlockState VHDLState) [TExpr]
forall backend.
(HasCallStack, Backend backend) =>
[HWType]
-> HWType
-> ([Text] -> Text)
-> [Text]
-> TExpr
-> State (BlockState backend) [TExpr]
outputFn ((Text -> HWType) -> [Text] -> [HWType]
forall a b. (a -> b) -> [a] -> [b]
map (HWType -> Text -> HWType
forall a b. a -> b -> a
const HWType
Bit) [Text]
inNames) HWType
Bool
((Text -> Text -> Text) -> Text -> [Text] -> Text
forall b a. (b -> a -> b) -> b -> [a] -> b
forall (t :: Type -> Type) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
(<>) Text
"" ([Text] -> Text) -> ([Text] -> [Text]) -> [Text] -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> [Text] -> [Text]
forall a. a -> [a] -> [a]
intersperse Text
" and " ([Text] -> [Text]) -> ([Text] -> [Text]) -> [Text] -> [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Text -> Text) -> [Text] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map (\Text
i -> Text
"(" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
i Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" = '1')")) [Text]
inNames
outputCoerce
:: (HasCallStack, Backend backend)
=> HWType
-> HWType
-> (Text -> Text)
-> Text
-> TExpr
-> State (BlockState backend) TExpr
outputCoerce :: forall backend.
(HasCallStack, Backend backend) =>
HWType
-> HWType
-> (Text -> Text)
-> Text
-> TExpr
-> State (BlockState backend) TExpr
outputCoerce HWType
fromType HWType
toType Text -> Text
exprStringFn Text
inName0 TExpr
expr_
| TExpr HWType
outType (Identifier Identifier
outName Maybe Modifier
Nothing) <- TExpr
expr_
, HWType
outType HWType -> HWType -> Bool
forall a. Eq a => a -> a -> Bool
== HWType
toType = do
inName1 <- Text -> StateT (BlockState backend) Identity Identifier
forall (m :: Type -> Type).
(HasCallStack, IdentifierSetMonad m) =>
Text -> m Identifier
Id.makeBasic Text
inName0
let inName2 = HasCallStack => Text -> Identifier
Text -> Identifier
Id.unsafeMake (Text -> Text
exprStringFn (Identifier -> Text
Id.toText Identifier
inName1))
exprIdent = Identifier -> Maybe Modifier -> Expr
Identifier Identifier
inName2 Maybe Modifier
forall a. Maybe a
Nothing
addDeclaration (NetDecl Nothing inName1 fromType)
addDeclaration (Assignment outName Cont exprIdent)
pure (TExpr fromType (Identifier inName1 Nothing))
outputCoerce HWType
_ HWType
toType Text -> Text
_ Text
_ TExpr
texpr = String -> StateT (BlockState backend) Identity TExpr
forall a. HasCallStack => String -> a
error (String -> StateT (BlockState backend) Identity TExpr)
-> String -> StateT (BlockState backend) Identity TExpr
forall a b. (a -> b) -> a -> b
$ String
"outputCoerce: the expression " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> TExpr -> String
forall a. Show a => a -> String
show TExpr
texpr
String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
" must be an Identifier with type " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> HWType -> String
forall a. Show a => a -> String
show HWType
toType
outputFn
:: (HasCallStack, Backend backend)
=> [HWType]
-> HWType
-> ([Text] -> Text)
-> [Text]
-> TExpr
-> State (BlockState backend) [TExpr]
outputFn :: forall backend.
(HasCallStack, Backend backend) =>
[HWType]
-> HWType
-> ([Text] -> Text)
-> [Text]
-> TExpr
-> State (BlockState backend) [TExpr]
outputFn [HWType]
fromTypes HWType
toType [Text] -> Text
exprFn [Text]
inNames0 (TExpr HWType
outType (Identifier Identifier
outName Maybe Modifier
Nothing))
| HWType
outType HWType -> HWType -> Bool
forall a. Eq a => a -> a -> Bool
== HWType
toType = do
inNames1 <- (Text -> StateT (BlockState backend) Identity Identifier)
-> [Text] -> StateT (BlockState backend) Identity [Identifier]
forall (t :: Type -> Type) (m :: Type -> Type) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: Type -> Type) a b.
Monad m =>
(a -> m b) -> [a] -> m [b]
mapM Text -> StateT (BlockState backend) Identity Identifier
forall (m :: Type -> Type).
(HasCallStack, IdentifierSetMonad m) =>
Text -> m Identifier
Id.makeBasic [Text]
inNames0
let idExpr = HasCallStack => Text -> Identifier
Text -> Identifier
Id.unsafeMake ([Text] -> Text
exprFn ((Identifier -> Text) -> [Identifier] -> [Text]
forall a b. (a -> b) -> [a] -> [b]
map Identifier -> Text
Id.toText [Identifier]
inNames1))
exprIdent = Identifier -> Maybe Modifier -> Expr
Identifier Identifier
idExpr Maybe Modifier
forall a. Maybe a
Nothing
sequenceOf_ each [ addDeclaration (NetDecl Nothing nm t)
| (nm, t) <- zip inNames1 fromTypes ]
addDeclaration (Assignment outName Cont exprIdent)
pure [ TExpr t (Identifier nm Nothing)
| (nm,t) <- zipEqual inNames1 fromTypes ]
outputFn [HWType]
_ HWType
outType [Text] -> Text
_ [Text]
_ TExpr
texpr =
String -> StateT (BlockState backend) Identity [TExpr]
forall a. HasCallStack => String -> a
error (String -> StateT (BlockState backend) Identity [TExpr])
-> String -> StateT (BlockState backend) Identity [TExpr]
forall a b. (a -> b) -> a -> b
$ String
"outputFn: the expression " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> TExpr -> String
forall a. Show a => a -> String
show TExpr
texpr
String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
" must be an Identifier with type " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> HWType -> String
forall a. Show a => a -> String
show HWType
outType
vec
:: (HasCallStack, Backend backend)
=> [TExpr]
-> State (BlockState backend) TExpr
vec :: forall backend.
(HasCallStack, Backend backend) =>
[TExpr] -> State (BlockState backend) TExpr
vec els :: [TExpr]
els@(TExpr
el:[TExpr]
_)
| (TExpr -> Bool) -> [TExpr] -> Bool
forall (t :: Type -> Type) a.
Foldable t =>
(a -> Bool) -> t a -> Bool
all (\TExpr
e -> TExpr -> HWType
ety TExpr
e HWType -> HWType -> Bool
forall a. Eq a => a -> a -> Bool
== TExpr -> HWType
ety TExpr
el) [TExpr]
els
= TExpr -> StateT (BlockState backend) Identity TExpr
forall a. a -> StateT (BlockState backend) Identity a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (HWType -> Expr -> TExpr
TExpr (Int -> HWType -> HWType
Vector ([TExpr] -> Int
forall a. [a] -> Int
forall (t :: Type -> Type) a. Foldable t => t a -> Int
length [TExpr]
els) (TExpr -> HWType
ety TExpr
el)) Expr
theVec)
| Bool
otherwise
= String -> StateT (BlockState backend) Identity TExpr
forall a. HasCallStack => String -> a
error (String -> StateT (BlockState backend) Identity TExpr)
-> String -> StateT (BlockState backend) Identity TExpr
forall a b. (a -> b) -> a -> b
$ String
"vec: elements not of same type: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ [TExpr] -> String
forall a. Show a => a -> String
show [TExpr]
els
where
theVec :: Expr
theVec = Int -> HWType -> [Expr] -> Expr
mkVectorChain ([TExpr] -> Int
forall a. [a] -> Int
forall (t :: Type -> Type) a. Foldable t => t a -> Int
length [TExpr]
els) (TExpr -> HWType
ety TExpr
el) ((TExpr -> Expr) -> [TExpr] -> [Expr]
forall a b. (a -> b) -> [a] -> [b]
map TExpr -> Expr
eex [TExpr]
els)
vec [] = String -> StateT (BlockState backend) Identity TExpr
forall a. HasCallStack => String -> a
error String
"vec: can't be used on empty lists"
constructProduct :: HWType -> [TExpr] -> TExpr
constructProduct :: HWType -> [TExpr] -> TExpr
constructProduct HWType
ty [TExpr]
els =
HWType -> Expr -> TExpr
TExpr HWType
ty (HWType -> Modifier -> [Expr] -> Expr
DataCon HWType
ty ((HWType, Int) -> Modifier
DC (HWType
ty,Int
0)) ((TExpr -> Expr) -> [TExpr] -> [Expr]
forall a b. (a -> b) -> [a] -> [b]
map TExpr -> Expr
eex [TExpr]
els))
tuple :: HasCallStack => [TExpr] -> TExpr
tuple :: HasCallStack => [TExpr] -> TExpr
tuple [] = String -> TExpr
forall a. HasCallStack => String -> a
error (String -> TExpr) -> String -> TExpr
forall a b. (a -> b) -> a -> b
$ String
"tuple: Cannot create empty tuple"
tuple [TExpr
_] =
String -> TExpr
forall a. HasCallStack => String -> a
error (String -> TExpr) -> String -> TExpr
forall a b. (a -> b) -> a -> b
$ String
"tuple: Cannot create 1-tuple"
tuple [TExpr]
els = HWType -> [TExpr] -> TExpr
constructProduct HWType
tupTy [TExpr]
els
where
#if MIN_VERSION_base(4,19,0)
tupTy :: HWType
tupTy = Text -> Maybe [Text] -> [HWType] -> HWType
Product (Text
tupModule Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
".Tuple" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Int -> Text
forall a. Show a => a -> Text
showt ([TExpr] -> Int
forall a. [a] -> Int
forall (t :: Type -> Type) a. Foldable t => t a -> Int
length [TExpr]
els)) Maybe [Text]
forall a. Maybe a
Nothing ((TExpr -> HWType) -> [TExpr] -> [HWType]
forall a b. (a -> b) -> [a] -> [b]
map TExpr -> HWType
ety [TExpr]
els)
tupModule :: Text
tupModule =
$(
let tupNm = ''(,)
in case (TH.nameModule tupNm, TH.nameBase tupNm) of
(Just modNm, "Tuple2") -> TH.lift modNm :: TH.ExpQ
_ -> error $ "tuple: (,) has an unexpected name: " <> show tupNm
)
#else
commas = Text.replicate (length els - 1) ","
tupTy = Product (tupModule <> ".(" <> commas <> ")") Nothing (map ety els)
tupModule =
$(
let tupNm = ''(,)
in case (TH.nameModule tupNm, TH.nameBase tupNm) of
(Just modNm, "(,)") -> TH.lift modNm :: TH.ExpQ
_ -> error $ "tuple: (,) has an unexpected name: " <> show tupNm
)
#endif
getStr :: TExpr -> Maybe String
getStr :: TExpr -> Maybe String
getStr (TExpr HWType
_ Expr
e) = Expr -> Maybe String
exprToString Expr
e
getBool :: TExpr -> Maybe Bool
getBool :: TExpr -> Maybe Bool
getBool (TExpr HWType
_ (Literal Maybe (HWType, Int)
_ (BoolLit Bool
b))) = Bool -> Maybe Bool
forall a. a -> Maybe a
Just Bool
b
getBool TExpr
_ = Maybe Bool
forall a. Maybe a
Nothing
getVec :: TExpr -> Maybe [TExpr]
getVec :: TExpr -> Maybe [TExpr]
getVec (TExpr (Void (Just (Vector Int
0 HWType
_) )) Expr
_) =
[TExpr] -> Maybe [TExpr]
forall a. a -> Maybe a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure []
getVec (TExpr (Vector Int
1 HWType
elementTy) (DataCon HWType
_ Modifier
VecAppend [Expr
e])) =
[TExpr] -> Maybe [TExpr]
forall a. a -> Maybe a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure [HWType -> Expr -> TExpr
TExpr HWType
elementTy Expr
e]
getVec (TExpr (Vector Int
n HWType
elementTy) (DataCon HWType
_ Modifier
VecAppend [Expr
e, Expr
es0])) = do
es1 <- TExpr -> Maybe [TExpr]
getVec (HWType -> Expr -> TExpr
TExpr (Int -> HWType -> HWType
Vector (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) HWType
elementTy) Expr
es0)
pure (TExpr elementTy e:es1)
getVec TExpr
_ = Maybe [TExpr]
forall a. Maybe a
Nothing
tExprToInteger :: TExpr -> Maybe Integer
tExprToInteger :: TExpr -> Maybe Integer
tExprToInteger (TExpr HWType
_ Expr
e) = Expr -> Maybe Integer
exprToInteger Expr
e
exprToInteger :: Expr -> Maybe Integer
exprToInteger :: Expr -> Maybe Integer
exprToInteger (DataCon HWType
_ Modifier
_ [Expr
n]) = Expr -> Maybe Integer
exprToInteger Expr
n
exprToInteger (Literal Maybe (HWType, Int)
_ (NumLit Integer
n)) = Integer -> Maybe Integer
forall a. a -> Maybe a
Just Integer
n
exprToInteger Expr
_ = Maybe Integer
forall a. Maybe a
Nothing
bitCoerce ::
(HasCallStack, Backend backend) =>
Text ->
HWType ->
TExpr ->
State (BlockState backend) TExpr
bitCoerce :: forall backend.
(HasCallStack, Backend backend) =>
Text -> HWType -> TExpr -> State (BlockState backend) TExpr
bitCoerce Text
nameHint HWType
destType e :: TExpr
e@(TExpr HWType
ety Expr
_)
| HWType -> Int
forall i. Num i => HWType -> i
tySize HWType
ety Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
/= forall i. Num i => HWType -> i
tySize @Int HWType
destType = String -> State (BlockState backend) TExpr
forall a. HasCallStack => String -> a
error String
"Size mismatch"
| HWType
ety HWType -> HWType -> Bool
forall a. Eq a => a -> a -> Bool
== HWType
destType = TExpr -> State (BlockState backend) TExpr
forall a. a -> StateT (BlockState backend) Identity a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure TExpr
e
| BitVector Int
_ <- HWType
ety = Text -> HWType -> TExpr -> State (BlockState backend) TExpr
forall backend.
(HasCallStack, Backend backend) =>
Text -> HWType -> TExpr -> State (BlockState backend) TExpr
fromBV Text
nameHint HWType
destType TExpr
e
| Bool
otherwise = Text -> HWType -> TExpr -> State (BlockState backend) TExpr
forall backend.
(HasCallStack, Backend backend) =>
Text -> HWType -> TExpr -> State (BlockState backend) TExpr
bitCoerce Text
nameHint HWType
destType (TExpr -> State (BlockState backend) TExpr)
-> State (BlockState backend) TExpr
-> State (BlockState backend) TExpr
forall (m :: Type -> Type) a b. Monad m => (a -> m b) -> m a -> m b
=<< Text -> TExpr -> State (BlockState backend) TExpr
forall backend.
Backend backend =>
Text -> TExpr -> State (BlockState backend) TExpr
toBV Text
nameHint TExpr
e
toBV ::
Backend backend =>
Text ->
TExpr ->
State (BlockState backend) TExpr
toBV :: forall backend.
Backend backend =>
Text -> TExpr -> State (BlockState backend) TExpr
toBV = [Attr Text] -> Text -> TExpr -> State (BlockState backend) TExpr
forall backend.
Backend backend =>
[Attr Text] -> Text -> TExpr -> State (BlockState backend) TExpr
toBvWithAttrs []
toBvWithAttrs ::
Backend backend =>
[Attr Text] ->
Text ->
TExpr ->
State (BlockState backend) TExpr
toBvWithAttrs :: forall backend.
Backend backend =>
[Attr Text] -> Text -> TExpr -> State (BlockState backend) TExpr
toBvWithAttrs [Attr Text]
attrs Text
bvName (TExpr HWType
aTy Expr
aExpr) =
Text -> TExpr -> State (BlockState backend) TExpr
forall backend.
Backend backend =>
Text -> TExpr -> State (BlockState backend) TExpr
assign Text
bvName (TExpr -> State (BlockState backend) TExpr)
-> TExpr -> State (BlockState backend) TExpr
forall a b. (a -> b) -> a -> b
$
HWType -> Expr -> TExpr
TExpr
([Attr Text] -> HWType -> HWType
annotated [Attr Text]
attrs (Int -> HWType
BitVector (HWType -> Int
forall i. Num i => HWType -> i
tySize HWType
aTy)))
(Maybe Identifier -> HWType -> Expr -> Expr
ToBv Maybe Identifier
forall a. Maybe a
Nothing HWType
aTy Expr
aExpr)
fromBV
:: (HasCallStack, Backend backend) =>
Text ->
HWType ->
TExpr ->
State (BlockState backend) TExpr
fromBV :: forall backend.
(HasCallStack, Backend backend) =>
Text -> HWType -> TExpr -> State (BlockState backend) TExpr
fromBV Text
resultName HWType
resultType e :: TExpr
e@TExpr{Expr
eex :: TExpr -> Expr
eex :: Expr
eex, ety :: TExpr -> HWType
ety = BitVector Int
_} =
case HWType
resultType of
BitVector{} -> TExpr -> State (BlockState backend) TExpr
forall a. a -> StateT (BlockState backend) Identity a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure TExpr
e
HWType
_ -> Text -> TExpr -> State (BlockState backend) TExpr
forall backend.
Backend backend =>
Text -> TExpr -> State (BlockState backend) TExpr
assign Text
resultName (HWType -> Expr -> TExpr
TExpr HWType
resultType (Maybe Identifier -> HWType -> Expr -> Expr
FromBv Maybe Identifier
forall a. Maybe a
Nothing HWType
resultType Expr
eex))
fromBV Text
resultName HWType
resultType e :: TExpr
e@TExpr{ety :: TExpr -> HWType
ety = Annotated [Attr Text]
_ bv :: HWType
bv@(BitVector Int
_)} =
case HWType
resultType of
BitVector{} -> TExpr -> State (BlockState backend) TExpr
forall a. a -> StateT (BlockState backend) Identity a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (HWType -> Expr -> TExpr
TExpr HWType
bv (TExpr -> Expr
eex TExpr
e))
HWType
_ -> Text -> TExpr -> State (BlockState backend) TExpr
forall backend.
Backend backend =>
Text -> TExpr -> State (BlockState backend) TExpr
assign Text
resultName (HWType -> Expr -> TExpr
TExpr HWType
resultType (Maybe Identifier -> HWType -> Expr -> Expr
FromBv Maybe Identifier
forall a. Maybe a
Nothing HWType
resultType (TExpr -> Expr
eex TExpr
e)))
fromBV Text
_ HWType
_ TExpr{HWType
ety :: TExpr -> HWType
ety :: HWType
ety} = String -> State (BlockState backend) TExpr
forall a. HasCallStack => String -> a
error (String -> State (BlockState backend) TExpr)
-> String -> State (BlockState backend) TExpr
forall a b. (a -> b) -> a -> b
$ String
"fromBV: expected BitVector, got: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> HWType -> String
forall a. Show a => a -> String
show HWType
ety
clog2 :: Num i => Integer -> i
clog2 :: forall a. Num a => Integer -> a
clog2 = Int -> i
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> i) -> (Integer -> Int) -> Integer -> i
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe Int
0 (Maybe Int -> Int) -> (Integer -> Maybe Int) -> Integer -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Integer -> Integer -> Maybe Int
clogBase Integer
2
tySize :: Num i => HWType -> i
tySize :: forall i. Num i => HWType -> i
tySize = Int -> i
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> i) -> (HWType -> Int) -> HWType -> i
forall b c a. (b -> c) -> (a -> b) -> a -> c
. HWType -> Int
typeSize
data LitHDL
= B Bool
| S String
| I Integer
deriving Int -> LitHDL -> ShowS
[LitHDL] -> ShowS
LitHDL -> String
(Int -> LitHDL -> ShowS)
-> (LitHDL -> String) -> ([LitHDL] -> ShowS) -> Show LitHDL
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> LitHDL -> ShowS
showsPrec :: Int -> LitHDL -> ShowS
$cshow :: LitHDL -> String
show :: LitHDL -> String
$cshowList :: [LitHDL] -> ShowS
showList :: [LitHDL] -> ShowS
Show
instance Num LitHDL where
+ :: LitHDL -> LitHDL -> LitHDL
(+) = LitHDL -> LitHDL -> LitHDL
forall a. HasCallStack => a
undefined
* :: LitHDL -> LitHDL -> LitHDL
(*) = LitHDL -> LitHDL -> LitHDL
forall a. HasCallStack => a
undefined
abs :: LitHDL -> LitHDL
abs = LitHDL -> LitHDL
forall a. HasCallStack => a
undefined
signum :: LitHDL -> LitHDL
signum = LitHDL -> LitHDL
forall a. HasCallStack => a
undefined
negate :: LitHDL -> LitHDL
negate = LitHDL -> LitHDL
forall a. HasCallStack => a
undefined
fromInteger :: Integer -> LitHDL
fromInteger = Integer -> LitHDL
I
instance IsString LitHDL where
fromString :: String -> LitHDL
fromString = String -> LitHDL
S
instHO
:: Backend backend
=> BlackBoxContext
-> Int
-> (HWType, BlackBoxTemplate)
-> [(TExpr, BlackBoxTemplate)]
-> State (BlockState backend) TExpr
instHO :: forall backend.
Backend backend =>
BlackBoxContext
-> Int
-> (HWType, BlackBoxTemplate)
-> [(TExpr, BlackBoxTemplate)]
-> State (BlockState backend) TExpr
instHO BlackBoxContext
bbCtx Int
fPos (HWType
resTy, BlackBoxTemplate
bbResTy) [(TExpr, BlackBoxTemplate)]
argsWithTypes = do
let ([TExpr]
args0, [BlackBoxTemplate]
argTypes) = [(TExpr, BlackBoxTemplate)] -> ([TExpr], [BlackBoxTemplate])
forall a b. [(a, b)] -> ([a], [b])
unzip [(TExpr, BlackBoxTemplate)]
argsWithTypes
fSubPos <- Int -> Maybe Int -> Int
forall a. a -> Maybe a -> a
fromMaybe Int
0 (Maybe Int -> Int)
-> (IntMap Int -> Maybe Int) -> IntMap Int -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> IntMap Int -> Maybe Int
forall a. Int -> IntMap a -> Maybe a
IntMap.lookup Int
fPos (IntMap Int -> Int)
-> StateT (BlockState backend) Identity (IntMap Int)
-> StateT (BlockState backend) Identity Int
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Getting (IntMap Int) (BlockState backend) (IntMap Int)
-> StateT (BlockState backend) Identity (IntMap Int)
forall s (m :: Type -> Type) a.
MonadState s m =>
Getting a s a -> m a
use Getting (IntMap Int) (BlockState backend) (IntMap Int)
forall backend (f :: Type -> Type).
Functor f =>
(IntMap Int -> f (IntMap Int))
-> BlockState backend -> f (BlockState backend)
bsHigherOrderCalls
bsHigherOrderCalls %= IntMap.insert fPos (succ fSubPos)
let
ctxName = [Text] -> Text
forall a. HasCallStack => [a] -> a
last ((Char -> Bool) -> Text -> [Text]
Text.split (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
==Char
'.') (BlackBoxContext -> Text
bbName BlackBoxContext
bbCtx))
baseArgName = Text
ctxName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"ho" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Int -> Text
forall a. Show a => a -> Text
showt Int
fPos Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Int -> Text
forall a. Show a => a -> Text
showt Int
fSubPos
argName a
n = Text
baseArgName Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_arg" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> a -> Text
forall a. Show a => a -> Text
showt a
n
args1 <- zipWithM (\Int
argN -> Text -> TExpr -> StateT (BlockState backend) Identity Identifier
forall backend.
Backend backend =>
Text -> TExpr -> State (BlockState backend) Identifier
toIdentifier' (Int -> Text
forall a. Show a => a -> Text
argName Int
argN)) [(0::Int)..] args0
let
args2 = (Identifier -> BlackBoxTemplate)
-> [Identifier] -> [BlackBoxTemplate]
forall a b. (a -> b) -> [a] -> [b]
map (Element -> BlackBoxTemplate
forall a. a -> [a]
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (Element -> BlackBoxTemplate)
-> (Identifier -> Element) -> Identifier -> BlackBoxTemplate
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Element
Text (Text -> Element) -> (Identifier -> Text) -> Identifier -> Element
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Identifier -> Text
Id.toLazyText) [Identifier]
args1
resName <- declare' (ctxName <> "_" <> "ho" <> showt fPos <> "_"
<> showt fSubPos <> "_res") resTy
let res = ([Text -> Element
Text (Identifier -> Text
Id.toLazyText Identifier
resName)], BlackBoxTemplate
bbResTy)
let component = Decl -> Element
Component (Int -> Int -> [(BlackBoxTemplate, BlackBoxTemplate)] -> Decl
Decl Int
fPos Int
fSubPos ((BlackBoxTemplate, BlackBoxTemplate)
res(BlackBoxTemplate, BlackBoxTemplate)
-> [(BlackBoxTemplate, BlackBoxTemplate)]
-> [(BlackBoxTemplate, BlackBoxTemplate)]
forall a. a -> [a] -> [a]
:[BlackBoxTemplate]
-> [BlackBoxTemplate] -> [(BlackBoxTemplate, BlackBoxTemplate)]
forall a b. [a] -> [b] -> [(a, b)]
zip [BlackBoxTemplate]
args2 [BlackBoxTemplate]
argTypes))
rendered0 <-
zoom bsBackend (string =<< (renderElem bbCtx component <*> pure 0))
let
layout = PageWidth -> LayoutOptions
LayoutOptions (Int -> Double -> PageWidth
AvailablePerLine Int
120 Double
0.4)
rendered1 = SimpleDocStream () -> Text
forall ann. SimpleDocStream ann -> Text
renderLazy (LayoutOptions -> Doc -> SimpleDocStream ()
forall ann. LayoutOptions -> Doc ann -> SimpleDocStream ann
layoutPretty LayoutOptions
layout Doc
rendered0)
addDeclaration $
BlackBoxD
("__INST_" <> bbName bbCtx <> "_BB_INTERNAL__") [] [] []
(BBTemplate [Text rendered1])
(emptyBBContext ("__INST_" <> bbName bbCtx <> "_BB_INTERNAL__"))
pure (TExpr resTy (Identifier resName Nothing))
compInBlock
:: forall backend
. Backend backend
=> Text
-> [(Text, HWType)]
-> [(Text, HWType)]
-> State (BlockState backend) ()
compInBlock :: forall backend.
Backend backend =>
Text
-> [(Text, HWType)]
-> [(Text, HWType)]
-> State (BlockState backend) ()
compInBlock Text
compName [(Text, HWType)]
inPorts0 [(Text, HWType)]
outPorts0 =
Declaration -> State (BlockState backend) ()
forall backend. Declaration -> State (BlockState backend) ()
addDeclaration (Text -> [(Text, PortDirection, HWType)] -> Declaration
CompDecl Text
compName ([(Text, PortDirection, HWType)]
inPorts1 [(Text, PortDirection, HWType)]
-> [(Text, PortDirection, HWType)]
-> [(Text, PortDirection, HWType)]
forall a. [a] -> [a] -> [a]
++ [(Text, PortDirection, HWType)]
outPorts1))
where
mkPort :: b -> (a, c) -> (a, b, c)
mkPort b
inOut (a
nm, c
ty) = (a
nm, b
inOut, c
ty)
inPorts1 :: [(Text, PortDirection, HWType)]
inPorts1 = PortDirection -> (Text, HWType) -> (Text, PortDirection, HWType)
forall {b} {a} {c}. b -> (a, c) -> (a, b, c)
mkPort PortDirection
In ((Text, HWType) -> (Text, PortDirection, HWType))
-> [(Text, HWType)] -> [(Text, PortDirection, HWType)]
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> [(Text, HWType)]
inPorts0
outPorts1 :: [(Text, PortDirection, HWType)]
outPorts1 = PortDirection -> (Text, HWType) -> (Text, PortDirection, HWType)
forall {b} {a} {c}. b -> (a, c) -> (a, b, c)
mkPort PortDirection
Out ((Text, HWType) -> (Text, PortDirection, HWType))
-> [(Text, HWType)] -> [(Text, PortDirection, HWType)]
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> [(Text, HWType)]
outPorts0
litTExpr :: LitHDL -> TExpr
litTExpr :: LitHDL -> TExpr
litTExpr (B Bool
b) = HWType -> Expr -> TExpr
TExpr HWType
Bool (Maybe (HWType, Int) -> Literal -> Expr
Literal Maybe (HWType, Int)
forall a. Maybe a
Nothing (Bool -> Literal
BoolLit Bool
b))
litTExpr (S String
s) = HWType -> Expr -> TExpr
TExpr HWType
String (Maybe (HWType, Int) -> Literal -> Expr
Literal Maybe (HWType, Int)
forall a. Maybe a
Nothing (String -> Literal
StringLit String
s))
litTExpr (I Integer
i) = HWType -> Expr -> TExpr
TExpr HWType
Integer (Maybe (HWType, Int) -> Literal -> Expr
Literal Maybe (HWType, Int)
forall a. Maybe a
Nothing (Integer -> Literal
NumLit Integer
i))
instDecl
:: forall backend
. Backend backend
=> EntityOrComponent
-> Identifier
-> Identifier
-> [(Text, TExpr)]
-> [(Text, TExpr)]
-> [(Text, TExpr)]
-> State (BlockState backend) ()
instDecl :: forall backend.
Backend backend =>
EntityOrComponent
-> Identifier
-> Identifier
-> [(Text, TExpr)]
-> [(Text, TExpr)]
-> [(Text, TExpr)]
-> State (BlockState backend) ()
instDecl EntityOrComponent
entOrComp Identifier
compName Identifier
instLbl [(Text, TExpr)]
params [(Text, TExpr)]
inPorts [(Text, TExpr)]
outPorts = do
inPorts' <- ((Text, TExpr)
-> StateT
(BlockState backend) Identity (Expr, PortDirection, HWType, Expr))
-> [(Text, TExpr)]
-> StateT
(BlockState backend) Identity [(Expr, PortDirection, HWType, Expr)]
forall (t :: Type -> Type) (m :: Type -> Type) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
forall (m :: Type -> Type) a b.
Monad m =>
(a -> m b) -> [a] -> m [b]
mapM (PortDirection
-> (Text, TExpr)
-> StateT
(BlockState backend) Identity (Expr, PortDirection, HWType, Expr)
mkPort PortDirection
In) [(Text, TExpr)]
inPorts
outPorts' <- mapM (mkPort Out) outPorts
addDeclaration $
InstDecl
entOrComp Nothing [] compName instLbl (mkParams params)
(NamedPortMap (inPorts' ++ outPorts'))
where
mkPort
:: PortDirection
-> (Text, TExpr)
-> StateT (BlockState backend) Identity (Expr, PortDirection, HWType, Expr)
mkPort :: PortDirection
-> (Text, TExpr)
-> StateT
(BlockState backend) Identity (Expr, PortDirection, HWType, Expr)
mkPort PortDirection
inOrOut (Text
nmText, TExpr
pExpr) = do
TExpr ty pExpr' <- Text -> TExpr -> State (BlockState backend) TExpr
forall backend.
Backend backend =>
Text -> TExpr -> State (BlockState backend) TExpr
toIdentifier (Text
nmText Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_port") TExpr
pExpr
pure (Identifier (Id.unsafeMake nmText) Nothing, inOrOut, ty, pExpr')
mkParams :: [(Text.Text, TExpr)] -> [(Expr, HWType, Expr)]
mkParams :: [(Text, TExpr)] -> [(Expr, HWType, Expr)]
mkParams = ((Text, TExpr) -> (Expr, HWType, Expr))
-> [(Text, TExpr)] -> [(Expr, HWType, Expr)]
forall a b. (a -> b) -> [a] -> [b]
map (((Text, TExpr) -> (Expr, HWType, Expr))
-> [(Text, TExpr)] -> [(Expr, HWType, Expr)])
-> ((Text, TExpr) -> (Expr, HWType, Expr))
-> [(Text, TExpr)]
-> [(Expr, HWType, Expr)]
forall a b. (a -> b) -> a -> b
$ \(Text
paramName, TExpr
texpr) ->
( Identifier -> Maybe Modifier -> Expr
Identifier (HasCallStack => Text -> Identifier
Text -> Identifier
Id.unsafeMake Text
paramName) Maybe Modifier
forall a. Maybe a
Nothing
, TExpr -> HWType
ety TExpr
texpr
, TExpr -> Expr
eex TExpr
texpr )
viaAnnotatedSignal
:: (HasCallStack, Backend backend)
=> Identifier
-> TExpr
-> TExpr
-> [Attr Text]
-> State (BlockState backend) ()
viaAnnotatedSignal :: forall backend.
(HasCallStack, Backend backend) =>
Identifier
-> TExpr -> TExpr -> [Attr Text] -> State (BlockState backend) ()
viaAnnotatedSignal Identifier
sigNm (TExpr HWType
fromTy Expr
fromExpr) (TExpr HWType
toTy (Identifier Identifier
outNm Maybe Modifier
Nothing)) [Attr Text]
attrs
| HWType
fromTy HWType -> HWType -> Bool
forall a. Eq a => a -> a -> Bool
== HWType
toTy = do
Declaration -> State (BlockState backend) ()
forall backend. Declaration -> State (BlockState backend) ()
addDeclaration (Maybe Text -> Identifier -> HWType -> Declaration
NetDecl Maybe Text
forall a. Maybe a
Nothing Identifier
sigNm ([Attr Text] -> HWType -> HWType
Annotated [Attr Text]
attrs HWType
fromTy))
Declaration -> State (BlockState backend) ()
forall backend. Declaration -> State (BlockState backend) ()
addDeclaration (Identifier -> Usage -> Expr -> Declaration
Assignment Identifier
sigNm Usage
Cont Expr
fromExpr)
Declaration -> State (BlockState backend) ()
forall backend. Declaration -> State (BlockState backend) ()
addDeclaration (Identifier -> Usage -> Expr -> Declaration
Assignment Identifier
outNm Usage
Cont (Identifier -> Maybe Modifier -> Expr
Identifier Identifier
sigNm Maybe Modifier
forall a. Maybe a
Nothing))
viaAnnotatedSignal Identifier
_ TExpr
inTExpr outTExpr :: TExpr
outTExpr@(TExpr HWType
_ (Identifier Identifier
_ Maybe Modifier
_)) [Attr Text]
_ =
String -> State (BlockState backend) ()
forall a. HasCallStack => String -> a
error (String -> State (BlockState backend) ())
-> String -> State (BlockState backend) ()
forall a b. (a -> b) -> a -> b
$ String
"viaAnnotatedSignal: The in and out expressions \"" String -> ShowS
forall a. Semigroup a => a -> a -> a
<> TExpr -> String
forall a. Show a => a -> String
show TExpr
inTExpr String -> ShowS
forall a. Semigroup a => a -> a -> a
<>
String
"\" and \"" String -> ShowS
forall a. Semigroup a => a -> a -> a
<> TExpr -> String
forall a. Show a => a -> String
show TExpr
outTExpr String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
"\" have non-matching types."
viaAnnotatedSignal Identifier
_ TExpr
_ TExpr
outTExpr [Attr Text]
_ =
String -> State (BlockState backend) ()
forall a. HasCallStack => String -> a
error (String -> State (BlockState backend) ())
-> String -> State (BlockState backend) ()
forall a b. (a -> b) -> a -> b
$ String
"viaAnnotatedSignal: The out expression \"" String -> ShowS
forall a. Semigroup a => a -> a -> a
<> TExpr -> String
forall a. Show a => a -> String
show TExpr
outTExpr String -> ShowS
forall a. Semigroup a => a -> a -> a
<>
String
"\" must be an Identifier."
tInputs :: BlackBoxContext -> [(TExpr, HWType)]
tInputs :: BlackBoxContext -> [(TExpr, HWType)]
tInputs = ((Expr, HWType, Bool) -> (TExpr, HWType))
-> [(Expr, HWType, Bool)] -> [(TExpr, HWType)]
forall a b. (a -> b) -> [a] -> [b]
map (\(Expr
x, HWType
t, Bool
_) -> (HWType -> Expr -> TExpr
TExpr HWType
t Expr
x, HWType
t)) ([(Expr, HWType, Bool)] -> [(TExpr, HWType)])
-> (BlackBoxContext -> [(Expr, HWType, Bool)])
-> BlackBoxContext
-> [(TExpr, HWType)]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. BlackBoxContext -> [(Expr, HWType, Bool)]
bbInputs
tResults :: BlackBoxContext -> [TExpr]
tResults :: BlackBoxContext -> [TExpr]
tResults = ((Expr, HWType) -> TExpr) -> [(Expr, HWType)] -> [TExpr]
forall a b. (a -> b) -> [a] -> [b]
map (\(Expr
x,HWType
t) -> HWType -> Expr -> TExpr
TExpr HWType
t Expr
x) ([(Expr, HWType)] -> [TExpr])
-> (BlackBoxContext -> [(Expr, HWType)])
-> BlackBoxContext
-> [TExpr]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. BlackBoxContext -> [(Expr, HWType)]
bbResults
toIdentifier'
:: Backend backend
=> Text
-> TExpr
-> State (BlockState backend) Identifier
toIdentifier' :: forall backend.
Backend backend =>
Text -> TExpr -> State (BlockState backend) Identifier
toIdentifier' Text
_ (TExpr HWType
_ (Identifier Identifier
aExpr Maybe Modifier
Nothing)) = Identifier -> StateT (BlockState backend) Identity Identifier
forall a. a -> StateT (BlockState backend) Identity a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure Identifier
aExpr
toIdentifier' Text
nm TExpr
texp = do
t <- Text -> TExpr -> State (BlockState backend) TExpr
forall backend.
Backend backend =>
Text -> TExpr -> State (BlockState backend) TExpr
assign Text
nm TExpr
texp
let nm' = case TExpr
t of
TExpr HWType
_ (Identifier Identifier
x Maybe Modifier
Nothing) -> Identifier
x
TExpr
t' -> String -> Identifier
forall a. HasCallStack => String -> a
error (String
"toIdentifier' expected an Identifier, but got: " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> TExpr -> String
forall a. Show a => a -> String
show TExpr
t')
pure nm'
toIdentifier
:: Backend backend
=> Text
-> TExpr
-> State (BlockState backend) TExpr
toIdentifier :: forall backend.
Backend backend =>
Text -> TExpr -> State (BlockState backend) TExpr
toIdentifier Text
nm TExpr
texp = do
id' <- Text -> TExpr -> State (BlockState backend) Identifier
forall backend.
Backend backend =>
Text -> TExpr -> State (BlockState backend) Identifier
toIdentifier' Text
nm TExpr
texp
pure (TExpr (ety texp) (Identifier id' Nothing))
andExpr
:: Backend backend
=> Text
-> TExpr
-> TExpr
-> State (BlockState backend) TExpr
andExpr :: forall backend.
Backend backend =>
Text -> TExpr -> TExpr -> State (BlockState backend) TExpr
andExpr Text
_ TExpr
T TExpr
bExpr = TExpr -> StateT (BlockState backend) Identity TExpr
forall a. a -> StateT (BlockState backend) Identity a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure TExpr
bExpr
andExpr Text
_ TExpr
F TExpr
_ = TExpr -> StateT (BlockState backend) Identity TExpr
forall a. a -> StateT (BlockState backend) Identity a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure TExpr
F
andExpr Text
_ TExpr
aExpr TExpr
T = TExpr -> StateT (BlockState backend) Identity TExpr
forall a. a -> StateT (BlockState backend) Identity a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure TExpr
aExpr
andExpr Text
_ TExpr
_ TExpr
F = TExpr -> StateT (BlockState backend) Identity TExpr
forall a. a -> StateT (BlockState backend) Identity a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure TExpr
F
andExpr Text
nm TExpr
a TExpr
b = do
aIdent <- Identifier -> Text
Id.toText (Identifier -> Text)
-> StateT (BlockState backend) Identity Identifier
-> StateT (BlockState backend) Identity Text
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> TExpr -> StateT (BlockState backend) Identity Identifier
forall backend.
Backend backend =>
Text -> TExpr -> State (BlockState backend) Identifier
toIdentifier' (Text
nm Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_a") TExpr
a
bIdent <- Id.toText <$> toIdentifier' (nm <> "_b") b
andTxt <-
uses bsBackend hdlKind <&> \case
HDL
VHDL -> Text
aIdent Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" and " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
bIdent
HDL
Verilog -> Text
aIdent Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" && " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
bIdent
HDL
SystemVerilog -> Text
aIdent Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" && " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
bIdent
assign nm $ TExpr Bool (Identifier (Id.unsafeMake andTxt) Nothing)
unsafeToActiveHigh
:: Backend backend
=> Text
-> TExpr
-> State (BlockState backend) TExpr
unsafeToActiveHigh :: forall backend.
Backend backend =>
Text -> TExpr -> State (BlockState backend) TExpr
unsafeToActiveHigh Text
nm TExpr
rExpr = do
resetLevel <- VDomainConfiguration -> ResetPolarity
vResetPolarity (VDomainConfiguration -> ResetPolarity)
-> StateT (BlockState backend) Identity VDomainConfiguration
-> StateT (BlockState backend) Identity ResetPolarity
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> State backend VDomainConfiguration
-> StateT (BlockState backend) Identity VDomainConfiguration
forall backend a.
Backend backend =>
State backend a -> State (BlockState backend) a
liftToBlockState (HWType -> State backend VDomainConfiguration
forall backend.
(Backend backend, HasCallStack) =>
HWType -> State backend VDomainConfiguration
getDomainConf (TExpr -> HWType
ety TExpr
rExpr))
case resetLevel of
ResetPolarity
ActiveHigh -> TExpr -> StateT (BlockState backend) Identity TExpr
forall a. a -> StateT (BlockState backend) Identity a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure TExpr
rExpr
ResetPolarity
ActiveLow -> Text -> TExpr -> StateT (BlockState backend) Identity TExpr
forall backend.
Backend backend =>
Text -> TExpr -> State (BlockState backend) TExpr
notExpr Text
nm TExpr
rExpr
unsafeToActiveLow
:: Backend backend
=> Text
-> TExpr
-> State (BlockState backend) TExpr
unsafeToActiveLow :: forall backend.
Backend backend =>
Text -> TExpr -> State (BlockState backend) TExpr
unsafeToActiveLow Text
nm TExpr
rExpr = do
resetLevel <- VDomainConfiguration -> ResetPolarity
vResetPolarity (VDomainConfiguration -> ResetPolarity)
-> StateT (BlockState backend) Identity VDomainConfiguration
-> StateT (BlockState backend) Identity ResetPolarity
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> State backend VDomainConfiguration
-> StateT (BlockState backend) Identity VDomainConfiguration
forall backend a.
Backend backend =>
State backend a -> State (BlockState backend) a
liftToBlockState (HWType -> State backend VDomainConfiguration
forall backend.
(Backend backend, HasCallStack) =>
HWType -> State backend VDomainConfiguration
getDomainConf (TExpr -> HWType
ety TExpr
rExpr))
case resetLevel of
ResetPolarity
ActiveLow -> TExpr -> StateT (BlockState backend) Identity TExpr
forall a. a -> StateT (BlockState backend) Identity a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure TExpr
rExpr
ResetPolarity
ActiveHigh -> Text -> TExpr -> StateT (BlockState backend) Identity TExpr
forall backend.
Backend backend =>
Text -> TExpr -> State (BlockState backend) TExpr
notExpr Text
nm TExpr
rExpr
notExpr
:: Backend backend
=> Text
-> TExpr
-> State (BlockState backend) TExpr
notExpr :: forall backend.
Backend backend =>
Text -> TExpr -> State (BlockState backend) TExpr
notExpr Text
_ TExpr
T = TExpr -> StateT (BlockState backend) Identity TExpr
forall a. a -> StateT (BlockState backend) Identity a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure TExpr
F
notExpr Text
_ TExpr
F = TExpr -> StateT (BlockState backend) Identity TExpr
forall a. a -> StateT (BlockState backend) Identity a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure TExpr
T
notExpr Text
nm TExpr
aExpr = do
aIdent <- Identifier -> Text
Id.toText (Identifier -> Text)
-> StateT (BlockState backend) Identity Identifier
-> StateT (BlockState backend) Identity Text
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> TExpr -> StateT (BlockState backend) Identity Identifier
forall backend.
Backend backend =>
Text -> TExpr -> State (BlockState backend) Identifier
toIdentifier' (Text
nm Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"_a") TExpr
aExpr
notTxt <- uses bsBackend hdlKind <&> \case
HDL
VHDL -> Text
"not " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
aIdent
HDL
Verilog -> Text
"! " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
aIdent
HDL
SystemVerilog -> Text
"! " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
aIdent
assign nm $ TExpr Bit (Identifier (Id.unsafeMake notTxt) Nothing)
pureToBV
:: Text
-> Int
-> TExpr
-> State (BlockState VHDLState) TExpr
pureToBV :: Text -> Int -> TExpr -> State (BlockState VHDLState) TExpr
pureToBV Text
nm Int
n TExpr
arg = do
arg' <- Identifier -> Text
Id.toText (Identifier -> Text)
-> StateT (BlockState VHDLState) Identity Identifier
-> StateT (BlockState VHDLState) Identity Text
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> TExpr -> StateT (BlockState VHDLState) Identity Identifier
forall backend.
Backend backend =>
Text -> TExpr -> State (BlockState backend) Identifier
toIdentifier' Text
nm TExpr
arg
let text = Text
"(0 to " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Int -> Text
forall a. Show a => a -> Text
showt Int
n Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
" => " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
arg' Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")"
assign nm $ TExpr (BitVector (n+1)) (Identifier (Id.unsafeMake text) Nothing)
pureToBVResized
:: Text
-> Int
-> TExpr
-> State (BlockState VHDLState) TExpr
pureToBVResized :: Text -> Int -> TExpr -> State (BlockState VHDLState) TExpr
pureToBVResized Text
nm Int
n TExpr
arg = do
arg' <- Identifier -> Text
Id.toText (Identifier -> Text)
-> StateT (BlockState VHDLState) Identity Identifier
-> StateT (BlockState VHDLState) Identity Text
forall (f :: Type -> Type) a b. Functor f => (a -> b) -> f a -> f b
<$> Text -> TExpr -> StateT (BlockState VHDLState) Identity Identifier
forall backend.
Backend backend =>
Text -> TExpr -> State (BlockState backend) Identifier
toIdentifier' Text
nm TExpr
arg
let text = Text
"std_logic_vector(resize(" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
arg' Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
", " Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Int -> Text
forall a. Show a => a -> Text
showt Int
n Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
"))"
assign nm $ TExpr (BitVector n) (Identifier (Id.unsafeMake text) Nothing)
open
:: Backend backend
=> HWType
-> State (BlockState backend) TExpr
open :: forall backend.
Backend backend =>
HWType -> State (BlockState backend) TExpr
open HWType
hwType = TExpr -> StateT (BlockState backend) Identity TExpr
forall a. a -> StateT (BlockState backend) Identity a
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (TExpr -> StateT (BlockState backend) Identity TExpr)
-> TExpr -> StateT (BlockState backend) Identity TExpr
forall a b. (a -> b) -> a -> b
$ HWType -> Expr -> TExpr
TExpr HWType
hwType (Identifier -> Maybe Modifier -> Expr
Identifier (HasCallStack => Text -> Identifier
Text -> Identifier
Id.unsafeMake Text
"open") Maybe Modifier
forall a. Maybe a
Nothing)