Unverified Commit bc79e30f by Ethan Sifferman Committed by GitHub

convert severity and elaboration system tasks (#276)

parent 12d977f0
...@@ -2,6 +2,9 @@ ...@@ -2,6 +2,9 @@
### New Features ### New Features
* Added conversion of severity system tasks and elaboration system tasks (e.g.,
`$info`) into `$display` tasks that include source file and scope information;
pass `-E SeverityTask` to disable this new conversion
* Added parsing support for `not`, `strong`, `weak`, `nexttime`, and * Added parsing support for `not`, `strong`, `weak`, `nexttime`, and
`s_nexttime` in assertion property expressions `s_nexttime` in assertion property expressions
* Added `--bugpoint` utility for minimizing test cases for issue submission * Added `--bugpoint` utility for minimizing test cases for issue submission
......
...@@ -102,7 +102,7 @@ Preprocessing: ...@@ -102,7 +102,7 @@ Preprocessing:
Conversion: Conversion:
--pass-through Dump input without converting --pass-through Dump input without converting
-E --exclude=CONV Exclude a particular conversion (Always, Assert, -E --exclude=CONV Exclude a particular conversion (Always, Assert,
Interface, Logic, or UnbasedUnsized) Interface, Logic, SeverityTask, or UnbasedUnsized)
-v --verbose Retain certain conversion artifacts -v --verbose Retain certain conversion artifacts
-w --write=MODE/FILE/DIR How to write output; default is 'stdout'; use -w --write=MODE/FILE/DIR How to write output; default is 'stdout'; use
'adjacent' to create a .v file next to each input; 'adjacent' to create a .v file next to each input;
......
...@@ -45,6 +45,7 @@ import qualified Convert.ParamType ...@@ -45,6 +45,7 @@ import qualified Convert.ParamType
import qualified Convert.PortDecl import qualified Convert.PortDecl
import qualified Convert.RemoveComments import qualified Convert.RemoveComments
import qualified Convert.ResolveBindings import qualified Convert.ResolveBindings
import qualified Convert.SeverityTask
import qualified Convert.Simplify import qualified Convert.Simplify
import qualified Convert.Stream import qualified Convert.Stream
import qualified Convert.StringParam import qualified Convert.StringParam
...@@ -119,6 +120,7 @@ initialPhases tops selectExclude = ...@@ -119,6 +120,7 @@ initialPhases tops selectExclude =
, selectExclude Job.Assert Convert.Assertion.convert , selectExclude Job.Assert Convert.Assertion.convert
, selectExclude Job.Always Convert.AlwaysKW.convert , selectExclude Job.Always Convert.AlwaysKW.convert
, Convert.Interface.disambiguate , Convert.Interface.disambiguate
, selectExclude Job.SeverityTask Convert.SeverityTask.convert
, Convert.Package.convert , Convert.Package.convert
, Convert.StructConst.convert , Convert.StructConst.convert
, Convert.PortDecl.convert , Convert.PortDecl.convert
......
...@@ -58,6 +58,10 @@ module Convert.Scoper ...@@ -58,6 +58,10 @@ module Convert.Scoper
, withinProcedureM , withinProcedureM
, procedureLoc , procedureLoc
, procedureLocM , procedureLocM
, sourceLocation
, sourceLocationM
, hierarchyPath
, hierarchyPathM
, scopedError , scopedError
, scopedErrorM , scopedErrorM
, isLoopVar , isLoopVar
...@@ -367,12 +371,25 @@ procedureLoc = sProcedureLoc ...@@ -367,12 +371,25 @@ procedureLoc = sProcedureLoc
debugLocation :: Scopes a -> String debugLocation :: Scopes a -> String
debugLocation s = debugLocation s =
hierarchy ++ hierarchy ++
if null latestTrace if null location
then " (use -v to get approximate source location)" then " (use -v to get approximate source location)"
else ", near " ++ latestTrace else ", near " ++ location
where
hierarchy = hierarchyPath s
location = sourceLocation s
sourceLocationM :: Monad m => ScoperT a m String
sourceLocationM = gets sourceLocation
sourceLocation :: Scopes a -> String
sourceLocation = sLatestTrace
hierarchyPathM :: Monad m => ScoperT a m String
hierarchyPathM = gets hierarchyPath
hierarchyPath :: Scopes a -> String
hierarchyPath = intercalate "." . map tierToStr . sCurrent
where where
hierarchy = intercalate "." $ map tierToStr $ sCurrent s
latestTrace = sLatestTrace s
tierToStr :: Tier -> String tierToStr :: Tier -> String
tierToStr (Tier "" _) = "<unnamed_block>" tierToStr (Tier "" _) = "<unnamed_block>"
tierToStr (Tier x "") = x tierToStr (Tier x "") = x
......
{- sv2v
- Author: Ethan Sifferman <ethan@sifferman.dev>
-
- Conversion of severity system tasks (IEEE 1800-2017 Section 20.10) and
- elaboration system tasks (Section 20.11) `$info`, `$warning`, `$error`, and
- `$fatal`, which sv2v collectively refers to as "severity tasks".
-
- 1. Severity task messages are converted into `$display` tasks.
- 2. `$fatal` tasks also run `$finish` directly after running `$display`.
-}
module Convert.SeverityTask (convert) where
import Data.Char (toUpper)
import Data.Functor ((<&>))
import Convert.Scoper
import Convert.Traverse
import Language.SystemVerilog.AST
type SC = Scoper ()
convert :: [AST] -> [AST]
convert = map $ traverseDescriptions traverseDescription
traverseDescription :: Description -> Description
traverseDescription = partScoper return traverseModuleItem return traverseStmt
-- convert elaboration severity tasks
traverseModuleItem :: ModuleItem -> SC ModuleItem
traverseModuleItem (ElabTask severity taskArgs) =
elab severity taskArgs "elaboration" [] <&> Initial
traverseModuleItem other = return other
-- convert standard severity tasks
traverseStmt :: Stmt -> SC Stmt
traverseStmt (SeverityStmt severity taskArgs) =
elab severity taskArgs "%0t" [Ident "$time"]
traverseStmt other = return other
elab :: Severity -> [Expr] -> String -> [Expr] -> SC Stmt
elab severity args prefixStr prefixArgs = do
scopeName <- hierarchyPathM
fileLocation <- sourceLocationM
let contextArg = String $ msg scopeName fileLocation
let stmtDisplay = call "$display" $ contextArg : prefixArgs ++ displayArgs
return $ Block Seq "" [] [stmtDisplay, stmtFinish]
where
msg scope file = severityToString severity ++ " [" ++ prefixStr ++ "] "
++ file ++ " - " ++ scope
++ if null displayArgs then "" else "\\n msg: "
displayArgs = if severity /= SeverityFatal || null args
then args
else tail args
stmtFinish = if severity /= SeverityFatal
then Null
else call "$finish" $ if null args then [] else [head args]
call :: Identifier -> [Expr] -> Stmt
call func args = Subroutine (Ident func) (Args args [])
severityToString :: Severity -> String
severityToString severity = toUpper ch : str
where '$' : ch : str = show severity
...@@ -27,6 +27,7 @@ data Exclude ...@@ -27,6 +27,7 @@ data Exclude
| Assert | Assert
| Interface | Interface
| Logic | Logic
| SeverityTask
| Succinct | Succinct
| UnbasedUnsized | UnbasedUnsized
deriving (Typeable, Data, Eq) deriving (Typeable, Data, Eq)
...@@ -83,7 +84,7 @@ defaultJob = Job ...@@ -83,7 +84,7 @@ defaultJob = Job
&= groupname "Conversion" &= groupname "Conversion"
, exclude = nam_ "exclude" &= name "E" &= typ "CONV" , exclude = nam_ "exclude" &= name "E" &= typ "CONV"
&= help ("Exclude a particular conversion (Always, Assert, Interface," &= help ("Exclude a particular conversion (Always, Assert, Interface,"
++ " Logic, or UnbasedUnsized)") ++ " Logic, SeverityTask, or UnbasedUnsized)")
, verbose = nam "verbose" &= help "Retain certain conversion artifacts" , verbose = nam "verbose" &= help "Retain certain conversion artifacts"
, write = Stdout &= ignore -- parsed from the flexible flag below , write = Stdout &= ignore -- parsed from the flexible flag below
, writeRaw = "s" &= name "write" &= name "w" &= explicit , writeRaw = "s" &= name "write" &= name "w" &= explicit
......
...@@ -98,6 +98,7 @@ executable sv2v ...@@ -98,6 +98,7 @@ executable sv2v
Convert.RemoveComments Convert.RemoveComments
Convert.ResolveBindings Convert.ResolveBindings
Convert.Scoper Convert.Scoper
Convert.SeverityTask
Convert.Simplify Convert.Simplify
Convert.Stream Convert.Stream
Convert.StringParam Convert.StringParam
......
...@@ -6,5 +6,6 @@ module top; ...@@ -6,5 +6,6 @@ module top;
$error; $error;
$error("%b", 3); $error("%b", 3);
$fatal; $fatal;
$fatal("%b", 4); $fatal(0);
$fatal(1, "%b", 4);
endmodule endmodule
affirm $finish;
affirm $display("Fatal [elaboration] elab_task.sv:9:5 - top");
affirm $finish(0);
affirm $display("Fatal [elaboration] elab_task.sv:10:5 - top\\n msg: ", "%b", 4);
affirm $finish(1);
module top;
initial $display("Info [elaboration] elab_task.sv:2:5 - top");
initial $display("Info [elaboration] elab_task.sv:3:5 - top\n msg: %b", 1);
initial $display("Warning [elaboration] elab_task.sv:4:5 - top");
initial $display("Warning [elaboration] elab_task.sv:5:5 - top\n msg: %b", 2);
initial $display("Error [elaboration] elab_task.sv:6:5 - top");
initial $display("Error [elaboration] elab_task.sv:7:5 - top\n msg: %b", 3);
initial begin
$display("Fatal [elaboration] elab_task.sv:8:5 - top");
$finish;
end
initial begin
$display("Fatal [elaboration] elab_task.sv:9:5 - top");
$finish(0);
end
initial begin
$display("Fatal [elaboration] elab_task.sv:10:5 - top\n msg: %b", 4);
$finish(1);
end
endmodule
module top;
initial begin
$info;
$info("%b", 1);
$warning;
$warning("%b", 2);
$error;
$error("%b", 3);
$fatal;
$fatal(0);
$fatal(1, "%b", 4);
end
endmodule
affirm $finish;
affirm $display("Fatal [%0t] severity_task.sv:10:9 - top.<unnamed_block>", $time);
affirm $finish(0);
affirm $display("Fatal [%0t] severity_task.sv:11:9 - top.<unnamed_block>\\n msg: ", $time, "%b", 4);
affirm $finish(1);
module top;
initial begin
$display("Info [%0t] severity_task.sv:3:9 - top.<unnamed_block>", $time);
$display("Info [%0t] severity_task.sv:4:9 - top.<unnamed_block>\n msg: ", $time, "%b", 1);
$display("Warning [%0t] severity_task.sv:5:9 - top.<unnamed_block>", $time);
$display("Warning [%0t] severity_task.sv:6:9 - top.<unnamed_block>\n msg: ", $time, "%b", 2);
$display("Error [%0t] severity_task.sv:7:9 - top.<unnamed_block>", $time);
$display("Error [%0t] severity_task.sv:8:9 - top.<unnamed_block>\n msg: ", $time, "%b", 3);
$display("Fatal [%0t] severity_task.sv:9:9 - top.<unnamed_block>", $time);
$finish;
$display("Fatal [%0t] severity_task.sv:10:9 - top.<unnamed_block>", $time);
$finish(0);
$display("Fatal [%0t] severity_task.sv:11:9 - top.<unnamed_block>\n msg: ", $time, "%b", 4);
$finish(1);
end
endmodule
...@@ -77,6 +77,9 @@ assertConverts() { ...@@ -77,6 +77,9 @@ assertConverts() {
ac_tmpd=$SHUNIT_TMPDIR/ac-conv-tmpd.v ac_tmpd=$SHUNIT_TMPDIR/ac-conv-tmpd.v
convert "conversion of pass through of $ac_file" $ac_tmpd $ac_tmpc convert "conversion of pass through of $ac_file" $ac_tmpd $ac_tmpc
# remove source locations when checking the --pass-through invariant
removeSourceLocation $ac_file $ac_tmpa
removeSourceLocation $ac_tmpc $ac_tmpd
diff $ac_tmpa $ac_tmpd > /dev/null diff $ac_tmpa $ac_tmpd > /dev/null
assertTrue "pass through then conversion differs for $ac_file" $? assertTrue "pass through then conversion differs for $ac_file" $?
...@@ -173,6 +176,11 @@ simulateAndCompare() { ...@@ -173,6 +176,11 @@ simulateAndCompare() {
simulate $cvs_vcd $cvs_log $cs $tb simulate $cvs_vcd $cvs_log $cs $tb
simulate $cvv_vcd $cvv_log $cv $tb simulate $cvv_vcd $cvv_log $cv $tb
# clean log files by source locations
removeSourceLocation $ve $ref_log
removeSourceLocation $cs $cvs_log
removeSourceLocation $cv $cvv_log
# compare reference verilog to converted succinct # compare reference verilog to converted succinct
output=`diff $ref_vcd $cvs_vcd` output=`diff $ref_vcd $cvs_vcd`
assertTrue "VE/CS VCDs are different:\n$output" $? assertTrue "VE/CS VCDs are different:\n$output" $?
...@@ -199,3 +207,7 @@ runAndCapture() { ...@@ -199,3 +207,7 @@ runAndCapture() {
stdout=`cat $SHUNIT_TMPDIR/stdout` stdout=`cat $SHUNIT_TMPDIR/stdout`
stderr=`cat $SHUNIT_TMPDIR/stderr` stderr=`cat $SHUNIT_TMPDIR/stderr`
} }
removeSourceLocation() {
sed -i.bak -E 's#'$1':[0-9]+(:[0-9]+)?#<removed_source_location>#g' $2
}
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