Unverified Commit bc79e30f by Ethan Sifferman Committed by GitHub

convert severity and elaboration system tasks (#276)

parent 12d977f0
......@@ -2,6 +2,9 @@
### 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
`s_nexttime` in assertion property expressions
* Added `--bugpoint` utility for minimizing test cases for issue submission
......
......@@ -102,7 +102,7 @@ Preprocessing:
Conversion:
--pass-through Dump input without converting
-E --exclude=CONV Exclude a particular conversion (Always, Assert,
Interface, Logic, or UnbasedUnsized)
Interface, Logic, SeverityTask, or UnbasedUnsized)
-v --verbose Retain certain conversion artifacts
-w --write=MODE/FILE/DIR How to write output; default is 'stdout'; use
'adjacent' to create a .v file next to each input;
......
......@@ -45,6 +45,7 @@ import qualified Convert.ParamType
import qualified Convert.PortDecl
import qualified Convert.RemoveComments
import qualified Convert.ResolveBindings
import qualified Convert.SeverityTask
import qualified Convert.Simplify
import qualified Convert.Stream
import qualified Convert.StringParam
......@@ -119,6 +120,7 @@ initialPhases tops selectExclude =
, selectExclude Job.Assert Convert.Assertion.convert
, selectExclude Job.Always Convert.AlwaysKW.convert
, Convert.Interface.disambiguate
, selectExclude Job.SeverityTask Convert.SeverityTask.convert
, Convert.Package.convert
, Convert.StructConst.convert
, Convert.PortDecl.convert
......
......@@ -58,6 +58,10 @@ module Convert.Scoper
, withinProcedureM
, procedureLoc
, procedureLocM
, sourceLocation
, sourceLocationM
, hierarchyPath
, hierarchyPathM
, scopedError
, scopedErrorM
, isLoopVar
......@@ -367,12 +371,25 @@ procedureLoc = sProcedureLoc
debugLocation :: Scopes a -> String
debugLocation s =
hierarchy ++
if null latestTrace
if null 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
hierarchy = intercalate "." $ map tierToStr $ sCurrent s
latestTrace = sLatestTrace s
tierToStr :: Tier -> String
tierToStr (Tier "" _) = "<unnamed_block>"
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
| Assert
| Interface
| Logic
| SeverityTask
| Succinct
| UnbasedUnsized
deriving (Typeable, Data, Eq)
......@@ -83,7 +84,7 @@ defaultJob = Job
&= groupname "Conversion"
, exclude = nam_ "exclude" &= name "E" &= typ "CONV"
&= help ("Exclude a particular conversion (Always, Assert, Interface,"
++ " Logic, or UnbasedUnsized)")
++ " Logic, SeverityTask, or UnbasedUnsized)")
, verbose = nam "verbose" &= help "Retain certain conversion artifacts"
, write = Stdout &= ignore -- parsed from the flexible flag below
, writeRaw = "s" &= name "write" &= name "w" &= explicit
......
......@@ -98,6 +98,7 @@ executable sv2v
Convert.RemoveComments
Convert.ResolveBindings
Convert.Scoper
Convert.SeverityTask
Convert.Simplify
Convert.Stream
Convert.StringParam
......
......@@ -6,5 +6,6 @@ module top;
$error;
$error("%b", 3);
$fatal;
$fatal("%b", 4);
$fatal(0);
$fatal(1, "%b", 4);
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() {
ac_tmpd=$SHUNIT_TMPDIR/ac-conv-tmpd.v
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
assertTrue "pass through then conversion differs for $ac_file" $?
......@@ -173,6 +176,11 @@ simulateAndCompare() {
simulate $cvs_vcd $cvs_log $cs $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
output=`diff $ref_vcd $cvs_vcd`
assertTrue "VE/CS VCDs are different:\n$output" $?
......@@ -199,3 +207,7 @@ runAndCapture() {
stdout=`cat $SHUNIT_TMPDIR/stdout`
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