diff --git a/README.md b/README.md index 3424d17..17fb32e 100644 --- a/README.md +++ b/README.md @@ -81,16 +81,16 @@ A parser library for System Verilog. | Clause | Exist | Pass | Clause | Exist | Pass | Clause | Exist | Pass | Clause | Exist | Pass | | ------ | ----- | ---- | ------ | ----- | ---- | ------ | ----- | ---- | ------ | ----- | ---- | -| 3 | x | x | 13 | x | | 23 | x | | 33 | x | | -| 4 | x | x | 14 | x | | 24 | x | x | 34 | x | | -| 5 | x | x | 15 | x | | 25 | x | | 35 | x | | +| 3 | x | x | 13 | x | x | 23 | x | | 33 | x | | +| 4 | x | x | 14 | x | x | 24 | x | x | 34 | x | | +| 5 | x | x | 15 | x | x | 25 | x | | 35 | x | | | 6 | x | x | 16 | x | | 26 | x | | 36 | x | x | | 7 | x | x | 17 | x | | 27 | x | | | | | | 8 | x | x | 18 | x | | 28 | x | x | | | | | 9 | x | x | 19 | x | | 29 | x | | | | | | 10 | x | x | 20 | x | | 30 | x | | | | | -| 11 | x | | 21 | x | | 31 | x | | | | | -| 12 | x | | 22 | | | 32 | x | x | | | | +| 11 | x | x | 21 | x | | 31 | x | | | | | +| 12 | x | x | 22 | | | 32 | x | x | | | | ## Missing entry of specification diff --git a/sv-parser-parser/src/behavioral_statements/clocking_block.rs b/sv-parser-parser/src/behavioral_statements/clocking_block.rs index dc51a9d..4a65729 100644 --- a/sv-parser-parser/src/behavioral_statements/clocking_block.rs +++ b/sv-parser-parser/src/behavioral_statements/clocking_block.rs @@ -129,9 +129,9 @@ pub(crate) fn clocking_item_assertion(s: Span) -> IResult { #[packrat_parser] pub(crate) fn default_skew(s: Span) -> IResult { alt(( + default_skew_input_output, default_skew_input, default_skew_output, - default_skew_input_output, ))(s) } @@ -176,9 +176,9 @@ pub(crate) fn default_skew_input_output(s: Span) -> IResult { #[packrat_parser] pub(crate) fn clocking_direction(s: Span) -> IResult { alt(( + clocking_direction_input_output, clocking_direction_input, clocking_direction_output, - clocking_direction_input_output, clocking_direction_inout, ))(s) } diff --git a/sv-parser-parser/src/behavioral_statements/conditional_statements.rs b/sv-parser-parser/src/behavioral_statements/conditional_statements.rs index ff3ed14..32de996 100644 --- a/sv-parser-parser/src/behavioral_statements/conditional_statements.rs +++ b/sv-parser-parser/src/behavioral_statements/conditional_statements.rs @@ -49,12 +49,12 @@ pub(crate) fn cond_predicate(s: Span) -> IResult { #[packrat_parser] pub(crate) fn expression_or_cond_pattern(s: Span) -> IResult { alt(( - map(expression, |x| { - ExpressionOrCondPattern::Expression(Box::new(x)) - }), map(cond_pattern, |x| { ExpressionOrCondPattern::CondPattern(Box::new(x)) }), + map(expression, |x| { + ExpressionOrCondPattern::Expression(Box::new(x)) + }), ))(s) } diff --git a/sv-parser-parser/src/declarations/assertion_declarations.rs b/sv-parser-parser/src/declarations/assertion_declarations.rs index cec4be3..ebbb346 100644 --- a/sv-parser-parser/src/declarations/assertion_declarations.rs +++ b/sv-parser-parser/src/declarations/assertion_declarations.rs @@ -255,7 +255,7 @@ pub(crate) fn property_port_list(s: Span) -> IResult { #[packrat_parser] pub(crate) fn property_port_item(s: Span) -> IResult { let (s, a) = many0(attribute_instance)(s)?; - let (s, b) = opt(pair(local, opt(property_lvar_port_direction)))(s)?; + let (s, b) = opt(pair(keyword("local"), opt(property_lvar_port_direction)))(s)?; let (s, c) = property_formal_type(s)?; let (s, d) = formal_port_identifier(s)?; let (s, e) = many0(variable_dimension)(s)?; @@ -311,7 +311,9 @@ pub(crate) fn property_expr(s: Span) -> IResult { property_expr_implication_nonoverlapped, property_expr_followed_by_overlapped, property_expr_followed_by_nonoverlapped, - map(sequence_expr, |x| PropertyExpr::SequenceExpr(Box::new(x))), + map(terminated(sequence_expr, peek(not(symbol("(")))), |x| { + PropertyExpr::SequenceExpr(Box::new(x)) + }), property_expr_strong, property_expr_weak, property_expr_paren, @@ -783,7 +785,7 @@ pub(crate) fn sequence_port_list(s: Span) -> IResult { #[packrat_parser] pub(crate) fn sequence_port_item(s: Span) -> IResult { let (s, a) = many0(attribute_instance)(s)?; - let (s, b) = opt(pair(local, opt(sequence_lvar_port_direction)))(s)?; + let (s, b) = opt(pair(keyword("local"), opt(sequence_lvar_port_direction)))(s)?; let (s, c) = sequence_formal_type(s)?; let (s, d) = formal_port_identifier(s)?; let (s, e) = many0(variable_dimension)(s)?; @@ -1153,7 +1155,7 @@ pub(crate) fn sequence_list_of_arguments_named(s: Span) -> IResult IResult { alt(( - map(event_expression, |x| { + map(event_expression_sequence_actual_arg, |x| { SequenceActualArg::EventExpression(Box::new(x)) }), map(sequence_expr, |x| { @@ -1162,6 +1164,30 @@ pub(crate) fn sequence_actual_arg(s: Span) -> IResult { ))(s) } +#[tracable_parser] +#[packrat_parser] +pub(crate) fn event_expression_sequence_actual_arg(s: Span) -> IResult { + alt(( + event_expression_or_sequence_actual_arg, + event_expression_expression, + event_expression_sequence, + event_expression_paren, + ))(s) +} + +#[recursive_parser] +#[tracable_parser] +#[packrat_parser] +pub(crate) fn event_expression_or_sequence_actual_arg(s: Span) -> IResult { + let (s, a) = event_expression_sequence_actual_arg(s)?; + let (s, b) = keyword("or")(s)?; + let (s, c) = event_expression_sequence_actual_arg(s)?; + Ok(( + s, + EventExpression::Or(Box::new(EventExpressionOr { nodes: (a, b, c) })), + )) +} + #[tracable_parser] #[packrat_parser] pub(crate) fn boolean_abbrev(s: Span) -> IResult { diff --git a/sv-parser-parser/src/declarations/delays.rs b/sv-parser-parser/src/declarations/delays.rs index a439893..f8ae8e7 100644 --- a/sv-parser-parser/src/declarations/delays.rs +++ b/sv-parser-parser/src/declarations/delays.rs @@ -66,10 +66,10 @@ pub(crate) fn delay2_mintypmax(s: Span) -> IResult { #[packrat_parser] pub(crate) fn delay_value(s: Span) -> IResult { alt(( + map(keyword("1step"), |x| DelayValue::Step1(Box::new(x))), map(time_literal, |x| DelayValue::TimeLiteral(Box::new(x))), map(unsigned_number, |x| DelayValue::UnsignedNumber(Box::new(x))), map(real_number, |x| DelayValue::RealNumber(Box::new(x))), map(ps_identifier, |x| DelayValue::PsIdentifier(Box::new(x))), - map(keyword("1step"), |x| DelayValue::Step1(Box::new(x))), ))(s) } diff --git a/sv-parser-parser/src/expressions/expressions.rs b/sv-parser-parser/src/expressions/expressions.rs index 5f8655e..462b1dc 100644 --- a/sv-parser-parser/src/expressions/expressions.rs +++ b/sv-parser-parser/src/expressions/expressions.rs @@ -144,15 +144,15 @@ pub(crate) fn constant_mintypmax_expression_ternary( #[packrat_parser] pub(crate) fn constant_param_expression(s: Span) -> IResult { alt(( - map(symbol("$"), |x| { - ConstantParamExpression::Dollar(Box::new(x)) - }), map(constant_mintypmax_expression, |x| { ConstantParamExpression::ConstantMintypmaxExpression(Box::new(x)) }), map(data_type, |x| { ConstantParamExpression::DataType(Box::new(x)) }), + map(symbol("$"), |x| { + ConstantParamExpression::Dollar(Box::new(x)) + }), ))(s) } @@ -160,11 +160,11 @@ pub(crate) fn constant_param_expression(s: Span) -> IResult IResult { alt(( - map(symbol("$"), |x| ParamExpression::Dollar(Box::new(x))), map(mintypmax_expression, |x| { ParamExpression::MintypmaxExpression(Box::new(x)) }), map(data_type, |x| ParamExpression::DataType(Box::new(x))), + map(symbol("$"), |x| ParamExpression::Dollar(Box::new(x))), ))(s) } diff --git a/sv-parser-parser/src/expressions/primaries.rs b/sv-parser-parser/src/expressions/primaries.rs index d0efad8..43917af 100644 --- a/sv-parser-parser/src/expressions/primaries.rs +++ b/sv-parser-parser/src/expressions/primaries.rs @@ -13,6 +13,9 @@ pub(crate) fn constant_primary(s: Span) -> IResult { map(primary_literal, |x| { ConstantPrimary::PrimaryLiteral(Box::new(x)) }), + map(constant_function_call, |x| { + ConstantPrimary::ConstantFunctionCall(Box::new(x)) + }), constant_primary_ps_parameter, constant_primary_specparam, map(genvar_identifier, |x| { @@ -22,9 +25,6 @@ pub(crate) fn constant_primary(s: Span) -> IResult { constant_primary_enum, constant_primary_concatenation, constant_primary_multiple_concatenation, - map(constant_function_call, |x| { - ConstantPrimary::ConstantFunctionCall(Box::new(x)) - }), map(constant_let_expression, |x| { ConstantPrimary::ConstantLetExpression(Box::new(x)) }), diff --git a/sv-parser-parser/src/expressions/subroutine_calls.rs b/sv-parser-parser/src/expressions/subroutine_calls.rs index 520f737..5e6b475 100644 --- a/sv-parser-parser/src/expressions/subroutine_calls.rs +++ b/sv-parser-parser/src/expressions/subroutine_calls.rs @@ -22,9 +22,9 @@ pub(crate) fn tf_call(s: Span) -> IResult { #[packrat_parser] pub(crate) fn system_tf_call(s: Span) -> IResult { alt(( - system_tf_call_arg_optional, - system_tf_call_arg_data_type, system_tf_call_arg_expression, + system_tf_call_arg_data_type, + system_tf_call_arg_optional, ))(s) } @@ -55,7 +55,10 @@ pub(crate) fn system_tf_call_arg_data_type(s: Span) -> IResult IResult { let (s, a) = system_tf_identifier(s)?; let (s, b) = paren(pair( - list(symbol(","), opt(expression)), + list( + terminated(symbol(","), peek(not(clocking_event))), + opt(expression), + ), opt(pair(symbol(","), opt(clocking_event))), ))(s)?; Ok(( @@ -104,7 +107,10 @@ pub(crate) fn list_of_arguments(s: Span) -> IResult { #[tracable_parser] #[packrat_parser] pub(crate) fn list_of_arguments_ordered(s: Span) -> IResult { - let (s, a) = list(symbol(","), opt(expression))(s)?; + let (s, a) = list( + terminated(symbol(","), peek(not(symbol(".")))), + opt(expression), + )(s)?; let (s, b) = many0(tuple(( symbol(","), symbol("."), diff --git a/sv-parser-parser/src/source_text/module_parameters_and_ports.rs b/sv-parser-parser/src/source_text/module_parameters_and_ports.rs index bf8395c..a82ca90 100644 --- a/sv-parser-parser/src/source_text/module_parameters_and_ports.rs +++ b/sv-parser-parser/src/source_text/module_parameters_and_ports.rs @@ -316,12 +316,12 @@ pub(crate) fn net_port_header_or_interface_port_header( s: Span, ) -> IResult { alt(( - map(net_port_header, |x| { - NetPortHeaderOrInterfacePortHeader::NetPortHeader(Box::new(x)) - }), map(interface_port_header, |x| { NetPortHeaderOrInterfacePortHeader::InterfacePortHeader(Box::new(x)) }), + map(net_port_header, |x| { + NetPortHeaderOrInterfacePortHeader::NetPortHeader(Box::new(x)) + }), ))(s) } diff --git a/sv-parser-parser/src/tests.rs b/sv-parser-parser/src/tests.rs index 2a5b9b5..b028de2 100644 --- a/sv-parser-parser/src/tests.rs +++ b/sv-parser-parser/src/tests.rs @@ -6,6 +6,14 @@ macro_rules! test { ( $x:expr, $y:expr, $z:pat ) => { nom_packrat::init!(); let info = SpanInfo::default(); + #[cfg(feature = "trace")] + let info = info.set_tracable_info( + info.get_tracable_info() + .fold("white_space") + .fold("number") + .fold("binary_operator") + .fold("unary_operator"), + ); let ret = all_consuming($x)(Span::new_extra($y, info)); if let $z = ret { } else { @@ -5206,23 +5214,25 @@ mod spec { end"##, Ok((_, _)) ); - //test!( - // many1(module_item), - // r##"package pex_gen9_common_expressions; - // let valid_arb(request, valid, override) = |(request & valid) || override; - // endpackage + test!( + source_text, + r##"package pex_gen9_common_expressions; + let valid_arb(request, valid, override) = |(request & valid) || override; + endpackage - // module my_checker; - // import pex_gen9_common_expressions::*; - // logic a, b; - // wire [1:0] req; - // wire [1:0] vld; - // logic ovr; - // if (valid_arb(.request(req), .valid(vld), .override(ovr))) begin - // end - // endmodule"##, - // Ok((_, _)) - //); + module my_checker; + import pex_gen9_common_expressions::*; + logic a, b; + wire [1:0] req; + wire [1:0] vld; + logic ovr; + initial begin + if (valid_arb(.request(req), .valid(vld), .override(ovr))) begin + end + end + endmodule"##, + Ok((_, _)) + ); test!( many1(module_item), r##"let mult(x, y) = ($bits(x) + $bits(y))'(x * y);"##, @@ -5239,20 +5249,20 @@ mod spec { end"##, Ok((_, _)) ); - //test!( - // many1(module_item), - // r##"initial begin - // task write_value; - // input logic [31:0] addr; - // input logic [31:0] value; - // endtask + test!( + many1(module_item), + r##"task write_value; + input logic [31:0] addr; + input logic [31:0] value; + endtask - // let addr = top.block1.unit1.base + top.block1.unit2.displ; + let addr = top.block1.unit1.base + top.block1.unit2.displ; - // write_value(addr, 0); - // end"##, - // Ok((_, _)) - //); + initial begin + write_value(addr, 0); + end"##, + Ok((_, _)) + ); test!( many1(module_item), r##"module m; @@ -5343,6 +5353,8 @@ mod spec { endmodule : top"##, Ok((_, _)) ); + // TODO + // assign can't have block_identifier like assert //test!( // many1(module_item), // r##"module m(); @@ -5354,10 +5366,10 @@ mod spec { // for (genvar i = 0; i < 3; i++) begin : L0 // if (i !=1) begin : L1 // let my_let(x) = !x || b && c[i]; - // s1: assign d[2 – i] = my_let(a)); // OK + // s1: assign d[2 - i] = my_let(a); // OK // end : L1 // end : L0 - // s2: assign e = L0[0].L1.my_let(a)); // Illegal + // s2: assign e = L0[0].L1.my_let(a); // Illegal // endmodule : m"##, // Ok((_, _)) //); @@ -5413,39 +5425,39 @@ mod spec { endmodule : m"##, Ok((_, _)) ); - //test!( - // many1(module_item), - // r##"module m(input clock); - // logic a; - // let p1(x) = $past(x); - // let p2(x) = $past(x,,,@(posedge clock)); - // let s(x) = $sampled(x); - // always_comb begin - // a1: assert(p1(a)); - // a2: assert(p2(a)); - // a3: assert(s(a)); - // end - // a4: assert property(@(posedge clock) p1(a)); - // endmodule : m"##, - // Ok((_, _)) - //); - //test!( - // many1(module_item), - // r##"module m(input clock); - // logic a; - // let p1(x) = $past(x); - // let p2(x) = $past(x,,,@(posedge clock)); - // let s(x) = $sampled(x); - // always_comb begin - // a1: assert(($past(a))); // Illegal: no clock can be inferred - // a2: assert(($past(a,,,@(posedge clock)))); - // a3: assert(($sampled (a))); - // end - // a4: assert property(@(posedge clock)($past(a))); // @(posedge clock) - // // is inferred - // endmodule : m"##, - // Ok((_, _)) - //); + test!( + many1(module_item), + r##"module m(input clock); + logic a; + let p1(x) = $past(x); + let p2(x) = $past(x,,,@(posedge clock)); + let s(x) = $sampled(x); + always_comb begin + a1: assert(p1(a)); + a2: assert(p2(a)); + a3: assert(s(a)); + end + a4: assert property(@(posedge clock) p1(a)); + endmodule : m"##, + Ok((_, _)) + ); + test!( + many1(module_item), + r##"module m(input clock); + logic a; + let p1(x) = $past(x); + let p2(x) = $past(x,,,@(posedge clock)); + let s(x) = $sampled(x); + always_comb begin + a1: assert(($past(a))); // Illegal: no clock can be inferred + a2: assert(($past(a,,,@(posedge clock)))); + a3: assert(($sampled (a))); + end + a4: assert property(@(posedge clock)($past(a))); // @(posedge clock) + // is inferred + endmodule : m"##, + Ok((_, _)) + ); } #[test] @@ -5561,24 +5573,24 @@ mod spec { end"##, Ok((_, _)) ); - //test!( - // many1(module_item), - // r##"module fsm(); - // function bit f1(bit a, bit not_a) - // a1: unique if (a); - // else if (not_a); - // endfunction + test!( + many1(module_item), + r##"module fsm(); + function bit f1(bit a, bit not_a); + a1: unique if (a); + else if (not_a); + endfunction - // always_comb begin : b1 - // some_stuff = f1(c, d); - // end + always_comb begin : b1 + some_stuff = f1(c, d); + end - // always_comb begin : b2 - // other_stuff = f1(e, f); - // end - // endmodule"##, - // Ok((_, _)) - //); + always_comb begin : b2 + other_stuff = f1(e, f); + end + endmodule"##, + Ok((_, _)) + ); test!( many1(module_item), r##"initial begin @@ -5794,6 +5806,8 @@ mod spec { end"##, Ok((_, _)) ); + // TODO + // tagged can't have paren. //test!( // many1(module_item), // r##"initial begin @@ -5805,6 +5819,8 @@ mod spec { // end"##, // Ok((_, _)) //); + // TODO + // tagged can't have paren. //test!( // many1(module_item), // r##"initial begin @@ -5817,6 +5833,8 @@ mod spec { // end"##, // Ok((_, _)) //); + // TODO + // tagged can't have paren. //test!( // many1(module_item), // r##"initial begin @@ -5827,6 +5845,8 @@ mod spec { // end"##, // Ok((_, _)) //); + // TODO + // tagged can't have paren. //test!( // many1(module_item), // r##"initial begin @@ -5838,6 +5858,8 @@ mod spec { // end"##, // Ok((_, _)) //); + // TODO + // tagged can't have paren. //test!( // many1(module_item), // r##"initial begin @@ -6165,63 +6187,63 @@ mod spec { endmodule: tryfact"##, Ok((_, _)) ); - //test!( - // many1(module_item), - // r##"module ram_model (address, write, chip_select, data); - // parameter data_width = 8; - // parameter ram_depth = 256; - // localparam addr_width = clogb2(ram_depth); - // input [addr_width - 1:0] address; - // input write, chip_select; - // inout [data_width - 1:0] data; + test!( + many1(module_item), + r##"module ram_model (address, write, chip_select, data); + parameter data_width = 8; + parameter ram_depth = 256; + localparam addr_width = clogb2(ram_depth); + input [addr_width - 1:0] address; + input write, chip_select; + inout [data_width - 1:0] data; - // //define the clogb2 function - // function integer clogb2 (input [31:0] value); - // value = value - 1; - // for (clogb2 = 0; value > 0; clogb2 = clogb2 + 1) - // value = value >> 1; - // endfunction + //define the clogb2 function + function integer clogb2 (input [31:0] value); + value = value - 1; + for (clogb2 = 0; value > 0; clogb2 = clogb2 + 1) + value = value >> 1; + endfunction - // logic [data_width - 1:0] data_store[0:ram_depth - 1]; - // //the rest of the ram model - // endmodule: ram_model"##, - // Ok((_, _)) - //); + logic [data_width - 1:0] data_store[0:ram_depth - 1]; + //the rest of the ram model + endmodule: ram_model"##, + Ok((_, _)) + ); test!( many1(module_item), r##"ram_model #(32,421) ram_a0(a_addr,a_wr,a_cs,a_data);"##, Ok((_, _)) ); - //test!( - // many1(module_item), - // r##"class IntClass; - // int a; - // endclass + test!( + many1(module_item), + r##"class IntClass; + int a; + endclass - // IntClass address=new(), stack=new(); + IntClass address=new(), stack=new(); - // function automatic bit watch_for_zero( IntClass p ); - // fork - // forever @p.a begin - // if ( p.a == 0 ) $display (“Unexpected zero”); - // end - // join_none - // return ( p.a == 0 ); - // endfunction + function automatic bit watch_for_zero( IntClass p ); + fork + forever @p.a begin + if ( p.a == 0 ) $display ("Unexpected zero"); + end + join_none + return ( p.a == 0 ); + endfunction - // function bit start_check(); - // return ( watch_for_zero( address ) | watch_for_zero( stack ) ); - // endfunction + function bit start_check(); + return ( watch_for_zero( address ) | watch_for_zero( stack ) ); + endfunction - // bit y = watch_for_zero( stack ); // illegal + bit y = watch_for_zero( stack ); // illegal - // initial if ( start_check() ) $display ( “OK”); // legal + initial if ( start_check() ) $display ( "OK"); // legal - // initial fork - // if (start_check() ) $display( “OK too”); // legal - // join_none"##, - // Ok((_, _)) - //); + initial fork + if (start_check() ) $display( "OK too"); // legal + join_none"##, + Ok((_, _)) + ); test!( many1(module_item), r##"function automatic int crc( byte packet [1000:1] ); @@ -6323,35 +6345,37 @@ mod spec { end"##, Ok((_, _)) ); - //test!( - // many1(module_item), - // r##"initial begin - // //fun( .s("yes"), 2 ); // illegal - // fun( 2, .s("yes") ); // OK - // end"##, - // Ok((_, _)) - //); - //test!( - // many1(module_item), - // r##"virtual class C#(parameter DECODE_W, parameter ENCODE_W = $clog2(DECODE_W)); - // static function logic [ENCODE_W-1:0] ENCODER_f - // (input logic [DECODE_W-1:0] DecodeIn); - // ENCODER_f = '0; - // for (int i=0; i (posedge clk1) - // end - // endmodule - // endmodule"##, - // Ok((_, _)) - //); + test!( + many1(module_item), + r##"module processor(); + clocking busA @(posedge clk1); endclocking + clocking busB @(negedge clk2); endclocking + module cpu( interface y ); + default clocking busA ; + initial begin + ## 5; // use busA => (posedge clk1) + end + endmodule + endmodule"##, + Ok((_, _)) + ); test!( many1(module_item), r##"clocking cb @(negedge clk); @@ -6676,33 +6696,33 @@ mod spec { endmodule"##, Ok((_, _)) ); - //test!( - // many1(module_item), - // r##"module top; - // logic a, b, c, clk; - // global clocking top_clocking @(clk); endclocking + test!( + many1(module_item), + r##"module top; + logic a, b, c, clk; + global clocking top_clocking @(clk); endclocking - // property p1(req, ack); - // @($global_clock) req |=> ack; - // endproperty + property p1(req, ack); + @($global_clock) req |=> ack; + endproperty - // property p2(req, ack, interrupt); - // @($global_clock) accept_on(interrupt) p1(req, ack); - // endproperty + property p2(req, ack, interrupt); + @($global_clock) accept_on(interrupt) p1(req, ack); + endproperty - // my_checker check( - // p2(a, b, c), - // @$global_clock a[*1:$] ##1 b); - // endmodule + my_checker check( + p2(a, b, c), + @($global_clock) a[*1:$] ##1 b); + endmodule - // checker my_checker(property p, sequence s); - // logic checker_clk; - // global clocking checker_clocking @(checker_clk); endclocking - // assert property (p); - // cover property (s); - // endchecker"##, - // Ok((_, _)) - //); + checker my_checker(property p, sequence s); + logic checker_clk; + global clocking checker_clocking @(checker_clk); endclocking + assert property (p); + cover property (s); + endchecker"##, + Ok((_, _)) + ); test!( many1(module_item), r##"initial begin @@ -6912,28 +6932,28 @@ mod spec { end"##, Ok((_, _)) ); - //test!( - // many1(module_item), - // r##"initial begin - // event done, blast; // declare two new events - // event done_too = done; // declare done_too as alias to done + test!( + many1(module_item), + r##"event done, blast; // declare two new events + event done_too = done; // declare done_too as alias to done - // task trigger( event ev ); - // -> ev; - // endtask + task trigger( event ev ); + -> ev; + endtask - // fork - // @ done_too; // wait for done through done_too - // #1 trigger( done ); // trigger done through task trigger - // join + initial begin + fork + @ done_too; // wait for done through done_too + #1 trigger( done ); // trigger done through task trigger + join - // fork - // -> blast; - // wait ( blast.triggered ); - // join - // end"##, - // Ok((_, _)) - //); + fork + -> blast; + wait ( blast.triggered ); + join + end"##, + Ok((_, _)) + ); test!( many1(module_item), r##"initial begin @@ -7011,16 +7031,16 @@ mod spec { #[test] fn clause16() { - //test!( - // many1(module_item), - // r##"initial begin - // assert_f: assert(f) $info("passed"); else $error("failed"); - // assume_inputs: assume (in_a || in_b) $info("assumption holds"); - // else $error("assumption does not hold"); - // cover_a_and_b: cover (in_a && in_b) $info("in_a && in_b == 1 covered"); - // end"##, - // Ok((_, _)) - //); + test!( + many1(module_item), + r##"initial begin + assert_f: assert(f) $info("passed"); else $error("failed"); + assume_inputs: assume (in_a || in_b) $info("assumption holds"); + else $error("assumption does not hold"); + cover_a_and_b: cover (in_a && in_b) $info("in_a && in_b == 1 covered"); + end"##, + Ok((_, _)) + ); test!( many1(module_item), r##"time t; @@ -7034,14 +7054,14 @@ mod spec { end"##, Ok((_, _)) ); - //test!( - // many1(module_item), - // r##"initial begin - // assert (myfunc(a,b)) count1 = count + 1; else ->event1; - // assert (y == 0) else flag = 1; - // end"##, - // Ok((_, _)) - //); + test!( + many1(module_item), + r##"initial begin + assert (myfunc(a,b)) count1 = count + 1; else ->event1; + assert (y == 0) else flag = 1; + end"##, + Ok((_, _)) + ); test!( many1(module_item), r##"assign not_a = !a; @@ -7051,15 +7071,15 @@ mod spec { end"##, Ok((_, _)) ); - //test!( - // many1(module_item), - // r##"always @(a or b) begin : b1 - // a3: assert #0 (a == b) rptobj.success(0); else rptobj.error(0, a, b); - // #1; - // a4: assert #0 (a == b) rptobj.success(1); else rptobj.error(1, a, b); - // end"##, - // Ok((_, _)) - //); + test!( + many1(module_item), + r##"always @(a or b) begin : b1 + a3: assert #0 (a == b) rptobj.success(0); else rptobj.error(0, a, b); + #1; + a4: assert #0 (a == b) rptobj.success(1); else rptobj.error(1, a, b); + end"##, + Ok((_, _)) + ); test!( many1(module_item), r##"always_comb begin : b1 @@ -7096,42 +7116,42 @@ mod spec { end"##, Ok((_, _)) ); - //test!( - // many1(module_item), - // r##"module dut(input logic clk, input logic a, input logic b); - // logic c; - // always_ff @(posedge clk) - // c <= b; - // a1: assert #0 (!(a & c)) $display("Pass"); else $display("Fail"); - // a2: assert final (!(a & c)) $display("Pass"); else $display("Fail"); - // endmodule + test!( + many1(module_item), + r##"module dut(input logic clk, input logic a, input logic b); + logic c; + always_ff @(posedge clk) + c <= b; + a1: assert #0 (!(a & c)) $display("Pass"); else $display("Fail"); + a2: assert final (!(a & c)) $display("Pass"); else $display("Fail"); + endmodule - // program tb(input logic clk, output logic a, output logic b); - // default clocking m @(posedge clk); - // default input #0; - // default output #0; - // output a; - // output b; - // endclocking + program tb(input logic clk, output logic a, output logic b); + default clocking m @(posedge clk); + default input #0; + default output #0; + output a; + output b; + endclocking - // initial begin - // a = 1; - // b = 0; - // ##10; - // b = 1; - // ##1; - // a = 0; - // end - // endprogram + initial begin + a = 1; + b = 0; + ##10; + b = 1; + ##1; + a = 0; + end + endprogram - // module sva_svtb; - // bit clk; - // logic a, b; - // dut dut (.*); - // tb tb (.*); - // endmodule"##, - // Ok((_, _)) - //); + module sva_svtb; + bit clk; + logic a, b; + dut dut (.*); + tb tb (.*); + endmodule"##, + Ok((_, _)) + ); test!( many1(module_item), r##"module m (input a, b); @@ -7173,40 +7193,40 @@ mod spec { end"##, Ok((_, _)) ); - //test!( - // many1(module_item), - // r##"module fsm(); - // function bit f (int a, int b) - // a1: assert #0 (a == b); - // endfunction + test!( + many1(module_item), + r##"module fsm(); + function bit f (int a, int b); + a1: assert #0 (a == b); + endfunction - // always_comb begin : b1 - // some_stuff = f(x,y); - // end + always_comb begin : b1 + some_stuff = f(x,y); + end - // always_comb begin : b2 - // other_stuff = f(z,w); - // end - // endmodule"##, - // Ok((_, _)) - //); - //test!( - // many1(module_item), - // r##"global clocking @clk; endclocking - // assert property(@$global_clock a);"##, - // Ok((_, _)) - //); + always_comb begin : b2 + other_stuff = f(z,w); + end + endmodule"##, + Ok((_, _)) + ); + test!( + many1(module_item), + r##"global clocking @clk; endclocking + assert property(@($global_clock) a);"##, + Ok((_, _)) + ); test!( many1(module_item), r##"assert property(@clk a);"##, Ok((_, _)) ); - //test!( - // many1(module_item), - // r##"base_rule1: assert property (cont_prop(rst,in1,in2)) $display("%m, passing"); - // else $display("%m, failed");"##, - // Ok((_, _)) - //); + test!( + many1(module_item), + r##"base_rule1: assert property (cont_prop(rst,in1,in2)) $display("%m, passing"); + else $display("%m, failed");"##, + Ok((_, _)) + ); test!( many1(module_item), r##"bit a; @@ -7223,30 +7243,30 @@ mod spec { endproperty"##, Ok((_, _)) ); - //test!( - // many1(module_item), - // r##"bit [2:0] count; - // realtime t; + test!( + many1(module_item), + r##"bit [2:0] count; + realtime t; - // initial count = 0; - // always @(posedge clk) begin - // if (count == 0) t = $realtime; //capture t in a procedural context - // count++; - // end + initial count = 0; + always @(posedge clk) begin + if (count == 0) t = $realtime; //capture t in a procedural context + count++; + end - // property p1; - // @(posedge clk) - // count == 7 |-> $realtime – t < 50.5; - // endproperty + property p1; + @(posedge clk) + count == 7 |-> $realtime - t < 50.5; + endproperty - // property p2; - // realtime l_t; - // @(posedge clk) - // (count == 0, l_t = $realtime) ##1 (count == 7)[->1] |-> - // $realtime – l_t < 50.5; - // endproperty"##, - // Ok((_, _)) - //); + property p2; + realtime l_t; + @(posedge clk) + (count == 0, l_t = $realtime) ##1 (count == 7)[->1] |-> + $realtime - l_t < 50.5; + endproperty"##, + Ok((_, _)) + ); test!( many1(module_item), r##"sequence delay_example(x, y, min, max, delay1); @@ -7339,20 +7359,20 @@ mod spec { r##"cover property (x ##2 y[*3:$] ##1 z);"##, Ok((_, _)) ); - //test!( - // many1(module_item), - // r##"sequence event_arg_example (event ev); - // @(ev) x ##1 y; - // endsequence + test!( + many1(module_item), + r##"sequence event_arg_example (event ev); + @(ev) x ##1 y; + endsequence - // cover property (event_arg_example(posedge clk));"##, - // Ok((_, _)) - //); - //test!( - // many1(module_item), - // r##"cover property (@(posedge clk) x ##1 y));"##, - // Ok((_, _)) - //); + cover property (event_arg_example(posedge clk));"##, + Ok((_, _)) + ); + test!( + many1(module_item), + r##"cover property (@(posedge clk) x ##1 y);"##, + Ok((_, _)) + ); test!( many1(module_item), r##"sequence event_arg_example2 (reg sig); @@ -7362,11 +7382,11 @@ mod spec { cover property (event_arg_example2(clk));"##, Ok((_, _)) ); - //test!( - // many1(module_item), - // r##"cover property (@(posedge clk) x ##1 y));"##, - // Ok((_, _)) - //); + test!( + many1(module_item), + r##"cover property (@(posedge clk) x ##1 y);"##, + Ok((_, _)) + ); test!( many1(module_item), r##"sequence s(bit a, bit b); @@ -7376,56 +7396,39 @@ mod spec { endsequence"##, Ok((_, _)) ); - //test!( - // many1(module_item), - // r##"logic b_d, d_d; - // sequence legal_loc_var_formal ( - // local inout logic a, - // local logic b = b_d, // input inferred, default actual argument b_d - // c, // local input logic inferred, no default - // // actual argument - // d = d_d, // local input logic inferred, default actual - // // argument d_d - // logic e, f // e and f are not local variable formal arguments - // ); - // logic g = c, h = g || d; - // endsequence"##, - // Ok((_, _)) - //); - //test!( - // many1(module_item), - // r##"sequence illegal_loc_var_formal ( - // output logic a, // illegal: local must be specified with - // // direction - // local inout logic b, - // c = 1'b0,// default actual argument illegal for inout - // local d = expr, // illegal: type must be specified explicitly - // local event e, // illegal: event is a type disallowed in - // // 16.6 - // local logic f = g // g shall not refer to the local variable - // // below and must be resolved upward from - // // this declaration - // ); - // logic g = b; - // endsequence"##, - // Ok((_, _)) - //); - //test!( - // many1(module_item), - // r##"sequence sub_seq2(local inout int lv); - // (a ##1 !a, lv += data_in) - // ##1 !b[*0:$] ##1 b && (data_out == lv); - // endsequence - // sequence seq2; - // int v1; - // (c, v1 = data) - // ##1 sub_seq2(v1) // lv is initialized by assigning it the value of v1; - // // when the instance sub_seq2(v1) matches, v1 is - // // assigned the value of lv - // ##1 (do1 == v1); - // endsequence"##, - // Ok((_, _)) - //); + test!( + many1(module_item), + r##"logic b_d, d_d; + sequence legal_loc_var_formal ( + local inout logic a, + local logic b = b_d, // input inferred, default actual argument b_d + c, // local input logic inferred, no default + // actual argument + d = d_d, // local input logic inferred, default actual + // argument d_d + logic e, f // e and f are not local variable formal arguments + ); + logic g = c, h = g || d; + g ##1 h; + endsequence"##, + Ok((_, _)) + ); + test!( + many1(module_item), + r##"sequence sub_seq2(local inout int lv); + (a ##1 !a, lv += data_in) + ##1 !b[*0:$] ##1 b && (data_out == lv); + endsequence + sequence seq2; + int v1; + (c, v1 = data) + ##1 sub_seq2(v1) // lv is initialized by assigning it the value of v1; + // when the instance sub_seq2(v1) matches, v1 is + // assigned the value of lv + ##1 (do1 == v1); + endsequence"##, + Ok((_, _)) + ); test!( many1(module_item), r##"sequence seq2_inlined; @@ -7487,22 +7490,22 @@ mod spec { assert property (done |=> (out == $past(q, 2,enable)) );"##, Ok((_, _)) ); - //test!( - // many1(module_item), - // r##"bit clk, fclk, req, gnt, en; + test!( + many1(module_item), + r##"bit clk, fclk, req, gnt, en; - // a1: assert property - // (@(posedge clk) en && $rose(req) |=> gnt); - // a2: assert property - // (@(posedge clk) en && $rose(req, @(posedge fclk)) |=> gnt);"##, - // Ok((_, _)) - //); - //test!( - // many1(module_item), - // r##"always_ff @(posedge clk1) - // reg1 <= $rose(b, @(posedge clk2));"##, - // Ok((_, _)) - //); + a1: assert property + (@(posedge clk) en && $rose(req) |=> gnt); + a2: assert property + (@(posedge clk) en && $rose(req, @(posedge fclk)) |=> gnt);"##, + Ok((_, _)) + ); + test!( + many1(module_item), + r##"always_ff @(posedge clk1) + reg1 <= $rose(b, @(posedge clk2));"##, + Ok((_, _)) + ); test!( many1(module_item), r##"always @(posedge clk) begin @@ -15580,34 +15583,7 @@ mod spec { fn debug() { test!( many1(module_item), - r##"initial begin - //typedef union tagged { - // struct { - // bit [4:0] reg1, reg2, regd; - // } Add; - // union tagged { - // bit [9:0] JmpU; - // struct { - // bit [1:0] cc; - // bit [9:0] addr; - // } JmpC; - // } Jmp; - //} Instr; - - //Instr i1, i2; - - // Create an Add instruction with its 3 register fields - i1 = ( e - ? tagged Add '{ e1, 4, ed } // struct members by position - : tagged Add '{ reg2:e2, regd:3, reg1:19 }); // by name (order irrelevant) - - //// Create a Jump instruction, with "unconditional" sub-opcode - //i1 = tagged Jmp (tagged JmpU 239); - - //// Create a Jump instruction, with "conditional" sub-opcode - //i2 = tagged Jmp (tagged JmpC '{ 2, 83 }); // inner struct by position - //i2 = tagged Jmp (tagged JmpC '{ cc:2, addr:83 }); // by name - end"##, + r##"sequence legal_loc_var_formal ( local logic b = b_d, d = d_d); g ##1 h; endsequence"##, Ok((_, _)) ); } diff --git a/sv-parser-syntaxtree/src/declarations/assertion_declarations.rs b/sv-parser-syntaxtree/src/declarations/assertion_declarations.rs index 1d0440a..2f19ba1 100644 --- a/sv-parser-syntaxtree/src/declarations/assertion_declarations.rs +++ b/sv-parser-syntaxtree/src/declarations/assertion_declarations.rs @@ -128,7 +128,7 @@ pub struct PropertyPortList { pub struct PropertyPortItem { pub nodes: ( Vec, - Option<(Local, Option)>, + Option<(Keyword, Option)>, PropertyFormalType, FormalPortIdentifier, Vec, @@ -399,7 +399,7 @@ pub struct SequencePortList { pub struct SequencePortItem { pub nodes: ( Vec, - Option<(Local, Option)>, + Option<(Keyword, Option)>, SequenceFormalType, FormalPortIdentifier, Vec,