From 35e75c06044927ab1afcc857224a263f3d6538db Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Fri, 20 Mar 2020 21:13:57 -0400 Subject: [PATCH] language support for strengths --- src/Convert/Interface.hs | 4 +- src/Convert/Logic.hs | 9 ++- src/Convert/Traverse.hs | 10 ++- src/Language/SystemVerilog/AST/Decl.hs | 4 +- src/Language/SystemVerilog/AST/ModuleItem.hs | 20 +++-- src/Language/SystemVerilog/AST/Type.hs | 80 ++++++++++++++++++-- src/Language/SystemVerilog/Parser/Parse.y | 36 ++++++++- 7 files changed, 137 insertions(+), 26 deletions(-) diff --git a/src/Convert/Interface.hs b/src/Convert/Interface.hs index 564863f..26593da 100644 --- a/src/Convert/Interface.hs +++ b/src/Convert/Interface.hs @@ -324,8 +324,8 @@ inlineInterface (ports, items) (instanceName, instanceParams, instancePorts) = portBindingItem :: PortBinding -> Maybe ModuleItem portBindingItem (ident, Just expr) = Just $ if declDirs Map.! ident == Input - then Assign Nothing (LHSIdent ident) expr - else Assign Nothing (toLHS expr) (Ident ident) + then Assign AssignOptionNone (LHSIdent ident) expr + else Assign AssignOptionNone (toLHS expr) (Ident ident) portBindingItem (_, Nothing) = Nothing declDirs = execWriter $ diff --git a/src/Convert/Logic.hs b/src/Convert/Logic.hs index 491757c..794fae3 100644 --- a/src/Convert/Logic.hs +++ b/src/Convert/Logic.hs @@ -77,9 +77,9 @@ convertDescription ports orig = fixModuleItem :: ModuleItem -> ModuleItem -- rewrite bad continuous assignments to use procedural assignments - fixModuleItem (Assign Nothing lhs expr) = + fixModuleItem (Assign AssignOptionNone lhs expr) = if Set.disjoint usedIdents origIdents - then Assign Nothing lhs expr + then Assign AssignOptionNone lhs expr else AlwaysC AlwaysComb $ Asgn AsgnOpEq Nothing lhs expr where usedIdents = execWriter $ collectNestedLHSsM lhsIdents lhs @@ -106,7 +106,8 @@ convertDescription ports orig = collectNestedExprsM exprIdents expr tmp = "sv2v_tmp_" ++ instanceName ++ "_" ++ portName tmpExpr = Ident tmp - t = Net TWire Unspecified [(DimsFn FnBits $ Right expr, Number "1")] + t = Net (NetType TWire) Unspecified + [(DimsFn FnBits $ Right expr, Number "1")] items = [ MIPackageItem $ Decl $ Variable Local t tmp [] Nothing , AlwaysC AlwaysComb $ Asgn AsgnOpEq Nothing lhs tmpExpr] @@ -125,7 +126,7 @@ convertDescription ports orig = where t = if Set.member ident fixedIdents then IntegerVector TReg sg - else Net TWire sg + else Net (NetType TWire) sg convertModuleItem other = other -- all other logics (i.e. inside of functions) become regs convertDecl :: Decl -> Decl diff --git a/src/Convert/Traverse.hs b/src/Convert/Traverse.hs index 0291390..a47e4c6 100644 --- a/src/Convert/Traverse.hs +++ b/src/Convert/Traverse.hs @@ -576,11 +576,15 @@ traverseExprsM' strat exprMapper = moduleItemMapper stmtMapper stmt >>= return . Initial moduleItemMapper (Final stmt) = stmtMapper stmt >>= return . Final - moduleItemMapper (Assign delay lhs expr) = do - delay' <- maybeExprMapper delay + moduleItemMapper (Assign opt lhs expr) = do + opt' <- case opt of + AssignOptionNone -> return $ AssignOptionNone + AssignOptionDrive ds -> return $ AssignOptionDrive ds + AssignOptionDelay delay -> + exprMapper delay >>= return . AssignOptionDelay lhs' <- lhsMapper lhs expr' <- exprMapper expr - return $ Assign delay' lhs' expr' + return $ Assign opt' lhs' expr' moduleItemMapper (MIPackageItem (Function lifetime ret f decls stmts)) = do ret' <- typeMapper ret decls' <- diff --git a/src/Language/SystemVerilog/AST/Decl.hs b/src/Language/SystemVerilog/AST/Decl.hs index 8e5481b..1bff7a0 100644 --- a/src/Language/SystemVerilog/AST/Decl.hs +++ b/src/Language/SystemVerilog/AST/Decl.hs @@ -2,9 +2,9 @@ - Author: Zachary Snow - Initial Verilog AST Author: Tom Hawkins - - - SystemVerilog left-hand sides (aka lvals) + - SystemVerilog data, net, and paramter declarations - - - TODO: Normal parameters can be declared with no default valu. + - TODO: Normal parameters can be declared with no default value. -} module Language.SystemVerilog.AST.Decl diff --git a/src/Language/SystemVerilog/AST/ModuleItem.hs b/src/Language/SystemVerilog/AST/ModuleItem.hs index cff23e3..65038e7 100644 --- a/src/Language/SystemVerilog/AST/ModuleItem.hs +++ b/src/Language/SystemVerilog/AST/ModuleItem.hs @@ -13,6 +13,7 @@ module Language.SystemVerilog.AST.ModuleItem , AlwaysKW (..) , NInputGateKW (..) , NOutputGateKW (..) + , AssignOption (..) ) where import Data.List (intercalate) @@ -29,12 +30,12 @@ import Language.SystemVerilog.AST.Expr (Expr(Ident, Nil), Range, TypeOrExpr, sho import Language.SystemVerilog.AST.GenItem (GenItem) import Language.SystemVerilog.AST.LHS (LHS) import Language.SystemVerilog.AST.Stmt (Stmt, AssertionItem, Timing(Delay)) -import Language.SystemVerilog.AST.Type (Identifier) +import Language.SystemVerilog.AST.Type (Identifier, DriveStrength) data ModuleItem = MIAttr Attr ModuleItem | AlwaysC AlwaysKW Stmt - | Assign (Maybe Expr) LHS Expr + | Assign AssignOption LHS Expr | Defparam LHS Expr | Instance Identifier [ParamBinding] Identifier (Maybe Range) [PortBinding] | Genvar Identifier @@ -52,6 +53,7 @@ instance Show ModuleItem where show (MIPackageItem i) = show i show (MIAttr attr mi ) = printf "%s %s" (show attr) (show mi) show (AlwaysC k b) = printf "%s %s" (show k) (show b) + show (Assign o a b) = printf "assign %s%s = %s;" (showPad o) (show a) (show b) show (Defparam a b) = printf "defparam %s = %s;" (show a) (show b) show (Genvar x ) = printf "genvar %s;" x show (Generate b ) = printf "generate\n%s\nendgenerate" (indent $ unlines' $ map show b) @@ -62,9 +64,6 @@ instance Show ModuleItem where showGate kw d x $ show lhs : map show exprs show (NOutputGate kw d x lhss expr) = showGate kw d x $ (map show lhss) ++ [show expr] - show (Assign d a b) = - printf "assign %s%s = %s;" delayStr (show a) (show b) - where delayStr = maybe "" (\e -> "#(" ++ show e ++ ") ") d show (AssertionItem (mx, a)) = if mx == Nothing then show a @@ -151,3 +150,14 @@ data NOutputGateKW instance Show NOutputGateKW where show GateBuf = "buf" show GateNot = "not" + +data AssignOption + = AssignOptionNone + | AssignOptionDelay Expr + | AssignOptionDrive DriveStrength + deriving Eq + +instance Show AssignOption where + show AssignOptionNone = "" + show (AssignOptionDelay de) = printf "#(%s)" (show de) + show (AssignOptionDrive ds) = show ds diff --git a/src/Language/SystemVerilog/AST/Type.hs b/src/Language/SystemVerilog/AST/Type.hs index 7e59b02..0e5f3dd 100644 --- a/src/Language/SystemVerilog/AST/Type.hs +++ b/src/Language/SystemVerilog/AST/Type.hs @@ -9,13 +9,18 @@ module Language.SystemVerilog.AST.Type ( Identifier , Field - , Type (..) - , Signing (..) - , Packing (..) - , NetType (..) - , IntegerVectorType (..) - , IntegerAtomType (..) - , NonIntegerType (..) + , Type (..) + , Signing (..) + , Packing (..) + , NetType (..) + , IntegerVectorType (..) + , IntegerAtomType (..) + , NonIntegerType (..) + , NetTypeAndStrength (..) + , DriveStrength (..) + , Strength0 (..) + , Strength1 (..) + , ChargeStrength (..) , typeRanges , nullRange , elaborateIntegerAtom @@ -35,7 +40,7 @@ data Type = IntegerVector IntegerVectorType Signing [Range] | IntegerAtom IntegerAtomType Signing | NonInteger NonIntegerType - | Net NetType Signing [Range] + | Net NetTypeAndStrength Signing [Range] | Implicit Signing [Range] | Alias (Maybe Identifier) Identifier [Range] | Enum (Maybe Type) [Item] [Range] @@ -217,3 +222,62 @@ data Packing instance Show Packing where show (Unpacked) = "" show (Packed s) = "packed" ++ (showPadBefore s) + +data NetTypeAndStrength + = NetType NetType + | NetTypeDrive NetType DriveStrength + | NetTypeCharge NetType ChargeStrength + deriving (Eq, Ord) + +instance Show NetTypeAndStrength where + show (NetType nt ) = show nt + show (NetTypeDrive nt ds) = printf "%s %s" (show nt) (show ds) + show (NetTypeCharge nt cs) = printf "%s %s" (show nt) (show cs) + +data DriveStrength + = DriveStrength Strength0 Strength1 + deriving (Eq, Ord) + +instance Show DriveStrength where + show (DriveStrength s0 s1) = printf "(%s, %s)" (show s0) (show s1) + +data Strength0 + = Supply0 + | Strong0 + | Pull0 + | Weak0 + | Highz0 + deriving (Eq, Ord) + +instance Show Strength0 where + show Supply0 = "supply0" + show Strong0 = "strong0" + show Pull0 = "pull0" + show Weak0 = "weak0" + show Highz0 = "highz0" + +data Strength1 + = Supply1 + | Strong1 + | Pull1 + | Weak1 + | Highz1 + deriving (Eq, Ord) + +instance Show Strength1 where + show Supply1 = "supply1" + show Strong1 = "strong1" + show Pull1 = "pull1" + show Weak1 = "weak1" + show Highz1 = "highz1" + +data ChargeStrength + = Small + | Medium + | Large + deriving (Eq, Ord) + +instance Show ChargeStrength where + show Small = "(small)" + show Medium = "(medium)" + show Large = "(large)" diff --git a/src/Language/SystemVerilog/Parser/Parse.y b/src/Language/SystemVerilog/Parser/Parse.y index 1fd8167..f9134db 100644 --- a/src/Language/SystemVerilog/Parser/Parse.y +++ b/src/Language/SystemVerilog/Parser/Parse.y @@ -449,7 +449,7 @@ TypeNonIdent :: { Type } : PartialType OptSigning Dimensions { $1 $2 $3 } | "type" "(" Expr ")" { TypeOf $3 } PartialType :: { Signing -> [Range] -> Type } - : NetType { Net $1 } + : NetTypeAndStrength { Net $1 } | IntegerVectorType { IntegerVector $1 } | IntegerAtomType { \sg -> \[] -> IntegerAtom $1 sg } | NonIntegerType { \Unspecified -> \[] -> NonInteger $1 } @@ -465,6 +465,11 @@ EnumBaseType :: { Maybe Type } : opt(Type) { $1 } | DimensionsNonEmpty { Just $ Implicit Unspecified $1 } +NetTypeAndStrength :: { NetTypeAndStrength } + : NetType %prec "+" { NetType $1 } + | NetType DriveStrength %prec "*" { NetTypeDrive $1 $2 } + | NetType ChargeStrength %prec "*" { NetTypeCharge $1 $2 } + Signing :: { Signing } : "signed" { Signed } | "unsigned" { Unsigned } @@ -656,7 +661,7 @@ NonGenerateModuleItem :: { [ModuleItem] } : DeclTokens(";") { parseDTsAsModuleItems $1 } | ParameterDecl(";") { map (MIPackageItem . Decl) $1 } | "defparam" LHSAsgns ";" { map (uncurry Defparam) $2 } - | "assign" opt(DelayControl) LHSAsgns ";" { map (uncurry $ Assign $2) $3 } + | "assign" AssignOption LHSAsgns ";" { map (uncurry $ Assign $2) $3 } | AlwaysKW Stmt { [AlwaysC $1 $2] } | "initial" Stmt { [Initial $2] } | "final" Stmt { [Final $2] } @@ -668,6 +673,11 @@ NonGenerateModuleItem :: { [ModuleItem] } | AttributeInstance ModuleItem { map (MIAttr $1) $2 } | AssertionItem { [AssertionItem $1] } +AssignOption :: { AssignOption } + : {- empty -} { AssignOptionNone } + | DelayControl { AssignOptionDelay $1 } + | DriveStrength { AssignOptionDrive $1 } + -- for ModuleItem, for now AssertionItem :: { AssertionItem } : ConcurrentAssertionItem { $1 } @@ -769,6 +779,28 @@ NOutputGateKW :: { NOutputGateKW } : "buf" { GateBuf } | "not" { GateNot } +DriveStrength :: { DriveStrength } + : "(" Strength0 "," Strength1 ")" { DriveStrength $2 $4 } + | "(" Strength1 "," Strength0 ")" { DriveStrength $4 $2 } + | "(" Strength0 "," "highz1" ")" { DriveStrength $2 Highz1 } + | "(" Strength1 "," "highz0" ")" { DriveStrength Highz0 $2 } + | "(" "highz0" "," Strength1 ")" { DriveStrength Highz0 $4 } + | "(" "highz1" "," Strength0 ")" { DriveStrength $4 Highz1 } +Strength0 :: { Strength0 } + : "supply0" { Supply0 } + | "strong0" { Strong0 } + | "pull0" { Pull0 } + | "weak0" { Weak0 } +Strength1 :: { Strength1 } + : "supply1" { Supply1 } + | "strong1" { Strong1 } + | "pull1" { Pull1 } + | "weak1" { Weak1 } +ChargeStrength :: { ChargeStrength } + : "(" "small" ")" { Small } + | "(" "medium" ")" { Medium } + | "(" "large" ")" { Large } + LHSAsgns :: { [(LHS, Expr)] } : LHSAsgn { [$1] } | LHSAsgns "," LHSAsgn { $1 ++ [$3] }