I have been to create a proof of concept for an instance inside an instance, and I am getting a "complete binding error", which I have not been able to get past. I have searched online, and though I found similar cases, they could not explain mine. I have tried to minimize the code as much as possible for readability. The basic block is an adder (called alu_unit
), which is instantiated by a block_unit
, which right now only contains the alu_unit
. The block_unit
is instantiated by sc_main
, which assigns a value, and runs the simulation. I will place the code below for all units:
alu.h
#include <systemc.h>
SC_MODULE (alu_unit) {
sc_in < sc_int < 64 > > addA_in{"addA_in"};
sc_in < sc_int < 64 > > addB_in{"addB_in"};
sc_in < sc_lv <1> > carry_in{"carry_in"};
sc_out < sc_int < 64 > > sum_busout{"sum_busout"};
void sumc();
SC_CTOR(alu_unit) {
SC_THREAD(sumc);
sensitive << addA_in << addB_in << carry_in;
}
~alu_unit() { };
};
alu.cpp
#include "alu.h"
void alu_unit::sumc()
{
sum_busout.write(addA_in.read() + addB_in.read() + carry_in.read().to_int());
};
block.h
#include <systemc.h>
#include "alu.h"
SC_MODULE (block_unit) {
sc_in_clk clock;
sc_in < sc_int < 64 > > addA_in{"addA_in"};
sc_in < sc_int < 64 > > addB_in{"addB_in"};
sc_in < sc_lv <1> > carry_in{"carry_in"};
sc_out < sc_int <64> > sum_regout{"sum_busout"};
/* Instance declarations */
alu_unit alu1;
// Function declarations
void myblock();
SC_CTOR(block_unit):alu1("alu1") {
SC_THREAD(myblock);
sensitive << clock.pos();
}
~block_unit() { };
};
block.cpp
#include "block.h"
void block_unit::myblock()
{
wait();
while (true) {
// Input binding
// Port conections for block alu1
alu1.addA_in(addA_in);
alu1.addB_in(addB_in);
alu1.carry_in(carry_in);
alu1.sum_busout(sum_regout);
wait();
}
}
main.cpp
#include <systemc.h>
#include "block.h"
int sc_main(int argc, char **argv) {
sc_signal < sc_int < 64 > > addA_s;
sc_signal < sc_int < 64 > > addB_s;
sc_signal < sc_lv < 1 > > carry_s;
sc_signal < sc_int < 64 > > sum_s;
// 1ns clock with 50% duty cycle
sc_clock clock("clock", 1, SC_NS, 0.5);
block_unit block1("block1");
sc_start(55, SC_NS);
addA_s = 4;
addB_s = 3;
carry_s = 1;
block1.clock(clock);
block1.addA_in(addA_s);
block1.addB_in(addB_s);
block1.carry_in(carry_s);
block1.sum_regout.bind(sum_s);
sc_trace_file *tf = sc_create_vcd_trace_file("vcd_trace.vcd");
sc_trace(tf, clock, "clock");
sc_trace(tf, addA_s, "addA");
sc_trace(tf, addB_s, "addb");
sc_trace(tf, carry_s, "carry");
sc_trace(tf, sum_s, "sum");
sc_stop();
return 0;
}
The compilation works fine using:
g++ -I. -I/usr/local/systemc/include -O0 -g3 -Wall -c -lsystemc -std=gnu++11 alu.cpp -o alu.o
[...]
g++ -I/usr/local/systemc/include -L. -L/usr/local/systemc/lib-linux64 -o main -lsystemc -std=gnu++11 alu.o block.o main.o -lsystemc
And simulation fails as follows:
Error: (E109) complete binding failed: port not bound: port 'block1.alu1.sum_busout' (sc_out)
Any help would be greatly appreciated. I am happy to give SystemC a try, which is why I am doing these proofs of concepts.
There are a few things that look odd.
I don't think you want to use bind
in sc_main
to make the connection to sum_regout
.
I think it would be better to make the connections in sc_main
before calling sc_start
.
I don't think you want to make connections to alu
inside the myblock
function.
I don't know the exact reason for the E109
error, but the error goes away with the following code:
//////////////////////// block.h
#include <systemc.h>
#include "alu.h"
SC_MODULE (block_unit) {
sc_in_clk clock;
sc_in < sc_int < 64 > > addA_in{"addA_in"};
sc_in < sc_int < 64 > > addB_in{"addB_in"};
sc_in < sc_lv <1> > carry_in{"carry_in"};
sc_out < sc_int <64> > sum_regout{"sum_regout"};
alu_unit alu1;
// Function declarations
void myblock();
SC_CTOR(block_unit):alu1("alu1") {
alu1.addA_in(addA_in);
alu1.addB_in(addB_in);
alu1.carry_in(carry_in);
alu1.sum_busout(sum_regout);
SC_THREAD(myblock);
sensitive << clock.pos();
}
~block_unit() { };
};
////////////////////////// block.cpp
#include "block.h"
void block_unit::myblock()
{
wait();
while (true) {
wait();
}
}
//////////////////////// main.cpp
#include <systemc.h>
#include "block.h"
int sc_main(int argc, char **argv) {
sc_signal < sc_int < 64 > > addA_s;
sc_signal < sc_int < 64 > > addB_s;
sc_signal < sc_lv < 1 > > carry_s;
sc_signal < sc_int < 64 > > sum_s;
// 1ns clock with 50% duty cycle
sc_clock clock("clock", 1, SC_NS, 0.5);
block_unit block1("block1");
block1.clock(clock);
block1.addA_in(addA_s);
block1.addB_in(addB_s);
block1.carry_in(carry_s);
block1.sum_regout(sum_s);
sc_start(55, SC_NS);
addA_s = 4;
addB_s = 3;
carry_s = 1;
sc_trace_file *tf = sc_create_vcd_trace_file("vcd_trace.vcd");
sc_trace(tf, clock, "clock");
sc_trace(tf, addA_s, "addA");
sc_trace(tf, addB_s, "addb");
sc_trace(tf, carry_s, "carry");
sc_trace(tf, sum_s, "sum");
sc_stop();
return 0;
}
Here is a link on edaplayground