Support multi-dimensional arrays as inputs/outputs

This commit is contained in:
Wilson Snyder 2010-01-19 13:18:40 -05:00
parent 2e9ade61b2
commit bded8755a1
6 changed files with 111 additions and 11 deletions

View File

@ -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]

View File

@ -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()) {

View File

@ -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()) {

View File

@ -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;

View File

@ -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

View File

@ -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.*',
);