mirror of https://github.com/zachjs/sv2v.git
refactored to leverage Scoper and updated tests
This commit is contained in:
parent
1bb76cbe32
commit
fe3c93e82f
|
|
@ -2,6 +2,9 @@
|
|||
|
||||
### New Features
|
||||
|
||||
* Added conversion of severity system tasks and elaboration system tasks (e.g.,
|
||||
`$info`) into `$display` tasks including source file and scope information;
|
||||
set `-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
|
||||
|
|
|
|||
|
|
@ -120,11 +120,11 @@ 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
|
||||
, Convert.ParamNoDefault.convert tops
|
||||
, selectExclude Job.SeverityTask Convert.SeverityTask.convert
|
||||
, Convert.ResolveBindings.convert
|
||||
, Convert.UnnamedGenBlock.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
|
||||
|
|
|
|||
|
|
@ -1,50 +1,59 @@
|
|||
{- sv2v
|
||||
- Author: Ethan Sifferman <ethan@sifferman.dev>
|
||||
-
|
||||
- Conversion of standard and elaboration severity tasks `$info`, `$warning`,
|
||||
- `$error`, and `$fatal` (20.10 and 20.11).
|
||||
- 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 run `$finish` directly after running `$display`.
|
||||
- 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 $ traverseModuleItems convertModuleItem
|
||||
convert = map $ traverseDescriptions traverseDescription
|
||||
|
||||
-- Convert Elaboration Severity Tasks
|
||||
convertModuleItem :: ModuleItem -> ModuleItem
|
||||
convertModuleItem (ElabTask severity taskArgs) =
|
||||
Initial $ elab severity taskArgs "Elaboration" []
|
||||
convertModuleItem other =
|
||||
traverseStmts (traverseNestedStmts convertStmt) other
|
||||
traverseDescription :: Description -> Description
|
||||
traverseDescription = partScoper return traverseModuleItem return traverseStmt
|
||||
|
||||
-- Convert Standard Severity Tasks
|
||||
convertStmt :: Stmt -> Stmt
|
||||
convertStmt (SeverityStmt severity taskArgs) =
|
||||
elab severity taskArgs "[%0t]" [Ident "$time"]
|
||||
convertStmt other = other
|
||||
-- convert elaboration severity tasks
|
||||
traverseModuleItem :: ModuleItem -> SC ModuleItem
|
||||
traverseModuleItem (ElabTask severity taskArgs) =
|
||||
elab severity taskArgs "elaboration" [] <&> Initial
|
||||
traverseModuleItem other = return other
|
||||
|
||||
elab :: Severity -> [Expr] -> String -> [Expr] -> Stmt
|
||||
elab severity taskArgs prefixStr prefixArgs =
|
||||
Block Seq "" [] [stmtDisplay, stmtFinish]
|
||||
-- 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
|
||||
stmtDisplay = call "$display" $ msg : prefixArgs ++ args
|
||||
msg = String $ prefixStr ++ ' ' : severityToString severity ++ ':' : trailingSpace
|
||||
trailingSpace = if null args then "" else " "
|
||||
args = if severity /= SeverityFatal || null taskArgs
|
||||
then taskArgs
|
||||
else tail taskArgs
|
||||
msg scope file = severityToString severity ++ " [" ++ prefixStr ++ "] "
|
||||
++ file ++ " - " ++ scope ++ if null displayArgs then "" else " - "
|
||||
displayArgs = if severity /= SeverityFatal || null args
|
||||
then args
|
||||
else tail args
|
||||
stmtFinish = if severity /= SeverityFatal
|
||||
then Null
|
||||
else call "$finish" argsFinish
|
||||
argsFinish = if null taskArgs then [] else [head taskArgs]
|
||||
else call "$finish" $ if null args then [] else [head args]
|
||||
|
||||
call :: Identifier -> [Expr] -> Stmt
|
||||
call func args = Subroutine (Ident func) (Args args [])
|
||||
|
|
|
|||
|
|
@ -7,5 +7,5 @@ module top;
|
|||
$error("%b", 3);
|
||||
$fatal;
|
||||
$fatal(0);
|
||||
$fatal(0, "%b", 4);
|
||||
$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 - ", "%b", 4);
|
||||
affirm $finish(1);
|
||||
|
|
@ -1,20 +1,20 @@
|
|||
module top;
|
||||
initial $display("Elaboration Info:");
|
||||
initial $display("Elaboration Info: ", "%b", 1);
|
||||
initial $display("Elaboration Warning:");
|
||||
initial $display("Elaboration Warning: ", "%b", 2);
|
||||
initial $display("Elaboration Error:");
|
||||
initial $display("Elaboration Error: ", "%b", 3);
|
||||
initial $display("Info [elaboration] elab_task.sv:2:5 - top");
|
||||
initial $display("Info [elaboration] elab_task.sv:3:5 - top - %b", 1);
|
||||
initial $display("Warning [elaboration] elab_task.sv:4:5 - top");
|
||||
initial $display("Warning [elaboration] elab_task.sv:5:5 - top - %b", 2);
|
||||
initial $display("Error [elaboration] elab_task.sv:6:5 - top");
|
||||
initial $display("Error [elaboration] elab_task.sv:7:5 - top - %b", 3);
|
||||
initial begin
|
||||
$display("Elaboration Fatal:");
|
||||
$display("Fatal [elaboration] elab_task.sv:8:5 - top");
|
||||
$finish;
|
||||
end
|
||||
initial begin
|
||||
$display("Elaboration Fatal:");
|
||||
$display("Fatal [elaboration] elab_task.sv:9:5 - top");
|
||||
$finish(0);
|
||||
end
|
||||
initial begin
|
||||
$display("Elaboration Fatal: ", "%b", 4);
|
||||
$finish(0);
|
||||
$display("Fatal [elaboration] elab_task.sv:10:5 - top - %b", 4);
|
||||
$finish(1);
|
||||
end
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -1,4 +0,0 @@
|
|||
affirm $finish;
|
||||
affirm $display("Elaboration Fatal:");
|
||||
affirm $finish(0);
|
||||
affirm $display("Elaboration Fatal: ", "%b", 4);
|
||||
|
|
@ -8,6 +8,6 @@ module top;
|
|||
$error("%b", 3);
|
||||
$fatal;
|
||||
$fatal(0);
|
||||
$fatal(0, "%b", 4);
|
||||
$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> - ", $time, "%b", 4);
|
||||
affirm $finish(1);
|
||||
|
|
@ -1,16 +1,16 @@
|
|||
module top;
|
||||
initial begin
|
||||
$display("[%0t] Info:", $time);
|
||||
$display("[%0t] Info: ", $time, "%b", 1);
|
||||
$display("[%0t] Warning:", $time);
|
||||
$display("[%0t] Warning: ", $time, "%b", 2);
|
||||
$display("[%0t] Error:", $time);
|
||||
$display("[%0t] Error: ", $time, "%b", 3);
|
||||
$display("[%0t] Fatal:", $time);
|
||||
$display("Info [%0t] severity_task.sv:3:9 - top.<unnamed_block>", $time);
|
||||
$display("Info [%0t] severity_task.sv:4:9 - top.<unnamed_block> - ", $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> - ", $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> - ", $time, "%b", 3);
|
||||
$display("Fatal [%0t] severity_task.sv:9:9 - top.<unnamed_block>", $time);
|
||||
$finish;
|
||||
$display("[%0t] Fatal:", $time);
|
||||
$finish(0);
|
||||
$display("[%0t] Fatal: ", $time, "%b", 4);
|
||||
$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> - ", $time, "%b", 4);
|
||||
$finish(1);
|
||||
end
|
||||
endmodule
|
||||
|
|
|
|||
|
|
@ -1,4 +0,0 @@
|
|||
affirm $finish;
|
||||
affirm $display("[%0t] Fatal:", $time);
|
||||
affirm $finish(0);
|
||||
affirm $display("[%0t] Fatal: ", $time, "%b", 4);
|
||||
|
|
@ -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,10 +176,10 @@ simulateAndCompare() {
|
|||
simulate $cvs_vcd $cvs_log $cs $tb
|
||||
simulate $cvv_vcd $cvv_log $cv $tb
|
||||
|
||||
# clean log files by removing filenames
|
||||
sed -i.bak -E 's#'$ve':[[:digit:]]+#'$ve'#g' $ref_log
|
||||
sed -i.bak -E 's#'$cs':[[:digit:]]+#'$ve'#g' $cvs_log
|
||||
sed -i.bak -E 's#'$cv':[[:digit:]]+#'$ve'#g' $cvv_log
|
||||
# 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`
|
||||
|
|
@ -204,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