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.
|
*** 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]
|
**** 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()) {
|
if (nodep->isIO()) {
|
||||||
bool isArray = !nodep->dtypeSkipRefp()->castBasicDType();
|
bool isArray = !nodep->dtypeSkipRefp()->castBasicDType();
|
||||||
if (nodep->isSc()) {
|
if (nodep->isSc()) {
|
||||||
if (isArray) {
|
|
||||||
nodep->v3error("Unsupported: SystemC inputs and outputs must be simple data types; no arrays");
|
|
||||||
}
|
|
||||||
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
|
||||||
if (nodep->attrScClocked() && nodep->isInput()) {
|
if (nodep->attrScClocked() && nodep->isInput()) {
|
||||||
|
|
@ -889,6 +886,11 @@ void EmitCStmts::emitVarDecl(AstVar* nodep, const string& prefixIfImp) {
|
||||||
puts(">\t");
|
puts(">\t");
|
||||||
}
|
}
|
||||||
puts(nodep->name());
|
puts(nodep->name());
|
||||||
|
if (isArray) {
|
||||||
|
for (AstArrayDType* arrayp=nodep->dtypeSkipRefp()->castArrayDType(); arrayp; arrayp = arrayp->dtypeSkipRefp()->castArrayDType()) {
|
||||||
|
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(),
|
||||||
|
|
@ -961,22 +963,29 @@ void EmitCStmts::emitVarDecl(AstVar* nodep, const string& prefixIfImp) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmitCStmts::emitVarCtors() {
|
void EmitCStmts::emitVarCtors() {
|
||||||
ofp()->indentInc();
|
if (!m_ctorVarsVec.empty()) {
|
||||||
bool first = true;
|
ofp()->indentInc();
|
||||||
for (vector<AstVar*>::iterator it = m_ctorVarsVec.begin(); it != m_ctorVarsVec.end(); ++it) {
|
puts("\n");
|
||||||
if (first) {
|
puts("#if (SYSTEMC_VERSION>20011000)\n"); // SystemC 2.0.1 and newer
|
||||||
first=false;
|
bool first = true;
|
||||||
puts("\n");
|
for (vector<AstVar*>::iterator it = m_ctorVarsVec.begin(); it != m_ctorVarsVec.end(); ++it) {
|
||||||
puts("#if (SYSTEMC_VERSION>20011000)\n"); // SystemC 2.0.1 and newer
|
AstVar* varp = *it;
|
||||||
puts(" : ");
|
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(", ");
|
puts ("\n#endif\n");
|
||||||
if (ofp()->exceededWidth()) puts("\n ");
|
ofp()->indentDec();
|
||||||
puts((*it)->name());
|
|
||||||
puts("("); putsQuoted((*it)->name()); puts(")");
|
|
||||||
}
|
}
|
||||||
if (!first) puts ("\n#endif\n");
|
|
||||||
ofp()->indentDec();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EmitCStmts::emitSimpleOk(AstNodeMath* nodep) {
|
bool EmitCStmts::emitSimpleOk(AstNodeMath* nodep) {
|
||||||
|
|
@ -1500,7 +1509,22 @@ void EmitCImp::emitSensitives() {
|
||||||
for (AstNode* nodep=m_modp->stmtsp(); nodep; nodep = nodep->nextp()) {
|
for (AstNode* nodep=m_modp->stmtsp(); nodep; nodep = nodep->nextp()) {
|
||||||
if (AstVar* varp = nodep->castVar()) {
|
if (AstVar* varp = nodep->castVar()) {
|
||||||
if (varp->isInput() && (varp->isScSensitive() || varp->isUsedClock())) {
|
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 {
|
class V3Global {
|
||||||
// Globals
|
// 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
|
int m_debugFileNumber; // Number to append to debug files created
|
||||||
bool m_assertDTypesResolved; // Tree should have dtypep()'s
|
bool m_assertDTypesResolved; // Tree should have dtypep()'s
|
||||||
bool m_assertWidthsMatch; // Tree should have width()==widthMin()
|
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; }
|
if (!$::Driver) { use FindBin; exec("$FindBin::Bin/bootstrap.pl", @ARGV, $0); die; }
|
||||||
# DESCRIPTION: Verilator: Verilog Test driver/expect definition
|
# 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
|
# redistribute it and/or modify it under the terms of either the GNU
|
||||||
# Lesser General Public License Version 3 or the Perl Artistic License
|
# Lesser General Public License Version 3 or the Perl Artistic License
|
||||||
# Version 2.0.
|
# Version 2.0.
|
||||||
|
|
||||||
|
top_filename("t/t_mem_multi_io2.v");
|
||||||
|
|
||||||
|
$Self->{vlt} or $Self->skip("Verilator only test");
|
||||||
|
|
||||||
compile (
|
compile (
|
||||||
verilator_flags2 => ["-sp"],
|
make_top_shell => 0,
|
||||||
fails=>$Self->{v3},
|
make_main => 0,
|
||||||
nc=>0,
|
verilator_flags2 => ["--exe $Self->{t_dir}/t_mem_multi_io2.cpp"],
|
||||||
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.*',
|
execute (
|
||||||
);
|
check_finished=>1,
|
||||||
|
);
|
||||||
|
|
||||||
ok(1);
|
ok(1);
|
||||||
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