    {-|
    Copyright  :  (C) 2015-2016, University of Twente,
                      2017     , Google Inc.,
                      2021-2023, 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

    -- Define a synthesis domain with a clock with a period of 20000 \/ps\/. Signal
    -- coming from the reset button is low when pressed, and high when not pressed.
    'Clash.Explicit.Signal.createDomain'
      vSystem{vName=\"DomInput\", vPeriod=20000, vResetPolarity=ActiveLow}
    -- Define a synthesis domain with a clock with a period of 50000 \/ps\/.
    '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
        rst50
        enaBtn
        modeBtn
     where
      -- Start with the first LED turned on, in rotate mode, with the counter on zero
      initialStateBlinkerT = (1, False, 0)

      -- Instantiate a PLL: this stabilizes the incoming clock signal and releases
      -- the reset output 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. Since the signature of topEntity already specifies the
      -- Dom50 domain, we don't need any type signatures to specify the domain here.
      (clk50, rst50) = 'Clash.Intel.ClockGen.altpllSync' clk20 rstBtn

    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 NoGeneralizedNewtypeDeriving #-}
    {-# 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
    $c== :: TopEntity -> TopEntity -> Bool
    == :: TopEntity -> TopEntity -> Bool
    $c/= :: TopEntity -> TopEntity -> Bool
    /= :: TopEntity -> TopEntity -> Bool
    Eq,Typeable TopEntity
    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 -> Constr
    TopEntity -> DataType
    (forall b. Data b => b -> b) -> TopEntity -> 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)
    $cgfoldl :: forall (c :: Type -> Type).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> TopEntity -> c TopEntity
    gfoldl :: forall (c :: Type -> Type).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> TopEntity -> 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
    gunfold :: forall (c :: Type -> Type).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c TopEntity
    $ctoConstr :: TopEntity -> Constr
    toConstr :: TopEntity -> Constr
    $cdataTypeOf :: TopEntity -> DataType
    dataTypeOf :: TopEntity -> DataType
    $cdataCast1 :: forall (t :: Type -> Type) (c :: Type -> Type).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c TopEntity)
    dataCast1 :: forall (t :: Type -> Type) (c :: Type -> Type).
    Typeable t =>
    (forall d. Data d => c (t d)) -> 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)
    dataCast2 :: forall (t :: Type -> Type -> Type) (c :: Type -> Type).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c TopEntity)
    $cgmapT :: (forall b. Data b => b -> b) -> TopEntity -> TopEntity
    gmapT :: (forall b. Data b => b -> b) -> TopEntity -> TopEntity
    $cgmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> TopEntity -> r
    gmapQl :: forall r r'.
    (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
    gmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> TopEntity -> r
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> TopEntity -> [u]
    gmapQ :: forall u. (forall d. Data d => d -> u) -> TopEntity -> [u]
    $cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> TopEntity -> u
    gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> TopEntity -> u
    $cgmapM :: forall (m :: Type -> Type).
    Monad m =>
    (forall d. Data d => d -> m d) -> TopEntity -> m TopEntity
    gmapM :: forall (m :: Type -> Type).
    Monad m =>
    (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
    gmapMp :: forall (m :: Type -> Type).
    MonadPlus m =>
    (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
    gmapMo :: forall (m :: Type -> Type).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> TopEntity -> m 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
    $cshowsPrec :: Int -> TopEntity -> ShowS
    showsPrec :: Int -> TopEntity -> ShowS
    $cshow :: TopEntity -> String
    show :: TopEntity -> String
    $cshowList :: [TopEntity] -> ShowS
    showList :: [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
    $cfrom :: forall x. TopEntity -> Rep TopEntity x
    from :: forall x. TopEntity -> Rep TopEntity x
    $cto :: forall x. Rep TopEntity x -> TopEntity
    to :: forall x. Rep TopEntity x -> TopEntity
    Generic)

    instance Lift TopEntity where
      lift :: forall (m :: Type -> Type). Quote m => TopEntity -> m Exp
    lift (Synthesize String
    name [PortName]
    inputs PortName
    output) =
        [m Exp] -> m Exp
    forall (m :: Type -> Type). Quote m => [m Exp] -> m Exp
    TH.appsE
          [ Name -> m Exp
    forall (m :: Type -> Type). Quote m => Name -> m Exp
    TH.conE 'Synthesize
          , String -> m Exp
    forall t (m :: Type -> Type). (Lift t, Quote m) => t -> m Exp
    forall (m :: Type -> Type). Quote m => String -> m Exp
    lift String
    name
          , [PortName] -> m Exp
    forall t (m :: Type -> Type). (Lift t, Quote m) => t -> m Exp
    forall (m :: Type -> Type). Quote m => [PortName] -> m Exp
    lift [PortName]
    inputs
          , PortName -> m Exp
    forall t (m :: Type -> Type). (Lift t, Quote m) => t -> m Exp
    forall (m :: Type -> Type). Quote m => PortName -> m Exp
    lift PortName
    output
          ]
      lift (TestBench Name
    _) = String -> m Exp
    forall a. HasCallStack => String -> a
    error String
    "Cannot lift a TestBench"
    #if MIN_VERSION_template_haskell(2,16,0)
      liftTyped :: forall (m :: Type -> Type).
    Quote m =>
    TopEntity -> Code m TopEntity
    liftTyped = TopEntity -> Code m TopEntity
    forall a (m :: Type -> Type). (Lift a, Quote m) => a -> Code m 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
    $c== :: PortName -> PortName -> Bool
    == :: PortName -> PortName -> Bool
    $c/= :: PortName -> PortName -> Bool
    /= :: PortName -> PortName -> Bool
    Eq,Typeable PortName
    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 -> Constr
    PortName -> DataType
    (forall b. Data b => b -> b) -> PortName -> 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)
    $cgfoldl :: forall (c :: Type -> Type).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> PortName -> c PortName
    gfoldl :: forall (c :: Type -> Type).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> PortName -> 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
    gunfold :: forall (c :: Type -> Type).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c PortName
    $ctoConstr :: PortName -> Constr
    toConstr :: PortName -> Constr
    $cdataTypeOf :: PortName -> DataType
    dataTypeOf :: PortName -> DataType
    $cdataCast1 :: forall (t :: Type -> Type) (c :: Type -> Type).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c PortName)
    dataCast1 :: forall (t :: Type -> Type) (c :: Type -> Type).
    Typeable t =>
    (forall d. Data d => c (t d)) -> 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)
    dataCast2 :: forall (t :: Type -> Type -> Type) (c :: Type -> Type).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c PortName)
    $cgmapT :: (forall b. Data b => b -> b) -> PortName -> PortName
    gmapT :: (forall b. Data b => b -> b) -> PortName -> PortName
    $cgmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> PortName -> r
    gmapQl :: forall r r'.
    (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
    gmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> PortName -> r
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> PortName -> [u]
    gmapQ :: forall u. (forall d. Data d => d -> u) -> PortName -> [u]
    $cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> PortName -> u
    gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> PortName -> u
    $cgmapM :: forall (m :: Type -> Type).
    Monad m =>
    (forall d. Data d => d -> m d) -> PortName -> m PortName
    gmapM :: forall (m :: Type -> Type).
    Monad m =>
    (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
    gmapMp :: forall (m :: Type -> Type).
    MonadPlus m =>
    (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
    gmapMo :: forall (m :: Type -> Type).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> PortName -> m 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
    $cshowsPrec :: Int -> PortName -> ShowS
    showsPrec :: Int -> PortName -> ShowS
    $cshow :: PortName -> String
    show :: PortName -> String
    $cshowList :: [PortName] -> ShowS
    showList :: [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
    $cfrom :: forall x. PortName -> Rep PortName x
    from :: forall x. PortName -> Rep PortName x
    $cto :: forall x. Rep PortName x -> PortName
    to :: forall x. Rep PortName x -> PortName
    Generic,(forall (m :: Type -> Type). Quote m => PortName -> m Exp)
    -> (forall (m :: Type -> Type).
        Quote m =>
        PortName -> Code m PortName)
    -> Lift PortName
    forall t.
    (forall (m :: Type -> Type). Quote m => t -> m Exp)
    -> (forall (m :: Type -> Type). Quote m => t -> Code m t) -> Lift t
    forall (m :: Type -> Type). Quote m => PortName -> m Exp
    forall (m :: Type -> Type). Quote m => PortName -> Code m PortName
    $clift :: forall (m :: Type -> Type). Quote m => PortName -> m Exp
    lift :: forall (m :: Type -> Type). Quote m => PortName -> m Exp
    $cliftTyped :: forall (m :: Type -> Type). Quote m => PortName -> Code m PortName
    liftTyped :: forall (m :: Type -> Type). Quote m => PortName -> Code m PortName
    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
      { t_name :: String
    t_name   = String
    name
      , t_inputs :: [PortName]
    t_inputs = []
      , t_output :: PortName
    t_output = String -> PortName
    PortName String
    ""
      }