Commit 5fd21ebf by Zachary Snow

improved parsing in declaration contexts

- support for additional assignment statements in loop initializations
- greatly improved error messaging in these contexts
- decl parser takes in the ending token; significant related refactoring
- pass through elaboration system tasks
- removed non-blocking assignment operator precedence hack
- preliminary nosim test suite for features unsupported by iverilog
parent 6ee558b6
......@@ -625,6 +625,11 @@ traverseNodesM exprMapper declMapper typeMapper lhsMapper stmtMapper =
a' <- traverseAssertionStmtsM stmtMapper a
a'' <- traverseAssertionExprsM exprMapper a'
return $ AssertionItem (mx, a'')
moduleItemMapper (ElabTask severity (Args pnArgs kwArgs)) = do
pnArgs' <- mapM exprMapper pnArgs
kwArgs' <- fmap (zip kwNames) $ mapM exprMapper kwExprs
return $ ElabTask severity $ Args pnArgs' kwArgs'
where (kwNames, kwExprs) = unzip kwArgs
genItemMapper = traverseGenItemExprsM exprMapper
......
......@@ -14,6 +14,7 @@ module Language.SystemVerilog.AST.ModuleItem
, NInputGateKW (..)
, NOutputGateKW (..)
, AssignOption (..)
, Severity (..)
) where
import Data.List (intercalate)
......@@ -24,7 +25,7 @@ import Language.SystemVerilog.AST.ShowHelp
import Language.SystemVerilog.AST.Attr (Attr)
import Language.SystemVerilog.AST.Decl (Direction)
import Language.SystemVerilog.AST.Description (PackageItem)
import Language.SystemVerilog.AST.Expr (Expr(Nil), pattern Ident, Range, showRanges, ParamBinding, showParams)
import Language.SystemVerilog.AST.Expr (Expr(Nil), pattern Ident, Range, showRanges, ParamBinding, showParams, Args)
import Language.SystemVerilog.AST.GenItem (GenItem)
import Language.SystemVerilog.AST.LHS (LHS)
import Language.SystemVerilog.AST.Stmt (Stmt, AssertionItem, Timing(Delay))
......@@ -41,6 +42,7 @@ data ModuleItem
| Modport Identifier [ModportDecl]
| Initial Stmt
| Final Stmt
| ElabTask Severity Args
| MIPackageItem PackageItem
| NInputGate NInputGateKW Expr Identifier LHS [Expr]
| NOutputGate NOutputGateKW Expr Identifier [LHS] Expr
......@@ -58,6 +60,7 @@ instance Show ModuleItem where
show (Modport x l) = printf "modport %s(\n%s\n);" x (indent $ intercalate ",\n" $ map showModportDecl l)
show (Initial s ) = printf "initial %s" (show s)
show (Final s ) = printf "final %s" (show s)
show (ElabTask s a) = printf "%s%s;" (show s) (show a)
show (NInputGate kw d x lhs exprs) =
showGate kw d x $ show lhs : map show exprs
show (NOutputGate kw d x lhss expr) =
......@@ -148,3 +151,16 @@ instance Show AssignOption where
show AssignOptionNone = ""
show (AssignOptionDelay de) = printf "#(%s)" (show de)
show (AssignOptionDrive s0 s1) = printf "(%s, %s)" (show s0) (show s1)
data Severity
= SeverityInfo
| SeverityWarning
| SeverityError
| SeverityFatal
deriving Eq
instance Show Severity where
show SeverityInfo = "$info"
show SeverityWarning = "$warning"
show SeverityError = "$error"
show SeverityFatal = "$fatal"
......@@ -401,7 +401,6 @@ time { Token Lit_time _ _ }
-- operator precedences, from *lowest* to *highest*
%nonassoc DefaultStrength
%nonassoc DriveStrength ChargeStrength
%nonassoc Asgn
%nonassoc NoElse
%nonassoc "else"
%right "|->" "|=>" "#-#" "#=#"
......@@ -630,17 +629,17 @@ Strength :: { Strength }
DeclTokens(delim) :: { [DeclToken] }
: DeclTokensBase(DeclTokens(delim), delim) { $1 }
DeclTokensBase(repeat, delim) :: { [DeclToken] }
: DeclToken delim { [$1] }
: DeclToken DTDelim(delim) { [$1, $2] }
| DeclToken repeat { [$1] ++ $2 }
| IdentifierP ParamBindings repeat { [uncurry DTIdent $1, DTParams (fst $1) $2] ++ $3 }
| DeclTokenAsgn "," repeat { [$1, DTComma (tokenPosition $2)] ++ $3 }
| DeclTokenAsgn delim { [$1] }
| DeclTokenAsgn DTDelim(delim) { [$1, $2] }
DeclToken :: { DeclToken }
: "," { DTComma $ tokenPosition $1 }
| "[" "]" { DTAutoDim $ tokenPosition $1 }
| "const" { DTConst $ tokenPosition $1 }
| "var" { DTVar $ tokenPosition $1 }
| PartSelectP { uncurry DTRange $1 }
| PartSelectP { uncurry (DTRange $ fst $1) (snd $1) }
| IdentifierP { uncurry DTIdent $1 }
| DirectionP { uncurry DTDir $1 }
| LHSConcatP { uncurry DTConcat $1 }
......@@ -655,21 +654,23 @@ DeclToken :: { DeclToken }
| "{" StreamOp Concat "}" { DTStream (tokenPosition $1) $2 (RawNum 1) (map toLHS $3) }
| "type" "(" Expr ")" { uncurry DTType $ makeTypeOf $1 $3 }
| IncOrDecOperatorP { DTAsgn (fst $1) (AsgnOp $ snd $1) Nothing (RawNum 1) }
| "<=" opt(DelayOrEvent) Expr %prec Asgn { DTAsgn (tokenPosition $1) AsgnOpNonBlocking $2 $3 }
| IdentifierP "::" Identifier { uncurry DTPSIdent $1 $3 }
| IdentifierP ParamBindings "::" Identifier { uncurry DTCSIdent $1 $2 $4 }
DTDelim(delim) :: { DeclToken }
: delim { DTEnd (tokenPosition $1) (head $ tokenString $1) }
DeclTokenAsgn :: { DeclToken }
: "=" opt(DelayOrEvent) Expr { DTAsgn (tokenPosition $1) AsgnOpEq $2 $3 }
| AsgnBinOpP Expr { uncurry DTAsgn $1 Nothing $2 }
| "<=" opt(DelayOrEvent) Expr { DTAsgn (tokenPosition $1) AsgnOpNonBlocking $2 $3 }
PortDeclTokens(delim) :: { [DeclToken] }
: DeclTokensBase(PortDeclTokens(delim), delim) { $1 }
| GenericInterfaceDecl PortDeclTokens(delim) { $1 ++ $2}
| GenericInterfaceDecl delim { $1 }
| GenericInterfaceDecl DTDelim(delim) { $1 ++ [$2] }
| AttributeInstanceP PortDeclTokens(delim) { uncurry DTAttr $1 : $2 }
ModuleDeclTokens(delim) :: { [DeclToken] }
: DeclTokensBase(ModuleDeclTokens(delim), delim) { $1 }
| GenericInterfaceDecl ModuleDeclTokens(delim) { $1 ++ $2}
| GenericInterfaceDecl delim { $1 }
| GenericInterfaceDecl DTDelim(delim) { $1 ++ [$2] }
GenericInterfaceDecl :: { [DeclToken] }
: "interface" IdentifierP { [DTType (tokenPosition $1) (\Unspecified -> InterfaceT "" ""), uncurry DTIdent $2] }
......
module top;
if (1 == 0)
wire foo;
else
$info("foo");
endmodule
module top;
initial begin
integer x, y;
x = 0;
y = 3;
for (x += 1; x < y; x++)
$display("A x = %0d", x);
end
initial begin
integer x, y;
x = 0;
for (x += 1, y = 3; x < y; x++)
$display("B x = %0d", x);
end
initial begin
integer x, y;
x = 0;
for (y = 3, x += 1; x < y; x++)
$display("C x = %0d", x);
end
initial
for (integer x = 0, y = 3; x < y; x++)
$display("D x = %0d", x);
initial
for (integer x = 0, byte y = 3; x < y; x++)
$display("E x = %0d", x);
initial begin
integer x, y;
x = 0;
for (x++, y = 3; x < y; x++)
$display("F x = %0d", x);
end
initial begin
integer x, y;
x = 0;
for (y = 3, x++; x < y; x++)
$display("G x = %0d", x);
end
initial begin
integer x, y;
x = 0;
for (--x, y = 3; x < y; x++)
$display("H x = %0d", x);
end
initial begin
integer x, y;
x = 0;
for (y = 3, --x; x < y; x++)
$display("I x = %0d", x);
end
initial begin
integer x, y;
x = 0;
y = 2;
for (--y, ++y, y++, ++x, --x, --x; x < y; x++)
$display("J x = %0d", x);
end
endmodule
module top;
`define LOOP(ID, START) \
x = 0; \
for (x = START; x < 3; x = x + 1) \
$display(`"ID x = %0d`", x);
initial begin : blk
integer x;
`LOOP(A, 1)
`LOOP(B, 1)
`LOOP(C, 1)
`LOOP(D, 0)
`LOOP(E, 0)
`LOOP(F, 1)
`LOOP(G, 1)
`LOOP(H, -1)
`LOOP(I, -1)
`LOOP(J, -1)
end
endmodule
// pattern: auto_dim_int\.sv:3:15: Parse error: expected comma or end of declarations
module top;
integer x [] = 1;
endmodule
// pattern: block_start_1\.sv:4:9: Parse error: expected primary token or type
module top;
initial begin
,;
end
endmodule
// pattern: block_start_2\.sv:4:9: Parse error: expected primary token or type
module top;
initial begin
= 1;
end
endmodule
// pattern: block_start_3\.sv:4:9: Parse error: expected primary token or type
module top;
initial begin
P::Q = 1;
end
endmodule
// pattern: block_start_4\.sv:4:11: Parse error: unexpected statement token
module top;
initial begin
a , ;
end
endmodule
// pattern: decl_bare\.sv:3:5: Parse error: declaration missing type information
module top;
a;
endmodule
// pattern: decl_missing_comma\.sv:3:15: Parse error: expected comma or end of declarations
module top;
integer a b;
endmodule
// pattern: decl_trailing_comma\.sv:3:16: Parse error: unexpected token in declaration
module top;
integer a, ;
endmodule
// pattern: elab_task_stray_after_args\.sv:3:12: Parse error: unexpected token after elaboration system task
module top;
$info(), ;
endmodule
// pattern: elab_task_stray_before_args\.sv:3:11: Parse error: unexpected token after elaboration system task
module top;
$info , ();
endmodule
// pattern: elab_task_stray_no_args\.sv:3:11: Parse error: unexpected token after elaboration system task
module top;
$info , ;
endmodule
// pattern: for loop declaration missing initialization
// pattern: for_loop_decl_no_init\.sv:4:14: Parse error: for loop declaration of "x" is missing initialization
module top;
initial
for (integer x; x < 3; x = x + 1)
......
// pattern: for_loop_init_bare\.sv:3:19: Parse error: expected assignment operator
module top;
initial for (a,; 1; a++) ;
endmodule
// pattern: for_loop_init_delay\.sv:4:20: Parse error: unexpected timing modifier in for loop initialization
module top;
integer x;
initial for (x = #1 1; 1; x++) ;
endmodule
// pattern: for_loop_init_nblk\.sv:4:20: Parse error: unexpected non-blocking assignment in for loop initialization
module top;
integer x;
initial for (x <= 1; 1; x++) ;
endmodule
// pattern: for_loop_init_stray\.sv:3:22: Parse error: expected ',' or ';'
module top;
initial for (a++ b++; 1; a++) ;
endmodule
// pattern: instantiation_extra_comma\.sv:3:18: Parse error: expected instantiation before delimiter
// pattern: instantiation_extra_comma\.sv:3:18: Parse error: expected instantiation before ','
module top;
example a(), , b();
endmodule
// pattern: instantiation_missing_ports\.sv:3:14: Parse error: expected port connections before delimiter
// pattern: instantiation_missing_ports\.sv:3:14: Parse error: expected port connections before ','
module top;
example a, c();
endmodule
// pattern: instantiation_trailing_comma\.sv:3:16: Parse error: unexpected end of instantiation list
// pattern: instantiation_trailing_comma\.sv:3:18: Parse error: expected instantiation before ';'
module top;
example a(), ;
endmodule
// pattern: port_list_incomplete\.sv:2:17: Parse error: expected identifier
module top(input);
endmodule
// pattern: run_on_decl_item.sv:3:16: Parse error: unexpected comma-separated declarations
// pattern: run_on_decl_item\.sv:3:16: Parse error: unexpected token in declaration
module top;
integer x, byte y;
endmodule
// pattern: run_on_decl_stmt.sv:4:20: Parse error: unexpected comma-separated declarations
// pattern: run_on_decl_stmt\.sv:4:20: Parse error: unexpected token in declaration
module top;
initial begin
integer x, byte y;
......
module top;
$info;
$info("%b", 1);
$warning;
$warning("%b", 2);
$error;
$error("%b", 3);
$fatal;
$fatal("%b", 4);
endmodule
#!/bin/bash
addTest() {
test=$1
eval "test_$test() { assertConverts $test.sv; }"
suite_addTest test_$test
}
source ../lib/functions.sh
source ../lib/discover.sh
. shunit2
module top;
trireg (small) x;
trireg (medium) y;
trireg (large) z;
endmodule
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