2020-07-12 23:06:27 +02:00
|
|
|
{-# LANGUAGE PatternSynonyms #-}
|
2019-03-23 00:24:45 +01:00
|
|
|
{- sv2v
|
|
|
|
|
- Author: Zachary Snow <zach@zachjs.com>
|
|
|
|
|
- Initial Verilog AST Author: Tom Hawkins <tomahawkins@gmail.com>
|
|
|
|
|
-
|
|
|
|
|
- SystemVerilog expressions
|
|
|
|
|
-}
|
|
|
|
|
|
|
|
|
|
module Language.SystemVerilog.AST.Expr
|
|
|
|
|
( Expr (..)
|
|
|
|
|
, Range
|
2019-09-09 07:38:14 +02:00
|
|
|
, TypeOrExpr
|
2019-12-08 23:36:25 +01:00
|
|
|
, ExprOrRange
|
2019-04-04 02:24:09 +02:00
|
|
|
, Args (..)
|
2019-04-05 19:53:52 +02:00
|
|
|
, PartSelectMode (..)
|
2019-09-14 18:31:44 +02:00
|
|
|
, DimsFn (..)
|
|
|
|
|
, DimFn (..)
|
2019-03-23 00:24:45 +01:00
|
|
|
, showAssignment
|
|
|
|
|
, showRanges
|
2019-12-22 01:31:56 +01:00
|
|
|
, showExprOrRange
|
2020-07-09 01:46:37 +02:00
|
|
|
, ParamBinding
|
|
|
|
|
, showParams
|
2020-07-12 23:06:27 +02:00
|
|
|
, pattern RawNum
|
2019-03-23 00:24:45 +01:00
|
|
|
) where
|
|
|
|
|
|
|
|
|
|
import Data.List (intercalate)
|
|
|
|
|
import Text.Printf (printf)
|
|
|
|
|
|
2020-07-12 23:06:27 +02:00
|
|
|
import Language.SystemVerilog.AST.Number (Number(..))
|
2019-03-23 00:24:45 +01:00
|
|
|
import Language.SystemVerilog.AST.Op
|
|
|
|
|
import Language.SystemVerilog.AST.ShowHelp
|
|
|
|
|
import {-# SOURCE #-} Language.SystemVerilog.AST.Type
|
|
|
|
|
|
|
|
|
|
type Range = (Expr, Expr)
|
|
|
|
|
|
2019-09-09 07:38:14 +02:00
|
|
|
type TypeOrExpr = Either Type Expr
|
2019-12-08 23:36:25 +01:00
|
|
|
type ExprOrRange = Either Expr Range
|
2019-09-09 07:38:14 +02:00
|
|
|
|
2020-07-12 23:06:27 +02:00
|
|
|
pattern RawNum :: Integer -> Expr
|
|
|
|
|
pattern RawNum n = Number (Decimal (-32) True n)
|
|
|
|
|
|
2019-03-23 00:24:45 +01:00
|
|
|
data Expr
|
|
|
|
|
= String String
|
2020-07-12 23:06:27 +02:00
|
|
|
| Real String
|
|
|
|
|
| Number Number
|
2019-10-07 03:21:58 +02:00
|
|
|
| Time String
|
2020-07-10 05:01:18 +02:00
|
|
|
| Ident Identifier
|
|
|
|
|
| PSIdent Identifier Identifier
|
2020-07-09 01:46:37 +02:00
|
|
|
| CSIdent Identifier [ParamBinding] Identifier
|
2019-04-05 19:53:52 +02:00
|
|
|
| Range Expr PartSelectMode Range
|
2019-03-23 00:24:45 +01:00
|
|
|
| Bit Expr Expr
|
|
|
|
|
| Repeat Expr [Expr]
|
|
|
|
|
| Concat [Expr]
|
2019-09-02 00:42:13 +02:00
|
|
|
| Stream StreamOp Expr [Expr]
|
2019-10-19 22:22:39 +02:00
|
|
|
| Call Expr Args
|
2019-03-23 00:24:45 +01:00
|
|
|
| UniOp UniOp Expr
|
|
|
|
|
| BinOp BinOp Expr Expr
|
|
|
|
|
| Mux Expr Expr Expr
|
2019-09-09 07:38:14 +02:00
|
|
|
| Cast TypeOrExpr Expr
|
2019-09-14 18:31:44 +02:00
|
|
|
| DimsFn DimsFn TypeOrExpr
|
|
|
|
|
| DimFn DimFn TypeOrExpr Expr
|
2019-03-23 00:24:45 +01:00
|
|
|
| Dot Expr Identifier
|
2019-10-14 01:01:42 +02:00
|
|
|
| Pattern [(Identifier, Expr)]
|
2019-12-08 23:36:25 +01:00
|
|
|
| Inside Expr [ExprOrRange]
|
2019-10-06 22:13:34 +02:00
|
|
|
| MinTypMax Expr Expr Expr
|
2019-09-09 07:38:14 +02:00
|
|
|
| Nil
|
2019-03-23 00:24:45 +01:00
|
|
|
deriving (Eq, Ord)
|
|
|
|
|
|
|
|
|
|
instance Show Expr where
|
2019-09-09 07:38:14 +02:00
|
|
|
show (Nil ) = ""
|
2019-10-07 03:21:58 +02:00
|
|
|
show (Time str ) = str
|
2019-03-23 00:24:45 +01:00
|
|
|
show (Ident str ) = str
|
2020-07-12 23:06:27 +02:00
|
|
|
show (Real str ) = str
|
|
|
|
|
show (Number n ) = show n
|
2019-04-24 09:37:47 +02:00
|
|
|
show (PSIdent x y ) = printf "%s::%s" x y
|
2020-07-09 01:46:37 +02:00
|
|
|
show (CSIdent x p y) = printf "%s#%s::%s" x (showParams p) y
|
2019-03-23 00:24:45 +01:00
|
|
|
show (String str ) = printf "\"%s\"" str
|
|
|
|
|
show (Bit e b ) = printf "%s[%s]" (show e) (show b)
|
2019-04-05 19:53:52 +02:00
|
|
|
show (Range e m r) = printf "%s[%s%s%s]" (show e) (show $ fst r) (show m) (show $ snd r)
|
2019-03-23 00:24:45 +01:00
|
|
|
show (Repeat e l ) = printf "{%s {%s}}" (show e) (commas $ map show l)
|
|
|
|
|
show (Concat l ) = printf "{%s}" (commas $ map show l)
|
2019-09-02 00:42:13 +02:00
|
|
|
show (Stream o e l) = printf "{%s %s%s}" (show o) (show e) (show $ Concat l)
|
2019-09-14 18:31:44 +02:00
|
|
|
show (Cast tore e ) = printf "%s'(%s)" (showEither tore) (show e)
|
|
|
|
|
show (DimsFn f v ) = printf "%s(%s)" (show f) (showEither v)
|
|
|
|
|
show (DimFn f v e) = printf "%s(%s, %s)" (show f) (showEither v) (show e)
|
2019-12-08 23:36:25 +01:00
|
|
|
show (Inside e l ) = printf "(%s inside { %s })" (show e) (intercalate ", " strs)
|
|
|
|
|
where
|
|
|
|
|
strs = map showExprOrRange l
|
2019-03-23 00:24:45 +01:00
|
|
|
show (Pattern l ) =
|
|
|
|
|
printf "'{\n%s\n}" (indent $ intercalate ",\n" $ map showPatternItem l)
|
|
|
|
|
where
|
2019-10-14 01:01:42 +02:00
|
|
|
showPatternItem :: (Identifier, Expr) -> String
|
|
|
|
|
showPatternItem ("" , e) = show e
|
|
|
|
|
showPatternItem (':' : n, e) = showPatternItem (n, e)
|
|
|
|
|
showPatternItem (n , e) = printf "%s: %s" n (show e)
|
2019-10-06 22:13:34 +02:00
|
|
|
show (MinTypMax a b c) = printf "(%s : %s : %s)" (show a) (show b) (show c)
|
2020-06-14 15:20:30 +02:00
|
|
|
show (e @ UniOp{}) = showsPrec 0 e ""
|
|
|
|
|
show (e @ BinOp{}) = showsPrec 0 e ""
|
|
|
|
|
show (e @ Dot {}) = showsPrec 0 e ""
|
|
|
|
|
show (e @ Mux {}) = showsPrec 0 e ""
|
|
|
|
|
show (e @ Call {}) = showsPrec 0 e ""
|
|
|
|
|
|
|
|
|
|
showsPrec _ (UniOp o e ) =
|
|
|
|
|
shows o .
|
|
|
|
|
showUniOpPrec e
|
|
|
|
|
showsPrec _ (BinOp o a b) =
|
|
|
|
|
showBinOpPrec a .
|
|
|
|
|
showChar ' ' .
|
|
|
|
|
shows o .
|
|
|
|
|
showChar ' ' .
|
|
|
|
|
showBinOpPrec b
|
|
|
|
|
showsPrec _ (Dot e n ) =
|
|
|
|
|
shows e .
|
|
|
|
|
showChar '.' .
|
|
|
|
|
showString n
|
|
|
|
|
showsPrec _ (Mux c a b) =
|
|
|
|
|
showChar '(' .
|
|
|
|
|
shows c .
|
|
|
|
|
showString " ? " .
|
|
|
|
|
shows a .
|
|
|
|
|
showString " : " .
|
|
|
|
|
shows b .
|
|
|
|
|
showChar ')'
|
|
|
|
|
showsPrec _ (Call e l ) =
|
|
|
|
|
shows e .
|
|
|
|
|
shows l
|
|
|
|
|
showsPrec _ e = \s -> show e ++ s
|
2019-03-23 00:24:45 +01:00
|
|
|
|
2019-03-30 06:27:48 +01:00
|
|
|
data Args
|
2020-06-14 21:56:09 +02:00
|
|
|
= Args [Expr] [(Identifier, Expr)]
|
2019-03-30 06:27:48 +01:00
|
|
|
deriving (Eq, Ord)
|
|
|
|
|
|
|
|
|
|
instance Show Args where
|
2019-10-12 01:22:55 +02:00
|
|
|
show (Args pnArgs kwArgs) = "(" ++ (commas strs) ++ ")"
|
2019-03-30 06:27:48 +01:00
|
|
|
where
|
2020-06-14 21:56:09 +02:00
|
|
|
strs = (map show pnArgs) ++ (map showKwArg kwArgs)
|
|
|
|
|
showKwArg (x, e) = printf ".%s(%s)" x (show e)
|
2019-03-30 06:27:48 +01:00
|
|
|
|
2019-04-05 19:53:52 +02:00
|
|
|
data PartSelectMode
|
|
|
|
|
= NonIndexed
|
|
|
|
|
| IndexedPlus
|
|
|
|
|
| IndexedMinus
|
|
|
|
|
deriving (Eq, Ord)
|
|
|
|
|
|
|
|
|
|
instance Show PartSelectMode where
|
|
|
|
|
show NonIndexed = ":"
|
|
|
|
|
show IndexedPlus = "+:"
|
|
|
|
|
show IndexedMinus = "-:"
|
|
|
|
|
|
2019-09-14 18:31:44 +02:00
|
|
|
data DimsFn
|
|
|
|
|
= FnBits
|
|
|
|
|
| FnDimensions
|
|
|
|
|
| FnUnpackedDimensions
|
|
|
|
|
deriving (Eq, Ord)
|
|
|
|
|
|
|
|
|
|
data DimFn
|
|
|
|
|
= FnLeft
|
|
|
|
|
| FnRight
|
|
|
|
|
| FnLow
|
|
|
|
|
| FnHigh
|
|
|
|
|
| FnIncrement
|
|
|
|
|
| FnSize
|
|
|
|
|
deriving (Eq, Ord)
|
|
|
|
|
|
|
|
|
|
instance Show DimsFn where
|
|
|
|
|
show FnBits = "$bits"
|
|
|
|
|
show FnDimensions = "$dimensions"
|
|
|
|
|
show FnUnpackedDimensions = "$unpacked_dimensions"
|
|
|
|
|
|
|
|
|
|
instance Show DimFn where
|
|
|
|
|
show FnLeft = "$left"
|
|
|
|
|
show FnRight = "$right"
|
|
|
|
|
show FnLow = "$low"
|
|
|
|
|
show FnHigh = "$high"
|
|
|
|
|
show FnIncrement = "$increment"
|
|
|
|
|
show FnSize = "$size"
|
|
|
|
|
|
|
|
|
|
|
2020-06-14 21:56:09 +02:00
|
|
|
showAssignment :: Expr -> String
|
|
|
|
|
showAssignment Nil = ""
|
|
|
|
|
showAssignment val = " = " ++ show val
|
2019-03-23 00:24:45 +01:00
|
|
|
|
|
|
|
|
showRanges :: [Range] -> String
|
|
|
|
|
showRanges [] = ""
|
|
|
|
|
showRanges l = " " ++ (concatMap showRange l)
|
|
|
|
|
|
|
|
|
|
showRange :: Range -> String
|
|
|
|
|
showRange (h, l) = printf "[%s:%s]" (show h) (show l)
|
2019-04-04 02:24:09 +02:00
|
|
|
|
2019-12-22 01:31:56 +01:00
|
|
|
showExprOrRange :: ExprOrRange -> String
|
|
|
|
|
showExprOrRange (Left x) = show x
|
|
|
|
|
showExprOrRange (Right x) = show x
|
|
|
|
|
|
2020-06-14 15:20:30 +02:00
|
|
|
showUniOpPrec :: Expr -> ShowS
|
|
|
|
|
showUniOpPrec (e @ UniOp{}) = (showParen True . shows) e
|
|
|
|
|
showUniOpPrec (e @ BinOp{}) = (showParen True . shows) e
|
|
|
|
|
showUniOpPrec e = shows e
|
2020-02-15 20:11:09 +01:00
|
|
|
|
2020-06-14 15:20:30 +02:00
|
|
|
showBinOpPrec :: Expr -> ShowS
|
|
|
|
|
showBinOpPrec (e @ BinOp{}) = (showParen True . shows) e
|
|
|
|
|
showBinOpPrec e = shows e
|
2020-02-15 20:11:09 +01:00
|
|
|
|
2020-07-09 01:46:37 +02:00
|
|
|
type ParamBinding = (Identifier, TypeOrExpr)
|
|
|
|
|
|
|
|
|
|
showParams :: [ParamBinding] -> String
|
|
|
|
|
showParams params = indentedParenList $ map showParam params
|
|
|
|
|
|
|
|
|
|
showParam :: ParamBinding -> String
|
|
|
|
|
showParam ("*", Right Nil) = ".*"
|
|
|
|
|
showParam (i, arg) =
|
|
|
|
|
printf fmt i (either show show arg)
|
|
|
|
|
where fmt = if i == "" then "%s%s" else ".%s(%s)"
|