SystemVerilog support for implicit named port connections
authortux3 <barrdetwix@gmail.com>
Tue, 4 Jun 2019 22:47:54 +0000 (00:47 +0200)
committertux3 <barrdetwix@gmail.com>
Thu, 6 Jun 2019 16:07:49 +0000 (18:07 +0200)
This is the `foo foo(.port1, .port2);` SystemVerilog syntax
introduced in IEEE1800-2005.

frontends/verilog/verilog_parser.y
tests/simple/run-test.sh
tests/tools/autotest.sh
tests/various/implicit_ports.sv [new file with mode: 0644]
tests/various/implicit_ports.ys [new file with mode: 0644]

index 8244a8f444d231e174a64eeda3094699c7a9595a..983445011a14ac7e3e5470cc6c6c890cf309def4 100644 (file)
@@ -154,7 +154,7 @@ struct specify_rise_fall {
 %token TOK_INCREMENT TOK_DECREMENT TOK_UNIQUE TOK_PRIORITY
 
 %type <ast> range range_or_multirange  non_opt_range non_opt_multirange range_or_signed_int
-%type <ast> wire_type expr basic_expr concat_list rvalue lvalue lvalue_concat_list
+%type <ast> wire_type expr basic_expr concat_list rvalue lvalue lvalue_concat_list named_port
 %type <string> opt_label opt_sva_label tok_prim_wrapper hierarchical_id
 %type <boolean> opt_signed opt_property unique_case_attr
 %type <al> attr case_attr
@@ -1541,18 +1541,26 @@ cell_port:
                astbuf2->children.push_back(node);
                node->children.push_back($1);
        } |
-       '.' TOK_ID '(' expr ')' {
-               AstNode *node = new AstNode(AST_ARGUMENT);
-               node->str = *$2;
-               astbuf2->children.push_back(node);
-               node->children.push_back($4);
-               delete $2;
+       named_port '(' ')' | // not connected
+       named_port '(' expr ')' {
+               ($1)->children.push_back($3);
        } |
-       '.' TOK_ID '(' ')' {
+       named_port {
+               // SV implied port
+               if (!sv_mode)
+                       frontend_verilog_yyerror("Implicit .name port connection in port list (%s). This is not supported unless read_verilog is called with -sv!", $1->str.c_str());
+               auto id_node = new AstNode(AST_IDENTIFIER);
+               id_node->str = ($1)->str;
+               ($1)->children.push_back(id_node);
+       };
+
+named_port:
+       '.' TOK_ID {
                AstNode *node = new AstNode(AST_ARGUMENT);
                node->str = *$2;
-               astbuf2->children.push_back(node);
                delete $2;
+               astbuf2->children.push_back(node);
+               $$ = node;
        };
 
 always_stmt:
index aaa1cf9406c3eb6d2c6734df5c91c1c643cd38b3..967ac49f25553decbb5fab3cddd236f993a48b19 100755 (executable)
@@ -17,4 +17,5 @@ if ! which iverilog > /dev/null ; then
   exit 1
 fi
 
-exec ${MAKE:-make} -f ../tools/autotest.mk $seed *.v
+shopt -s nullglob
+exec ${MAKE:-make} -f ../tools/autotest.mk $seed *.{sv,v}
index 920474a846ae2318d8aafabb4e0b68d290f3a323..0a511f29cc84b57e7e0bf3e891abe61ddcbc3402 100755 (executable)
@@ -89,6 +89,13 @@ done
 
 compile_and_run() {
        exe="$1"; output="$2"; shift 2
+       ext=${1##*.}
+       if [ "$ext" == "sv" ]; then
+               language_gen="-g2012"
+       else
+               language_gen="-g2005"
+       fi
+
        if $use_modelsim; then
                altver=$( ls -v /opt/altera/ | grep '^[0-9]' | tail -n1; )
                /opt/altera/$altver/modelsim_ase/bin/vlib work
@@ -99,7 +106,7 @@ compile_and_run() {
                /opt/Xilinx/Vivado/$xilver/bin/xvlog $xinclude_opts -d outfile=\"$output\" "$@"
                /opt/Xilinx/Vivado/$xilver/bin/xelab -R work.testbench
        else
-               iverilog $include_opts -Doutfile=\"$output\" -s testbench -o "$exe" "$@"
+               iverilog $language_gen $include_opts -Doutfile=\"$output\" -s testbench -o "$exe" "$@"
                vvp -n "$exe"
        fi
 }
@@ -110,7 +117,7 @@ for fn
 do
        bn=${fn%.*}
        ext=${fn##*.}
-       if [[ "$ext" != "v" ]] && [[ "$ext" != "aag" ]] && [[ "$ext" != "aig" ]]; then
+       if [[ "$ext" != "v" ]] && [[ "$ext" != "sv" ]] && [[ "$ext" != "aag" ]] && [[ "$ext" != "aig" ]]; then
                echo "Invalid argument: $fn" >&2
                exit 1
        fi
@@ -123,6 +130,10 @@ do
                echo -n "Test: $bn "
        fi
 
+       if [ "$ext" == sv ]; then
+               frontend="$frontend -sv"
+       fi
+
        rm -f ${bn}.{err,log,skip}
        mkdir -p ${bn}.out
        rm -rf ${bn}.out/*
diff --git a/tests/various/implicit_ports.sv b/tests/various/implicit_ports.sv
new file mode 100644 (file)
index 0000000..6a766bd
--- /dev/null
@@ -0,0 +1,19 @@
+// Test implicit port connections
+module alu (input [2:0] a, input [2:0] b, input cin, output cout, output [2:0] result);
+       assign cout = cin;
+       assign result = a + b;
+endmodule
+
+module named_ports(output [2:0] alu_result, output cout);
+       wire [2:0] a = 3'b010, b = 3'b100;
+       wire cin = 1;
+
+       alu alu (
+               .a(a),
+               .b, // Implicit connection is equivalent to .b(b)
+               .cin(), // Explicitely unconnected
+               .cout(cout),
+               .result(alu_result)
+       );
+endmodule
+
diff --git a/tests/various/implicit_ports.ys b/tests/various/implicit_ports.ys
new file mode 100644 (file)
index 0000000..7b47649
--- /dev/null
@@ -0,0 +1,8 @@
+read_verilog -sv implicit_ports.sv
+proc; opt
+
+flatten
+select -module named_ports
+
+sat -verify -prove alu_result 6
+sat -verify -set-all-undef cout