From be26e8da1be29fdc867feb25ab5f9a8c1167f761 Mon Sep 17 00:00:00 2001 From: Varun Koyyalagunta Date: Sun, 22 Jan 2023 21:24:36 -0600 Subject: [PATCH] Support struct I/O in --lib-create (#3378) (#3892) --- src/V3EmitV.cpp | 7 +- test_regress/t/t_hier_block_struct.pl | 24 +++++++ test_regress/t/t_hier_block_struct.v | 98 +++++++++++++++++++++++++++ 3 files changed, 128 insertions(+), 1 deletion(-) create mode 100755 test_regress/t/t_hier_block_struct.pl create mode 100644 test_regress/t/t_hier_block_struct.v diff --git a/src/V3EmitV.cpp b/src/V3EmitV.cpp index f55c3c074..d9f05b302 100644 --- a/src/V3EmitV.cpp +++ b/src/V3EmitV.cpp @@ -614,12 +614,17 @@ class EmitVBaseVisitor VL_NOT_FINAL : public EmitCBaseVisitor { iterate(nodep->subDTypep()); iterateAndNextConstNull(nodep->rangep()); } + void visit(AstRefDType* nodep) override { iterate(nodep->skipRefp()); } void visit(AstNodeUOrStructDType* nodep) override { puts(nodep->verilogKwd() + " "); if (nodep->packed()) puts("packed "); puts("\n"); puts("{"); - iterateAndNextConstNull(nodep->membersp()); + for (AstMemberDType* itemp = nodep->membersp(); itemp; + itemp = VN_AS(itemp->nextp(), MemberDType)) { + iterate(itemp); + puts(";"); + } puts("}"); } void visit(AstMemberDType* nodep) override { diff --git a/test_regress/t/t_hier_block_struct.pl b/test_regress/t/t_hier_block_struct.pl new file mode 100755 index 000000000..0bce0213b --- /dev/null +++ b/test_regress/t/t_hier_block_struct.pl @@ -0,0 +1,24 @@ +#!/usr/bin/env perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2022 by Wilson Snyder. This program is free software; you +# can redistribute it and/or modify it under the terms of either the GNU +# Lesser General Public License Version 3 or the Perl Artistic License +# Version 2.0. +# SPDX-License-Identifier: LGPL-3.0-only OR Artistic-2.0 + +scenarios(simulator => 1); + +compile( + verilator_flags2 => ['--hierarchical'] + ); + +execute( + check_finished => 1, + ); + +file_grep($Self->{obj_dir} . "/VTest/Test.sv", /^module\s+(\S+)\s+/, "Test"); + +ok(1); +1; diff --git a/test_regress/t/t_hier_block_struct.v b/test_regress/t/t_hier_block_struct.v new file mode 100644 index 000000000..a3bec94b6 --- /dev/null +++ b/test_regress/t/t_hier_block_struct.v @@ -0,0 +1,98 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed under the Creative Commons Public Domain, for +// any use, without warranty, 2022 by Varun Koyyalagunta. +// SPDX-License-Identifier: CC0-1.0 + +typedef struct packed { + logic x; +} nested_named_t; + +typedef struct packed { + struct packed { + logic x; + } nested_anonymous; + nested_named_t nested_named; + logic [1:0] x; +} nibble_t; + +module t( + clk + ); + input clk; + + integer cyc = 0; + logic [63:0] crc; + logic [63:0] sum; + + // Take CRC data and apply to testblock inputs + nibble_t[7:0] in; + assign in = crc[31:0]; + + nibble_t[7:0] out; + + Test test( + .out0 ({out[1], out[0]}), + .out1 ({{out[5], out[4]}, {out[3], out[2]}}), + .out2 (out[6]), + .out3 (out[7]), + .clk (clk), + .in0 (in[0]), + .in1 (in[1]), + .in2 ({in[5], in[4], in[3], in[2]}), + .in3 ({in[7], in[6]})); + + // Aggregate outputs into a single result vector + wire [63:0] result = {32'h0, out}; + + // Test loop + always @ (posedge clk) begin +`ifdef TEST_VERBOSE + $write("[%0t] cyc==%0d crc=%x result=%x\n", $time, cyc, crc, result); +`endif + cyc <= cyc + 1; + crc <= {crc[62:0], crc[63] ^ crc[2] ^ crc[0]}; + sum <= result ^ {sum[62:0], sum[63] ^ sum[2] ^ sum[0]}; + if (cyc == 0) begin + // Setup + crc <= 64'h5aef0c8d_d70a4497; + sum <= '0; + end + else if (cyc < 10) begin + sum <= '0; + end + else if (cyc < 90) begin + end + else if (cyc == 99) begin + $write("[%0t] cyc==%0d crc=%x sum=%x\n", $time, cyc, crc, sum); + if (crc !== 64'hc77bb9b3784ea091) $stop; + // What checksum will we end up with (above print should match) +`define EXPECTED_SUM 64'h4afe43fb79d7b71e + if (sum !== `EXPECTED_SUM) $stop; + $write("*-* All Finished *-*\n"); + $finish; + end + end + +endmodule + +module Test( + // Outputs + output nibble_t [1:0] out0, + output nibble_t [1:0] out1[2], + output nibble_t out2, + output nibble_t out3, + // Inputs + input clk, + input nibble_t in0, + input nibble_t in1, + input nibble_t [3:0] in2, + input nibble_t in3[2] + ); /*verilator hier_block*/ + + + always @(posedge clk) begin + {out3, out2, out1[0], out1[1], out0} <= {in3[0], in3[1], in2, in1, in0}; + end + +endmodule