From f5d6683422daf2cdc849ecc15bc47f83e059fe5a Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Sat, 14 Sep 2019 12:31:44 -0400 Subject: [PATCH] generalization of array dimension(s) system functions --- src/Convert/Bits.hs | 28 ++++++++------ src/Convert/Logic.hs | 2 +- src/Convert/Stream.hs | 10 ++--- src/Convert/Struct.hs | 16 ++++++-- src/Convert/Traverse.hs | 22 ++++++++--- src/Convert/Typedef.hs | 3 +- src/Language/SystemVerilog/AST/Expr.hs | 41 +++++++++++++++++++-- src/Language/SystemVerilog/Parser/Lex.x | 11 +++++- src/Language/SystemVerilog/Parser/Parse.y | 29 +++++++++++++-- src/Language/SystemVerilog/Parser/Tokens.hs | 8 ++++ 10 files changed, 134 insertions(+), 36 deletions(-) diff --git a/src/Convert/Bits.hs b/src/Convert/Bits.hs index 933de80..3d63ae4 100644 --- a/src/Convert/Bits.hs +++ b/src/Convert/Bits.hs @@ -26,7 +26,11 @@ import Language.SystemVerilog.AST type Info = Map.Map Identifier (Type, [Range]) convert :: [AST] -> [AST] -convert = map $ traverseDescriptions convertDescription +convert files = + if files == files' + then files + else convert files' + where files' = map (traverseDescriptions convertDescription) files convertDescription :: Description -> Description convertDescription = @@ -54,28 +58,28 @@ traverseExprM = traverseNestedExprsM $ stately converter -- simplify a bits expression given scoped type information convertExpr :: Info -> Expr -> Expr -convertExpr _ (Bits (Left t)) = +convertExpr _ (DimsFn FnBits (Left t)) = case t of IntegerVector _ _ rs -> dimensionsSize rs Implicit _ rs -> dimensionsSize rs Net _ rs -> dimensionsSize rs - _ -> Bits $ Left t -convertExpr info (Bits (Right e)) = + _ -> DimsFn FnBits $ Left t +convertExpr info (DimsFn FnBits (Right e)) = case e of Ident x -> case Map.lookup x info of - Nothing -> Bits $ Right e + Nothing -> DimsFn FnBits $ Right e Just (t, rs) -> simplify $ BinOp Mul (dimensionsSize rs) - (convertExpr info $ Bits $ Left t) + (convertExpr info $ DimsFn FnBits $ Left t) Concat exprs -> foldl (BinOp Add) (Number "0") $ map (convertExpr info) $ - map (Bits . Right) $ + map (DimsFn FnBits . Right) $ exprs Range expr mode range -> simplify $ BinOp Mul size - (convertExpr info $ Bits $ Right $ Bit expr (Number "0")) + (convertExpr info $ DimsFn FnBits $ Right $ Bit expr (Number "0")) where size = case mode of NonIndexed -> rangeSize range @@ -83,16 +87,16 @@ convertExpr info (Bits (Right e)) = IndexedMinus -> snd range Bit (Ident x) idx -> case Map.lookup x info of - Nothing -> Bits $ Right $ Bit (Ident x) idx + Nothing -> DimsFn FnBits $ Right $ Bit (Ident x) idx Just (t, rs) -> - convertExpr info $ Bits $ Left t' + convertExpr info $ DimsFn FnBits $ Left t' where t' = popRange t rs - Stream _ _ exprs -> convertExpr info $ Bits $ Right $ Concat exprs + Stream _ _ exprs -> convertExpr info $ DimsFn FnBits $ Right $ Concat exprs Number n -> case elemIndex '\'' n of Nothing -> Number "32" Just idx -> Number $ take idx n - _ -> Bits $ Right e + _ -> DimsFn FnBits $ Right e convertExpr _ other = other -- combines the given type and dimensions and returns a new type with the diff --git a/src/Convert/Logic.hs b/src/Convert/Logic.hs index e6a037e..14b1f7c 100644 --- a/src/Convert/Logic.hs +++ b/src/Convert/Logic.hs @@ -101,7 +101,7 @@ convertDescription ports orig = collectNestedExprsM exprIdents expr tmp = "sv2v_tmp_" ++ instanceName ++ "_" ++ portName tmpExpr = Ident tmp - t = Net TWire [(Bits $ Right expr, Number "1")] + t = Net TWire [(DimsFn FnBits $ Right expr, Number "1")] items = [ MIPackageItem $ Decl $ Variable Local t tmp [] Nothing , AlwaysC AlwaysComb $ AsgnBlk AsgnOpEq lhs tmpExpr] diff --git a/src/Convert/Stream.hs b/src/Convert/Stream.hs index ca7a368..dc51581 100644 --- a/src/Convert/Stream.hs +++ b/src/Convert/Stream.hs @@ -79,8 +79,8 @@ traverseAsgnM (lhs, Stream StreamR _ exprs) constructor = return $ constructor lhs expr where expr = Concat $ exprs ++ [Repeat delta [Number "1'b0"]] - size = Bits $ Right $ lhsToExpr lhs - exprSize = Bits $ Right (Concat exprs) + size = DimsFn FnBits $ Right $ lhsToExpr lhs + exprSize = DimsFn FnBits $ Right (Concat exprs) delta = BinOp Sub size exprSize traverseAsgnM (LHSStream StreamR _ lhss, expr) constructor = return $ constructor (LHSConcat lhss) expr @@ -88,13 +88,13 @@ traverseAsgnM (lhs, Stream StreamL chunk exprs) constructor = do return $ streamerBlock chunk size constructor lhs expr where expr = Concat $ Repeat delta [Number "1'b0"] : exprs - size = Bits $ Right $ lhsToExpr lhs - exprSize = Bits $ Right (Concat exprs) + size = DimsFn FnBits $ Right $ lhsToExpr lhs + exprSize = DimsFn FnBits $ Right (Concat exprs) delta = BinOp Sub size exprSize traverseAsgnM (LHSStream StreamL chunk lhss, expr) constructor = do return $ streamerBlock chunk size constructor lhs expr where lhs = LHSConcat lhss - size = Bits $ Right expr + size = DimsFn FnBits $ Right expr traverseAsgnM (lhs, expr) constructor = return $ constructor lhs expr diff --git a/src/Convert/Struct.hs b/src/Convert/Struct.hs index 810f562..6c2de5c 100644 --- a/src/Convert/Struct.hs +++ b/src/Convert/Struct.hs @@ -446,10 +446,14 @@ convertAsgn structs types (lhs, expr) = (t, Cast (Left t) (snd $ convertSubExpr sub)) convertSubExpr (Cast (Right e) sub) = (Implicit Unspecified [], Cast (Right e) (snd $ convertSubExpr sub)) - convertSubExpr (Bits (Left t)) = (Implicit Unspecified [], Bits (Left t)) - convertSubExpr (Bits (Right e)) = - (Implicit Unspecified [], Bits (Right e')) - where e' = snd $ convertSubExpr e + convertSubExpr (DimsFn f tore) = + (Implicit Unspecified [], DimsFn f tore') + where tore' = convertTypeOrExpr tore + convertSubExpr (DimFn f tore e) = + (Implicit Unspecified [], DimFn f tore' e') + where + tore' = convertTypeOrExpr tore + e' = snd $ convertSubExpr e convertSubExpr (Pattern items) = if all (== Nothing) $ map fst items' then (Implicit Unspecified [], Concat $ map snd items') @@ -459,6 +463,10 @@ convertAsgn structs types (lhs, expr) = mapItem (mx, e) = (mx, snd $ convertSubExpr e) convertSubExpr Nil = (Implicit Unspecified [], Nil) + convertTypeOrExpr :: TypeOrExpr -> TypeOrExpr + convertTypeOrExpr (Left t) = Left t + convertTypeOrExpr (Right e) = Right $ snd $ convertSubExpr e + -- lookup the range of a field in its unstructured type lookupUnstructRange :: TypeFunc -> Identifier -> Range lookupUnstructRange structTf fieldName = diff --git a/src/Convert/Traverse.hs b/src/Convert/Traverse.hs index ae188f5..8907549 100644 --- a/src/Convert/Traverse.hs +++ b/src/Convert/Traverse.hs @@ -411,6 +411,9 @@ traverseNestedExprsM mapper = exprMapper maybeExprMapper Nothing = return Nothing maybeExprMapper (Just e) = exprMapper e >>= return . Just + typeOrExprMapper (Left t) = return $ Left t + typeOrExprMapper (Right e) = + exprMapper e >>= return . Right em (String s) = return $ String s em (Number s) = return $ Number s em (Ident i) = return $ Ident i @@ -456,9 +459,12 @@ traverseNestedExprsM mapper = exprMapper e1' <- exprMapper e1 e2' <- exprMapper e2 return $ Cast (Right e1') e2' - em (Bits (Right e)) = - exprMapper e >>= return . Bits . Right - em (Bits (Left t)) = return $ Bits (Left t) + em (DimsFn f tore) = + typeOrExprMapper tore >>= return . DimsFn f + em (DimFn f tore e) = do + tore' <- typeOrExprMapper tore + e' <- exprMapper e + return $ DimFn f tore' e' em (Dot e x) = exprMapper e >>= \e' -> return $ Dot e' x em (Pattern l) = do @@ -832,10 +838,16 @@ traverseTypesM mapper item = fullMapper = traverseNestedTypesM mapper maybeMapper Nothing = return Nothing maybeMapper (Just t) = fullMapper t >>= return . Just + typeOrExprMapper (Right e) = return $ Right e + typeOrExprMapper (Left t) = + fullMapper t >>= return . Left exprMapper (Cast (Left t) e) = fullMapper t >>= \t' -> return $ Cast (Left t') e - exprMapper (Bits (Left t)) = - fullMapper t >>= return . Bits . Left + exprMapper (DimsFn f tore) = + typeOrExprMapper tore >>= return . DimsFn f + exprMapper (DimFn f tore e) = do + tore' <- typeOrExprMapper tore + return $ DimFn f tore' e exprMapper other = return other declMapper (Param s t x e) = fullMapper t >>= \t' -> return $ Param s t' x e diff --git a/src/Convert/Typedef.hs b/src/Convert/Typedef.hs index 9061ddb..1bcd6a3 100644 --- a/src/Convert/Typedef.hs +++ b/src/Convert/Typedef.hs @@ -58,7 +58,8 @@ convertDescription globalTypes description = convertTypeOrExpr other = other convertExpr :: Expr -> Expr convertExpr (Cast v e) = Cast (convertTypeOrExpr v) e - convertExpr (Bits v) = Bits $ convertTypeOrExpr v + convertExpr (DimsFn f v) = DimsFn f (convertTypeOrExpr v) + convertExpr (DimFn f v e) = DimFn f (convertTypeOrExpr v) e convertExpr other = other convertModuleItem :: ModuleItem -> ModuleItem convertModuleItem (Instance m params x r p) = diff --git a/src/Language/SystemVerilog/AST/Expr.hs b/src/Language/SystemVerilog/AST/Expr.hs index bd9ebe2..3e59e58 100644 --- a/src/Language/SystemVerilog/AST/Expr.hs +++ b/src/Language/SystemVerilog/AST/Expr.hs @@ -11,6 +11,8 @@ module Language.SystemVerilog.AST.Expr , TypeOrExpr , Args (..) , PartSelectMode (..) + , DimsFn (..) + , DimFn (..) , showAssignment , showRanges , simplify @@ -48,7 +50,8 @@ data Expr | BinOp BinOp Expr Expr | Mux Expr Expr Expr | Cast TypeOrExpr Expr - | Bits TypeOrExpr + | DimsFn DimsFn TypeOrExpr + | DimFn DimFn TypeOrExpr Expr | Dot Expr Identifier | Pattern [(Maybe Identifier, Expr)] | Nil @@ -69,9 +72,10 @@ instance Show Expr where show (BinOp o a b) = printf "(%s %s %s)" (show a) (show o) (show b) show (Dot e n ) = printf "%s.%s" (show e) n show (Mux c a b) = printf "(%s ? %s : %s)" (show c) (show a) (show b) - show (Call ps f l) = printf "%s%s(%s)" (maybe "" (++ "::") ps) f (show l) - show (Cast tore e ) = printf "%s'(%s)" (showEither tore) (show e) - show (Bits tore ) = printf "$bits(%s)" (showEither tore) + show (Call ps f l) = printf "%s%s(%s)" (maybe "" (++ "::") ps) f (show l) + 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) show (Pattern l ) = printf "'{\n%s\n}" (indent $ intercalate ",\n" $ map showPatternItem l) where @@ -101,6 +105,35 @@ instance Show PartSelectMode where show IndexedPlus = "+:" show IndexedMinus = "-:" +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" + + showAssignment :: Show a => Maybe a -> String showAssignment Nothing = "" showAssignment (Just val) = " = " ++ show val diff --git a/src/Language/SystemVerilog/Parser/Lex.x b/src/Language/SystemVerilog/Parser/Lex.x index 9348cf1..a429149 100644 --- a/src/Language/SystemVerilog/Parser/Lex.x +++ b/src/Language/SystemVerilog/Parser/Lex.x @@ -115,7 +115,16 @@ $decimalDigit = [0-9] tokens :- - "$bits" { tok KW_dollar_bits } + "$bits" { tok KW_dollar_bits } + "$dimensions" { tok KW_dollar_dimensions } + "$unpacked_dimensions" { tok KW_dollar_unpacked_dimensions } + "$left" { tok KW_dollar_left } + "$right" { tok KW_dollar_right } + "$low" { tok KW_dollar_low } + "$high" { tok KW_dollar_high } + "$increment" { tok KW_dollar_increment } + "$size" { tok KW_dollar_size } + "accept_on" { tok KW_accept_on } "alias" { tok KW_alias } "always" { tok KW_always } diff --git a/src/Language/SystemVerilog/Parser/Parse.y b/src/Language/SystemVerilog/Parser/Parse.y index e3eb29f..f42948d 100644 --- a/src/Language/SystemVerilog/Parser/Parse.y +++ b/src/Language/SystemVerilog/Parser/Parse.y @@ -26,7 +26,16 @@ import Language.SystemVerilog.Parser.Tokens %token -"$bits" { Token KW_dollar_bits _ _ } +"$bits" { Token KW_dollar_bits _ _ } +"$dimensions" { Token KW_dollar_dimensions _ _ } +"$unpacked_dimensions" { Token KW_dollar_unpacked_dimensions _ _ } +"$left" { Token KW_dollar_left _ _ } +"$right" { Token KW_dollar_right _ _ } +"$low" { Token KW_dollar_low _ _ } +"$high" { Token KW_dollar_high _ _ } +"$increment" { Token KW_dollar_increment _ _ } +"$size" { Token KW_dollar_size _ _ } + "accept_on" { Token KW_accept_on _ _ } "alias" { Token KW_alias _ _ } "always" { Token KW_always _ _ } @@ -1011,7 +1020,9 @@ Expr :: { Expr } | Number { Number $1 } | Identifier "(" CallArgs ")" { Call (Nothing) $1 $3 } | Identifier "::" Identifier "(" CallArgs ")" { Call (Just $1) $3 $5 } - | "$bits" "(" TypeOrExpr ")" { Bits $3 } + | DimsFn "(" TypeOrExpr ")" { DimsFn $1 $3 } + | DimFn "(" TypeOrExpr ")" { DimFn $1 $3 (Number "1") } + | DimFn "(" TypeOrExpr "," Expr ")" { DimFn $1 $3 $5 } | Identifier { Ident $1 } | Identifier "::" Identifier { PSIdent $1 $3 } | Expr PartSelect { Range $1 (fst $2) (snd $2) } @@ -1088,7 +1099,7 @@ StreamOp :: { StreamOp } : "<<" { StreamL } | ">>" { StreamR } StreamSize :: { Expr } - : TypeNonIdent { Bits $ Left $1 } + : TypeNonIdent { DimsFn FnBits (Left $1) } | Expr { $1 } GenItemOrNull :: { GenItem } @@ -1152,6 +1163,18 @@ IncOrDecOperator :: { BinOp } : "++" { Add } | "--" { Sub } +DimsFn :: { DimsFn } + : "$bits" { FnBits } + | "$dimensions" { FnDimensions } + | "$unpacked_dimensions" { FnUnpackedDimensions } +DimFn :: { DimFn } + : "$left" { FnLeft } + | "$right" { FnRight } + | "$low" { FnLow } + | "$high" { FnHigh } + | "$increment" { FnIncrement } + | "$size" { FnSize } + { parseError :: [Token] -> a diff --git a/src/Language/SystemVerilog/Parser/Tokens.hs b/src/Language/SystemVerilog/Parser/Tokens.hs index bd30022..f3939c1 100644 --- a/src/Language/SystemVerilog/Parser/Tokens.hs +++ b/src/Language/SystemVerilog/Parser/Tokens.hs @@ -30,6 +30,14 @@ data Token data TokenName = KW_dollar_bits + | KW_dollar_dimensions + | KW_dollar_unpacked_dimensions + | KW_dollar_left + | KW_dollar_right + | KW_dollar_low + | KW_dollar_high + | KW_dollar_increment + | KW_dollar_size | KW_accept_on | KW_alias | KW_always