forked from github/verilator
Fix arrayed input compile error, bug645. Try 2.
This commit is contained in:
parent
6a69813326
commit
84efd239a5
@ -86,6 +86,13 @@ public:
|
|||||||
}
|
}
|
||||||
void emitOpName(AstNode* nodep, const string& format,
|
void emitOpName(AstNode* nodep, const string& format,
|
||||||
AstNode* lhsp, AstNode* rhsp, AstNode* thsp);
|
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
|
// VISITORS
|
||||||
virtual void visit(AstNodeAssign* nodep, AstNUser*) {
|
virtual void visit(AstNodeAssign* nodep, AstNUser*) {
|
||||||
@ -788,7 +795,7 @@ class EmitCImp : EmitCStmts {
|
|||||||
|
|
||||||
if (!m_blkChangeDetVec.empty()) puts("return __req;\n");
|
if (!m_blkChangeDetVec.empty()) puts("return __req;\n");
|
||||||
|
|
||||||
// puts("__Vm_activity = true;\n");
|
//puts("__Vm_activity = true;\n");
|
||||||
puts("}\n");
|
puts("}\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -875,7 +882,6 @@ public:
|
|||||||
void EmitCStmts::emitVarDecl(AstVar* nodep, const string& prefixIfImp) {
|
void EmitCStmts::emitVarDecl(AstVar* nodep, const string& prefixIfImp) {
|
||||||
AstBasicDType* basicp = nodep->basicp(); if (!basicp) nodep->v3fatalSrc("Unimplemented: Outputting this data type");
|
AstBasicDType* basicp = nodep->basicp(); if (!basicp) nodep->v3fatalSrc("Unimplemented: Outputting this data type");
|
||||||
if (nodep->isIO()) {
|
if (nodep->isIO()) {
|
||||||
bool isArray = !nodep->dtypeSkipRefp()->castBasicDType();
|
|
||||||
if (nodep->isSc()) {
|
if (nodep->isSc()) {
|
||||||
m_ctorVarsVec.push_back(nodep);
|
m_ctorVarsVec.push_back(nodep);
|
||||||
ofp()->putAlign(nodep->isStatic(), 4); // sc stuff is a structure, so bigger alignment
|
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(">\t");
|
||||||
}
|
}
|
||||||
puts(nodep->name());
|
puts(nodep->name());
|
||||||
if (isArray) {
|
emitDeclArrayBrackets(nodep);
|
||||||
for (AstUnpackArrayDType* arrayp=nodep->dtypeSkipRefp()->castUnpackArrayDType(); arrayp;
|
|
||||||
arrayp = arrayp->subDTypep()->skipRefp()->castUnpackArrayDType()) {
|
|
||||||
puts("["+cvtToStr(arrayp->elementsConst())+"]");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
puts(";\n");
|
puts(";\n");
|
||||||
} else { // C++ signals
|
} else { // C++ signals
|
||||||
ofp()->putAlign(nodep->isStatic(), nodep->dtypeSkipRefp()->widthAlignBytes(),
|
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 if (nodep->isOutput()) puts("VL_OUT");
|
||||||
else nodep->v3fatalSrc("Unknown type");
|
else nodep->v3fatalSrc("Unknown type");
|
||||||
|
|
||||||
if (basicp->isQuad()) puts("64");
|
if (nodep->isQuad()) puts("64");
|
||||||
else if (basicp->widthMin() <= 8) puts("8");
|
else if (nodep->widthMin() <= 8) puts("8");
|
||||||
else if (basicp->widthMin() <= 16) puts("16");
|
else if (nodep->widthMin() <= 16) puts("16");
|
||||||
else if (basicp->isWide()) puts("W");
|
else if (nodep->isWide()) puts("W");
|
||||||
|
|
||||||
if (isArray) {
|
puts("("+nodep->name());
|
||||||
puts("("+nodep->name());
|
emitDeclArrayBrackets(nodep);
|
||||||
for (AstUnpackArrayDType* arrayp=nodep->dtypeSkipRefp()->castUnpackArrayDType(); arrayp;
|
// If it's a packed struct/array then nodep->width is the whole thing, msb/lsb is just lowest dimension
|
||||||
arrayp = arrayp->subDTypep()->skipRefp()->castUnpackArrayDType()) {
|
puts(","+cvtToStr(basicp->lsb()+nodep->width()-1)
|
||||||
puts("["+cvtToStr(arrayp->elementsConst())+"]");
|
+","+cvtToStr(basicp->lsb()));
|
||||||
}
|
if (nodep->isWide()) puts(","+cvtToStr(nodep->widthWords()));
|
||||||
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("("+nodep->name()
|
|
||||||
+","+cvtToStr(basicp->msb())
|
|
||||||
+","+cvtToStr(basicp->lsb())
|
|
||||||
+","+cvtToStr(basicp->widthWords()));
|
|
||||||
}
|
|
||||||
puts(");\n");
|
puts(");\n");
|
||||||
}
|
}
|
||||||
} else if (basicp && basicp->isOpaque()) {
|
} else if (basicp && basicp->isOpaque()) {
|
||||||
// strings and other fundamental c types
|
// strings and other fundamental c types
|
||||||
puts(nodep->vlArgType(true,false));
|
puts(nodep->vlArgType(true,false));
|
||||||
// This isn't very robust and may need cleanup for other data types
|
emitDeclArrayBrackets(nodep);
|
||||||
for (AstUnpackArrayDType* arrayp=nodep->dtypeSkipRefp()->castUnpackArrayDType(); arrayp;
|
|
||||||
arrayp = arrayp->subDTypep()->skipRefp()->castUnpackArrayDType()) {
|
|
||||||
puts("["+cvtToStr(arrayp->elementsConst())+"]");
|
|
||||||
}
|
|
||||||
puts(";\n");
|
puts(";\n");
|
||||||
} else {
|
} else {
|
||||||
// Arrays need a small alignment, but may need different padding after.
|
// 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("::"); }
|
if (prefixIfImp!="") { puts(prefixIfImp); puts("::"); }
|
||||||
puts(nodep->name());
|
puts(nodep->name());
|
||||||
// This isn't very robust and may need cleanup for other data types
|
emitDeclArrayBrackets(nodep);
|
||||||
for (AstUnpackArrayDType* arrayp=nodep->dtypeSkipRefp()->castUnpackArrayDType(); arrayp;
|
|
||||||
arrayp = arrayp->subDTypep()->skipRefp()->castUnpackArrayDType()) {
|
|
||||||
puts("["+cvtToStr(arrayp->elementsConst())+"]");
|
|
||||||
}
|
|
||||||
// If it's a packed struct/array then nodep->width is the whole thing, msb/lsb is just lowest dimension
|
// 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()));
|
if (nodep->isWide()) puts(","+cvtToStr(nodep->widthWords()));
|
||||||
puts(");\n");
|
puts(");\n");
|
||||||
}
|
}
|
||||||
|
34
test_regress/t/t_mem_multi_io3.cpp
Normal file
34
test_regress/t/t_mem_multi_io3.cpp
Normal 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;
|
||||||
|
}
|
52
test_regress/t/t_mem_multi_io3.v
Normal file
52
test_regress/t/t_mem_multi_io3.v
Normal 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
|
21
test_regress/t/t_mem_multi_io3_cc.pl
Executable file
21
test_regress/t/t_mem_multi_io3_cc.pl
Executable 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;
|
21
test_regress/t/t_mem_multi_io3_sc.pl
Executable file
21
test_regress/t/t_mem_multi_io3_sc.pl
Executable 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;
|
Loading…
Reference in New Issue
Block a user