{-|
Copyright  :  (C) 2017, Google Inc
                  2019, Myrtle Software Ltd
                  2025, QBayLogic B.V.
License    :  BSD2 (see the file LICENSE)
Maintainer :  QBayLogic B.V. <devops@qbaylogic.com>

We simulate DDR signal by using 'Signal's which have exactly half the period
(or double the speed) of our normal 'Signal's.

The primitives in this module can be used to produce or consume DDR signals.

DDR signals are not meant to be used internally in a design,
but only to communicate with the outside world.

In some cases hardware specific DDR IN registers can be inferred by synthesis
tools from these generic primitives. But to be sure your design will synthesize
to dedicated hardware resources use the functions from "Clash.Intel.DDR"
or "Clash.Xilinx.DDR".
-}

{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskellQuotes #-}
{-# LANGUAGE TypeFamilies #-}

module Clash.Explicit.DDR
  ( ddrIn
  , ddrOut
  , ddrForwardClock
    -- * Internal
  , ddrIn#
  , ddrOut#
  , ddrForwardClock#
  )
where

import Data.List.Infinite (Infinite(..), (...))
import Data.String.Interpolate (__i)
import GHC.Stack (HasCallStack, withFrozenCallStack)
import Unsafe.Coerce (unsafeCoerce)

import Clash.Annotations.Primitive (hasBlackBox, Primitive(..), HDL(..))
import Clash.Explicit.Prelude hiding ((:<))
import Clash.Signal.Internal

{- $setup
>>> :set -XNoImplicitPrelude -XTypeFamilies -XFlexibleInstances
>>> import Clash.Explicit.Prelude
>>> import Clash.Explicit.DDR
>>> :{
instance KnownDomain "Fast" where
  type KnownConf "Fast" = 'DomainConfiguration "Fast" 5000 'Rising 'Asynchronous 'Defined 'ActiveHigh
  knownDomain = SDomainConfiguration SSymbol SNat SRising SAsynchronous SDefined SActiveHigh
:}

-}

-- | DDR input primitive
--
-- Consumes a DDR input signal and produces a regular signal containing a pair
-- of values.
--
-- >>> printX $ sampleN 5 $ ddrIn systemClockGen systemResetGen enableGen (-1,-2,-3) (fromList [0..10] :: Signal "Fast" Int)
-- [(-1,-2),(-1,-2),(-3,2),(3,4),(5,6)]
ddrIn
  :: ( HasCallStack
     , NFDataX a
     , KnownConfiguration fast ('DomainConfiguration fast fPeriod edge reset init polarity)
     , KnownConfiguration slow ('DomainConfiguration slow (2*fPeriod) edge reset init polarity) )
  => Clock slow
  -- ^ clock
  -> Reset slow
  -- ^ reset
  -> Enable slow
  -> (a, a, a)
  -- ^ reset values
  -> Signal fast a
  -- ^ DDR input signal
  -> Signal slow (a, a)
  -- ^ normal speed output pairs
ddrIn :: Clock slow
-> Reset slow
-> Enable slow
-> (a, a, a)
-> Signal fast a
-> Signal slow (a, a)
ddrIn Clock slow
clk Reset slow
rst Enable slow
en (a
i0,a
i1,a
i2) =
  (HasCallStack => Signal fast a -> Signal slow (a, a))
-> Signal fast a -> Signal slow (a, a)
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack ((HasCallStack => Signal fast a -> Signal slow (a, a))
 -> Signal fast a -> Signal slow (a, a))
-> (HasCallStack => Signal fast a -> Signal slow (a, a))
-> Signal fast a
-> Signal slow (a, a)
forall a b. (a -> b) -> a -> b
$ Clock slow
-> Reset slow
-> Enable slow
-> a
-> a
-> a
-> Signal fast a
-> Signal slow (a, a)
forall a (slow :: Domain) (fast :: Domain) (fPeriod :: Nat)
       (polarity :: ResetPolarity) (edge :: ActiveEdge)
       (reset :: ResetKind) (init :: InitBehavior).
(HasCallStack, NFDataX a,
 KnownConfiguration
   fast ('DomainConfiguration fast fPeriod edge reset init polarity),
 KnownConfiguration
   slow
   ('DomainConfiguration
      slow (2 * fPeriod) edge reset init polarity)) =>
Clock slow
-> Reset slow
-> Enable slow
-> a
-> a
-> a
-> Signal fast a
-> Signal slow (a, a)
ddrIn# Clock slow
clk Reset slow
rst Enable slow
en a
i0 a
i1 a
i2


-- For details about all the seq's en seqX's
-- see the [Note: register strictness annotations] in Clash.Signal.Internal
ddrIn#
  :: forall a slow fast fPeriod polarity edge reset init
   . ( HasCallStack
     , NFDataX a
     , KnownConfiguration fast ('DomainConfiguration fast fPeriod edge reset init polarity)
     , KnownConfiguration slow ('DomainConfiguration slow (2*fPeriod) edge reset init polarity) )
  => Clock slow
  -> Reset slow
  -> Enable slow
  -> a
  -> a
  -> a
  -> Signal fast a
  -> Signal slow (a,a)
ddrIn# :: Clock slow
-> Reset slow
-> Enable slow
-> a
-> a
-> a
-> Signal fast a
-> Signal slow (a, a)
ddrIn# (Clock SSymbol slow
_ Maybe (Signal slow Femtoseconds)
Nothing) (Reset slow -> Signal slow Bool
forall (dom :: Domain).
KnownDomain dom =>
Reset dom -> Signal dom Bool
unsafeToActiveHigh -> Signal slow Bool
hRst) (Enable slow -> Signal slow Bool
forall (dom :: Domain). Enable dom -> Signal dom Bool
fromEnable -> Signal slow Bool
ena) a
i0 a
i1 a
i2 =
  case forall (dom :: Domain) (sync :: ResetKind).
(KnownDomain dom, DomainResetKind dom ~ sync) =>
SResetKind sync
forall (sync :: ResetKind).
(KnownDomain fast, DomainResetKind fast ~ sync) =>
SResetKind sync
resetKind @fast of
    SResetKind reset
SAsynchronous ->
      (a, a, a)
-> Signal slow Bool
-> Signal slow Bool
-> Signal fast a
-> Signal slow (a, a)
goAsync
        ( String -> a
forall a. (NFDataX a, HasCallStack) => String -> a
deepErrorX String
"ddrIn: initial value 0 undefined"
        , String -> a
forall a. (NFDataX a, HasCallStack) => String -> a
deepErrorX String
"ddrIn: initial value 1 undefined"
        , String -> a
forall a. (NFDataX a, HasCallStack) => String -> a
deepErrorX String
"ddrIn: initial value 2 undefined" )
        Signal slow Bool
hRst
        Signal slow Bool
ena
    SResetKind reset
SSynchronous ->
      (a, a, a)
-> Signal slow Bool
-> Signal slow Bool
-> Signal fast a
-> Signal slow (a, a)
goSync
        ( String -> a
forall a. (NFDataX a, HasCallStack) => String -> a
deepErrorX String
"ddrIn: initial value 0 undefined"
        , String -> a
forall a. (NFDataX a, HasCallStack) => String -> a
deepErrorX String
"ddrIn: initial value 1 undefined"
        , String -> a
forall a. (NFDataX a, HasCallStack) => String -> a
deepErrorX String
"ddrIn: initial value 2 undefined" )
        Signal slow Bool
hRst
        Signal slow Bool
ena
  where
    goSync
      :: (a, a, a)
      -> Signal slow Bool
      -> Signal slow Bool
      -> Signal fast a
      -> Signal slow (a,a)
    goSync :: (a, a, a)
-> Signal slow Bool
-> Signal slow Bool
-> Signal fast a
-> Signal slow (a, a)
goSync (a
o0,a
o1,a
o2) rt :: Signal slow Bool
rt@(~(Bool
r :- Signal slow Bool
rs)) ~(Bool
e :- Signal slow Bool
es) as :: Signal fast a
as@(~(a
x0 :- a
x1 :- Signal fast a
xs)) =
      let (a
o0',a
o1',a
o2') = if Bool
r then (a
i0,a
i1,a
i2) else (a
o2,a
x0,a
x1)
      in a
o0 a -> Signal slow (a, a) -> Signal slow (a, a)
forall a b. a -> b -> b
`seqX` a
o1 a -> Signal slow (a, a) -> Signal slow (a, a)
forall a b. a -> b -> b
`seqX` (a
o0,a
o1)
           (a, a) -> Signal slow (a, a) -> Signal slow (a, a)
forall (dom :: Domain) a. a -> Signal dom a -> Signal dom a
:- (Signal slow Bool
rt Signal slow Bool -> Signal slow (a, a) -> Signal slow (a, a)
`seq` Signal fast a
as Signal fast a -> Signal slow (a, a) -> Signal slow (a, a)
`seq` if Bool
e then (a, a, a)
-> Signal slow Bool
-> Signal slow Bool
-> Signal fast a
-> Signal slow (a, a)
goSync (a
o0',a
o1',a
o2') Signal slow Bool
rs Signal slow Bool
es Signal fast a
xs
                                      else (a, a, a)
-> Signal slow Bool
-> Signal slow Bool
-> Signal fast a
-> Signal slow (a, a)
goSync (a
o0 ,a
o1 ,a
o2)  Signal slow Bool
rs Signal slow Bool
es Signal fast a
xs)

    goAsync
      :: (a, a, a)
      -> Signal slow Bool
      -> Signal slow Bool
      -> Signal fast a
      -> Signal slow (a, a)
    goAsync :: (a, a, a)
-> Signal slow Bool
-> Signal slow Bool
-> Signal fast a
-> Signal slow (a, a)
goAsync (a
o0,a
o1,a
o2) ~(Bool
r :- Signal slow Bool
rs) ~(Bool
e :- Signal slow Bool
es) as :: Signal fast a
as@(~(a
x0 :- a
x1 :- Signal fast a
xs)) =
      let (a
o0',a
o1',a
o2',a
o3',a
o4') = if Bool
r then (a
i0,a
i1,a
i0,a
i1,a
i2) else (a
o0,a
o1,a
o2,a
x0,a
x1)
      in a
o0' a -> Signal slow (a, a) -> Signal slow (a, a)
forall a b. a -> b -> b
`seqX` a
o1' a -> Signal slow (a, a) -> Signal slow (a, a)
forall a b. a -> b -> b
`seqX` (a
o0',a
o1')
           (a, a) -> Signal slow (a, a) -> Signal slow (a, a)
forall (dom :: Domain) a. a -> Signal dom a -> Signal dom a
:- (Signal fast a
as Signal fast a -> Signal slow (a, a) -> Signal slow (a, a)
`seq` if Bool
e then (a, a, a)
-> Signal slow Bool
-> Signal slow Bool
-> Signal fast a
-> Signal slow (a, a)
goAsync (a
o2',a
o3',a
o4') Signal slow Bool
rs Signal slow Bool
es Signal fast a
xs
                             else (a, a, a)
-> Signal slow Bool
-> Signal slow Bool
-> Signal fast a
-> Signal slow (a, a)
goAsync (a
o0',a
o1',a
o2') Signal slow Bool
rs Signal slow Bool
es Signal fast a
xs)

ddrIn# Clock slow
_ Reset slow
_ Enable slow
_ a
_ a
_ a
_ =
  String -> Signal fast a -> Signal slow (a, a)
forall a. HasCallStack => String -> a
error String
"ddrIn#: dynamic clocks not supported"
-- See: https://github.com/clash-lang/clash-compiler/pull/2511
{-# CLASH_OPAQUE ddrIn# #-}
{-# ANN ddrIn# hasBlackBox #-}

-- | DDR output primitive
--
-- Produces a DDR output signal from a normal signal of pairs of input.
--
-- >>> sampleN 7 (ddrOut systemClockGen systemResetGen enableGen (-1) (fromList [(0,1),(2,3),(4,5)]) :: Signal "Fast" Int)
-- [-1,-1,-1,2,3,4,5]
ddrOut
  :: ( HasCallStack
     , NFDataX a
     , KnownConfiguration fast ('DomainConfiguration fast fPeriod edge reset init polarity)
     , KnownConfiguration slow ('DomainConfiguration slow (2*fPeriod) edge reset init polarity) )
  => Clock slow
  -> Reset slow
  -> Enable slow
  -> a
  -- ^ reset value
  -> Signal slow (a, a)
  -- ^ Normal speed input pairs
  -> Signal fast a
  -- ^ DDR output signal
ddrOut :: Clock slow
-> Reset slow
-> Enable slow
-> a
-> Signal slow (a, a)
-> Signal fast a
ddrOut Clock slow
clk Reset slow
rst Enable slow
en a
i0 =
  (Signal slow a -> Signal slow a -> Signal fast a)
-> (Signal slow a, Signal slow a) -> Signal fast a
forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry ((HasCallStack => Signal slow a -> Signal slow a -> Signal fast a)
-> Signal slow a -> Signal slow a -> Signal fast a
forall a. HasCallStack => (HasCallStack => a) -> a
withFrozenCallStack ((HasCallStack => Signal slow a -> Signal slow a -> Signal fast a)
 -> Signal slow a -> Signal slow a -> Signal fast a)
-> (HasCallStack =>
    Signal slow a -> Signal slow a -> Signal fast a)
-> Signal slow a
-> Signal slow a
-> Signal fast a
forall a b. (a -> b) -> a -> b
$ Clock slow
-> Reset slow
-> Enable slow
-> a
-> Signal slow a
-> Signal slow a
-> Signal fast a
forall a (fast :: Domain) (fPeriod :: Nat) (edge :: ActiveEdge)
       (reset :: ResetKind) (init :: InitBehavior)
       (polarity :: ResetPolarity) (slow :: Domain).
(HasCallStack, NFDataX a,
 KnownConfiguration
   fast ('DomainConfiguration fast fPeriod edge reset init polarity),
 KnownConfiguration
   slow
   ('DomainConfiguration
      slow (2 * fPeriod) edge reset init polarity)) =>
Clock slow
-> Reset slow
-> Enable slow
-> a
-> Signal slow a
-> Signal slow a
-> Signal fast a
ddrOut# Clock slow
clk Reset slow
rst Enable slow
en a
i0) ((Signal slow a, Signal slow a) -> Signal fast a)
-> (Signal slow (a, a) -> (Signal slow a, Signal slow a))
-> Signal slow (a, a)
-> Signal fast a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Signal slow (a, a) -> (Signal slow a, Signal slow a)
forall a (dom :: Domain).
Bundle a =>
Signal dom a -> Unbundled dom a
unbundle


ddrOut#
  :: ( HasCallStack
     , NFDataX a
     , KnownConfiguration fast ('DomainConfiguration fast fPeriod edge reset init polarity)
     , KnownConfiguration slow ('DomainConfiguration slow (2*fPeriod) edge reset init polarity) )
  => Clock slow
  -> Reset slow
  -> Enable slow
  -> a
  -> Signal slow a
  -> Signal slow a
  -> Signal fast a
ddrOut# :: Clock slow
-> Reset slow
-> Enable slow
-> a
-> Signal slow a
-> Signal slow a
-> Signal fast a
ddrOut# Clock slow
clk Reset slow
rst Enable slow
en a
i0 Signal slow a
xs Signal slow a
ys =
    -- We only observe one reset value, because when the mux switches on the
    -- next clock level, the second register will already be outputting its
    -- first input.
    --
    -- That is why we drop the first value of the stream.
    let (a
_ :- Signal fast a
out) = Signal slow a -> Signal slow a -> Signal fast a
forall (dom :: Domain) a (dom :: Domain) (dom :: Domain).
Signal dom a -> Signal dom a -> Signal dom a
zipSig Signal slow a
xs' Signal slow a
ys' in Signal fast a
out
  where
    xs' :: Signal slow a
xs' = Clock slow
-> Reset slow
-> Enable slow
-> a
-> a
-> Signal slow a
-> Signal slow a
forall (dom :: Domain) a.
(KnownDomain dom, NFDataX a) =>
Clock dom
-> Reset dom
-> Enable dom
-> a
-> a
-> Signal dom a
-> Signal dom a
register# Clock slow
clk Reset slow
rst Enable slow
en (String -> a
forall a. HasCallStack => String -> a
errorX String
"ddrOut: unreachable error") a
i0 Signal slow a
xs
    ys' :: Signal slow a
ys' = Clock slow
-> Reset slow
-> Enable slow
-> a
-> a
-> Signal slow a
-> Signal slow a
forall (dom :: Domain) a.
(KnownDomain dom, NFDataX a) =>
Clock dom
-> Reset dom
-> Enable dom
-> a
-> a
-> Signal dom a
-> Signal dom a
register# Clock slow
clk Reset slow
rst Enable slow
en (String -> a
forall a. (NFDataX a, HasCallStack) => String -> a
deepErrorX String
"ddrOut: initial value undefined") a
i0 Signal slow a
ys
    zipSig :: Signal dom a -> Signal dom a -> Signal dom a
zipSig (a
a :- Signal dom a
as) (a
b :- Signal dom a
bs) = a
a a -> Signal dom a -> Signal dom a
forall (dom :: Domain) a. a -> Signal dom a -> Signal dom a
:- a
b a -> Signal dom a -> Signal dom a
forall (dom :: Domain) a. a -> Signal dom a -> Signal dom a
:- Signal dom a -> Signal dom a -> Signal dom a
zipSig Signal dom a
as Signal dom a
bs
-- See: https://github.com/clash-lang/clash-compiler/pull/2511
{-# CLASH_OPAQUE ddrOut# #-}
{-# ANN ddrOut# hasBlackBox #-}

-- | Use a DDR output primitive to forward a clock to an output pin
--
-- This function allows outputting a clock signal on a DDR-capable output pin.
-- As with the DDR output primitive itself, the created clock cannot be used
-- internally in the design.
--
-- The @ddrOut@ primitive passed in will always have its enable asserted. If the
-- @Enable@ input of @ddrForwardClock@ is deasserted, the data inputs of the
-- @ddrOut@ primitive will switch to achieve the desired output signal. This is
-- because the behavior of the enable input of the DDR primitive differs between
-- vendor-specific primitives.
--
-- The @Reset@ input of this function is passed on to the @ddrOut@ primitive and
-- not otherwise used by @ddrForwardClock@.
--
-- With the @phase@ argument, the phase relation between input and output clock
-- can be defined. With the argument @Nothing@, the clocks are in phase: the
-- active edge of the output clock is on the active edge of the input clock,
-- even if the domains differ on what the active edge is.
--
-- With the @idle@ argument, the output level when the @Enable@ input is
-- deasserted can be defined. With @Nothing@, it will be 0 for a clock with the
-- rising edge as the active edge, and 1 for a clock with the falling edge as
-- the active edge.
--
-- __NB__: The deassertion of the @Enable@ input or the assertion of the @Reset@
-- input is not faithfully simulated in Haskell simulation: Haskell simulation
-- of a Clash design has clocks that always run. The generated HDL will actually
-- output an idle state when @Enable@ is deasserted (and the reset depends on
-- the @ddrOut@ primitive used).
ddrForwardClock
  :: forall domDDR domOut domIn
   . KnownDomain domOut
  => DomainPeriod domIn ~ DomainPeriod domOut
  => DomainPeriod domIn ~ (2 * DomainPeriod domDDR)
  => Clock domIn
  -> Reset domIn
  -> Enable domIn
  -> Maybe Bit
  -- ^ @idle@: Output value when @Enable@ is deasserted
  -> Maybe Bit
  -- ^ @phase@: Value to output at active edge of incoming clock
  -> (Clock domIn -> Reset domIn -> Enable domIn -> Signal domIn (Bit, Bit)
      -> Signal domDDR Bit)
  -- ^ @ddrOut@ primitive to use
  -> Clock domOut
ddrForwardClock :: Clock domIn
-> Reset domIn
-> Enable domIn
-> Maybe Bit
-> Maybe Bit
-> (Clock domIn
    -> Reset domIn
    -> Enable domIn
    -> Signal domIn (Bit, Bit)
    -> Signal domDDR Bit)
-> Clock domOut
ddrForwardClock Clock domIn
clk Reset domIn
rst Enable domIn
en Maybe Bit
idle Maybe Bit
phase Clock domIn
-> Reset domIn
-> Enable domIn
-> Signal domIn (Bit, Bit)
-> Signal domDDR Bit
oddr =
  Clock domIn -> Signal domDDR Bit -> Clock domOut
forall (domOut :: Domain) (domIn :: Domain) (domDDR :: Domain).
(KnownDomain domOut, DomainPeriod domIn ~ DomainPeriod domOut,
 DomainPeriod domIn ~ (2 * DomainPeriod domDDR)) =>
Clock domIn -> Signal domDDR Bit -> Clock domOut
ddrForwardClock# Clock domIn
clk (Signal domDDR Bit -> Clock domOut)
-> Signal domDDR Bit -> Clock domOut
forall a b. (a -> b) -> a -> b
$ Clock domIn
-> Reset domIn
-> Enable domIn
-> Signal domIn (Bit, Bit)
-> Signal domDDR Bit
oddr Clock domIn
clk Reset domIn
rst Enable domIn
forall (dom :: Domain). Enable dom
enableGen Signal domIn (Bit, Bit)
ins
 where
  ins :: Signal domIn (Bit, Bit)
ins =
    Signal domIn Bool
-> Signal domIn (Bit, Bit)
-> Signal domIn (Bit, Bit)
-> Signal domIn (Bit, Bit)
forall (f :: Type -> Type) a.
Applicative f =>
f Bool -> f a -> f a -> f a
mux
      (Enable domIn -> Signal domIn Bool
forall (dom :: Domain). Enable dom -> Signal dom Bool
fromEnable Enable domIn
en)
      ((Bit, Bit) -> Signal domIn (Bit, Bit)
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (Bit
activeLevel, Bit -> Bit
forall a. Bits a => a -> a
complement Bit
activeLevel))
      ((Bit, Bit) -> Signal domIn (Bit, Bit)
forall (f :: Type -> Type) a. Applicative f => a -> f a
pure (Bit
idleLevel, Bit
idleLevel))
  activeLevel :: Bit
activeLevel =
    case Maybe Bit
phase of
      Maybe Bit
Nothing ->
        case forall (dom :: Domain) (edge :: ActiveEdge).
(KnownDomain dom, DomainActiveEdge dom ~ edge) =>
SActiveEdge edge
forall (edge :: ActiveEdge).
(KnownDomain domOut,
 DomainConfigurationActiveEdge (KnownConf domOut) ~ edge) =>
SActiveEdge edge
activeEdge @domOut of
          SActiveEdge (DomainConfigurationActiveEdge (KnownConf domOut))
SRising -> Bit
1
          SActiveEdge (DomainConfigurationActiveEdge (KnownConf domOut))
SFalling -> Bit
0
      Just Bit
x -> Bit
x
  idleLevel :: Bit
idleLevel =
    case Maybe Bit
idle of
      Maybe Bit
Nothing ->
        case forall (dom :: Domain) (edge :: ActiveEdge).
(KnownDomain dom, DomainActiveEdge dom ~ edge) =>
SActiveEdge edge
forall (edge :: ActiveEdge).
(KnownDomain domOut,
 DomainConfigurationActiveEdge (KnownConf domOut) ~ edge) =>
SActiveEdge edge
activeEdge @domOut of
          SActiveEdge (DomainConfigurationActiveEdge (KnownConf domOut))
SRising -> Bit
0
          SActiveEdge (DomainConfigurationActiveEdge (KnownConf domOut))
SFalling -> Bit
1
      Just Bit
x -> Bit
x

ddrForwardClock#
  :: KnownDomain domOut
  => DomainPeriod domIn ~ DomainPeriod domOut
  => DomainPeriod domIn ~ (2 * DomainPeriod domDDR)
  => Clock domIn
  -> Signal domDDR Bit
  -> Clock domOut
ddrForwardClock# :: Clock domIn -> Signal domDDR Bit -> Clock domOut
ddrForwardClock# (Clock SSymbol domIn
SSymbol Maybe (Signal domIn Femtoseconds)
periods) Signal domDDR Bit
ddrSignal =
  SSymbol domOut
-> Maybe (Signal domOut Femtoseconds) -> Clock domOut
forall (dom :: Domain).
SSymbol dom -> Maybe (Signal dom Femtoseconds) -> Clock dom
Clock (Signal domDDR Bit
ddrSignal Signal domDDR Bit -> SSymbol domOut -> SSymbol domOut
`seq` SSymbol domOut
forall (s :: Domain). KnownSymbol s => SSymbol s
SSymbol) (Maybe (Signal domIn Femtoseconds)
-> Maybe (Signal domOut Femtoseconds)
forall a b. a -> b
unsafeCoerce Maybe (Signal domIn Femtoseconds)
periods)
-- See: https://github.com/clash-lang/clash-compiler/pull/2511
{-# CLASH_OPAQUE ddrForwardClock# #-}
{-# ANN ddrForwardClock# (
  let
    bbName = show 'ddrForwardClock#
    _knownDomOut
      :< _domInOutPeriod
      :< _domDDRPeriod
      :< _clkIn
      :< ddrSignal
      :< _ = ((0 :: Int)...)
  in InlineYamlPrimitive [VHDL] [__i|
    BlackBox:
      name: #{bbName}
      kind: Expression
      template: ~TYPMO'(~ARG[#{ddrSignal}])
      workInfo: Never
    |]) #-}
{-# ANN ddrForwardClock# (
  let
    bbName = show 'ddrForwardClock#
    _knownDomOut
      :< _domInOutPeriod
      :< _domDDRPeriod
      :< _clkIn
      :< ddrSignal
      :< _ = ((0 :: Int)...)
  in InlineYamlPrimitive [Verilog, SystemVerilog] [__i|
    BlackBox:
      name: #{bbName}
      kind: Expression
      template: ~ARG[#{ddrSignal}]
      workInfo: Never
    |]) #-}