From bded8755a1e36a18eb581d5792b0cc4a0c27b57a Mon Sep 17 00:00:00 2001 From: Wilson Snyder Date: Tue, 19 Jan 2010 13:18:40 -0500 Subject: [PATCH] Support multi-dimensional arrays as inputs/outputs --- Changes | 2 + src/V3EmitC.cpp | 30 ++++++++++---- src/V3LinkResolve.cpp | 5 ++- test_regress/t/t_mem_multi_io.pl | 20 +++++++++ test_regress/t/t_mem_multi_io.v | 62 ++++++++++++++++++++++++++++ test_regress/t/t_mem_multi_io_bad.pl | 3 +- 6 files changed, 111 insertions(+), 11 deletions(-) create mode 100755 test_regress/t/t_mem_multi_io.pl create mode 100644 test_regress/t/t_mem_multi_io.v diff --git a/Changes b/Changes index 48dbddafe..ab8671590 100644 --- a/Changes +++ b/Changes @@ -17,6 +17,8 @@ indicates the contributor was also the author of the fix; Thanks! *** Support assignments of multidimensional slices, bug170. [by Byron Bradley] +*** Support multidimensional inputs/outputs, bug171. [by Byron Bradley] + *** Support "reg [1:0][1:0][1:0]" and "reg x [3][2]", bug176. [Byron Bradley] *** Support declarations in loop initializers, bug172. [by Byron Bradley] diff --git a/src/V3EmitC.cpp b/src/V3EmitC.cpp index ee0d6b658..7370c4bef 100644 --- a/src/V3EmitC.cpp +++ b/src/V3EmitC.cpp @@ -830,7 +830,11 @@ public: void EmitCStmts::emitVarDecl(AstVar* nodep, const string& prefixIfImp) { AstBasicDType* basicp = nodep->basicp(); if (!basicp) nodep->v3fatalSrc("Unimplemented: Outputting this data type"); if (nodep->isIO()) { + bool isArray = !nodep->dtypeSkipRefp()->castBasicDType(); if (nodep->isSc()) { + if (isArray) { + nodep->v3error("Unsupported: SystemC inputs and outputs must be simple data types; no arrays"); + } m_ctorVarsVec.push_back(nodep); ofp()->putAlign(nodep->isStatic(), 4); // sc stuff is a structure, so bigger alignment if (nodep->attrScClocked() && nodep->isInput()) { @@ -858,14 +862,24 @@ void EmitCStmts::emitVarDecl(AstVar* nodep, const string& prefixIfImp) { else if (nodep->widthMin() <= 8) puts("8"); else if (nodep->widthMin() <= 16) puts("16"); - if (!nodep->isWide()) - puts("("+nodep->name() - +","+cvtToStr(basicp->msb()) - +","+cvtToStr(basicp->lsb())); - else puts("W("+nodep->name() - +","+cvtToStr(basicp->msb()) - +","+cvtToStr(basicp->lsb()) - +","+cvtToStr(basicp->widthWords())); + if (isArray) { + if (nodep->isWide()) puts("W"); + puts("("+nodep->name()); + for (AstArrayDType* arrayp=nodep->dtypeSkipRefp()->castArrayDType(); arrayp; arrayp = arrayp->dtypeSkipRefp()->castArrayDType()) { + puts("["+cvtToStr(arrayp->elementsConst())+"]"); + } + puts(","+cvtToStr(basicp->msb())+","+cvtToStr(basicp->lsb())); + if (basicp->isWide()) puts(","+cvtToStr(basicp->widthWords())); + } else { + if (!basicp->isWide()) + puts("("+nodep->name() + +","+cvtToStr(basicp->msb()) + +","+cvtToStr(basicp->lsb())); + else puts("W("+nodep->name() + +","+cvtToStr(basicp->msb()) + +","+cvtToStr(basicp->lsb()) + +","+cvtToStr(basicp->widthWords())); + } puts(");\n"); } } else if (basicp && basicp->isOpaque()) { diff --git a/src/V3LinkResolve.cpp b/src/V3LinkResolve.cpp index 7c40355eb..f2d6415b9 100644 --- a/src/V3LinkResolve.cpp +++ b/src/V3LinkResolve.cpp @@ -84,8 +84,9 @@ private: virtual void visit(AstVar* nodep, AstNUser*) { nodep->iterateChildren(*this); - if (nodep->isIO() && !nodep->dtypeSkipRefp()->castBasicDType()) { - nodep->v3error("Unsupported: Inputs and outputs must be simple data types; no arrays"); + if (nodep->isIO() && !(nodep->dtypeSkipRefp()->castBasicDType() || + nodep->dtypeSkipRefp()->castArrayDType())) { + nodep->v3error("Unsupported: Inputs and outputs must be simple data types"); } if (m_ftaskp) nodep->funcLocal(true); if (nodep->isSigModPublic()) { diff --git a/test_regress/t/t_mem_multi_io.pl b/test_regress/t/t_mem_multi_io.pl new file mode 100755 index 000000000..50bf56f60 --- /dev/null +++ b/test_regress/t/t_mem_multi_io.pl @@ -0,0 +1,20 @@ +#!/usr/bin/perl +if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; } +# DESCRIPTION: Verilator: Verilog Test driver/expect definition +# +# Copyright 2003 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. + +compile ( + # Disable inlining, this test is trivial without it + verilator_flags2 => ["-Oi --trace"], + ); + +execute ( + check_finished=>1, + ); + +ok(1); +1; diff --git a/test_regress/t/t_mem_multi_io.v b/test_regress/t/t_mem_multi_io.v new file mode 100644 index 000000000..5c1c09646 --- /dev/null +++ b/test_regress/t/t_mem_multi_io.v @@ -0,0 +1,62 @@ +// DESCRIPTION: Verilator: Verilog Test module +// +// This file ONLY is placed into the Public Domain, for any use, +// without warranty, 2009 by Wilson Snyder. + +module t (/*AUTOARG*/ + // Inputs + clk + ); + + input clk; + + logic [7:0] arr [7:0]; + logic [7:0] arri [7:0]; + + has_array am1 (.clk(clk), .arri(arr), .arro(arri)); + + integer cyc; initial cyc = 0; + + initial begin + for (int i = 0; i < 8; i++) begin + arr[i] = 0; + end + end + + always @(posedge clk) begin + cyc <= cyc + 1; + if (cyc == 5 && arri[1] != 8) begin + $stop; + end + for (int i = 0; i < 7; ++i) begin + arr[i+1] <= arr[i]; + end + arr[0] <= arr[0] + 1; + end + +endmodule : t + +module has_array ( + input clk, + input logic [7:0] arri [7:0], + output logic [7:0] arro [7:0] + ); + + integer cyc; initial cyc = 0; + + always @(posedge clk) begin + cyc <= cyc + 1; + if (arri[0] == 10 && cyc == 10) begin + $write("*-* All Finished *-*\n"); + $finish; + end + end + + always @(posedge clk) begin + for (integer i = 0; i < 7; ++i) begin + arro[i+1] <= arro[i]; + end + arro[0] = arro[0] + 2; + end + +endmodule : has_array diff --git a/test_regress/t/t_mem_multi_io_bad.pl b/test_regress/t/t_mem_multi_io_bad.pl index 1d6e98680..7c03ae629 100755 --- a/test_regress/t/t_mem_multi_io_bad.pl +++ b/test_regress/t/t_mem_multi_io_bad.pl @@ -8,10 +8,11 @@ if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); di # Version 2.0. compile ( + verilator_flags2 => ["-sp"], fails=>$Self->{v3}, nc=>0, expect=> -'%Error: t/t_mem_multi_io_bad.v:\d+: Unsupported: Inputs and outputs must be simple data types; no arrays +'%Error: t/t_mem_multi_io_bad.v:\d+: Unsupported: SystemC inputs and outputs must be simple data types; no arrays %Error: Exiting due to.*', );