Error E109 - complete binding failed: port not bound - systemc

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

Related

Changing signal on every posedge of clock in SC_THREAD

I want to implement module, which when is called to work changes signal x the way below:
1 clk pos.edge : x = 0 // 1st phase
2 clk pos.edge : x = 0 // 2nd phase
3 clk pos.edge : x = 1 // 3rd phase
And then stops until called again.
I have function foo() in my module, which is called from main and allows thread work_foo() to execute on the posedge of clock.
I tried to do it this way (with wait()), and in some simple test it gives right wave, but it is an inappropriate way: my_module.h:
#include "systemc.h"
SC_MODULE (my_module)
{
sc_in <bool> clk;
sc_out <sc_logic> x;
sc_signal <bool> valid;
void foo()
{
valid = 1;
return;
}
void work_foo()
{
while (true)
{
if (valid == 1)
{ // foo() was called
if (phase == 0)
{
x = SC_LOGIC_0;
wait(); // waiting for the next tick
x = SC_LOGIC_0;
wait(); // waiting for the next tick
x = SC_LOGIC_1;
wait(); // waiting for the next tick
}
else
{
valid=0;
wait();
}
}
}
SC_HAS_PROCESS(my_module);
my_module(sc_module_name name):
sc_module(name),
clk("clk"), x("x"), valid("valid")
{
SC_THREAD(work_foo);
//dont_initialize();
sensitive<<clk.pos();
valid=0;
}
};
main.cpp:
#include "systemc.h"
#include "my_module.h"
int sc_main (int argc, char* argv[])
{
sc_clock clock("clock", 10, SC_NS);
sc_signal<sc_logic > x;
my_module mm("my_mod");
mm.clk(clock);
mm.x(x);
mm.foo ();
sc_start(200, SC_NS);
sc_stop();
return 0;
}
And now I'm trying to implement it another way. I was advised to use additional sc_signal (or variable) in my module, which indicates the incrementing number of the phase. The problem is what this gets looped at the very start. How can I solve this?
#include "systemc.h"
SC_MODULE (my_module)
{
sc_in <bool> clk;
sc_out <sc_logic> x;
sc_signal <bool> valid;
sc_signal <uint> phase;
void foo()
{
valid = 1;
return;
}
void work_foo()
{
while (true)
{
if (valid == 1)
{
if (phase == 0)
{
x = SC_LOGIC_0;
phase=phase+1;
}
else if (phase == 1)
{
x = SC_LOGIC_0;
phase=phase+1;
}
else if (phase == 2)
{
x = SC_LOGIC_1;
phase=phase+1;
}
}
else
{
phase=0;
valid=0;
wait();
}
}
}
SC_HAS_PROCESS(my_module);
my_module(sc_module_name name):
sc_module(name),
clk("clk"), x("x"), valid("valid")
{
SC_THREAD(work_foo);
//dont_initialize();
sensitive<<clk.pos();
valid=0;
phase=0;
}
};

compare images using systemC

I wrote in this forum asking for help to solve this problem that took ame a lot of my time,i write my first program using systemC, I will expain my aim as much as I can , I stored 2 matrix of pixel value of image in two different text files, I write a systemC code that load two matrix and apply somme of absolute difference, if number of different superior of a Threshold the code displays message (motion).
My code composed of two modules, the first module check if there a number stored in a text file, if yes this Module will automates the other module to load the two matrix and compare them, I really need this code for my project graduation any help or suggestion.
#include "systemC.h"
#include "string.h"
#include "stdio.h"
#include"stdlib.h"
#include <time.h>
#include <math.h> /* fabs */
#include <fstream>
#include <iostream>
#include <fstream>
using namespace std;
#define _CRT_SECURE_NO_WARNINGS
_CRT_SECURE_NO_WARNINGS
double elapsed;
int H = 0;
int D = 0;
int a, b;
int in = false;
int L = 0;
char *mode1 = "r";
char *mode2 = "w";
int i, j, k;
int rows1, cols1, rows2, cols2;
bool fileFound = false;
FILE *SwitchContext;
FILE *image1;
FILE *image2;
FILE *image3;
int sum = 0;
clock_t start = clock();
SC_MODULE(synchronization)
{
sc_in<bool>sig ;
SC_CTOR(synchronization)
{
SC_METHOD(synchroprocess)
}
void synchroprocess()
{
cout << "\n Running Automation";
SwitchContext = fopen("F:/SWITCH CONTEXT.txt", mode2);
fscanf(SwitchContext, "%d", &L);
while (L != 0)
{
cout << "waiting...";
}
sig == true;
}
};
SC_MODULE(imageProcess)
{
sc_in<bool>sig;
SC_CTOR(imageProcess)
{
SC_METHOD(MotionDetector)
sensitive(sig);
}
void MotionDetector()
{
image3 = fopen("F:/image3.txt", mode2);
do
{
char *mode1 = "r";
char *mode2 = "w";
image1 = fopen("F:/image1.txt", mode1);
if (!image1)
{
printf("File Not Found!!\n");
fileFound = true;
}
else
fileFound = false;
}
while (fileFound);
do
{
image2 = fopen("F:/image2.txt", mode1);
if (!image2)
{
printf("File Not Found!!\n");
fileFound = true;
}
else
fileFound = false;
}
while (fileFound);
rows1 = rows2 = 384;
cols1 = cols2 = 512;
int **mat1 = (int **)malloc(rows1 * sizeof(int*));
for (i = 0; i < rows1; i++)
mat1[i] = (int *)malloc(cols1 * sizeof(int));
i = 0;
int **mat2 = (int **)malloc(rows2 * sizeof(int*));
for (i = 0; i < rows2; i++)
mat2[i] = (int *)malloc(cols2 * sizeof(int));
i = 0;
while (!feof(image1))
{
for (i = 0; i < rows1; i++)
{
for (j = 0; j < cols1; j++)
fscanf(image1, "%d%", &mat1[i][j]);
}
}
i = 0;
j = 0;
while (!feof(image2))
{
for (i = 0; i < rows2; i++)
{
for (j = 0; j < cols2; j++)
fscanf(image2, "%d%", &mat2[i][j]);
}
}
i = 0;
j = 0;
printf("\n\n");
for (i = 0; i < rows1; i++)
{
for (j = 0; j < cols1; j++) {
a = abs(mat1[i][j] = mat2[i][j]);
b = b + a;
}
}
i = j = 0;
D = b / 196608;
if (D > 0.9)
{
printf("%d,&K");
printf("MOTION...DETECTED");
getchar();
sc_pause;
for (i = 0; i < rows1; i++) {
for (j = 0; j < cols1; j++)
{
fprintf(image3, "%d ", mat2[i][j]);
}
fprintf(image3, "\n");
}
printf("\n Image Saved....");
std::ofstream mon_fichier("F:\toto.txt");
mon_fichier << elapsed << '\n';
}
fclose(image1);
fclose(image2);
fclose(image3);
clock_t end = clock();
elapsed = ((double)end - start) / CLOCKS_PER_SEC;
printf("time is %f", elapsed);
}
};
int sc_main(int argc, char* argv[])
{
imageProcess master("EE2");
master.MotionDetector();
sc_start();
return(0);
}
What you did is basically wrong.
You copy pasted code to SC_MODULE, this code is simple C code
(Do not mix C and C++ files)
This is not how you use clock
What you should do:
You need to check if your algorithm works, for this you do not need SystemC at all
Then you can replace data types with HW one and check if it still works
Then you have to find which data interface is used in HW and how to use this interface
Then you have to tweak your alg. to work with this interface (There you can use SC_MODULE, sc ports etc...)
Also take look at SC_CTHREAD, you will need it.
Without any informations about target platform I can not provide any other help.

Need help in getting the process name based on the pid in aix

I need to write a C program in AIX environment which will give me the process name.
I can get the pid but not the process name based on the pid. Any specific system calls available in aix environment??
Thanks
getprocs is likely what you want. I created this under AIX 5.x.
I have a little routine that cycles thru all processes and dumps their information.
while ((numproc = getprocs(pinfo, sizeof(struct procsinfo),
NULL,
0,
&index,
MAXPROCS)) > 0 ) {
for (i = 0;i < numproc; i++) {
/* skip zombie processes */
if (pinfo[i].pi_state==SZOMB)
continue;
printf("%-6d %-4d %-10d %-16s\n", pinfo[i].pi_pid, pinfo[i].pi_uid, pinfo[i].pi_start, pinfo[i].pi_comm);
}
}
....
I realize this is an old question.
But, to convert the #CoreyStup answer into a function that more closely addresses the OP, I offer this: (tested on AIX 6.1, using: g++ -o pn pn.cc)
--- pn.cc ---
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string>
#include <iostream>
#include <procinfo.h>
#include <sys/types.h>
using namespace std;
string getProcName(int pid)
{
struct procsinfo pinfo[16];
int numproc;
int index = 0;
while((numproc = getprocs(pinfo, sizeof(struct procsinfo), NULL, 0, &index, 16)) > 0)
{
for(int i=0; i<numproc; ++i)
{
// skip zombies
if (pinfo[i].pi_state == SZOMB)
continue;
if (pid == pinfo[i].pi_pid)
{
return pinfo[i].pi_comm;
}
}
}
return "";
}
int main(int argc, char** argv)
{
for(int i=1; i<argc; ++i)
{
int pid = atoi(argv[i]);
string name = getProcName(pid);
cout << "pid: " << pid << " == '" << name << "'" << endl;
}
return 0;
}

How to use MPI_Reduce to Sum different values from Different groups of processors independently

I am trying to divide my processors into groups then add the summation of each group
independently ... but I couldn't find the result correctly until now.
a simple example is as follows:
int main(int argc, char** argv)
{
int size, rank,i=0,localsum1=0,globalsum1=0,localsum2=0,globalsum2=0;
MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD,&size);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
if(rank==0)
{
}
else if(rank==1)
{
localsum1 += 5;
MPI_Reduce(&localsum1,&globalsum1,2,MPI_INT,MPI_SUM,0,MPI_COMM_WORLD);
}
else if(rank==2)
{
localsum2 += 10;
MPI_Reduce(&localsum2,&globalsum2,2,MPI_INT,MPI_SUM,0,MPI_COMM_WORLD);
}
if(rank==0)
{
printf("globalsum1 = %d \n",globalsum1);
printf("globalsum2 = %d \n",globalsum2);
}
MPI_Finalize();
return (EXIT_SUCCESS);
}
I can't figure out what is missing here ... can anyone help?
MPI_Reduce is a collective operation. What that means is that all tasks in the participating communicator must make the MPI_Reduce() call. In the above, rank 0 never calls MPI_Reduce() so this program will hang as some of the other processors wait for participation from rank 0 which will never come.
Also, because it is a collective operation on the entire communicator, you need to do some work to partition the reduction. One way is just to reduce an array of ints, and have each processor contribute only to its element in the array:
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
int main(int argc, char** argv)
{
int size, rank;
MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD,&size);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
int localsum[2] = {0,0};
int globalsum[2] = {0,0};
if(rank % 2 == 1)
{
localsum[0] += 5;
}
else if( rank > 0 && (rank % 2 == 0))
{
localsum[1] += 10;
}
MPI_Reduce(localsum,globalsum,2,MPI_INT,MPI_SUM,0,MPI_COMM_WORLD);
if(rank==0)
{
printf("globalsum1 = %d \n",globalsum[0]);
printf("globalsum2 = %d \n",globalsum[1]);
}
MPI_Finalize();
return (EXIT_SUCCESS);
}
where running now gives
$ mpicc -o reduce reduce.c
$ mpirun -np 3 ./reduce
globalsum1 = 5
globalsum2 = 10
Otherwise, you can create communicators that only connect the processors you want to be involved in each sum, and do the reductions within each commuicator. Below is a not-very-pretty way to do this. This is quite powerful in general but more complicated than the first solution:
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
int main(int argc, char** argv)
{
int size, rank;
MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD,&size);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
int localsum = 0;
int globalsum = 0;
MPI_Comm comm_evens_plus_root, comm_odds_plus_root;
MPI_Group grp_evens_plus_root, grp_odds_plus_root, grp_world;
MPI_Comm_group(MPI_COMM_WORLD, &grp_world);
int *ranks = malloc((size/2 + 1) * sizeof(rank));
int i,j;
for (i=1, j=0; i<size; i+=2, j+=1)
ranks[j] = i;
MPI_Group_excl(grp_world, j, ranks, &grp_evens_plus_root);
MPI_Comm_create(MPI_COMM_WORLD, grp_evens_plus_root, &comm_evens_plus_root);
for (i=2, j=0; i<size; i+=2, j+=1)
ranks[j] = i;
MPI_Group_excl(grp_world, j, ranks, &grp_odds_plus_root);
MPI_Comm_create(MPI_COMM_WORLD, grp_odds_plus_root, &comm_odds_plus_root);
free(ranks);
if(rank % 2 == 1)
{
localsum += 5;
MPI_Reduce(&localsum,&globalsum,1,MPI_INT,MPI_SUM,0,comm_odds_plus_root);
}
else if( rank > 0 && (rank % 2 == 0))
{
localsum += 10;
MPI_Reduce(&localsum,&globalsum,1,MPI_INT,MPI_SUM,0,comm_evens_plus_root);
}
if(rank==0)
{
MPI_Reduce(&localsum,&globalsum,1,MPI_INT,MPI_SUM,0,comm_odds_plus_root);
printf("globalsum1 = %d \n",globalsum);
MPI_Reduce(&localsum,&globalsum,1,MPI_INT,MPI_SUM,0,comm_evens_plus_root);
printf("globalsum2 = %d \n",globalsum);
}
MPI_Comm_free(&comm_odds_plus_root);
MPI_Comm_free(&comm_evens_plus_root);
MPI_Group_free(&grp_odds_plus_root);
MPI_Group_free(&grp_evens_plus_root);
MPI_Finalize();
return (EXIT_SUCCESS);
}
Running gives
$ mpicc -o reduce2 reduce2.c
$ mpirun -np 3 ./reduce
globalsum1 = 5
globalsum2 = 10

How to print using g++ with printf correctly?

I am compiling this code with g++:
#include <pthread.h>
#include <iostream>
#include <cstdlib>
#include <string>
#include <stdio.h>
using namespace std;
#define num_threads 3
#define car_limit 4
pthread_mutex_t mutex; // mutex lock
pthread_t cid; // thread id
pthread_attr_t attr; // thread attrubutes
void *OneCar(void *dir);
void ArriveBridge(int *direction);
void CrossBridge();
void ExitBridge(int *direction);
int main()
{
int dir[3] = {0,1,1};
pthread_mutex_init(&mutex, NULL);
pthread_attr_init(&attr);
//cout<< "Pthread Create" << endl;
printf("Pthread Create\n");
for(int i = 0; i < num_threads; i++)
{
pthread_create(&cid, &attr, OneCar, (void *)&dir[i]);
}
return 0;
}
void ArriveBridge(int *direction)
{
//cout<<"Arrive"<<*direction << endl;
int dr;
if(*direction == 0)
dr=0;
else
dr=1;
printf("Arrive%d", dr);
}
void CrossBridge(int *dir)
{
char d;
if(*dir == 0)
d = 'N';
else
d = 'S';
//cout<<"Crossing Bridge going:"<<d<<endl;
printf("Crossing Bridge going %c", d);
}
void ExitBridge(int *direction)
{
//cout<<"Exit" <<*direction<<endl;
int dr;
if(*direction == 0)
dr=0;
else
dr=1;
printf("Exit%d\n", dr);
}
void *OneCar(void *dir)
{
int *cardir;
cardir = (int *) dir;
//cout<<*cardir;
ArriveBridge(cardir);
CrossBridge(cardir);
ExitBridge(cardir);
return 0;
}
and I am expecting this result printed to the screen:
> Pthread Create
> Arrive0Crossing Bridge going NExit0
> Arrive1Crossing Bridge going SExit1
> Arrive1Crossing Bridge going NExit1
But i get this instead:
Pthread Create
Arrive0Crossing Bridge going NExit0
Why doesnt it print the rest out?
You need to use "pthread_join" in main to wait for all threads to exit before your program terminates. You should also use an array to hold the id of each thread that you create:
pthread_t cid[num_threads]; // thread id`
You'll then want to call join on every thread you create:
for(int i = 0; i < num_threads; i++)
{
pthread_create(&cid[i], &attr, OneCar, (void *)&dir[i]);
}
for(int i = 0; i < num_threads; ++i)
{
pthread_join(cid[i], NULL);
};
Running the modified code now gives:
Pthread Create
Arrive0Crossing Bridge going NExit0
Arrive1Crossing Bridge going SExit1
Arrive1Crossing Bridge going SExit1
Have you tried joining your threads at the end of main? It could be that the program is terminating before the other threads are completely finished.
You missed the newlines ("\n"):
printf("Arrive%d\n", dr);
printf("Crossing Bridge going %c\n", d);
Because of that, the streams are probably not flushed. Additionally, if you don't wait for your threads (pthread_join) your program will exit before the threads could do their work.