From 764a11af7f861dfbf9e2c40422fe7b02f7a166c2 Mon Sep 17 00:00:00 2001 From: Zachary Snow Date: Sun, 20 Aug 2023 13:56:03 -0400 Subject: [PATCH] more warnings for empty output scenarios --- src/sv2v.hs | 41 ++++++++++++++----------- test/warning/class.sv | 3 ++ test/warning/function.sv | 4 +++ test/warning/run.sh | 65 +++++++++++++++++++++------------------- test/warning/task.sv | 3 ++ 5 files changed, 69 insertions(+), 47 deletions(-) create mode 100644 test/warning/class.sv create mode 100644 test/warning/function.sv create mode 100644 test/warning/task.sv diff --git a/src/sv2v.hs b/src/sv2v.hs index 3f63ca5..339fb45 100644 --- a/src/sv2v.hs +++ b/src/sv2v.hs @@ -10,37 +10,44 @@ import System.FilePath (combine, splitExtension) import Control.Monad (when, zipWithM_) import Control.Monad.Except (runExceptT) +import Data.List (nub) import Convert (convert) import Job (readJob, Job(..), Write(..)) import Language.SystemVerilog.AST import Language.SystemVerilog.Parser (parseFiles, Config(..)) -isInterface :: Description -> Bool -isInterface (Part _ _ Interface _ _ _ _ ) = True -isInterface _ = False - -isPackage :: Description -> Bool -isPackage Package{} = True -isPackage _ = False - isComment :: Description -> Bool isComment (PackageItem (Decl CommentDecl{})) = True isComment _ = False +droppedKind :: Description -> Identifier +droppedKind description = + case description of + Part _ _ Interface _ _ _ _ -> "interface" + Package{} -> "package" + Class{} -> "class" + PackageItem Function{} -> "function" + PackageItem Task {} -> "task" + PackageItem (Decl Param{}) -> "localparam" + _ -> "" + emptyWarnings :: AST -> AST -> IO () emptyWarnings before after = - if all isComment before || not (all isComment after) then + if all isComment before || not (all isComment after) || null kinds then return () - else if any isInterface before then - hPutStrLn 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 isPackage before then - hPutStrLn stderr $ "Warning: Source includes packages but no modules." - ++ " Please convert packages alongside the modules that use them." + else if elem "interface" kinds then + hPutStrLn stderr $ "Warning: Source includes an interface but the" + ++ " output is empty because there are no modules without any" + ++ " interface ports. Please convert interfaces alongside the" + ++ " modules that instantiate them." else - return () + hPutStrLn stderr $ "Warning: Source includes a " ++ kind ++ " but no" + ++ " modules. Such elements are elaborated into the modules that" + ++ " use them. Please convert all sources in one invocation." + where + kinds = nub $ filter (not . null) $ map droppedKind before + kind = head kinds rewritePath :: FilePath -> IO FilePath rewritePath path = do diff --git a/test/warning/class.sv b/test/warning/class.sv new file mode 100644 index 0000000..d694885 --- /dev/null +++ b/test/warning/class.sv @@ -0,0 +1,3 @@ +class Class; + localparam X = 1; +endclass diff --git a/test/warning/function.sv b/test/warning/function.sv new file mode 100644 index 0000000..becf844 --- /dev/null +++ b/test/warning/function.sv @@ -0,0 +1,4 @@ +function Function; + input integer inp; + return inp * 2; +endfunction diff --git a/test/warning/run.sh b/test/warning/run.sh index 1d34f33..1f044ac 100755 --- a/test/warning/run.sh +++ b/test/warning/run.sh @@ -1,12 +1,14 @@ #!/bin/bash NO_FILES_WARNING="Warning: No input files specified (try \`sv2v --help\`)" -PACKAGE_WARNING="Warning: Source includes packages but no modules. Please convert packages alongside the modules that use them." -INTERFACE_WARNING="Warning: Source includes an interface but output is empty because there is no top-level module which has no ports which are interfaces." +INTERFACE_WARNING="Warning: Source includes an interface but the output is empty because there are no modules without any interface ports. Please convert interfaces alongside the modules that instantiate them." PORT_CONN_ATTR_WARNING="attr.sv:6:11: Warning: Ignored port connection attributes (* foo *)(* bar *)." test_default() { - runAndCapture interface.sv module.sv package.sv + runAndCapture \ + interface.sv module.sv \ + package.sv class.sv \ + localparam.sv task.sv function.sv assertTrue "default conversion should succeed" $result assertNotNull "stdout should not be empty" "$stdout" assertNull "stderr should be empty" "$stderr" @@ -26,46 +28,49 @@ test_port_conn_attr() { assertEquals "stderr should should have warning" "$PORT_CONN_ATTR_WARNING" "$stderr" } -test_only_package() { - runAndCapture package.sv +no_modules_test() { + file=$1 + warning="$2" + + runAndCapture $file assertTrue "conversion should succeed" $result assertNull "stdout should be empty" "$stdout" - assertEquals "stderr should have warning" "$PACKAGE_WARNING" "$stderr" -} + assertEquals "stderr should have warning" "$warning" "$stderr" -test_only_package_verbose() { - runAndCapture -v package.sv + runAndCapture -v $file assertTrue "conversion should succeed" $result assertNotNull "stdout should not be empty" "$stdout" - assertEquals "stderr should have warning" "$PACKAGE_WARNING" "$stderr" + assertEquals "stderr should have warning" "$warning" "$stderr" } test_only_interface() { - runAndCapture interface.sv - assertTrue "conversion should succeed" $result - assertNull "stdout should be empty" "$stdout" - assertEquals "stderr should have warning" "$INTERFACE_WARNING" "$stderr" + no_modules_test interface.sv "$INTERFACE_WARNING" } -test_only_interface_verbose() { - runAndCapture -v interface.sv - assertTrue "conversion should succeed" $result - assertNotNull "stdout should not be empty" "$stdout" - assertEquals "stderr should have warning" "$INTERFACE_WARNING" "$stderr" +basic_no_modules_test() { + kind=$1 + warning="Warning: Source includes a $kind but no modules. Such elements are elaborated into the modules that use them. Please convert all sources in one invocation." + no_modules_test $kind.sv "$warning" +} + +test_only_package() { + basic_no_modules_test package +} + +test_only_class() { + basic_no_modules_test class +} + +test_only_function() { + basic_no_modules_test function +} + +test_only_task() { + basic_no_modules_test task } test_only_localparam() { - runAndCapture localparam.sv - assertTrue "conversion should succeed" $result - assertNull "stdout should be empty" "$stdout" - assertNull "stderr should be empty" "$stderr" -} - -test_only_localparam_verbose() { - runAndCapture -v localparam.sv - assertTrue "conversion should succeed" $result - assertNotNull "stdout should not be empty" "$stdout" - assertNull "stderr should be empty" "$stderr" + basic_no_modules_test localparam } source ../lib/functions.sh diff --git a/test/warning/task.sv b/test/warning/task.sv new file mode 100644 index 0000000..18427d8 --- /dev/null +++ b/test/warning/task.sv @@ -0,0 +1,3 @@ +task Task; + $display("Hello!"); +endtask