{-|
Copyright  :  (C) 2015-2016, University of Twente,
                  2017     , Google Inc.,
                  2021-2022, QBayLogic B.V.
License    :  BSD2 (see the file LICENSE)
Maintainer :  QBayLogic B.V. <devops@qbaylogic.com>

'TopEntity' annotations allow us to control hierarchy and naming aspects of the
Clash compiler. We have the 'Synthesize' and 'TestBench' annotation.

=== 'Synthesize' annotation

The 'Synthesize' annotation allows us to:

    * Assign names to entities (VHDL) \/ modules ((System)Verilog), and their
      ports.
    * Put generated HDL files of a logical (sub)entity in their own directory.
    * Use cached versions of generated HDL, i.e., prevent recompilation of
      (sub)entities that have not changed since the last run. Caching is based
      on a @.manifest@ which is generated alongside the HDL; deleting this file
      means deleting the cache; changing this file will result in /undefined/
      behavior.

Functions with a 'Synthesize' annotation must adhere to the following
restrictions:

    * Although functions with a 'Synthesize' annotation can of course depend
      on functions with another 'Synthesize' annotation, they must not be
      mutually recursive.
    * Functions with a 'Synthesize' annotation must be completely /monomorphic/
      and /first-order/, and cannot have any /non-representable/ arguments or
      result.

Also take the following into account when using 'Synthesize' annotations.

    * The Clash compiler is based on the GHC Haskell compiler, and the GHC
      machinery does not understand 'Synthesize' annotations and it might
      subsequently decide to inline those functions. You should therefor also
      add a @{\-\# NOINLINE f \#-\}@ pragma to the functions which you give
      a 'Synthesize' functions.
    * Functions with a 'Synthesize' annotation will not be specialized
      on constants.

Finally, the root module, the module which you pass as an argument to the
Clash compiler must either have:

    * A function with a 'Synthesize' annotation.
    * A function called /topEntity/.

You apply 'Synthesize' annotations to functions using an @ANN@ pragma:

@
{\-\# ANN f (Synthesize {t_name = ..., ...  }) \#-\}
f x = ...
@

For example, given the following specification:

@
module Blinker where

import Clash.Prelude
import Clash.Intel.ClockGen

'Clash.Explicit.Signal.createDomain' vSystem{vName=\"DomInput\", vPeriod=20000}
'Clash.Explicit.Signal.createDomain' vSystem{vName=\"Dom50\", vPeriod=50000}

topEntity
  :: Clock DomInput
  -> Reset DomInput
  -> Enable Dom50
  -> Signal Dom50 Bit
  -> Signal Dom50 (BitVector 8)
topEntity clk20 rstBtn enaBtn modeBtn =
  'Clash.Signal.exposeClockResetEnable'
    ('Clash.Prelude.mealy' blinkerT initialStateBlinkerT . 'Clash.Prelude.isRising' 1)
    clk50
    rstSync
    enaBtn
    modeBtn
 where
  -- Start with the first LED turned on, in rotate mode, with the counter on zero
  initialStateBlinkerT = (1, False, 0)

  -- Signal coming from the reset button is low when pressed, and high when
  -- not pressed. We convert this signal to the polarity of our domain with
  -- /unsafeFromLowPolarity/.
  rst = 'Clash.Signal.unsafeFromLowPolarity' ('Clash.Signal.unsafeFromReset' rstBtn)

  -- Instantiate a PLL: this stabilizes the incoming clock signal and indicates
  -- when the signal is stable. We're also using it to transform an incoming
  -- clock signal running at 20 MHz to a clock signal running at 50 MHz.
  (clk50, pllStable) =
    'Clash.Intel.ClockGen.altpll'
      \@Dom50
      (SSymbol @"altpll50")
      clk20
      rst

  -- Synchronize reset to clock signal coming from PLL. We want the reset to
  -- remain active while the PLL is NOT stable, hence the conversion with
  -- /unsafeFromLowPolarity/
  rstSync =
    'Clash.Prelude.resetSynchronizer'
      clk50
      ('Clash.Signal.unsafeFromLowPolarity' pllStable)

blinkerT
  :: (BitVector 8, Bool, Index 16650001)
  -> Bool
  -> ((BitVector 8, Bool, Index 16650001), BitVector 8)
blinkerT (leds,mode,cntr) key1R = ((leds',mode',cntr'),leds)
  where
    -- clock frequency = 50e6  (50 MHz)
    -- led update rate = 333e-3 (every 333ms)
    cnt_max = 16650000 -- 50e6 * 333e-3

    cntr' | cntr == cnt_max = 0
          | otherwise       = cntr + 1

    mode' | key1R     = not mode
          | otherwise = mode

    leds' | cntr == 0 = if mode then complement leds
                                else rotateL leds 1
          | otherwise = leds
@

The Clash compiler would normally generate the following
@topEntity.vhdl@ file:

@
-- Automatically generated VHDL-93
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use IEEE.MATH_REAL.ALL;
use std.textio.all;
use work.all;
use work.Blinker_topEntity_types.all;

entity topEntity is
  port(-- clock
       clk20   : in Blinker_topEntity_types.clk_DomInput;
       -- reset
       rstBtn  : in Blinker_topEntity_types.rst_DomInput;
       -- enable
       enaBtn  : in Blinker_topEntity_types.en_Dom50;
       modeBtn : in std_logic;
       result  : out std_logic_vector(7 downto 0));
end;

architecture structural of topEntity is
  ...
end;
@

However, if we add the following 'Synthesize' annotation in the file:

@
{\-\# ANN topEntity
  ('Synthesize'
    { t_name   = "blinker"
    , t_inputs = [ PortName \"CLOCK_50\"
                 , PortName \"KEY0\"
                 , PortName \"KEY1\"
                 , PortName \"KEY2\" ]
    , t_output = PortName \"LED\"
    }) \#-\}
@

The Clash compiler will generate the following @blinker.vhdl@ file instead:

@
-- Automatically generated VHDL-93
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
use IEEE.MATH_REAL.ALL;
use std.textio.all;
use work.all;
use work.blinker_types.all;

entity blinker is
  port(-- clock
       CLOCK_50 : in blinker_types.clk_DomInput;
       -- reset
       KEY0     : in blinker_types.rst_DomInput;
       -- enable
       KEY1     : in blinker_types.en_Dom50;
       KEY2     : in std_logic;
       LED      : out std_logic_vector(7 downto 0));
end;

architecture structural of blinker is
  ...
end;
@

Where we now have:

* A top-level component that is called @blinker@.
* Inputs and outputs that have a /user/-chosen name: @CLOCK_50@, @KEY0@, @KEY1@, @KEY2@, @LED@, etc.

See the documentation of 'Synthesize' for the meaning of all its fields.

=== 'TestBench' annotation

Tell what binder is the test bench for a 'Synthesize'-annotated binder.

@
entityBeingTested :: ...
entityBeingTested = ...
{\-\# NOINLINE entityBeingTested \#-\}
{\-\# ANN entityBeingTested (defSyn "entityBeingTested") \#-\}


myTestBench :: Signal System Bool
myTestBench = ... entityBeingTested ...
{\-\# NOINLINE myTestBench \#-\}
{\-\# ANN myTestBench (TestBench \'entityBeingTested) \#-\}
@

The 'TestBench' annotation actually already implies a 'Synthesize' annotation on
the device under test, so the 'defSyn' in the example could have been omitted.
We recommend you supply 'defSyn' explicitly nonetheless. In any case, it will
still need the @NOINLINE@ annotation.
-}

{-# LANGUAGE CPP #-}
{-# LANGUAGE TemplateHaskellQuotes #-}

{-# LANGUAGE Safe #-}

{-# OPTIONS_HADDOCK show-extensions #-}

module Clash.Annotations.TopEntity
  ( -- * Data types
    TopEntity (..)
  , PortName (..)
    -- * Convenience functions
  , defSyn
  )
where

import           GHC.Generics
import qualified Language.Haskell.TH        as TH
import           Language.Haskell.TH.Syntax (Lift(..))
#if MIN_VERSION_template_haskell(2,16,0)
import           Language.Haskell.TH.Compat
#endif
import           Data.Data

-- | TopEntity annotation
data TopEntity
  -- | Instruct the Clash compiler to use this top-level function as a separately
  -- synthesizable component.
  = Synthesize
  { TopEntity -> String
t_name    :: String
  -- ^ The name the top-level component should have, put in a correspondingly
  -- named file.
  , TopEntity -> [PortName]
t_inputs  :: [PortName]
  -- ^ List of names that are assigned in-order to the inputs of the component.
  , TopEntity -> PortName
t_output  :: PortName
  -- ^ Name assigned in-order to the outputs of the component. As a Haskell
  -- function can only truly return a single value -- with multiple values
  -- \"wrapped\" by a tuple -- this field is not a list, but a single
  -- @'PortName'@. Use @'PortProduct'@ to give names to the individual components
  -- of the output tuple.
  }
  -- | Tell what binder is the 'TestBench' for a 'Synthesize'-annotated binder.
  --
  -- @
  -- {\-\# NOINLINE myTestBench \#-\}
  -- {\-\# ANN myTestBench (TestBench \'entityBeingTested) \#-\}
  -- @
  | TestBench TH.Name
  deriving (TopEntity -> TopEntity -> Bool
(TopEntity -> TopEntity -> Bool)
-> (TopEntity -> TopEntity -> Bool) -> Eq TopEntity
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: TopEntity -> TopEntity -> Bool
$c/= :: TopEntity -> TopEntity -> Bool
== :: TopEntity -> TopEntity -> Bool
$c== :: TopEntity -> TopEntity -> Bool
Eq,Typeable TopEntity
DataType
Constr
Typeable TopEntity
-> (forall (c :: Type -> Type).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> TopEntity -> c TopEntity)
-> (forall (c :: Type -> Type).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c TopEntity)
-> (TopEntity -> Constr)
-> (TopEntity -> DataType)
-> (forall (t :: Type -> Type) (c :: Type -> Type).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c TopEntity))
-> (forall (t :: Type -> Type -> Type) (c :: Type -> Type).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c TopEntity))
-> ((forall b. Data b => b -> b) -> TopEntity -> TopEntity)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> TopEntity -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> TopEntity -> r)
-> (forall u. (forall d. Data d => d -> u) -> TopEntity -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> TopEntity -> u)
-> (forall (m :: Type -> Type).
    Monad m =>
    (forall d. Data d => d -> m d) -> TopEntity -> m TopEntity)
-> (forall (m :: Type -> Type).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> TopEntity -> m TopEntity)
-> (forall (m :: Type -> Type).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> TopEntity -> m TopEntity)
-> Data TopEntity
TopEntity -> DataType
TopEntity -> Constr
(forall b. Data b => b -> b) -> TopEntity -> TopEntity
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> TopEntity -> c TopEntity
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c TopEntity
forall a.
Typeable a
-> (forall (c :: Type -> Type).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: Type -> Type).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: Type -> Type) (c :: Type -> Type).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: Type -> Type -> Type) (c :: Type -> Type).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: Type -> Type).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: Type -> Type).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: Type -> Type).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> TopEntity -> u
forall u. (forall d. Data d => d -> u) -> TopEntity -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> TopEntity -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> TopEntity -> r
forall (m :: Type -> Type).
Monad m =>
(forall d. Data d => d -> m d) -> TopEntity -> m TopEntity
forall (m :: Type -> Type).
MonadPlus m =>
(forall d. Data d => d -> m d) -> TopEntity -> m TopEntity
forall (c :: Type -> Type).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c TopEntity
forall (c :: Type -> Type).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> TopEntity -> c TopEntity
forall (t :: Type -> Type) (c :: Type -> Type).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c TopEntity)
forall (t :: Type -> Type -> Type) (c :: Type -> Type).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c TopEntity)
$cTestBench :: Constr
$cSynthesize :: Constr
$tTopEntity :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> TopEntity -> m TopEntity
$cgmapMo :: forall (m :: Type -> Type).
MonadPlus m =>
(forall d. Data d => d -> m d) -> TopEntity -> m TopEntity
gmapMp :: (forall d. Data d => d -> m d) -> TopEntity -> m TopEntity
$cgmapMp :: forall (m :: Type -> Type).
MonadPlus m =>
(forall d. Data d => d -> m d) -> TopEntity -> m TopEntity
gmapM :: (forall d. Data d => d -> m d) -> TopEntity -> m TopEntity
$cgmapM :: forall (m :: Type -> Type).
Monad m =>
(forall d. Data d => d -> m d) -> TopEntity -> m TopEntity
gmapQi :: Int -> (forall d. Data d => d -> u) -> TopEntity -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> TopEntity -> u
gmapQ :: (forall d. Data d => d -> u) -> TopEntity -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> TopEntity -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> TopEntity -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> TopEntity -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> TopEntity -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> TopEntity -> r
gmapT :: (forall b. Data b => b -> b) -> TopEntity -> TopEntity
$cgmapT :: (forall b. Data b => b -> b) -> TopEntity -> TopEntity
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c TopEntity)
$cdataCast2 :: forall (t :: Type -> Type -> Type) (c :: Type -> Type).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c TopEntity)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c TopEntity)
$cdataCast1 :: forall (t :: Type -> Type) (c :: Type -> Type).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c TopEntity)
dataTypeOf :: TopEntity -> DataType
$cdataTypeOf :: TopEntity -> DataType
toConstr :: TopEntity -> Constr
$ctoConstr :: TopEntity -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c TopEntity
$cgunfold :: forall (c :: Type -> Type).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c TopEntity
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> TopEntity -> c TopEntity
$cgfoldl :: forall (c :: Type -> Type).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> TopEntity -> c TopEntity
$cp1Data :: Typeable TopEntity
Data,Int -> TopEntity -> ShowS
[TopEntity] -> ShowS
TopEntity -> String
(Int -> TopEntity -> ShowS)
-> (TopEntity -> String)
-> ([TopEntity] -> ShowS)
-> Show TopEntity
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [TopEntity] -> ShowS
$cshowList :: [TopEntity] -> ShowS
show :: TopEntity -> String
$cshow :: TopEntity -> String
showsPrec :: Int -> TopEntity -> ShowS
$cshowsPrec :: Int -> TopEntity -> ShowS
Show,(forall x. TopEntity -> Rep TopEntity x)
-> (forall x. Rep TopEntity x -> TopEntity) -> Generic TopEntity
forall x. Rep TopEntity x -> TopEntity
forall x. TopEntity -> Rep TopEntity x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep TopEntity x -> TopEntity
$cfrom :: forall x. TopEntity -> Rep TopEntity x
Generic)

instance Lift TopEntity where
  lift :: TopEntity -> Q Exp
lift (Synthesize String
name [PortName]
inputs PortName
output) =
    [Q Exp] -> Q Exp
TH.appsE
      [ Name -> Q Exp
TH.conE 'Synthesize
      , String -> Q Exp
forall t. Lift t => t -> Q Exp
lift String
name
      , [PortName] -> Q Exp
forall t. Lift t => t -> Q Exp
lift [PortName]
inputs
      , PortName -> Q Exp
forall t. Lift t => t -> Q Exp
lift PortName
output
      ]
  lift (TestBench Name
_) = String -> Q Exp
forall a. HasCallStack => String -> a
error String
"Cannot lift a TestBench"
#if MIN_VERSION_template_haskell(2,16,0)
  liftTyped :: TopEntity -> Q (TExp TopEntity)
liftTyped = TopEntity -> Q (TExp TopEntity)
forall a. Lift a => a -> Q (TExp a)
liftTypedFromUntyped
#endif

-- | Give port names for arguments/results.
--
-- Give a data type and function:
--
-- @
-- data T = MkT Int Bool
--
-- {\-\# ANN f (defSyn "f") \#-\}
-- f :: Int -> T -> (T,Bool)
-- f a b = ...
-- @
--
-- Clash would normally generate the following VHDL entity:
--
-- @
-- entity f is
--   port(a      : in signed(63 downto 0);
--        b_0    : in signed(63 downto 0);
--        b_1    : in boolean;
--        result : out std_logic_vector(65 downto 0));
-- end;
-- @
--
-- However, we can change this by using 'PortName's. So by:
--
-- @
-- {\-\# ANN f
--    (Synthesize
--       { t_name   = "f"
--       , t_inputs = [ PortName \"a\"
--                    , PortName \"b\" ]
--       , t_output = PortName \"res\" }) \#-\}
-- f :: Int -> T -> (T,Bool)
-- f a b = ...
-- @
--
-- we get:
--
-- @
-- entity f is
--   port(a   : in signed(63 downto 0);
--        b   : in std_logic_vector(64 downto 0);
--        res : out std_logic_vector(65 downto 0));
-- end;
-- @
--
-- If we want to name fields for tuples/records we have to use 'PortProduct'
--
-- @
-- {\-\# ANN f
--    (Synthesize
--       { t_name   = "f"
--       , t_inputs = [ PortName \"a\"
--                    , PortProduct \"\" [ PortName \"b\", PortName \"c\" ] ]
--       , t_output = PortProduct \"res\" [PortName \"q\"] }) \#-\}
-- f :: Int -> T -> (T,Bool)
-- f a b = ...
-- @
--
-- So that we get:
--
-- @
-- entity f is
--   port(a     : in signed(63 downto 0);
--        b     : in signed(63 downto 0);
--        c     : in boolean;
--        res_q : out std_logic_vector(64 downto 0);
--        res_1 : out boolean);
-- end;
-- @
--
-- Notice how we didn't name the second field of the result, and the second
-- output port got 'PortProduct' name, \"res\", as a prefix for its name.
data PortName
  = PortName String
  -- ^ You want a port, with the given name, for the entire argument\/type
  --
  -- You can use an empty String ,@""@ , in case you want an auto-generated name.
  | PortProduct String [PortName]
  -- ^ You want to assign ports to fields of a product argument\/type
  --
  -- The first argument of 'PortProduct' is the name of:
  --
  -- 1. The signal/wire to which the individual ports are aggregated.
  --
  -- 2. The prefix for any unnamed ports below the 'PortProduct'
  --
  -- You can use an empty String ,@""@ , in case you want an auto-generated name.
  deriving (PortName -> PortName -> Bool
(PortName -> PortName -> Bool)
-> (PortName -> PortName -> Bool) -> Eq PortName
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PortName -> PortName -> Bool
$c/= :: PortName -> PortName -> Bool
== :: PortName -> PortName -> Bool
$c== :: PortName -> PortName -> Bool
Eq,Typeable PortName
DataType
Constr
Typeable PortName
-> (forall (c :: Type -> Type).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> PortName -> c PortName)
-> (forall (c :: Type -> Type).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c PortName)
-> (PortName -> Constr)
-> (PortName -> DataType)
-> (forall (t :: Type -> Type) (c :: Type -> Type).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c PortName))
-> (forall (t :: Type -> Type -> Type) (c :: Type -> Type).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c PortName))
-> ((forall b. Data b => b -> b) -> PortName -> PortName)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> PortName -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> PortName -> r)
-> (forall u. (forall d. Data d => d -> u) -> PortName -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> PortName -> u)
-> (forall (m :: Type -> Type).
    Monad m =>
    (forall d. Data d => d -> m d) -> PortName -> m PortName)
-> (forall (m :: Type -> Type).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> PortName -> m PortName)
-> (forall (m :: Type -> Type).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> PortName -> m PortName)
-> Data PortName
PortName -> DataType
PortName -> Constr
(forall b. Data b => b -> b) -> PortName -> PortName
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> PortName -> c PortName
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c PortName
forall a.
Typeable a
-> (forall (c :: Type -> Type).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: Type -> Type).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: Type -> Type) (c :: Type -> Type).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: Type -> Type -> Type) (c :: Type -> Type).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: Type -> Type).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: Type -> Type).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: Type -> Type).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> PortName -> u
forall u. (forall d. Data d => d -> u) -> PortName -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> PortName -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> PortName -> r
forall (m :: Type -> Type).
Monad m =>
(forall d. Data d => d -> m d) -> PortName -> m PortName
forall (m :: Type -> Type).
MonadPlus m =>
(forall d. Data d => d -> m d) -> PortName -> m PortName
forall (c :: Type -> Type).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c PortName
forall (c :: Type -> Type).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> PortName -> c PortName
forall (t :: Type -> Type) (c :: Type -> Type).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c PortName)
forall (t :: Type -> Type -> Type) (c :: Type -> Type).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c PortName)
$cPortProduct :: Constr
$cPortName :: Constr
$tPortName :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> PortName -> m PortName
$cgmapMo :: forall (m :: Type -> Type).
MonadPlus m =>
(forall d. Data d => d -> m d) -> PortName -> m PortName
gmapMp :: (forall d. Data d => d -> m d) -> PortName -> m PortName
$cgmapMp :: forall (m :: Type -> Type).
MonadPlus m =>
(forall d. Data d => d -> m d) -> PortName -> m PortName
gmapM :: (forall d. Data d => d -> m d) -> PortName -> m PortName
$cgmapM :: forall (m :: Type -> Type).
Monad m =>
(forall d. Data d => d -> m d) -> PortName -> m PortName
gmapQi :: Int -> (forall d. Data d => d -> u) -> PortName -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> PortName -> u
gmapQ :: (forall d. Data d => d -> u) -> PortName -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> PortName -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> PortName -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> PortName -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> PortName -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> PortName -> r
gmapT :: (forall b. Data b => b -> b) -> PortName -> PortName
$cgmapT :: (forall b. Data b => b -> b) -> PortName -> PortName
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c PortName)
$cdataCast2 :: forall (t :: Type -> Type -> Type) (c :: Type -> Type).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c PortName)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c PortName)
$cdataCast1 :: forall (t :: Type -> Type) (c :: Type -> Type).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c PortName)
dataTypeOf :: PortName -> DataType
$cdataTypeOf :: PortName -> DataType
toConstr :: PortName -> Constr
$ctoConstr :: PortName -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c PortName
$cgunfold :: forall (c :: Type -> Type).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c PortName
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> PortName -> c PortName
$cgfoldl :: forall (c :: Type -> Type).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> PortName -> c PortName
$cp1Data :: Typeable PortName
Data,Int -> PortName -> ShowS
[PortName] -> ShowS
PortName -> String
(Int -> PortName -> ShowS)
-> (PortName -> String) -> ([PortName] -> ShowS) -> Show PortName
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PortName] -> ShowS
$cshowList :: [PortName] -> ShowS
show :: PortName -> String
$cshow :: PortName -> String
showsPrec :: Int -> PortName -> ShowS
$cshowsPrec :: Int -> PortName -> ShowS
Show,(forall x. PortName -> Rep PortName x)
-> (forall x. Rep PortName x -> PortName) -> Generic PortName
forall x. Rep PortName x -> PortName
forall x. PortName -> Rep PortName x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep PortName x -> PortName
$cfrom :: forall x. PortName -> Rep PortName x
Generic,PortName -> Q Exp
PortName -> Q (TExp PortName)
(PortName -> Q Exp)
-> (PortName -> Q (TExp PortName)) -> Lift PortName
forall t. (t -> Q Exp) -> (t -> Q (TExp t)) -> Lift t
liftTyped :: PortName -> Q (TExp PortName)
$cliftTyped :: PortName -> Q (TExp PortName)
lift :: PortName -> Q Exp
$clift :: PortName -> Q Exp
Lift)

-- | Default 'Synthesize' annotation which has no specified names for the input
-- and output ports.
--
-- >>> defSyn "foo"
-- Synthesize {t_name = "foo", t_inputs = [], t_output = PortName ""}
defSyn :: String -> TopEntity
defSyn :: String -> TopEntity
defSyn String
name = Synthesize :: String -> [PortName] -> PortName -> TopEntity
Synthesize
  { t_name :: String
t_name   = String
name
  , t_inputs :: [PortName]
t_inputs = []
  , t_output :: PortName
t_output = String -> PortName
PortName String
""
  }