mirror of https://github.com/zachjs/sv2v.git
convert severity and elaboration system tasks (#276)
This commit is contained in:
parent
12d977f070
commit
bc79e30fe5
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -0,0 +1,64 @@
|
|||
{- 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
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
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);
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
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
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
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
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
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);
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
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
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue