From a803284be8a59b553e7d883a523be89f45702a64 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Mon, 25 Mar 2019 18:53:55 -0400 Subject: [PATCH] support for instantiations with a range --- src/Convert/Interface.hs | 6 ++-- src/Convert/StarPort.hs | 4 +-- src/Convert/Traverse.hs | 5 ++-- src/Language/SystemVerilog/AST.hs | 9 +++--- src/Language/SystemVerilog/Parser/Parse.y | 4 +-- .../SystemVerilog/Parser/ParseDecl.hs | 30 ++++++++++++------- 6 files changed, 35 insertions(+), 23 deletions(-) diff --git a/src/Convert/Interface.hs b/src/Convert/Interface.hs index 3d84b18..07cbaf9 100644 --- a/src/Convert/Interface.hs +++ b/src/Convert/Interface.hs @@ -54,7 +54,7 @@ convertDescription interfaces (Part Module name ports items) = tell (Map.empty, Map.singleton ident modportDecls) where modportDecls = lookupModport Nothing interfaceName modportName _ -> return () - collectInterface (Instance part _ ident _) = + collectInterface (Instance part _ ident Nothing _) = if Map.member part interfaces then tell (Map.singleton ident part, Map.empty) else return () @@ -73,12 +73,12 @@ convertDescription interfaces (Part Module name ports items) = mapper = \(dir, port, Just expr) -> Variable dir (lookupType interfaceItems expr) (ident ++ "_" ++ port) [] Nothing - mapInterface (Instance part params ident instancePorts) = + mapInterface (Instance part params ident Nothing instancePorts) = case Map.lookup part interfaces of Just interface -> Generate $ map GenModuleItem $ inlineInterface interface (ident, expandedPorts) - Nothing -> Instance part params ident expandedPorts + Nothing -> Instance part params ident Nothing expandedPorts where expandedPorts = concatMap expandPortBinding instancePorts mapInterface other = other diff --git a/src/Convert/StarPort.hs b/src/Convert/StarPort.hs index a1ac147..f264dd8 100644 --- a/src/Convert/StarPort.hs +++ b/src/Convert/StarPort.hs @@ -22,8 +22,8 @@ convert descriptions = getPorts _ = return () mapInstance :: ModuleItem -> ModuleItem - mapInstance (Instance m p x bindings) = - Instance m p x $ concatMap expandBinding bindings + mapInstance (Instance m p x r bindings) = + Instance m p x r $ concatMap expandBinding bindings where alreadyBound :: [Identifier] alreadyBound = map fst bindings diff --git a/src/Convert/Traverse.hs b/src/Convert/Traverse.hs index c5d103f..1313dbb 100644 --- a/src/Convert/Traverse.hs +++ b/src/Convert/Traverse.hs @@ -315,9 +315,10 @@ traverseExprsM mapper = moduleItemMapper decls' <- mapM declMapper decls stmts' <- mapM stmtMapper stmts return $ MIPackageItem $ Task lifetime f decls' stmts' - moduleItemMapper (Instance m params x l) = do + moduleItemMapper (Instance m params x r l) = do l' <- mapM portBindingMapper l - return $ Instance m params x l' + r' <- mapM rangeMapper r + return $ Instance m params x r' l' moduleItemMapper (Modport x l) = mapM modportDeclMapper l >>= return . Modport x moduleItemMapper (NInputGate kw x lhs exprs) = do diff --git a/src/Language/SystemVerilog/AST.hs b/src/Language/SystemVerilog/AST.hs index 7825bb5..fde0bfe 100644 --- a/src/Language/SystemVerilog/AST.hs +++ b/src/Language/SystemVerilog/AST.hs @@ -113,7 +113,7 @@ data ModuleItem | AlwaysC AlwaysKW Stmt | Assign LHS Expr | Defparam LHS Expr - | Instance Identifier [PortBinding] Identifier [PortBinding] + | Instance Identifier [PortBinding] Identifier (Maybe Range) [PortBinding] | Genvar Identifier | Generate [GenItem] | Modport Identifier [ModportDecl] @@ -145,9 +145,10 @@ instance Show ModuleItem where AlwaysC k b -> printf "%s %s" (show k) (show b) Assign a b -> printf "assign %s = %s;" (show a) (show b) Defparam a b -> printf "defparam %s = %s;" (show a) (show b) - Instance m params i ports - | null params -> printf "%s %s%s;" m i (showPorts ports) - | otherwise -> printf "%s #%s %s%s;" m (showPorts params) i (showPorts ports) + Instance m params i r ports + | null params -> printf "%s %s%s%s;" m i rStr (showPorts ports) + | otherwise -> printf "%s #%s %s%s%s;" m (showPorts params) i rStr (showPorts ports) + where rStr = maybe "" (\a -> showRanges [a] ++ " ") r Genvar x -> printf "genvar %s;" x Generate b -> printf "generate\n%s\nendgenerate" (indent $ unlines' $ map show b) Modport x l -> printf "modport %s(\n%s\n);" x (indent $ intercalate ",\n" $ map showModportDecl l) diff --git a/src/Language/SystemVerilog/Parser/Parse.y b/src/Language/SystemVerilog/Parser/Parse.y index 2ceabdd..c827793 100644 --- a/src/Language/SystemVerilog/Parser/Parse.y +++ b/src/Language/SystemVerilog/Parser/Parse.y @@ -460,8 +460,8 @@ Lifetime :: { Lifetime } : "static" { Static } | "automatic" { Automatic } -ModuleInstantiation :: { (Identifier, [PortBinding]) } - : Identifier "(" Bindings ")" { ($1, $3) } +ModuleInstantiation :: { [PortBinding] } + : "(" Bindings ")" { $2 } TFItems :: { [Decl] } : "(" DeclTokens(")") ";" { parseDTsAsDecls $2 } diff --git a/src/Language/SystemVerilog/Parser/ParseDecl.hs b/src/Language/SystemVerilog/Parser/ParseDecl.hs index ce2b6d5..3d27459 100644 --- a/src/Language/SystemVerilog/Parser/ParseDecl.hs +++ b/src/Language/SystemVerilog/Parser/ParseDecl.hs @@ -53,7 +53,7 @@ data DeclToken | DTDir Direction | DTType (Signing -> [Range] -> Type) | DTParams [PortBinding] - | DTInstance (Identifier, [PortBinding]) + | DTInstance [PortBinding] | DTBit Expr | DTConcat [LHS] | DTDot Identifier @@ -125,21 +125,31 @@ parseDTsAsModuleItems tokens = -- internal; parser for module instantiations parseDTsAsIntantiations :: [DeclToken] -> [ModuleItem] parseDTsAsIntantiations (DTIdent name : tokens) = - if not (all isInstanceOrComma rest) + if not (all isInstanceToken rest) then error $ "instantiations mixed with other items: " ++ (show rest) - else map (uncurry $ Instance name params) instances + else step rest where + step :: [DeclToken] -> [ModuleItem] + step [] = error $ "unexpected end of instantiation list: " ++ (show tokens) + step toks = + Instance name params x mr p : follow + where + (inst, toks') = span (DTComma /=) toks + (x, mr, p) = case inst of + [DTIdent a, DTRange s, DTInstance b] -> (a, Just s , b) + [DTIdent a, DTInstance b] -> (a, Nothing, b) + _ -> error $ "unrecognized instantiation: " ++ show inst + follow = x `seq` if null toks' then [] else step (tail toks') (params, rest) = case head tokens of DTParams ps -> (ps, tail tokens) _ -> ([], tokens) - instances = - map (\(DTInstance inst) -> inst) $ - filter (DTComma /=) $ rest - isInstanceOrComma :: DeclToken -> Bool - isInstanceOrComma (DTInstance _) = True - isInstanceOrComma DTComma = True - isInstanceOrComma _ = False + isInstanceToken :: DeclToken -> Bool + isInstanceToken (DTInstance _) = True + isInstanceToken (DTRange _) = True + isInstanceToken (DTIdent _) = True + isInstanceToken DTComma = True + isInstanceToken _ = False parseDTsAsIntantiations tokens = error $ "DeclTokens contain instantiations, but start with non-ident: "