Support arrayed SystemC I/O pins.
This commit is contained in:
parent
3429f41489
commit
9df8966f4a
2
Changes
2
Changes
|
|
@ -10,6 +10,8 @@ indicates the contributor was also the author of the fix; Thanks!
|
|||
|
||||
*** Report MULTIDRIVEN on memories set in multiple clock domains.
|
||||
|
||||
*** Support arrayed SystemC I/O pins. [Christophe Joly]
|
||||
|
||||
**** Fix core dump with over 100 deep UNOPTFLAT, bug432. [Joe Eiler]
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -872,9 +872,6 @@ void EmitCStmts::emitVarDecl(AstVar* nodep, const string& prefixIfImp) {
|
|||
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()) {
|
||||
|
|
@ -889,6 +886,11 @@ void EmitCStmts::emitVarDecl(AstVar* nodep, const string& prefixIfImp) {
|
|||
puts(">\t");
|
||||
}
|
||||
puts(nodep->name());
|
||||
if (isArray) {
|
||||
for (AstArrayDType* arrayp=nodep->dtypeSkipRefp()->castArrayDType(); arrayp; arrayp = arrayp->dtypeSkipRefp()->castArrayDType()) {
|
||||
puts("["+cvtToStr(arrayp->elementsConst())+"]");
|
||||
}
|
||||
}
|
||||
puts(";\n");
|
||||
} else { // C++ signals
|
||||
ofp()->putAlign(nodep->isStatic(), nodep->dtypeSkipRefp()->widthAlignBytes(),
|
||||
|
|
@ -961,22 +963,29 @@ void EmitCStmts::emitVarDecl(AstVar* nodep, const string& prefixIfImp) {
|
|||
}
|
||||
|
||||
void EmitCStmts::emitVarCtors() {
|
||||
ofp()->indentInc();
|
||||
bool first = true;
|
||||
for (vector<AstVar*>::iterator it = m_ctorVarsVec.begin(); it != m_ctorVarsVec.end(); ++it) {
|
||||
if (first) {
|
||||
first=false;
|
||||
puts("\n");
|
||||
puts("#if (SYSTEMC_VERSION>20011000)\n"); // SystemC 2.0.1 and newer
|
||||
puts(" : ");
|
||||
if (!m_ctorVarsVec.empty()) {
|
||||
ofp()->indentInc();
|
||||
puts("\n");
|
||||
puts("#if (SYSTEMC_VERSION>20011000)\n"); // SystemC 2.0.1 and newer
|
||||
bool first = true;
|
||||
for (vector<AstVar*>::iterator it = m_ctorVarsVec.begin(); it != m_ctorVarsVec.end(); ++it) {
|
||||
AstVar* varp = *it;
|
||||
bool isArray = !varp->dtypeSkipRefp()->castBasicDType();
|
||||
if (isArray) {
|
||||
puts("// Skipping array: ");
|
||||
puts(varp->name());
|
||||
puts("\n");
|
||||
} else {
|
||||
if (first) { puts(" : "); first=false; }
|
||||
else puts(", ");
|
||||
if (ofp()->exceededWidth()) puts("\n ");
|
||||
puts(varp->name());
|
||||
puts("("); putsQuoted(varp->name()); puts(")");
|
||||
}
|
||||
}
|
||||
else puts(", ");
|
||||
if (ofp()->exceededWidth()) puts("\n ");
|
||||
puts((*it)->name());
|
||||
puts("("); putsQuoted((*it)->name()); puts(")");
|
||||
puts ("\n#endif\n");
|
||||
ofp()->indentDec();
|
||||
}
|
||||
if (!first) puts ("\n#endif\n");
|
||||
ofp()->indentDec();
|
||||
}
|
||||
|
||||
bool EmitCStmts::emitSimpleOk(AstNodeMath* nodep) {
|
||||
|
|
@ -1500,7 +1509,22 @@ void EmitCImp::emitSensitives() {
|
|||
for (AstNode* nodep=m_modp->stmtsp(); nodep; nodep = nodep->nextp()) {
|
||||
if (AstVar* varp = nodep->castVar()) {
|
||||
if (varp->isInput() && (varp->isScSensitive() || varp->isUsedClock())) {
|
||||
puts("sensitive << "+varp->name()+";\n");
|
||||
int vects = 0;
|
||||
// This isn't very robust and may need cleanup for other data types
|
||||
for (AstArrayDType* arrayp=varp->dtypeSkipRefp()->castArrayDType(); arrayp;
|
||||
arrayp = arrayp->dtypeSkipRefp()->castArrayDType()) {
|
||||
int vecnum = vects++;
|
||||
if (arrayp->msb() < arrayp->lsb()) varp->v3fatalSrc("Should have swapped msb & lsb earlier.");
|
||||
string ivar = string("__Vi")+cvtToStr(vecnum);
|
||||
// MSVC++ pre V7 doesn't support 'for (int ...)', so declare in sep block
|
||||
puts("{ int __Vi"+cvtToStr(vecnum)+"="+cvtToStr(arrayp->lsb())+";");
|
||||
puts(" for (; "+ivar+"<="+cvtToStr(arrayp->msb()));
|
||||
puts("; ++"+ivar+") {\n");
|
||||
}
|
||||
puts("sensitive << "+varp->name());
|
||||
for (int v=0; v<vects; ++v) puts( "[__Vi"+cvtToStr(v)+"]");
|
||||
puts(";\n");
|
||||
for (int v=0; v<vects; ++v) puts( "}}\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,8 @@ class AstNetlist;
|
|||
|
||||
class V3Global {
|
||||
// Globals
|
||||
AstNetlist* m_rootp; // Root of entire netlist
|
||||
AstNetlist* m_rootp; // Root of entire netlist
|
||||
|
||||
int m_debugFileNumber; // Number to append to debug files created
|
||||
bool m_assertDTypesResolved; // Tree should have dtypep()'s
|
||||
bool m_assertWidthsMatch; // Tree should have width()==widthMin()
|
||||
|
|
|
|||
|
|
@ -0,0 +1,89 @@
|
|||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2008 by Lane Brooks
|
||||
|
||||
#if defined(T_MEM_MULTI_IO2_CC)
|
||||
# include "Vt_mem_multi_io2_cc.h"
|
||||
#elif defined(T_MEM_MULTI_IO2_SC)
|
||||
# include "Vt_mem_multi_io2_sc.h"
|
||||
#else
|
||||
# error "Unknown test"
|
||||
#endif
|
||||
|
||||
VM_PREFIX* tb = NULL;
|
||||
bool pass = true;
|
||||
|
||||
double sc_time_stamp() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void check(const char* bus, int got, int exp) {
|
||||
if (got != exp) {
|
||||
VL_PRINTF("%%Error: Data mismatch on '%s', got=%x, exp=%x\n", bus, got, exp);
|
||||
pass = false;
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
Verilated::debug(0);
|
||||
tb = new VM_PREFIX ("tb");
|
||||
|
||||
#ifdef SYSTEMC_VERSION
|
||||
sc_signal<vluint32_t> i3;
|
||||
sc_signal<vluint32_t> o3;
|
||||
sc_signal<vluint32_t> i34[4];
|
||||
sc_signal<vluint32_t> o34[4];
|
||||
sc_signal<vluint32_t> i345[4][5];
|
||||
sc_signal<vluint32_t> o345[4][5];
|
||||
|
||||
tb->i3(i3);
|
||||
tb->o3(o3);
|
||||
for (int i=0; i<4; i++) {
|
||||
tb->i34[i](i34[i]);
|
||||
tb->o34[i](o34[i]);
|
||||
for (int j=0; j<5; j++) {
|
||||
tb->i345[i][j](i345[i][j]);
|
||||
tb->o345[i][j](o345[i][j]);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// loop through every possibility and check the result
|
||||
#ifdef SYSTEMC_VERSION
|
||||
sc_start(1,SC_NS);
|
||||
# define ASSIGN(s,v) s.write(v)
|
||||
# define READ(s) s.read()
|
||||
#else
|
||||
tb->eval();
|
||||
# define ASSIGN(s,v) tb->s = (v)
|
||||
# define READ(s) tb->s
|
||||
#endif
|
||||
|
||||
ASSIGN(i3, 13);
|
||||
for (int i=0; i<4; i++) {
|
||||
ASSIGN(i34[i], i);
|
||||
for (int j=0; j<5; j++) {
|
||||
ASSIGN(i345[i][j], i*8 + j);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef SYSTEMC_VERSION
|
||||
sc_start(1,SC_NS);
|
||||
#else
|
||||
tb->eval();
|
||||
#endif
|
||||
|
||||
check("o3", READ(o3), 13);
|
||||
for (int i=0; i<4; i++) {
|
||||
check("o34", READ(o34[i]), i);
|
||||
for (int j=0; j<5; j++) {
|
||||
check("o345", READ(o345[i][j]), i*8 + j);
|
||||
}
|
||||
}
|
||||
|
||||
if (pass) {
|
||||
VL_PRINTF("*-* All Finished *-*\n");
|
||||
} else {
|
||||
vl_fatal(__FILE__,__LINE__,"top", "Unexpected results from test\n");
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2008 by Lane Brooks
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Outputs
|
||||
o3, o34, o345,
|
||||
// Inputs
|
||||
i3, i34, i345
|
||||
);
|
||||
input [15:0] i3;
|
||||
output wire [15:0] o3;
|
||||
input [15:0] i34 [3:0];
|
||||
output wire [15:0] o34 [3:0];
|
||||
input [15:0] i345 [3:0][4:0];
|
||||
output wire [15:0] o345 [3:0][4:0];
|
||||
|
||||
sub sub (.*);
|
||||
endmodule
|
||||
|
||||
module sub (/*AUTOARG*/
|
||||
// Outputs
|
||||
o3, o34, o345,
|
||||
// Inputs
|
||||
i3, i34, i345
|
||||
);
|
||||
input [15:0] i3;
|
||||
output wire [15:0] o3;
|
||||
input [15:0] i34 [3:0];
|
||||
output wire [15:0] o34 [3:0];
|
||||
input [15:0] i345 [3:0][4:0];
|
||||
output wire [15:0] o345 [3:0][4:0];
|
||||
|
||||
assign o3 = i3;
|
||||
assign o34 = i34;
|
||||
assign o345 = i345;
|
||||
|
||||
endmodule
|
||||
|
|
@ -2,19 +2,24 @@
|
|||
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
|
||||
# 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_io2.v");
|
||||
|
||||
$Self->{vlt} or $Self->skip("Verilator only test");
|
||||
|
||||
compile (
|
||||
verilator_flags2 => ["-sp"],
|
||||
fails=>$Self->{v3},
|
||||
nc=>0,
|
||||
expect=>
|
||||
'%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.*',
|
||||
);
|
||||
make_top_shell => 0,
|
||||
make_main => 0,
|
||||
verilator_flags2 => ["--exe $Self->{t_dir}/t_mem_multi_io2.cpp"],
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
#!/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_io2.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_io2.cpp --sc"],
|
||||
);
|
||||
|
||||
execute (
|
||||
check_finished=>1,
|
||||
);
|
||||
|
||||
ok(1);
|
||||
1;
|
||||
|
|
@ -1,12 +0,0 @@
|
|||
// DESCRIPTION: Verilator: Verilog Test module
|
||||
//
|
||||
// This file ONLY is placed into the Public Domain, for any use,
|
||||
// without warranty, 2005 by Wilson Snyder.
|
||||
|
||||
module t (/*AUTOARG*/
|
||||
// Outputs
|
||||
dim1
|
||||
);
|
||||
reg [1:0] dim1 [1:0];
|
||||
output dim1; // Bad, can't output multi-dim
|
||||
endmodule
|
||||
Loading…
Reference in New Issue