From 74d174a5cb83bb39528121255e87f1aa96b73a58 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Tue, 19 Mar 2024 14:27:11 -0400 Subject: [PATCH 1/3] Add Protocol instances for tuples up to arity 8 --- src/Protocols/Internal.hs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/Protocols/Internal.hs b/src/Protocols/Internal.hs index 782e1857..18c24a7c 100644 --- a/src/Protocols/Internal.hs +++ b/src/Protocols/Internal.hs @@ -197,6 +197,22 @@ instance Protocol (a, b, c, d) where type Fwd (a, b, c, d) = (Fwd a, Fwd b, Fwd c, Fwd d) type Bwd (a, b, c, d) = (Bwd a, Bwd b, Bwd c, Bwd d) +instance Protocol (a, b, c, d, e) where + type Fwd (a, b, c, d, e) = (Fwd a, Fwd b, Fwd c, Fwd d, Fwd e) + type Bwd (a, b, c, d, e) = (Bwd a, Bwd b, Bwd c, Bwd d, Bwd e) + +instance Protocol (a, b, c, d, e, f) where + type Fwd (a, b, c, d, e, f) = (Fwd a, Fwd b, Fwd c, Fwd d, Fwd e, Fwd f) + type Bwd (a, b, c, d, e, f) = (Bwd a, Bwd b, Bwd c, Bwd d, Bwd e, Bwd f) + +instance Protocol (a, b, c, d, e, f, g) where + type Fwd (a, b, c, d, e, f, g) = (Fwd a, Fwd b, Fwd c, Fwd d, Fwd e, Fwd f, Fwd g) + type Bwd (a, b, c, d, e, f, g) = (Bwd a, Bwd b, Bwd c, Bwd d, Bwd e, Bwd f, Bwd g) + +instance Protocol (a, b, c, d, e, f, g, h) where + type Fwd (a, b, c, d, e, f, g, h) = (Fwd a, Fwd b, Fwd c, Fwd d, Fwd e, Fwd f, Fwd g, Fwd h) + type Bwd (a, b, c, d, e, f, g, h) = (Bwd a, Bwd b, Bwd c, Bwd d, Bwd e, Bwd f, Bwd g, Bwd h) + 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) From 0e13dc62d0aba7cb22a8e1f74be0e00f4406d906 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Tue, 2 Apr 2024 20:06:07 -0400 Subject: [PATCH 2/3] Add export list to Protocols.Internal.Units.TH --- src/Protocols/Internal/Units/TH.hs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Protocols/Internal/Units/TH.hs b/src/Protocols/Internal/Units/TH.hs index fa0994f6..cb9f02b2 100644 --- a/src/Protocols/Internal/Units/TH.hs +++ b/src/Protocols/Internal/Units/TH.hs @@ -1,6 +1,6 @@ {-# OPTIONS_HADDOCK hide #-} -module Protocols.Internal.Units.TH where +module Protocols.Internal.Units.TH (unitsTupleInstances) where import Language.Haskell.TH From fb501807541d6db7132490c591e46da2563c37c5 Mon Sep 17 00:00:00 2001 From: Ben Gamari Date: Tue, 2 Apr 2024 20:08:42 -0400 Subject: [PATCH 3/3] Generate Protocol instances via template-haskell This ensures that instances are available up to maxTupleSize. --- clash-protocols.cabal | 1 + src/Protocols/Internal.hs | 31 +++++++++--------------------- src/Protocols/Internal/TH.hs | 37 ++++++++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 22 deletions(-) create mode 100644 src/Protocols/Internal/TH.hs diff --git a/clash-protocols.cabal b/clash-protocols.cabal index cd2ca014..bb79b7d2 100644 --- a/clash-protocols.cabal +++ b/clash-protocols.cabal @@ -181,6 +181,7 @@ library Protocols.Internal Protocols.Internal.TaggedBundle Protocols.Internal.TaggedBundle.TH + Protocols.Internal.TH Protocols.Internal.Units Protocols.Internal.Units.TH diff --git a/src/Protocols/Internal.hs b/src/Protocols/Internal.hs index 18c24a7c..d2127b3c 100644 --- a/src/Protocols/Internal.hs +++ b/src/Protocols/Internal.hs @@ -29,6 +29,9 @@ import Clash.Prelude (Signal, type (+), type (*)) import qualified Clash.Prelude as C import qualified Clash.Explicit.Prelude as CE +import Protocols.Internal.TH (protocolTupleInstances) +import Protocols.Cpp (maxTupleSize) + import Control.Arrow ((***)) import Data.Coerce (coerce) import Data.Default (Default(def)) @@ -185,33 +188,17 @@ 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) -instance Protocol (a, b, c) where - type Fwd (a, b, c) = (Fwd a, Fwd b, Fwd c) - type Bwd (a, b, c) = (Bwd a, Bwd b, Bwd c) - -instance Protocol (a, b, c, d) where - type Fwd (a, b, c, d) = (Fwd a, Fwd b, Fwd c, Fwd d) - type Bwd (a, b, c, d) = (Bwd a, Bwd b, Bwd c, Bwd d) - -instance Protocol (a, b, c, d, e) where - type Fwd (a, b, c, d, e) = (Fwd a, Fwd b, Fwd c, Fwd d, Fwd e) - type Bwd (a, b, c, d, e) = (Bwd a, Bwd b, Bwd c, Bwd d, Bwd e) - -instance Protocol (a, b, c, d, e, f) where - type Fwd (a, b, c, d, e, f) = (Fwd a, Fwd b, Fwd c, Fwd d, Fwd e, Fwd f) - type Bwd (a, b, c, d, e, f) = (Bwd a, Bwd b, Bwd c, Bwd d, Bwd e, Bwd f) - -instance Protocol (a, b, c, d, e, f, g) where - type Fwd (a, b, c, d, e, f, g) = (Fwd a, Fwd b, Fwd c, Fwd d, Fwd e, Fwd f, Fwd g) - type Bwd (a, b, c, d, e, f, g) = (Bwd a, Bwd b, Bwd c, Bwd d, Bwd e, Bwd f, Bwd g) -instance Protocol (a, b, c, d, e, f, g, h) where - type Fwd (a, b, c, d, e, f, g, h) = (Fwd a, Fwd b, Fwd c, Fwd d, Fwd e, Fwd f, Fwd g, Fwd h) - type Bwd (a, b, c, d, e, f, g, h) = (Bwd a, Bwd b, Bwd c, Bwd d, Bwd e, Bwd f, Bwd g, Bwd h) +-- Generate n-tuple instances, where n > 2 +protocolTupleInstances maxTupleSize instance C.KnownNat n => Protocol (C.Vec n a) where type Fwd (C.Vec n a) = C.Vec n (Fwd a) diff --git a/src/Protocols/Internal/TH.hs b/src/Protocols/Internal/TH.hs new file mode 100644 index 00000000..a17e18be --- /dev/null +++ b/src/Protocols/Internal/TH.hs @@ -0,0 +1,37 @@ +{-# OPTIONS_HADDOCK hide #-} + +module Protocols.Internal.TH (protocolTupleInstances) where + +import Language.Haskell.TH + +appTs :: Q Type -> [Q Type] -> Q Type +appTs = foldl appT + +protocolTupleInstances :: Int -> Q [Dec] +protocolTupleInstances n = mapM protocolTupleInstance [3..n] + +protocolTupleInstance :: Int -> Q Dec +protocolTupleInstance n = + instanceD + (pure []) -- context + (protocolConT `appT` tup) -- head + [mkTyInst fwdConName, mkTyInst bwdConName] -- body + + where + fwdConName = mkName "Fwd" + bwdConName = mkName "Bwd" + protocolConT = conT (mkName "Protocol") + + tyVars :: [TypeQ] + tyVars = map (varT . mkName . ('a':) . show) [1..n] + + tup = tupleT n `appTs` tyVars + + mkTyInst :: Name -> DecQ + mkTyInst con = + tySynInstD $ tySynEqn Nothing lhs rhs + where + lhs, rhs :: TypeQ + lhs = conT con `appT` tup + rhs = tupleT n `appTs` map (conT con `appT`) tyVars +