Commit 5891a0eb by Zachary Snow

improve edge case messaging

- error for unbound module instance interface ports
- warning for converting an interface alone
- warning for converting a package alone
- update terminology for modules removed by interface conversion
parent 54b07f72
...@@ -62,7 +62,7 @@ convertDescription parts (Part attrs extern Module lifetime name ports items) = ...@@ -62,7 +62,7 @@ convertDescription parts (Part attrs extern Module lifetime name ports items) =
Part attrs extern Module lifetime name ports items' Part attrs extern Module lifetime name ports items'
else else
PackageItem $ Decl $ CommentDecl $ PackageItem $ Decl $ CommentDecl $
"removed interface-using module: " ++ name "removed module with interface ports: " ++ name
where where
items' = evalScoper return traverseModuleItemM return return name items items' = evalScoper return traverseModuleItemM return return name items
...@@ -80,15 +80,21 @@ convertDescription parts (Part attrs extern Module lifetime name ports items) = ...@@ -80,15 +80,21 @@ convertDescription parts (Part attrs extern Module lifetime name ports items) =
convertNested $ Generate $ map GenModuleItem $ convertNested $ Generate $ map GenModuleItem $
inlineInstance rs [] inlineInstance rs []
partItems instanceName paramBindings portBindings partItems instanceName paramBindings portBindings
else if not $ null (extractModportInstances partInfo) then do else if null modportInstances then
modports <- embedScopes (\l () -> l) ()
-- inline instantiation of a module
convertNested $ Generate $ map GenModuleItem $
inlineInstance rs
(modportBindings modports)
partItems instanceName paramBindings portBindings
else
return instanceItem return instanceItem
else do
-- inline instantiation of a module
modportBindings <-
embedScopes (\l () -> getModportBindings l) ()
if length modportInstances /= length modportBindings
then
error $ "instance " ++ instanceName ++ " of " ++ part
++ " has interface ports "
++ showKeys modportInstances ++ ", but only "
++ showKeys modportBindings ++ " are connected"
else convertNested $ Generate $ map GenModuleItem $
inlineInstance rs modportBindings partItems
instanceName paramBindings portBindings
where where
Instance part rawParamBindings instanceName rs rawPortBindings = Instance part rawParamBindings instanceName rs rawPortBindings =
instanceItem instanceItem
...@@ -101,10 +107,11 @@ convertDescription parts (Part attrs extern Module lifetime name ports items) = ...@@ -101,10 +107,11 @@ convertDescription parts (Part attrs extern Module lifetime name ports items) =
portBindings = resolveBindings partPorts rawPortBindings portBindings = resolveBindings partPorts rawPortBindings
modportInstances = extractModportInstances partInfo modportInstances = extractModportInstances partInfo
modportBindings modports = mapMaybe getModportBindings modports = mapMaybe
(inferModportBinding modports modportInstances) $ (inferModportBinding modports modportInstances) $
map (second $ addImpliedSlice modports) portBindings map (second $ addImpliedSlice modports) portBindings
second f = \(a, b) -> (a, f b) second f = \(a, b) -> (a, f b)
showKeys = show . map fst
traverseModuleItemM other = return other traverseModuleItemM other = return other
...@@ -317,7 +324,7 @@ inlineInstance ranges modportBindings items ...@@ -317,7 +324,7 @@ inlineInstance ranges modportBindings items
inlineKind = inlineKind =
if null modportBindings if null modportBindings
then "interface" then "interface"
else "interface-using module" else "module"
comment = MIPackageItem $ Decl $ CommentDecl $ comment = MIPackageItem $ Decl $ CommentDecl $
"expanded " ++ inlineKind ++ " instance: " ++ instanceName "expanded " ++ inlineKind ++ " instance: " ++ instanceName
......
...@@ -10,6 +10,7 @@ import System.Exit ...@@ -10,6 +10,7 @@ import System.Exit
import Data.List (elemIndex) import Data.List (elemIndex)
import Job (readJob, files, exclude, incdir, define, siloed, skipPreprocessor) import Job (readJob, files, exclude, incdir, define, siloed, skipPreprocessor)
import Convert (convert) import Convert (convert)
import Language.SystemVerilog.AST
import Language.SystemVerilog.Parser (parseFiles) import Language.SystemVerilog.Parser (parseFiles)
splitDefine :: String -> (String, String) splitDefine :: String -> (String, String)
...@@ -18,6 +19,28 @@ splitDefine str = ...@@ -18,6 +19,28 @@ splitDefine str =
Nothing -> (str, "") Nothing -> (str, "")
Just idx -> (take idx str, drop (idx + 1) str) Just idx -> (take idx str, drop (idx + 1) str)
isInterface :: Description -> Bool
isInterface (Part _ _ Interface _ _ _ _ ) = True
isInterface _ = False
isPackage :: Description -> Bool
isPackage Package{} = True
isPackage _ = False
emptyWarnings :: [AST] -> [AST] -> IO ()
emptyWarnings before after =
if all null before || any (not . null) after then
return ()
else if any (any isInterface) before then
hPutStr stderr $ "Warning: Source includes an interface but output is "
++ "empty because there is no top-level module which has no ports "
++ "which are interfaces."
else if any (any isPackage) before then
hPutStr stderr $ "Warning: Source includes packages but no modules. "
++ "Please convert packages alongside the modules that use them."
else
return ()
main :: IO () main :: IO ()
main = do main = do
job <- readJob job <- readJob
...@@ -32,6 +55,7 @@ main = do ...@@ -32,6 +55,7 @@ main = do
Right asts -> do Right asts -> do
-- convert the files -- convert the files
let asts' = convert (exclude job) asts let asts' = convert (exclude job) asts
emptyWarnings asts asts'
-- print the converted files out -- print the converted files out
hPrint stdout $ concat asts' hPrint stdout $ concat asts'
exitSuccess exitSuccess
interface Interface;
logic x;
endinterface
module Module(i);
Interface i;
endmodule
module top;
Interface i();
Module m();
endmodule
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment