From 7124a4f00e536b4d5323a7488c1f65469dddb102 Mon Sep 17 00:00:00 2001 From: Yann Herklotz Date: Tue, 12 May 2020 12:21:36 +0100 Subject: Format with ormolu --- src/Verismith/Verilog/AST.hs | 906 +++++++++++++++++++++++++------------------ 1 file changed, 522 insertions(+), 384 deletions(-) (limited to 'src/Verismith/Verilog/AST.hs') diff --git a/src/Verismith/Verilog/AST.hs b/src/Verismith/Verilog/AST.hs index 5826a34..d870cfb 100644 --- a/src/Verismith/Verilog/AST.hs +++ b/src/Verismith/Verilog/AST.hs @@ -1,91 +1,176 @@ -{-| -Module : Verismith.Verilog.AST -Description : Definition of the Verilog AST types. -Copyright : (c) 2018-2019, Yann Herklotz -License : GPL-3 -Maintainer : yann [at] yannherklotz [dot] com -Stability : experimental -Poratbility : POSIX - -Defines the types to build a Verilog AST. --} - -{-# LANGUAGE DeriveAnyClass #-} -{-# LANGUAGE DeriveDataTypeable #-} -{-# LANGUAGE DeriveFoldable #-} -{-# LANGUAGE DeriveFunctor #-} -{-# LANGUAGE DeriveGeneric #-} -{-# LANGUAGE DeriveTraversable #-} -{-# LANGUAGE FlexibleInstances #-} +{-# LANGUAGE DeriveAnyClass #-} +{-# LANGUAGE DeriveDataTypeable #-} +{-# LANGUAGE DeriveFoldable #-} +{-# LANGUAGE DeriveFunctor #-} +{-# LANGUAGE DeriveGeneric #-} +{-# LANGUAGE DeriveTraversable #-} +{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE MultiParamTypeClasses #-} -{-# LANGUAGE RankNTypes #-} -{-# LANGUAGE StandaloneDeriving #-} -{-# LANGUAGE TemplateHaskell #-} -{-# LANGUAGE TypeFamilies #-} - +{-# LANGUAGE RankNTypes #-} +{-# LANGUAGE StandaloneDeriving #-} +{-# LANGUAGE TemplateHaskell #-} +{-# LANGUAGE TypeFamilies #-} + +-- | +-- Module : Verismith.Verilog.AST +-- Description : Definition of the Verilog AST types. +-- Copyright : (c) 2018-2019, Yann Herklotz +-- License : GPL-3 +-- Maintainer : yann [at] yannherklotz [dot] com +-- Stability : experimental +-- Poratbility : POSIX +-- +-- Defines the types to build a Verilog AST. module Verismith.Verilog.AST - ( -- * Top level types - SourceInfo(..), infoTop, infoSrc - , Verilog(..) + ( -- * Top level types + SourceInfo (..), + infoTop, + infoSrc, + Verilog (..), + -- * Primitives + -- ** Identifier - , Identifier(..) + Identifier (..), + -- ** Control - , Delay(..) - , Event(..) + Delay (..), + Event (..), + -- ** Operators - , BinaryOperator(..) - , UnaryOperator(..) + BinaryOperator (..), + UnaryOperator (..), + -- ** Task - , Task(..), taskName, taskExpr + Task (..), + taskName, + taskExpr, + -- ** Left hand side value - , LVal(..), regId, regExprId, regExpr, regSizeId, regSizeRange, regConc + LVal (..), + regId, + regExprId, + regExpr, + regSizeId, + regSizeRange, + regConc, + -- ** Ports - , PortDir(..) - , PortType(..) - , Port(..), portType, portSigned, portSize, portName + PortDir (..), + PortType (..), + Port (..), + portType, + portSigned, + portSize, + portName, + -- * Expression - , Expr(..) - , ConstExpr(..) - , ConstExprF(..), constToExpr, exprToConst - , Range(..), constNum, constParamId, constConcat, constUnOp, constPrim, constLhs - , constBinOp, constRhs, constCond, constTrue, constFalse, constStr + Expr (..), + ConstExpr (..), + ConstExprF (..), + constToExpr, + exprToConst, + Range (..), + constNum, + constParamId, + constConcat, + constUnOp, + constPrim, + constLhs, + constBinOp, + constRhs, + constCond, + constTrue, + constFalse, + constStr, + -- * Assignment - , Assign(..), assignReg, assignDelay, assignExpr - , ContAssign(..), contAssignNetLVal, contAssignExpr + Assign (..), + assignReg, + assignDelay, + assignExpr, + ContAssign (..), + contAssignNetLVal, + contAssignExpr, + -- ** Parameters - , Parameter(..), paramIdent, paramValue - , LocalParam(..), localParamIdent, localParamValue + Parameter (..), + paramIdent, + paramValue, + LocalParam (..), + localParamIdent, + localParamValue, + -- * Statment - , CaseType(..) - , CasePair(..) - , Statement(..), statDelay, statDStat, statEvent, statEStat, statements, stmntBA - , stmntNBA, stmntTask, stmntSysTask, stmntCondExpr, stmntCondTrue, stmntCondFalse - , stmntCaseType, stmntCaseExpr, stmntCasePair, stmntCaseDefault, forAssign, forExpr - , forIncr, forStmnt + CaseType (..), + CasePair (..), + Statement (..), + statDelay, + statDStat, + statEvent, + statEStat, + statements, + stmntBA, + stmntNBA, + stmntTask, + stmntSysTask, + stmntCondExpr, + stmntCondTrue, + stmntCondFalse, + stmntCaseType, + stmntCaseExpr, + stmntCasePair, + stmntCaseDefault, + forAssign, + forExpr, + forIncr, + forStmnt, + -- * Module - , ModDecl(..), modId, modOutPorts, modInPorts, modItems, modParams - , ModItem(..), modContAssign, modInstId, modInstName, modInstConns, _Initial, _Always - , paramDecl, localParamDecl, traverseModItem, declDir, declPort, declVal, ModConn(..) - , modConnName, modExpr + ModDecl (..), + modId, + modOutPorts, + modInPorts, + modItems, + modParams, + ModItem (..), + modContAssign, + modInstId, + modInstName, + modInstConns, + _Initial, + _Always, + paramDecl, + localParamDecl, + traverseModItem, + declDir, + declPort, + declVal, + ModConn (..), + modConnName, + modExpr, + -- * Useful Lenses and Traversals - , aModule, getModule, getSourceId, mainModule - , Annotations(..) - ) + aModule, + getModule, + getSourceId, + mainModule, + Annotations (..), + ) where -import Control.DeepSeq (NFData) -import Control.Lens hiding ((<|)) -import Data.Data -import Data.Data.Lens -import Data.Functor.Foldable.TH (makeBaseFunctor) -import Data.List.NonEmpty (NonEmpty (..), (<|)) -import Data.String (IsString, fromString) -import Data.Text (Text, pack) -import Data.Traversable (sequenceA) -import Data.Void (Void) -import GHC.Generics (Generic) -import Verismith.Verilog.BitVec +import Control.DeepSeq (NFData) +import Control.Lens hiding ((<|)) +import Data.Data +import Data.Data.Lens +import Data.Functor.Foldable.TH (makeBaseFunctor) +import Data.List.NonEmpty ((<|), NonEmpty (..)) +import Data.String (IsString, fromString) +import Data.Text (Text, pack) +import Data.Traversable (sequenceA) +import Data.Void (Void) +import GHC.Generics (Generic) +import Verismith.Verilog.BitVec class Functor m => Annotations m where removeAnn :: m a -> m a @@ -97,112 +182,128 @@ class Functor m => Annotations m where -- @ -- (* synthesis *) -- @ -data Attribute = AttrAssign Identifier ConstExpr - | AttrName Identifier - deriving (Eq, Show, Ord, Data, Generic, NFData) +data Attribute + = AttrAssign Identifier ConstExpr + | AttrName Identifier + deriving (Eq, Show, Ord, Data, Generic, NFData) -- | Annotations which can be added to the AST. These are supported in all the -- nodes of the AST and a custom type can be declared for them. -data Annotation a = Ann a - | AnnAttrs [Attribute] - deriving (Eq, Show, Ord, Data, Generic, NFData) +data Annotation a + = Ann a + | AnnAttrs [Attribute] + deriving (Eq, Show, Ord, Data, Generic, NFData) -- | 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 (Eq, Show, Ord, Data, Generic, NFData) +newtype Identifier = Identifier {getIdentifier :: Text} + deriving (Eq, Show, Ord, Data, Generic, NFData) + +$(makeWrapped ''Identifier) instance IsString Identifier where - fromString = Identifier . pack + fromString = Identifier . pack instance Semigroup Identifier where - Identifier a <> Identifier b = Identifier $ a <> b + Identifier a <> Identifier b = Identifier $ a <> b instance Monoid Identifier where - mempty = Identifier mempty + mempty = Identifier mempty -- | Verilog syntax for adding a delay, which is represented as @#num@. -newtype Delay = Delay { _getDelay :: Int } - deriving (Eq, Show, Ord, Data, Generic, NFData) +newtype Delay = Delay {_getDelay :: Int} + deriving (Eq, Show, Ord, Data, Generic, NFData) + +$(makeWrapped ''Delay) instance Num Delay where - Delay a + Delay b = Delay $ a + b - Delay a - Delay b = Delay $ a - b - Delay a * Delay b = Delay $ a * b - negate (Delay a) = Delay $ negate a - abs (Delay a) = Delay $ abs a - signum (Delay a) = Delay $ signum a - fromInteger = Delay . fromInteger + Delay a + Delay b = Delay $ a + b + Delay a - Delay b = Delay $ a - b + Delay a * Delay b = Delay $ a * b + negate (Delay a) = Delay $ negate a + abs (Delay a) = Delay $ abs a + signum (Delay a) = Delay $ signum a + fromInteger = Delay . fromInteger -- | Verilog syntax for an event, such as @\@x@, which is used for always blocks -data Event = EId {-# UNPACK #-} !Identifier - | EExpr !Expr - | EAll - | EPosEdge {-# UNPACK #-} !Identifier - | ENegEdge {-# UNPACK #-} !Identifier - | EOr !Event !Event - | EComb !Event !Event - deriving (Eq, Show, Ord, Data, Generic, NFData) +data Event + = EId {-# UNPACK #-} !Identifier + | EExpr !Expr + | EAll + | EPosEdge {-# UNPACK #-} !Identifier + | ENegEdge {-# UNPACK #-} !Identifier + | EOr !Event !Event + | EComb !Event !Event + deriving (Eq, Show, Ord, Data, Generic, NFData) + +$(makeBaseFunctor ''Event) instance Plated Event where - plate = uniplate + plate = uniplate -- | Binary operators that are currently supported in the verilog generation. -data BinaryOperator = BinPlus - | BinMinus - | BinTimes - | BinDiv - | BinMod - | BinEq - | BinNEq - | BinCEq - | BinCNEq - | BinLAnd - | BinLOr - | BinLT - | BinLEq - | BinGT - | BinGEq - | BinAnd - | BinOr - | BinXor - | BinXNor - | BinXNorInv - | BinPower - | BinLSL - | BinLSR - | BinASL - | BinASR - deriving (Eq, Show, Ord, Data, Generic, NFData) +data BinaryOperator + = BinPlus + | BinMinus + | BinTimes + | BinDiv + | BinMod + | BinEq + | BinNEq + | BinCEq + | BinCNEq + | BinLAnd + | BinLOr + | BinLT + | BinLEq + | BinGT + | BinGEq + | BinAnd + | BinOr + | BinXor + | BinXNor + | BinXNorInv + | BinPower + | BinLSL + | BinLSR + | BinASL + | BinASR + deriving (Eq, Show, Ord, Data, Generic, NFData) -- | Unary operators that are currently supported by the generator. -data UnaryOperator = UnPlus - | UnMinus - | UnLNot - | UnNot - | UnAnd - | UnNand - | UnOr - | UnNor - | UnXor - | UnNxor - | UnNxorInv - deriving (Eq, Show, Ord, Data, Generic, NFData) +data UnaryOperator + = UnPlus + | UnMinus + | UnLNot + | UnNot + | UnAnd + | UnNand + | UnOr + | UnNor + | UnXor + | UnNxor + | UnNxorInv + deriving (Eq, Show, Ord, Data, Generic, NFData) -- | Verilog expression, which can either be a primary expression, unary -- expression, binary operator expression or a conditional expression. -data Expr = Number {-# UNPACK #-} !BitVec - | Id {-# UNPACK #-} !Identifier - | VecSelect {-# UNPACK #-} !Identifier !Expr - | RangeSelect {-# UNPACK #-} !Identifier !Range - | Concat !(NonEmpty Expr) - | UnOp !UnaryOperator !Expr - | BinOp !Expr !BinaryOperator !Expr - | Cond !Expr !Expr !Expr - | Appl !Identifier !Expr - | Str {-# UNPACK #-} !Text - deriving (Eq, Show, Ord, Data, Generic, NFData) +data Expr + = Number {-# UNPACK #-} !BitVec + | Id {-# UNPACK #-} !Identifier + | VecSelect {-# UNPACK #-} !Identifier !Expr + | RangeSelect {-# UNPACK #-} !Identifier !Range + | Concat !(NonEmpty Expr) + | UnOp !UnaryOperator !Expr + | BinOp !Expr !BinaryOperator !Expr + | Cond !Expr !Expr !Expr + | Appl !Identifier !Expr + | Str {-# UNPACK #-} !Text + deriving (Eq, Show, Ord, Data, Generic, NFData) + +$(makeLenses ''Expr) + +$(makeBaseFunctor ''Expr) instance Num Expr where a + b = BinOp a BinPlus b @@ -229,54 +330,59 @@ instance Plated Expr where plate = uniplate -- | Constant expression, which are known before simulation at compile time. -data ConstExpr = ConstNum - { _constNum :: {-# UNPACK #-} !BitVec - } - | ParamId - { _constParamId :: {-# UNPACK #-} !Identifier - } - | ConstConcat - { _constConcat :: !(NonEmpty ConstExpr) - } - | ConstUnOp - { _constUnOp :: !UnaryOperator - , _constPrim :: !ConstExpr - } - | ConstBinOp - { _constLhs :: !ConstExpr - , _constBinOp :: !BinaryOperator - , _constRhs :: !ConstExpr - } - | ConstCond - { _constCond :: !ConstExpr - , _constTrue :: !ConstExpr - , _constFalse :: !ConstExpr - } - | ConstStr - { _constStr :: {-# UNPACK #-} !Text - } - deriving (Eq, Show, Ord, Data, Generic, NFData) +data ConstExpr + = ConstNum + { _constNum :: {-# UNPACK #-} !BitVec + } + | ParamId + { _constParamId :: {-# UNPACK #-} !Identifier + } + | ConstConcat + { _constConcat :: !(NonEmpty ConstExpr) + } + | ConstUnOp + { _constUnOp :: !UnaryOperator, + _constPrim :: !ConstExpr + } + | ConstBinOp + { _constLhs :: !ConstExpr, + _constBinOp :: !BinaryOperator, + _constRhs :: !ConstExpr + } + | ConstCond + { _constCond :: !ConstExpr, + _constTrue :: !ConstExpr, + _constFalse :: !ConstExpr + } + | ConstStr + { _constStr :: {-# UNPACK #-} !Text + } + deriving (Eq, Show, Ord, Data, Generic, NFData) + +$(makeLenses ''ConstExpr) + +$(makeBaseFunctor ''ConstExpr) constToExpr :: ConstExpr -> Expr -constToExpr (ConstNum a ) = Number a -constToExpr (ParamId a ) = Id a -constToExpr (ConstConcat a ) = Concat $ fmap constToExpr a -constToExpr (ConstUnOp a b ) = UnOp a $ constToExpr b +constToExpr (ConstNum a) = Number a +constToExpr (ParamId a) = Id a +constToExpr (ConstConcat a) = Concat $ fmap constToExpr a +constToExpr (ConstUnOp a b) = UnOp a $ constToExpr b constToExpr (ConstBinOp a b c) = BinOp (constToExpr a) b $ constToExpr c constToExpr (ConstCond a b c) = - Cond (constToExpr a) (constToExpr b) $ constToExpr c + Cond (constToExpr a) (constToExpr b) $ constToExpr c constToExpr (ConstStr a) = Str a exprToConst :: Expr -> ConstExpr -exprToConst (Number a ) = ConstNum a -exprToConst (Id a ) = ParamId a -exprToConst (Concat a ) = ConstConcat $ fmap exprToConst a -exprToConst (UnOp a b ) = ConstUnOp a $ exprToConst b +exprToConst (Number a) = ConstNum a +exprToConst (Id a) = ParamId a +exprToConst (Concat a) = ConstConcat $ fmap exprToConst a +exprToConst (UnOp a b) = ConstUnOp a $ exprToConst b exprToConst (BinOp a b c) = ConstBinOp (exprToConst a) b $ exprToConst c exprToConst (Cond a b c) = - ConstCond (exprToConst a) (exprToConst b) $ exprToConst c + ConstCond (exprToConst a) (exprToConst b) $ exprToConst c exprToConst (Str a) = ConstStr a -exprToConst _ = error "Not a constant expression" +exprToConst _ = error "Not a constant expression" instance Num ConstExpr where a + b = ConstBinOp a BinPlus b @@ -303,11 +409,14 @@ instance Plated ConstExpr where plate = uniplate -- | Task call, which is similar to function calls. -data Task = Task - { _taskName :: {-# UNPACK #-} !Identifier - , _taskExpr :: [Expr] - } - deriving (Eq, Show, Ord, Data, Generic, NFData) +data Task + = Task + { _taskName :: {-# UNPACK #-} !Identifier, + _taskExpr :: [Expr] + } + deriving (Eq, Show, Ord, Data, Generic, NFData) + +$(makeLenses ''Task) -- | Type that represents the left hand side of an assignment, which can be a -- concatenation such as in: @@ -315,54 +424,62 @@ data Task = Task -- @ -- {a, b, c} = 32'h94238; -- @ -data LVal = RegId - { _regId :: {-# UNPACK #-} !Identifier - } - | RegExpr - { _regExprId :: {-# UNPACK #-} !Identifier - , _regExpr :: !Expr - } - | RegSize - { _regSizeId :: {-# UNPACK #-} !Identifier - , _regSizeRange :: {-# UNPACK #-} !Range - } - | RegConcat - { _regConc :: [Expr] - } - deriving (Eq, Show, Ord, Data, Generic, NFData) +data LVal + = RegId + { _regId :: {-# UNPACK #-} !Identifier + } + | RegExpr + { _regExprId :: {-# UNPACK #-} !Identifier, + _regExpr :: !Expr + } + | RegSize + { _regSizeId :: {-# UNPACK #-} !Identifier, + _regSizeRange :: {-# UNPACK #-} !Range + } + | RegConcat + { _regConc :: [Expr] + } + deriving (Eq, Show, Ord, Data, Generic, NFData) + +$(makeLenses ''LVal) instance IsString LVal where fromString = RegId . fromString -- | Different port direction that are supported in Verilog. -data PortDir = PortIn - | PortOut - | PortInOut - deriving (Eq, Show, Ord, Data, Generic, NFData) +data PortDir + = PortIn + | PortOut + | PortInOut + deriving (Eq, Show, Ord, Data, Generic, NFData) -- | Currently, only @wire@ and @reg@ are supported, as the other net types are -- not that common and not a priority. -data PortType = Wire - | Reg - deriving (Eq, Show, Ord, Data, Generic, NFData) +data PortType + = Wire + | Reg + deriving (Eq, Show, Ord, Data, Generic, NFData) -- | Range that can be associated with any port or left hand side. Contains the -- msb and lsb bits as 'ConstExpr'. This means that they can be generated using -- parameters, which can in turn be changed at synthesis time. -data Range = Range - { rangeMSB :: !ConstExpr - , rangeLSB :: !ConstExpr - } - deriving (Eq, Show, Ord, Data, Generic, NFData) +data Range + = Range + { rangeMSB :: !ConstExpr, + rangeLSB :: !ConstExpr + } + deriving (Eq, Show, Ord, Data, Generic, NFData) + +$(makeLenses ''PortType) instance Num Range where - (Range s1 a) + (Range s2 b) = Range (s1 + s2) $ a + b - (Range s1 a) - (Range s2 b) = Range (s1 - s2) . max 0 $ a - b - (Range s1 a) * (Range s2 b) = Range (s1 * s2) $ a * b - negate = undefined - abs = id - signum _ = 1 - fromInteger = flip Range 0 . fromInteger . (-) 1 + (Range s1 a) + (Range s2 b) = Range (s1 + s2) $ a + b + (Range s1 a) - (Range s2 b) = Range (s1 - s2) . max 0 $ a - b + (Range s1 a) * (Range s2 b) = Range (s1 * s2) $ a * b + negate = undefined + abs = id + signum _ = 1 + fromInteger = flip Range 0 . fromInteger . (-) 1 -- | Port declaration. It contains information about the type of the port, the -- size, and the port name. It used to also contain information about if it was @@ -372,13 +489,16 @@ instance Num Range where -- -- This is now implemented inside '(ModDecl ann)' itself, which uses a list of output -- and input ports. -data Port = Port - { _portType :: !PortType - , _portSigned :: !Bool - , _portSize :: {-# UNPACK #-} !Range - , _portName :: {-# UNPACK #-} !Identifier - } - deriving (Eq, Show, Ord, Data, Generic, NFData) +data Port + = Port + { _portType :: !PortType, + _portSigned :: !Bool, + _portSize :: {-# UNPACK #-} !Range, + _portName :: {-# UNPACK #-} !Identifier + } + deriving (Eq, Show, Ord, Data, Generic, NFData) + +$(makeLenses ''Port) -- | This is currently a type because direct module declaration should also be -- added: @@ -386,40 +506,50 @@ data Port = Port -- @ -- mod a(.y(y1), .x1(x11), .x2(x22)); -- @ -data ModConn = ModConn - { _modExpr :: !Expr - } - | ModConnNamed - { _modConnName :: {-# UNPACK #-} !Identifier - , _modExpr :: !Expr - } - deriving (Eq, Show, Ord, Data, Generic, NFData) - -data Assign = Assign - { _assignReg :: !LVal - , _assignDelay :: !(Maybe Delay) - , _assignExpr :: !Expr - } - deriving (Eq, Show, Ord, Data, Generic, NFData) +data ModConn + = ModConn + { _modExpr :: !Expr + } + | ModConnNamed + { _modConnName :: {-# UNPACK #-} !Identifier, + _modExpr :: !Expr + } + deriving (Eq, Show, Ord, Data, Generic, NFData) + +$(makeLenses ''ModConn) + +data Assign + = Assign + { _assignReg :: !LVal, + _assignDelay :: !(Maybe Delay), + _assignExpr :: !Expr + } + deriving (Eq, Show, Ord, Data, Generic, NFData) + +$(makeLenses ''Assign) -- | Type for continuous assignment. -- -- @ -- assign x = 2'b1; -- @ -data ContAssign = ContAssign - { _contAssignNetLVal :: {-# UNPACK #-} !Identifier - , _contAssignExpr :: !Expr - } - deriving (Eq, Show, Ord, Data, Generic, NFData) +data ContAssign + = ContAssign + { _contAssignNetLVal :: {-# UNPACK #-} !Identifier, + _contAssignExpr :: !Expr + } + deriving (Eq, Show, Ord, Data, Generic, NFData) + +$(makeLenses ''ContAssign) -- | Case pair which contains an expression followed by a statement which will -- get executed if the expression matches the expression in the case statement. -data CasePair a = CasePair - { _casePairExpr :: !Expr - , _casePairStmnt :: !(Statement a) - } - deriving (Eq, Show, Ord, Data, Generic, NFData) +data CasePair a + = CasePair + { _casePairExpr :: !Expr, + _casePairStmnt :: !(Statement a) + } + deriving (Eq, Show, Ord, Data, Generic, NFData) instance Functor CasePair where fmap f (CasePair e s) = CasePair e $ fmap f s @@ -427,62 +557,72 @@ instance Functor CasePair where instance Annotations CasePair where removeAnn (CasePair e s) = CasePair e $ removeAnn s -traverseStmntCasePair :: Functor f => - (Statement a1 -> f (Statement a2)) -> CasePair a1 -> f (CasePair a2) +traverseStmntCasePair :: + Functor f => + (Statement a1 -> f (Statement a2)) -> + CasePair a1 -> + f (CasePair a2) traverseStmntCasePair f (CasePair a s) = CasePair a <$> f s -- | Type of case statement, which determines how it is interpreted. -data CaseType = CaseStandard - | CaseX - | CaseZ - deriving (Eq, Show, Ord, Data, Generic, NFData) +data CaseType + = CaseStandard + | CaseX + | CaseZ + deriving (Eq, Show, Ord, Data, Generic, NFData) -- | Statements in Verilog. -data Statement a = - TimeCtrl { _statDelay :: {-# UNPACK #-} !Delay - , _statDStat :: Maybe (Statement a) - -- ^ Time control (@#NUM@) - } - | EventCtrl { _statEvent :: !Event - , _statEStat :: Maybe (Statement a) - } - | SeqBlock { _statements :: [Statement a] -- ^ Sequential block (@begin ... end@) - -- ^ blocking assignment (@=@) - } - | BlockAssign { _stmntBA :: !Assign -- ^ blocking assignment (@=@) - -- ^ Non blocking assignment (@<=@) - } - | NonBlockAssign { _stmntNBA :: !Assign } -- ^ Non blocking assignment (@<=@) - | TaskEnable { _stmntTask :: !Task } - | SysTaskEnable { _stmntSysTask :: !Task } - | CondStmnt { _stmntCondExpr :: Expr - , _stmntCondTrue :: Maybe (Statement a) - , _stmntCondFalse :: Maybe (Statement a) - } - | StmntCase { _stmntCaseType :: !CaseType - , _stmntCaseExpr :: !Expr - , _stmntCasePair :: ![CasePair a] - , _stmntCaseDefault :: !(Maybe (Statement a)) - } - | ForLoop { _forAssign :: !Assign - , _forExpr :: Expr - , _forIncr :: !Assign - , _forStmnt :: Statement a - -- ^ Loop bounds shall be statically computable for a for loop. - } +data Statement a + = -- | Time control (@#NUM@) + TimeCtrl + { _statDelay :: {-# UNPACK #-} !Delay, + _statDStat :: Maybe (Statement a) + } + | EventCtrl + { _statEvent :: !Event, + _statEStat :: Maybe (Statement a) + } + | -- | Sequential block (@begin ... end@) + SeqBlock {_statements :: [Statement a]} + | -- | blocking assignment (@=@) + BlockAssign {_stmntBA :: !Assign} + | -- | Non blocking assignment (@<=@) + NonBlockAssign {_stmntNBA :: !Assign} + | TaskEnable {_stmntTask :: !Task} + | SysTaskEnable {_stmntSysTask :: !Task} + | CondStmnt + { _stmntCondExpr :: Expr, + _stmntCondTrue :: Maybe (Statement a), + _stmntCondFalse :: Maybe (Statement a) + } + | StmntCase + { _stmntCaseType :: !CaseType, + _stmntCaseExpr :: !Expr, + _stmntCasePair :: ![CasePair a], + _stmntCaseDefault :: !(Maybe (Statement a)) + } + | -- | Loop bounds shall be statically computable for a for loop. + ForLoop + { _forAssign :: !Assign, + _forExpr :: Expr, + _forIncr :: !Assign, + _forStmnt :: Statement a + } | StmntAnn a (Statement a) deriving (Eq, Show, Ord, Data, Generic, NFData) +$(makeLenses ''Statement) + instance Plated (Statement a) where - plate f (TimeCtrl d s) = TimeCtrl d <$> traverse f s - plate f (EventCtrl d s) = EventCtrl d <$> traverse f s - plate f (SeqBlock s) = SeqBlock <$> traverse f s - plate f (CondStmnt e s1 s2) = CondStmnt e <$> traverse f s1 <*> traverse f s2 - plate f (StmntCase a b c d) = - StmntCase a b <$> traverse (traverseStmntCasePair f) c - <*> traverse f d - plate f (ForLoop a b c d) = ForLoop a b c <$> f d - plate f a = pure a + plate f (TimeCtrl d s) = TimeCtrl d <$> traverse f s + plate f (EventCtrl d s) = EventCtrl d <$> traverse f s + plate f (SeqBlock s) = SeqBlock <$> traverse f s + plate f (CondStmnt e s1 s2) = CondStmnt e <$> traverse f s1 <*> traverse f s2 + plate f (StmntCase a b c d) = + StmntCase a b <$> traverse (traverseStmntCasePair f) c + <*> traverse f d + plate f (ForLoop a b c d) = ForLoop a b c <$> f d + plate f a = pure a instance Semigroup (Statement a) where (SeqBlock a) <> (SeqBlock b) = SeqBlock $ a <> b @@ -517,36 +657,49 @@ instance Annotations Statement where removeAnn s = s -- | Parameter that can be assigned in blocks or modules using @parameter@. -data Parameter = Parameter - { _paramIdent :: {-# UNPACK #-} !Identifier - , _paramValue :: ConstExpr - } - deriving (Eq, Show, Ord, Data, Generic, NFData) +data Parameter + = Parameter + { _paramIdent :: {-# UNPACK #-} !Identifier, + _paramValue :: ConstExpr + } + deriving (Eq, Show, Ord, Data, Generic, NFData) + +$(makeLenses ''Parameter) -- | Local parameter that can be assigned anywhere using @localparam@. It cannot -- be changed by initialising the module. -data LocalParam = LocalParam - { _localParamIdent :: {-# UNPACK #-} !Identifier - , _localParamValue :: ConstExpr - } - deriving (Eq, Show, Ord, Data, Generic, NFData) +data LocalParam + = LocalParam + { _localParamIdent :: {-# UNPACK #-} !Identifier, + _localParamValue :: ConstExpr + } + deriving (Eq, Show, Ord, Data, Generic, NFData) + +$(makeLenses ''LocalParam) -- | Module item which is the body of the module expression. -data ModItem a = ModCA { _modContAssign :: !ContAssign } - | ModInst { _modInstId :: {-# UNPACK #-} !Identifier - , _modInstName :: {-# UNPACK #-} !Identifier - , _modInstConns :: [ModConn] - } - | Initial !(Statement a) - | Always !(Statement a) - | Decl { _declDir :: !(Maybe PortDir) - , _declPort :: !Port - , _declVal :: Maybe ConstExpr - } - | ParamDecl { _paramDecl :: NonEmpty Parameter } - | LocalParamDecl { _localParamDecl :: NonEmpty LocalParam } - | ModItemAnn a (ModItem a) - deriving (Eq, Show, Ord, Data, Generic, NFData) +data ModItem a + = ModCA {_modContAssign :: !ContAssign} + | ModInst + { _modInstId :: {-# UNPACK #-} !Identifier, + _modInstName :: {-# UNPACK #-} !Identifier, + _modInstConns :: [ModConn] + } + | Initial !(Statement a) + | Always !(Statement a) + | Decl + { _declDir :: !(Maybe PortDir), + _declPort :: !Port, + _declVal :: Maybe ConstExpr + } + | ParamDecl {_paramDecl :: NonEmpty Parameter} + | LocalParamDecl {_localParamDecl :: NonEmpty LocalParam} + | ModItemAnn a (ModItem a) + deriving (Eq, Show, Ord, Data, Generic, NFData) + +$(makePrisms ''ModItem) + +$(makeLenses ''ModItem) instance Functor ModItem where fmap f (ModItemAnn a mi) = ModItemAnn (f a) $ fmap f mi @@ -565,15 +718,18 @@ instance Annotations ModItem where removeAnn mi = mi -- | 'module' module_identifier [list_of_ports] ';' { module_item } 'end_module' -data ModDecl a = ModDecl - { _modId :: {-# UNPACK #-} !Identifier - , _modOutPorts :: ![Port] - , _modInPorts :: ![Port] - , _modItems :: ![ModItem a] - , _modParams :: ![Parameter] - } - | ModDeclAnn a (ModDecl a) - deriving (Eq, Show, Ord, Data, Generic, NFData) +data ModDecl a + = ModDecl + { _modId :: {-# UNPACK #-} !Identifier, + _modOutPorts :: ![Port], + _modInPorts :: ![Port], + _modItems :: ![ModItem a], + _modParams :: ![Parameter] + } + | ModDeclAnn a (ModDecl a) + deriving (Eq, Show, Ord, Data, Generic, NFData) + +$(makeLenses ''ModDecl) instance Functor ModDecl where fmap f (ModDecl i out inp mis params) = ModDecl i out inp (fmap f <$> mis) params @@ -582,24 +738,26 @@ instance Annotations ModDecl where removeAnn (ModDecl i out inp mis params) = ModDecl i out inp (fmap removeAnn mis) params traverseModConn :: (Applicative f) => (Expr -> f Expr) -> ModConn -> f ModConn -traverseModConn f (ModConn e ) = ModConn <$> f e +traverseModConn f (ModConn e) = ModConn <$> f e traverseModConn f (ModConnNamed a e) = ModConnNamed a <$> f e traverseModItem :: (Applicative f) => (Expr -> f Expr) -> (ModItem ann) -> f (ModItem ann) traverseModItem f (ModCA (ContAssign a e)) = ModCA . ContAssign a <$> f e traverseModItem f (ModInst a b e) = - ModInst a b <$> sequenceA (traverseModConn f <$> e) + ModInst a b <$> sequenceA (traverseModConn f <$> e) traverseModItem _ e = pure e -- | The complete sourcetext for the Verilog module. -newtype Verilog a = Verilog { getVerilog :: [ModDecl a] } - deriving (Eq, Show, Ord, Data, Generic, NFData) +newtype Verilog a = Verilog {getVerilog :: [ModDecl a]} + deriving (Eq, Show, Ord, Data, Generic, NFData) + +$(makeWrapped ''Verilog) instance Semigroup (Verilog a) where - Verilog a <> Verilog b = Verilog $ a <> b + Verilog a <> Verilog b = Verilog $ a <> b instance Monoid (Verilog a) where - mempty = Verilog mempty + mempty = Verilog mempty instance Functor Verilog where fmap f (Verilog v) = Verilog $ fmap f <$> v @@ -609,17 +767,20 @@ instance Annotations Verilog where -- | Top level type which contains all the source code and associated -- information. -data SourceInfo a = SourceInfo - { _infoTop :: {-# UNPACK #-} !Text - , _infoSrc :: !(Verilog a) - } - deriving (Eq, Show, Ord, Data, Generic, NFData) +data SourceInfo a + = SourceInfo + { _infoTop :: {-# UNPACK #-} !Text, + _infoSrc :: !(Verilog a) + } + deriving (Eq, Show, Ord, Data, Generic, NFData) + +$(makeLenses ''SourceInfo) instance Semigroup (SourceInfo a) where - (SourceInfo t v) <> (SourceInfo _ v2) = SourceInfo t $ v <> v2 + (SourceInfo t v) <> (SourceInfo _ v2) = SourceInfo t $ v <> v2 instance Monoid (SourceInfo a) where - mempty = SourceInfo mempty mempty + mempty = SourceInfo mempty mempty instance Functor SourceInfo where fmap f (SourceInfo t v) = SourceInfo t $ fmap f v @@ -627,30 +788,6 @@ instance Functor SourceInfo where instance Annotations SourceInfo where removeAnn (SourceInfo t v) = SourceInfo t $ removeAnn v -$(makeLenses ''Expr) -$(makeLenses ''ConstExpr) -$(makeLenses ''Task) -$(makeLenses ''LVal) -$(makeLenses ''PortType) -$(makeLenses ''Port) -$(makeLenses ''ModConn) -$(makeLenses ''Assign) -$(makeLenses ''ContAssign) -$(makeLenses ''Statement) -$(makeLenses ''ModItem) -$(makeLenses ''Parameter) -$(makeLenses ''LocalParam) -$(makeLenses ''ModDecl) -$(makeLenses ''SourceInfo) -$(makeWrapped ''Verilog) -$(makeWrapped ''Identifier) -$(makeWrapped ''Delay) -$(makePrisms ''ModItem) - -$(makeBaseFunctor ''Event) -$(makeBaseFunctor ''Expr) -$(makeBaseFunctor ''ConstExpr) - getModule :: Traversal' (Verilog a) (ModDecl a) getModule = _Wrapped . traverse {-# INLINE getModule #-} @@ -665,25 +802,26 @@ aModule :: Identifier -> Lens' (SourceInfo a) (ModDecl a) aModule t = lens get_ set_ where set_ (SourceInfo top main) v = - SourceInfo top (main & getModule %~ update (getIdentifier t) v) - update top v m@(ModDecl (Identifier i) _ _ _ _) | i == top = v - | otherwise = m + SourceInfo top (main & getModule %~ update (getIdentifier t) v) + update top v m@(ModDecl (Identifier i) _ _ _ _) + | i == top = v + | otherwise = m update top v (ModDeclAnn _ m) = update top v m get_ (SourceInfo _ main) = - head . filter (f $ getIdentifier t) $ main ^.. getModule + head . filter (f $ getIdentifier t) $ main ^.. getModule f top (ModDecl (Identifier i) _ _ _ _) = i == top f top (ModDeclAnn _ m) = f top m - -- | May need to change this to Traversal to be safe. For now it will fail when -- the main has not been properly set with. mainModule :: Lens' (SourceInfo a) (ModDecl a) mainModule = lens get_ set_ where set_ (SourceInfo top main) v = - SourceInfo top (main & getModule %~ update top v) - update top v m@(ModDecl (Identifier i) _ _ _ _) | i == top = v - | otherwise = m + SourceInfo top (main & getModule %~ update top v) + update top v m@(ModDecl (Identifier i) _ _ _ _) + | i == top = v + | otherwise = m update top v (ModDeclAnn _ m) = update top v m get_ (SourceInfo top main) = head . filter (f top) $ main ^.. getModule f top (ModDecl (Identifier i) _ _ _ _) = i == top -- cgit