From bf52d2c2db6ee07df73b99524eb02a2da99a936b Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Sat, 15 Dec 2018 20:19:06 +0000 Subject: Fix documentation --- src/Test/VeriFuzz/CodeGen.hs | 24 +++++++++++++++ src/Test/VeriFuzz/Graph/CodeGen.hs | 18 ++++++++++-- src/Test/VeriFuzz/Graph/Random.hs | 16 ++++++++++ src/Test/VeriFuzz/Internal/Shared.hs | 17 +++++++++++ src/Test/VeriFuzz/VerilogAST.hs | 57 ++++++++++++++++++++++++++++-------- 5 files changed, 117 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/Test/VeriFuzz/CodeGen.hs b/src/Test/VeriFuzz/CodeGen.hs index 85f1d1c..755f52f 100644 --- a/src/Test/VeriFuzz/CodeGen.hs +++ b/src/Test/VeriFuzz/CodeGen.hs @@ -1,3 +1,16 @@ +{-| +Module : Test.VeriFuzz.CodeGen +Description : Code generation for Verilog AST. +Copyright : (c) Yann Herklotz Grave 2018 +License : GPL-3 +Maintainer : ymherklotz@gmail.com +Stability : experimental +Portability : POSIX + +This module generates the code from the Verilog AST defined in +"Test.VeriFuzz.VerilogAST". +-} + {-# LANGUAGE OverloadedStrings #-} module Test.VeriFuzz.CodeGen where @@ -9,14 +22,17 @@ import qualified Data.Text.IO as T import Test.VeriFuzz.Internal.Shared import Test.VeriFuzz.VerilogAST +-- | Convert the 'SourceText' type to 'Text' so that it can be rendered. genSourceText :: SourceText -> Text genSourceText source = fromList $ genDescription <$> source ^. getSourceText +-- | Generate the 'Description' to 'Text'. genDescription :: Description -> Text genDescription desc = genModuleDecl $ desc ^. getDescription +-- | Generate the 'ModuleDecl' for a module and convert it to 'Text'. genModuleDecl :: ModuleDecl -> Text genModuleDecl mod = "module " <> mod ^. moduleId . getIdentifier @@ -27,6 +43,7 @@ genModuleDecl mod = ports = sep ",\n" $ genPort <$> mod ^. modPorts modItems = fromList $ genModuleItem <$> mod ^. moduleItems +-- | Generate the 'Port' description. genPort :: Port -> Text genPort port = " " <> dir <> " " <> name @@ -34,14 +51,17 @@ genPort port = dir = genPortDir $ port ^. portDir name = port ^. portName . getIdentifier +-- | Convert the 'PortDir' type to 'Text'. genPortDir :: PortDir -> Text genPortDir Input = "input" genPortDir Output = "output" genPortDir InOut = "inout" +-- | Generate a 'ModuleItem'. genModuleItem :: ModuleItem -> Text genModuleItem (Assign assign) = genContAssign assign +-- | Generate the 'ContinuousAssignment' to 'Text'. genContAssign :: ContAssign -> Text genContAssign assign = " assign " <> name <> " = " <> expr <> ";\n" @@ -49,6 +69,7 @@ genContAssign assign = name = assign ^. contAssignNetLVal . getIdentifier expr = genExpr $ assign ^. contAssignExpr +-- | Generate 'Expression' to 'Text'. genExpr :: Expression -> Text genExpr (OpExpr exprRhs bin exprLhs) = genExpr exprRhs <> genBinaryOperator bin <> genExpr exprLhs @@ -56,6 +77,7 @@ genExpr (PrimExpr prim) = genPrimary prim genExpr _ = "TODO" +-- | Generate a 'PrimaryExpression' to 'Text'. genPrimary :: Primary -> Text genPrimary (PrimNum num) = neg <> sh (num ^. numSize) <> "'d" <> (sh . abs) n @@ -66,10 +88,12 @@ genPrimary (PrimNum num) = neg = if n <= 0 then "-" else "" genPrimary (PrimId ident) = ident ^. getIdentifier +-- | Convert 'BinaryOperator' to 'Text'. genBinaryOperator :: BinaryOperator -> Text genBinaryOperator BinAnd = " & " genBinaryOperator BinOr = " | " genBinaryOperator BinXor = " ^ " +-- | Render the 'Text' to 'IO'. This is equivalent to 'putStrLn'. render :: Text -> IO () render = T.putStrLn diff --git a/src/Test/VeriFuzz/Graph/CodeGen.hs b/src/Test/VeriFuzz/Graph/CodeGen.hs index 6f7aef6..43fee25 100644 --- a/src/Test/VeriFuzz/Graph/CodeGen.hs +++ b/src/Test/VeriFuzz/Graph/CodeGen.hs @@ -1,13 +1,27 @@ +{-| +Module : Test.VeriFuzz.Graph.Random +Description : Code generation directly from DAG. +Copyright : (c) Yann Herklotz Grave 2018 +License : GPL-3 +Maintainer : ymherklotz@gmail.com +Stability : experimental +Portability : POSIX + +Define the code generation directly from the random DAG. +-} + {-# LANGUAGE OverloadedStrings #-} -module Test.VeriFuzz.Graph.CodeGen where +module Test.VeriFuzz.Graph.CodeGen + ( generate + ) where import Data.Graph.Inductive (Graph, LNode, Node, indeg, labNodes, nodes, outdeg, pre) import Data.Maybe (fromMaybe) import Data.Text (Text, empty, pack) +import Test.VeriFuzz.Circuit import Test.VeriFuzz.Internal.Shared -import Test.VeriFuzz.Types fromNode :: Node -> Text fromNode node = pack $ "w" <> show node diff --git a/src/Test/VeriFuzz/Graph/Random.hs b/src/Test/VeriFuzz/Graph/Random.hs index e87036c..a31e374 100644 --- a/src/Test/VeriFuzz/Graph/Random.hs +++ b/src/Test/VeriFuzz/Graph/Random.hs @@ -1,9 +1,23 @@ +{-| +Module : Test.VeriFuzz.Graph.Random +Description : Random generation for DAG +Copyright : (c) Yann Herklotz Grave 2018 +License : GPL-3 +Maintainer : ymherklotz@gmail.com +Stability : experimental +Portability : POSIX + +Define the random generation for the directed acyclic graph. +-} + module Test.VeriFuzz.Graph.Random where import Data.Graph.Inductive (Graph, LEdge, mkGraph) import Test.QuickCheck (Arbitrary, Gen, arbitrary, generate, infiniteListOf, resize, suchThat) +-- | Gen instance to create an arbitrary edge, where the edges are limited by +-- `n` that is passed to it. arbitraryEdge :: (Arbitrary e) => Int -> Gen (LEdge e) arbitraryEdge n = do x <- with $ \a -> a < n && a > 0 && a /= n-1 @@ -13,6 +27,7 @@ arbitraryEdge n = do where with = suchThat . resize n $ arbitrary +-- | Gen instance for a random acyclic DAG. randomDAG :: (Arbitrary l, Arbitrary e, Graph gr) => Int -- ^ The number of nodes -> Gen (gr l e) -- ^ The generated graph. It uses Arbitrary to @@ -24,6 +39,7 @@ randomDAG n = do where nodes l = zip [0..n] $ take n l +-- | Generate a random acyclic DAG with an IO instance. genRandomDAG :: (Arbitrary l, Arbitrary e, Graph gr) => Int -> IO (gr l e) diff --git a/src/Test/VeriFuzz/Internal/Shared.hs b/src/Test/VeriFuzz/Internal/Shared.hs index 84e6af6..0e08d5a 100644 --- a/src/Test/VeriFuzz/Internal/Shared.hs +++ b/src/Test/VeriFuzz/Internal/Shared.hs @@ -1,14 +1,31 @@ +{-| +Module : Test.VeriFuzz.Internal.Shared +Description : Shared high level code used in the other modules internally. +Copyright : (c) Yann Herklotz Grave 2018 +License : GPL-3 +Maintainer : ymherklotz@gmail.com +Stability : experimental +Portability : POSIX + +Shared high level code used in the other modules internally. +-} + module Test.VeriFuzz.Internal.Shared where import Data.Maybe (fromMaybe) +-- | Fold up a list of Monoids using mappend and mempty as the first +-- element. fromList :: (Foldable t, Monoid a) => t a -> a fromList = foldl mappend mempty +-- | Combine the Monoid elements of a list and insert the seperation symbol in +-- between each element except the last one. sep :: (Monoid a) => a -> [a] -> a sep el l = fromMaybe mempty $ (fromList . fmap (<>el) <$> safe init l) <> safe last l +-- | Converts unsafe list functions in the Prelude to a safe version. safe :: ([a] -> b) -> [a] -> Maybe b safe _ [] = Nothing safe f l = Just $ f l diff --git a/src/Test/VeriFuzz/VerilogAST.hs b/src/Test/VeriFuzz/VerilogAST.hs index 41c855a..fc3c07b 100644 --- a/src/Test/VeriFuzz/VerilogAST.hs +++ b/src/Test/VeriFuzz/VerilogAST.hs @@ -1,3 +1,15 @@ +{-| +Module : Test.VeriFuzz.VerilogAST +Description : Definition of the Verilog AST types. +Copyright : (c) Yann Herklotz Grave 2018 +License : GPL-3 +Maintainer : ymherklotz@gmail.com +Stability : experimental +Portability : POSIX + +Defines the types to build a Verilog AST. +-} + {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-} @@ -8,26 +20,35 @@ import Data.Text as T import Data.Text (Text) import Test.QuickCheck as QC +-- | Identifier in Verilog. This is just a string of characters that can either +-- be lowercase and uppercase for now. This might change in the future though, +-- as Verilog supports many more characters in Identifiers. newtype Identifier = Identifier { _getIdentifier :: Text } deriving (Show) +-- | A number in Verilog which contains a size and a value. data Number = Number { _numSize :: Int , _numVal :: Int } deriving (Show) -data BinaryOperator = BinAnd - | BinOr - | BinXor +-- | Binary operators that are currently supported in the verilog generation. +data BinaryOperator = BinAnd -- ^ Binary And (&). + | BinOr -- ^ Binary Or (|). + | BinXor -- ^ Binary Xor (^). deriving (Show) -data UnaryOperator = UnNot - | UnMinus +-- | Unary operators that are currently supported by the generator. +data UnaryOperator = UnNot -- ^ Not (!). + | UnMinus -- ^ Minus (-). deriving (Show) -data Primary = PrimNum Number - | PrimId Identifier +-- | A primary expression which can either be a number or an identifier. +data Primary = PrimNum Number -- ^ Number in primary expression. + | PrimId Identifier -- ^ Identifier in primary expression. deriving (Show) +-- | Verilog expression, which can either be a primary expression, unary +-- expression, binary operator expression or a conditional expression. data Expression = PrimExpr Primary | UnPrimExpr { _exprUnOp :: UnaryOperator , _exprPrim :: Primary @@ -42,19 +63,23 @@ data Expression = PrimExpr Primary } deriving (Show) +-- | Continuous assignment which can be in the body of a statement. data ContAssign = ContAssign { _contAssignNetLVal :: Identifier , _contAssignExpr :: Expression } deriving (Show) -data PortDir = Input - | Output - | InOut +-- | Different port direction that are supported in Verilog. +data PortDir = Input -- ^ Input direction for port (@input@). + | Output -- ^ Output direction for port (@output@). + | InOut -- ^ Inout direction for port (@inout@). deriving (Show) -data Port = Port { _portName :: Identifier - , _portDir :: PortDir +-- | Port declaration. +data Port = Port { _portDir :: PortDir + , _portName :: Identifier } deriving (Show) +-- | Module item which is the body of the module expression. newtype ModuleItem = Assign ContAssign deriving (Show) @@ -64,9 +89,11 @@ data ModuleDecl = ModuleDecl { _moduleId :: Identifier , _moduleItems :: [ModuleItem] } deriving (Show) +-- | Description of the Verilog module. newtype Description = Description { _getDescription :: ModuleDecl } deriving (Show) +-- | The complete sourcetext for the Verilog module. newtype SourceText = SourceText { _getSourceText :: [Description] } deriving (Show) @@ -77,7 +104,7 @@ instance QC.Arbitrary Identifier where (QC.shuffle (['a'..'z'] <> ['A'..'Z']) >>= QC.sublistOf) instance QC.Arbitrary Number where - arbitrary = Number <$> (suchThat QC.arbitrary (>=0)) <*> QC.arbitrary + arbitrary = Number <$> (suchThat QC.arbitrary (>0)) <*> QC.arbitrary instance QC.Arbitrary BinaryOperator where arbitrary = QC.elements [BinAnd, BinOr, BinXor] @@ -132,14 +159,18 @@ makeLenses ''ContAssign -- Helper functions for the AST +-- | Create a number expression which will be stored in a primary expression. numExpr :: Int -> Int -> Expression numExpr = ((PrimExpr . PrimNum) .) . Number +-- | Create an empty module. emptyMod :: ModuleDecl emptyMod = ModuleDecl (Identifier "") [] [] +-- | Set a module name for a module declaration. setModName :: Text -> ModuleDecl -> ModuleDecl setModName str = moduleId .~ Identifier str +-- | Add a port to the module declaration. addModPort :: Port -> ModuleDecl -> ModuleDecl addModPort port = modPorts %~ (:) port -- cgit