Search code examples
systemchardware

Error E109 - complete binding failed: port not bound


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.


Solution

  • 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