diff --git a/src/verilog.y b/src/verilog.y index 569671371..d05221ce5 100644 --- a/src/verilog.y +++ b/src/verilog.y @@ -5117,10 +5117,28 @@ gateRangeE: ; gateBuf: - gateFront variable_lvalue ',' gatePinExpr ')' - { $$ = new AstAssignW{$1, $2, $4}; DEL($1); } - // UNSUP // IEEE: Multiple output variable_lvalues - // UNSUP // Causes conflict - need to take in variable_lvalue or a gatePinExpr + gateFront variable_lvalue ',' exprList ')' + { AstNodeExpr* inp = $4; + while (inp->nextp()) inp = VN_AS(inp->nextp(), NodeExpr); + $$ = new AstAssignW{$1, $2, GRAMMARP->createGatePin(inp->cloneTree(false))}; + for (AstNodeExpr* outp = $4; outp->nextp(); outp = VN_CAST(outp->nextp(), NodeExpr)) { + $$->addNext(new AstAssignW{$1, outp->cloneTree(false), + GRAMMARP->createGatePin(inp->cloneTree(false))}); + } + DEL($1); DEL($4); } + ; +gateNot: + gateFront variable_lvalue ',' exprList ')' + { AstNodeExpr* inp = $4; + while (inp->nextp()) inp = VN_AS(inp->nextp(), NodeExpr); + $$ = new AstAssignW{$1, $2, new AstNot{$1, + GRAMMARP->createGatePin(inp->cloneTree(false))}}; + for (AstNodeExpr* outp = $4; outp->nextp(); outp = VN_CAST(outp->nextp(), NodeExpr)) { + $$->addNext(new AstAssignW{$1, outp->cloneTree(false), + new AstNot{$1, + GRAMMARP->createGatePin(inp->cloneTree(false))}}); + } + DEL($1); DEL($4); } ; gateBufif0: gateFront variable_lvalue ',' gatePinExpr ',' gatePinExpr ')' @@ -5130,12 +5148,6 @@ gateBufif1: gateFront variable_lvalue ',' gatePinExpr ',' gatePinExpr ')' { $$ = new AstAssignW{$1, $2, new AstBufIf1{$1, $6, $4}}; DEL($1); } ; -gateNot: - gateFront variable_lvalue ',' gatePinExpr ')' - { $$ = new AstAssignW{$1, $2, new AstNot{$1, $4}}; DEL($1); } - // UNSUP // IEEE: Multiple output variable_lvalues - // UNSUP // Causes conflict - need to take in variable_lvalue or a gatePinExpr - ; gateNotif0: gateFront variable_lvalue ',' gatePinExpr ',' gatePinExpr ')' { $$ = new AstAssignW{$1, $2, new AstBufIf1{$1, new AstNot{$1, $6}, diff --git a/test_regress/t/t_gate_basic.v b/test_regress/t/t_gate_basic.v index 9a3e7fbab..326a23347 100644 --- a/test_regress/t/t_gate_basic.v +++ b/test_regress/t/t_gate_basic.v @@ -15,9 +15,10 @@ module t (/*AUTOARG*/ reg [31:0] a; reg [31:0] b; - wire [2:0] bf; buf BF0 (bf[0], a[0]), - BF1 (bf[1], a[1]), - BF2 (bf[2], a[2]); + wire [2:0] bf; + buf BF0 (bf[0], a[0]), + BF1 (bf[1], a[1]), + BF2 (bf[2], a[2]); // verilator lint_off IMPLICIT not #(0.108) NT0 (nt0, a[0]); @@ -29,6 +30,11 @@ module t (/*AUTOARG*/ xnor (xn0, a[0], b[0], b[2]); // verilator lint_on IMPLICIT + wire [2:0] bfm; + buf BFM (bfm[0], bfm[1], bfm[2], a[0]); + wire [2:0] ntm; + not NTM (ntm[0], ntm[1], ntm[2], a[0]); + parameter BITS=32; wire [BITS-1:0] ba; buf BARRAY [BITS-1:0] (ba, a); @@ -85,6 +91,8 @@ module t (/*AUTOARG*/ a <= 32'h529ab56f; b <= 32'h7835a237; if (bf !== 3'b100) $stop; + if (bfm != 3'b000) $stop; + if (ntm != 3'b111) $stop; if (nt0 !== 1'b1) $stop; if (an0 !== 1'b0) $stop; if (nd0 !== 1'b1) $stop; @@ -96,6 +104,8 @@ module t (/*AUTOARG*/ end if (cyc==3) begin if (bf !== 3'b111) $stop; + if (bfm != 3'b111) $stop; + if (ntm != 3'b000) $stop; if (nt0 !== 1'b0) $stop; if (an0 !== 1'b1) $stop; if (nd0 !== 1'b0) $stop; diff --git a/test_regress/t/t_gate_delay_unsup.out b/test_regress/t/t_gate_delay_unsup.out index c3e3e70fd..24b698bab 100644 --- a/test_regress/t/t_gate_delay_unsup.out +++ b/test_regress/t/t_gate_delay_unsup.out @@ -1,5 +1,5 @@ -%Warning-RISEFALLDLY: t/t_gate_basic.v:25:12: Unsupported: rising/falling/turn-off delays. Using the first delay - 25 | nand #(2,3) ND0 (nd0, a[0], b[0], b[1]); +%Warning-RISEFALLDLY: t/t_gate_basic.v:26:12: Unsupported: rising/falling/turn-off delays. Using the first delay + 26 | nand #(2,3) ND0 (nd0, a[0], b[0], b[1]); | ^ ... For warning description see https://verilator.org/warn/RISEFALLDLY?v=latest ... Use "/* verilator lint_off RISEFALLDLY */" and lint_on around source to disable this message.