Fix arrayed input compile error, bug645. Try 2.

This commit is contained in:
Wilson Snyder 2013-05-18 20:17:17 -04:00
parent 6a69813326
commit 84efd239a5
5 changed files with 151 additions and 41 deletions

View File

@ -86,6 +86,13 @@ public:
}
void emitOpName(AstNode* nodep, const string& format,
AstNode* lhsp, AstNode* rhsp, AstNode* thsp);
void emitDeclArrayBrackets(AstVar* nodep) {
// This isn't very robust and may need cleanup for other data types
for (AstUnpackArrayDType* arrayp=nodep->dtypeSkipRefp()->castUnpackArrayDType(); arrayp;
arrayp = arrayp->subDTypep()->skipRefp()->castUnpackArrayDType()) {
puts("["+cvtToStr(arrayp->elementsConst())+"]");
}
}
// VISITORS
virtual void visit(AstNodeAssign* nodep, AstNUser*) {
@ -875,7 +882,6 @@ 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()) {
m_ctorVarsVec.push_back(nodep);
ofp()->putAlign(nodep->isStatic(), 4); // sc stuff is a structure, so bigger alignment
@ -891,12 +897,7 @@ void EmitCStmts::emitVarDecl(AstVar* nodep, const string& prefixIfImp) {
puts(">\t");
}
puts(nodep->name());
if (isArray) {
for (AstUnpackArrayDType* arrayp=nodep->dtypeSkipRefp()->castUnpackArrayDType(); arrayp;
arrayp = arrayp->subDTypep()->skipRefp()->castUnpackArrayDType()) {
puts("["+cvtToStr(arrayp->elementsConst())+"]");
}
}
emitDeclArrayBrackets(nodep);
puts(";\n");
} else { // C++ signals
ofp()->putAlign(nodep->isStatic(), nodep->dtypeSkipRefp()->widthAlignBytes(),
@ -906,39 +907,23 @@ void EmitCStmts::emitVarDecl(AstVar* nodep, const string& prefixIfImp) {
else if (nodep->isOutput()) puts("VL_OUT");
else nodep->v3fatalSrc("Unknown type");
if (basicp->isQuad()) puts("64");
else if (basicp->widthMin() <= 8) puts("8");
else if (basicp->widthMin() <= 16) puts("16");
else if (basicp->isWide()) puts("W");
if (nodep->isQuad()) puts("64");
else if (nodep->widthMin() <= 8) puts("8");
else if (nodep->widthMin() <= 16) puts("16");
else if (nodep->isWide()) puts("W");
if (isArray) {
puts("("+nodep->name());
for (AstUnpackArrayDType* arrayp=nodep->dtypeSkipRefp()->castUnpackArrayDType(); arrayp;
arrayp = arrayp->subDTypep()->skipRefp()->castUnpackArrayDType()) {
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())
emitDeclArrayBrackets(nodep);
// If it's a packed struct/array then nodep->width is the whole thing, msb/lsb is just lowest dimension
puts(","+cvtToStr(basicp->lsb()+nodep->width()-1)
+","+cvtToStr(basicp->lsb()));
else puts("("+nodep->name()
+","+cvtToStr(basicp->msb())
+","+cvtToStr(basicp->lsb())
+","+cvtToStr(basicp->widthWords()));
}
if (nodep->isWide()) puts(","+cvtToStr(nodep->widthWords()));
puts(");\n");
}
} else if (basicp && basicp->isOpaque()) {
// strings and other fundamental c types
puts(nodep->vlArgType(true,false));
// This isn't very robust and may need cleanup for other data types
for (AstUnpackArrayDType* arrayp=nodep->dtypeSkipRefp()->castUnpackArrayDType(); arrayp;
arrayp = arrayp->subDTypep()->skipRefp()->castUnpackArrayDType()) {
puts("["+cvtToStr(arrayp->elementsConst())+"]");
}
emitDeclArrayBrackets(nodep);
puts(";\n");
} else {
// Arrays need a small alignment, but may need different padding after.
@ -960,13 +945,10 @@ void EmitCStmts::emitVarDecl(AstVar* nodep, const string& prefixIfImp) {
}
if (prefixIfImp!="") { puts(prefixIfImp); puts("::"); }
puts(nodep->name());
// This isn't very robust and may need cleanup for other data types
for (AstUnpackArrayDType* arrayp=nodep->dtypeSkipRefp()->castUnpackArrayDType(); arrayp;
arrayp = arrayp->subDTypep()->skipRefp()->castUnpackArrayDType()) {
puts("["+cvtToStr(arrayp->elementsConst())+"]");
}
emitDeclArrayBrackets(nodep);
// If it's a packed struct/array then nodep->width is the whole thing, msb/lsb is just lowest dimension
puts(","+cvtToStr(basicp->lsb()+nodep->width())+","+cvtToStr(basicp->lsb()));
puts(","+cvtToStr(basicp->lsb()+nodep->width()-1)
+","+cvtToStr(basicp->lsb()));
if (nodep->isWide()) puts(","+cvtToStr(nodep->widthWords()));
puts(");\n");
}

View File

@ -0,0 +1,34 @@
// -*- mode: C++; c-file-style: "cc-mode" -*-
//
// This file ONLY is placed into the Public Domain, for any use,
// without warranty.
#if defined(T_MEM_MULTI_IO3_CC)
# include "Vt_mem_multi_io3_cc.h"
#elif defined(T_MEM_MULTI_IO3_SC)
# include "Vt_mem_multi_io3_sc.h"
#else
# error "Unknown test"
#endif
VM_PREFIX* tb = NULL;
bool pass = true;
double sc_time_stamp() {
return 0;
}
int main() {
Verilated::debug(0);
tb = new VM_PREFIX ("tb");
// Just a constructor test
bool pass = true;
if (pass) {
VL_PRINTF("*-* All Finished *-*\n");
} else {
vl_fatal(__FILE__,__LINE__,"top", "Unexpected results from test\n");
}
return 0;
}

View File

@ -0,0 +1,52 @@
// This file ONLY is placed into the Public Domain, for any use,
// without warranty, 2013.
module t
(
input logic clk,
input logic daten,
input logic [8:0] datval,
output logic signed [3:0][3:0][35:0] datao
);
logic signed [3:0][3:0][3:0][8:0] datat;
genvar i;
generate
for (i=0; i<4; i++)begin
testio dut(.clk(clk), .arr3d_in(datat[i]), .arr2d_out(datao[i]));
end
endgenerate
genvar j;
generate
for (i=0; i<4; i++) begin
for (j=0; j<4; j++) begin
always_comb datat[i][j][0] = daten ? 9'h0 : datval;
always_comb datat[i][j][1] = daten ? 9'h1 : datval;
always_comb datat[i][j][2] = daten ? 9'h2 : datval;
always_comb datat[i][j][3] = daten ? 9'h3 : datval;
end
end
endgenerate
endmodule
module testio
(
input clk,
input logic signed [3:0] [3:0] [8:0] arr3d_in,
output logic signed [3:0] [35:0] arr2d_out
);
logic signed [3:0] [35:0] ar2d_out_pre;
always_comb ar2d_out_pre[0][35:0] = {arr3d_in[0][0][8:0], arr3d_in[0][1][8:0], arr3d_in[0][2][8:0], arr3d_in[0][3][8:0]};
always_comb ar2d_out_pre[0][35:0] = {arr3d_in[0][0][8:0], arr3d_in[0][1][8:0], arr3d_in[0][2][8:0], arr3d_in[0][3][8:0]};
always_comb ar2d_out_pre[0][35:0] = {arr3d_in[0][0][8:0], arr3d_in[0][1][8:0], arr3d_in[0][2][8:0], arr3d_in[0][3][8:0]};
always_comb ar2d_out_pre[0][35:0] = {arr3d_in[0][0][8:0], arr3d_in[0][1][8:0], arr3d_in[0][2][8:0], arr3d_in[0][3][8:0]};
always_ff @(posedge clk) begin
if (clk)
arr2d_out <= ar2d_out_pre;
end
endmodule

View File

@ -0,0 +1,21 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003-2009 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.
top_filename("t/t_mem_multi_io3.v");
$Self->{vlt} or $Self->skip("Verilator only test");
compile (
make_top_shell => 0,
make_main => 0,
verilator_flags2 => ["--exe $Self->{t_dir}/t_mem_multi_io3.cpp -Oi"],
);
ok(1);
1;

View File

@ -0,0 +1,21 @@
#!/usr/bin/perl
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
#
# Copyright 2003-2009 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.
top_filename("t/t_mem_multi_io3.v");
$Self->{vlt} or $Self->skip("Verilator only test");
compile (
make_top_shell => 0,
make_main => 0,
verilator_flags2 => ["--exe $Self->{t_dir}/t_mem_multi_io3.cpp --sc -Oi"],
);
ok(1);
1;