diff --git a/clash-protocols-base/clash-protocols-base.cabal b/clash-protocols-base/clash-protocols-base.cabal index a35f14ee..2b2a9740 100644 --- a/clash-protocols-base/clash-protocols-base.cabal +++ b/clash-protocols-base/clash-protocols-base.cabal @@ -112,7 +112,7 @@ library exposed-modules: Protocols.Cpp - Protocols.Internal + Protocols.Circuit Protocols.Internal.Classes Protocols.Internal.TaggedBundle Protocols.Internal.TaggedBundle.TH diff --git a/clash-protocols-base/src/Protocols/Circuit.hs b/clash-protocols-base/src/Protocols/Circuit.hs new file mode 100644 index 00000000..a088576c --- /dev/null +++ b/clash-protocols-base/src/Protocols/Circuit.hs @@ -0,0 +1,38 @@ +{-# OPTIONS_GHC -Wno-dodgy-exports #-} +{-# OPTIONS_GHC -fno-warn-orphans #-} + +module Protocols.Circuit ( + module Protocols.Internal.Classes, +) where + +import Clash.Signal +import Clash.Sized.Vector +import GHC.TypeNats (KnownNat) +import Protocols.Cpp (maxTupleSize) +import Protocols.Internal.TH +import Protocols.Internal.Classes + +instance Protocol () where + type Fwd () = () + type Bwd () = () + +{- | __NB__: The documentation only shows instances up to /3/-tuples. By +default, instances up to and including /12/-tuples will exist. If the flag +@large-tuples@ is set instances up to the GHC imposed limit will exist. The +GHC imposed limit is either 62 or 64 depending on the GHC version. +-} +instance Protocol (a, b) where + type Fwd (a, b) = (Fwd a, Fwd b) + type Bwd (a, b) = (Bwd a, Bwd b) + +-- Generate n-tuple instances, where n > 2 +protocolTupleInstances 3 maxTupleSize + +instance (KnownNat n) => Protocol (Vec n a) where + type Fwd (Vec n a) = Vec n (Fwd a) + type Bwd (Vec n a) = Vec n (Bwd a) + +-- XXX: Type families with Signals on LHS are currently broken on Clash: +instance Protocol (CSignal dom a) where + type Fwd (CSignal dom a) = Signal dom a + type Bwd (CSignal dom a) = Signal dom () diff --git a/clash-protocols-base/src/Protocols/Internal/Classes.hs b/clash-protocols-base/src/Protocols/Internal/Classes.hs index cba5a44d..1364b893 100644 --- a/clash-protocols-base/src/Protocols/Internal/Classes.hs +++ b/clash-protocols-base/src/Protocols/Internal/Classes.hs @@ -5,6 +5,7 @@ for instances. They are defined separately to avoid import loops. This module is not exported; the classes and their (orphan) instances are exported elsewhere. -} +{-# LANGUAGE RoleAnnotations #-} module Protocols.Internal.Classes where import Clash.Signal @@ -141,6 +142,16 @@ class (Protocol p) => IdleCircuit p where idleFwd :: Proxy p -> Fwd (p :: Type) idleBwd :: Proxy p -> Bwd (p :: Type) +{- | Circuit protocol with /Signal dom a/ in its forward direction, and +/()/ in its backward direction. Convenient for exposing protocol +internals, or simply for undirectional streams. +Note: 'CSignal' exists to work around [issue 760](https://github.com/clash-lang/clash-compiler/issues/760) + in Clash, where type families with 'Signal' on the LHS are broken. +-} +data CSignal (dom :: Domain) (a :: Type) + +type role CSignal nominal representational + {- | Force a /nack/ on the backward channel and /no data/ on the forward channel if reset is asserted. -} diff --git a/clash-protocols-base/src/Protocols/Plugin.hs b/clash-protocols-base/src/Protocols/Plugin.hs index 6258d88d..f4712618 100644 --- a/clash-protocols-base/src/Protocols/Plugin.hs +++ b/clash-protocols-base/src/Protocols/Plugin.hs @@ -15,7 +15,7 @@ module Protocols.Plugin ( import Prelude -- clash-protocols -import Protocols.Internal +import Protocols.Internal.Classes import Protocols.Internal.TaggedBundle import Protocols.Internal.Units import Protocols.Plugin.Internal diff --git a/clash-protocols-base/src/Protocols/Plugin/Internal.hs b/clash-protocols-base/src/Protocols/Plugin/Internal.hs index 6755fa6c..bd4ca866 100644 --- a/clash-protocols-base/src/Protocols/Plugin/Internal.hs +++ b/clash-protocols-base/src/Protocols/Plugin/Internal.hs @@ -7,7 +7,22 @@ module Protocols.Plugin.Internal where import Clash.Explicit.Prelude import Data.Tagged -import Protocols.Internal +import GHC.Base (Any) +import Protocols.Internal.Classes + +{- | Picked up by "Protocols.Plugin" to process protocol DSL. See +"Protocols.Plugin" for more information. +-} +circuit :: Any +circuit = + error "'protocol' called: did you forget to enable \"Protocols.Plugin\"?" + +{- | Picked up by "Protocols.Plugin" to tie circuits together. See +"Protocols.Plugin" for more information. +-} +(-<) :: Any +(-<) = + error "(-<) called: did you forget to enable \"Protocols.Plugin\"?" {- | Convenience type alias. A circuit where all parts are decorated with a tag, referring to the @a@ and @b@ in its main signature. This is (indirectly) diff --git a/clash-protocols/clash-protocols.cabal b/clash-protocols/clash-protocols.cabal index 1017ec5b..f6758d33 100644 --- a/clash-protocols/clash-protocols.cabal +++ b/clash-protocols/clash-protocols.cabal @@ -145,6 +145,7 @@ library Protocols.Axi4.WriteData Protocols.Axi4.WriteResponse Protocols.Df + Protocols.Internal Protocols.DfConv Protocols.Hedgehog Protocols.Hedgehog.Internal diff --git a/clash-protocols-base/src/Protocols/Internal.hs b/clash-protocols/src/Protocols/Internal.hs similarity index 94% rename from clash-protocols-base/src/Protocols/Internal.hs rename to clash-protocols/src/Protocols/Internal.hs index d82318b7..eaba0946 100644 --- a/clash-protocols-base/src/Protocols/Internal.hs +++ b/clash-protocols/src/Protocols/Internal.hs @@ -26,12 +26,11 @@ import GHC.Base (Any) import Prelude hiding (const, map) import qualified Clash.Explicit.Prelude as CE -import Clash.Prelude (Signal, type (*), type (+)) +import Clash.Prelude (type (*), type (+)) import qualified Clash.Prelude as C -import Protocols.Cpp (maxTupleSize) +import Protocols.Circuit import Protocols.Internal.Classes -import Protocols.Internal.TH (protocolTupleInstances) import Control.Arrow ((***)) import Data.Coerce (coerce) @@ -53,42 +52,6 @@ newtype Ack = Ack Bool instance Default Ack where def = Ack True -{- | Circuit protocol with /Signal dom a/ in its forward direction, and -/()/ in its backward direction. Convenient for exposing protocol -internals, or simply for undirectional streams. - -Note: 'CSignal' exists to work around [issue 760](https://github.com/clash-lang/clash-compiler/issues/760) - in Clash, where type families with 'Signal' on the LHS are broken. --} -data CSignal (dom :: CE.Domain) (a :: Type) - -type role CSignal nominal representational - -instance Protocol () where - type Fwd () = () - type Bwd () = () - -{- | __NB__: The documentation only shows instances up to /3/-tuples. By -default, instances up to and including /12/-tuples will exist. If the flag -@large-tuples@ is set instances up to the GHC imposed limit will exist. The -GHC imposed limit is either 62 or 64 depending on the GHC version. --} -instance Protocol (a, b) where - type Fwd (a, b) = (Fwd a, Fwd b) - type Bwd (a, b) = (Bwd a, Bwd b) - --- Generate n-tuple instances, where n > 2 -protocolTupleInstances 3 maxTupleSize - -instance (C.KnownNat n) => Protocol (C.Vec n a) where - type Fwd (C.Vec n a) = C.Vec n (Fwd a) - type Bwd (C.Vec n a) = C.Vec n (Bwd a) - --- XXX: Type families with Signals on LHS are currently broken on Clash: -instance Protocol (CSignal dom a) where - type Fwd (CSignal dom a) = Signal dom a - type Bwd (CSignal dom a) = Signal dom () - {- | Left-to-right circuit composition. @