Jump to content

Why does my SystemC simulation only run 1 thread and end?


rajatkmitra

Recommended Posts

I have 3 modules in my SystemC Test Bench -

Module 1 which is the test control module Looks like the following-

====================================================================================
#ifndef M_TEST_CONTROL_H
#define M_TEST_CONTROL_H

#include "systemc.h"
///////////////////////////////////////////////////////////
//This is just the test control module
///////////////////////////////////////////////////////////


SC_MODULE(m_test_control)
{


  //declairation of tests control signals
  sc_out<bool> enable_clk;


  SC_CTOR(m_test_control)
    {


      SC_THREAD(module_main);


    }




  void module_main(void);




};


#endif


void m_test_control::module_main(void)
{
  ///////////////////////////////////////////
  //Time 0 initialization
  ///////////////////////////////////////////
  enable_clk.write(0);
  wait(100, SC_NS);
  enable_clk.write(1);
  ///////////////////////////////////////////
  //Main Thread....
  ///////////////////////////////////////////
  //for(; {


    wait(100.00, SC_NS);
    cout<<" Stuck here "<< sc_time_stamp() << endl;
    //}






}
=====================================================================================
 
Module 2 which is the multi phase clock module looks like this -
 
========================================================================================================================
#ifndef M_MULTI_PHASE_CLOCK_GEN_H
#define M_MULTI_PHASE_CLOCK_GEN_H


#include "systemc.h"
///////////////////////////////////////////////////////////
//This module mimics the clock generator for the modulator
///////////////////////////////////////////////////////////


SC_MODULE(m_multi_phase_clock_gen)
{


  sc_out<bool> clk, clk_45, clk_90, clk_135;
  sc_out<bool> clk_180, clk_225, clk_270, clk_315;
  sc_in<bool> enable_clk;


  SC_CTOR(m_multi_phase_clock_gen)
    {


    
      SC_THREAD(module_main);
      //sensitive << enable_clk;




      ///////////////////////////////////////////////////
      //Danger !!!! - Never attempt to initialize ports
      //in constructor !!! We elaborte in this phase !!!
      ///////////////////////////////////////////////////


      //initialize all the phases --NOT !!!!
      //clk.write(0);
      //clk_45.write(0);
      //clk_90.write(0);
      //clk_135.write(0);
      //clk_180.write(0);
      //clk_225.write(0);
      //clk_270.write(0);
      //clk_315.write(0);


    }


  void module_main(void);


};


#endif


void m_multi_phase_clock_gen::module_main(void)
{


  ////////////////////////////////////////////////////
  //Time 0 initialization !!!
  ////////////////////////////////////////////////////
  cout << "Clock Generator Initialized at time " << sc_time_stamp() << endl;
  clk.write(0);
  clk_45.write(0);
  clk_90.write(0);
  clk_135.write(0);
  clk_180.write(0);
  clk_225.write(0);
  clk_270.write(0);
  clk_315.write(0);
  
  wait(1.00, SC_NS);


  ////////////////////////////////////////////////////
  //Main Thread...
  ////////////////////////////////////////////////////
  while(enable_clk.read()){
    
    //generate phase 0
    clk.write(!clk.read());
    wait(1.25, SC_NS);
    
    //generate phase 1
    clk_45.write(!clk_45.read());
    wait(1.25, SC_NS);
    
    //generate phase 2
    clk_90.write(!clk_90.read());      
    wait(1.25, SC_NS);
    
    //generate phase 3
    clk_135.write(!clk_135.read());
    wait(1.25, SC_NS);
    
    //generate phase 4
    clk_180.write(!clk_180.read());
    wait(1.25, SC_NS);
    
    //generate phase 5
    clk_225.write(!clk_225.read());
    wait(1.25, SC_NS);
    
    //generate phase 6
    clk_270.write(!clk_270.read());      
    wait(1.25, SC_NS);
    
    //generate phase 7
    clk_315.write(!clk_315.read());
    wait(1.25, SC_NS);
    
  }
  
  
}




========================================================================================================================
Module 3 is wrapped in a wrapper module called Analog_Core and this module looks like this -
 
========================================================================================================================
#ifndef M_ANALOG_CORE_H
#define M_ANALOG_CORE_H


#include "systemc.h"
#include "m_multi_phase_clock_gen.h"
//////////////////////////////////////////////////
//This module is the netlist of the Analog Core
//////////////////////////////////////////////////


SC_MODULE(m_analog_core)
{


  //top level I/O
  sc_out<bool> clk, clk_45, clk_90, clk_135;
  sc_out<bool> clk_180, clk_225, clk_270, clk_315;
  sc_in<bool> enable_clk;
  
  //internal modules
  m_multi_phase_clock_gen i_clock_gen;


  SC_CTOR(m_analog_core):
    //in constructor, name all ports, module instantiations and whatever can be named !!!
    i_clock_gen("i_clock_gen"),
    clk("clk"), clk_45("clk_45"), clk_90("clk_90"), clk_135("clk_135"),
    clk_180("clk_180"), clk_225("clk_225"), clk_270("clk_270"), clk_315("clk_315")
    {
      
      i_clock_gen.clk(clk);
      i_clock_gen.clk_45(clk_45);
      i_clock_gen.clk_90(clk_90);
      i_clock_gen.clk_135(clk_135);
      i_clock_gen.clk_180(clk_180);
      i_clock_gen.clk_225(clk_225);
      i_clock_gen.clk_270(clk_270);
      i_clock_gen.clk_315(clk_315);
      i_clock_gen.enable_clk(enable_clk);
     


    }


};




#endif
========================================================================================================================

Module 4 which is the pulse generator module looks line this -

========================================================================================================================

#ifndef M_PULSE_GEN_H
#define M_PULSE_GEN_H


#include "systemc.h"
///////////////////////////////////////////////////////////
//This module is the fractional pulse generator for the modulator
///////////////////////////////////////////////////////////




SC_MODULE(m_pulse_gen)
{
  sc_in <bool> clk, clk_45, clk_90, clk_135;
  sc_in <bool> clk_180, clk_225, clk_270, clk_315;
  sc_out<sc_uint<8> > pulse;




  
  SC_CTOR(m_pulse_gen)
    {
     
      SC_METHOD(module_main);
      sensitive << clk << clk_45 << clk_90 << clk_135;
      sensitive << clk_180 << clk_225 << clk_270 << clk_315;
      
    }
  
  void module_main(void);
  
};


#endif


void m_pulse_gen::module_main(void)
{


  //create a bus form the individual clock bits
  bool c_bus_bits[8];
  unsigned int c_bus;
  
  //create the pulse array
  bool frac_pulse[8];
  


  
  //this will create a bus that is a concatenation of all the 
  //clock phases...
  c_bus_bits[0] = clk;
  c_bus_bits[1] = clk_45;
  c_bus_bits[2] = clk_90;
  c_bus_bits[3] = clk_135;
  c_bus_bits[4] = clk_180;
  c_bus_bits[5] = clk_225;
  c_bus_bits[6] = clk_270;
  c_bus_bits[7] = clk_315;
  
  c_bus = 0;
  for(int ii=0; ii < 8; ii++){
    c_bus = c_bus | (c_bus_bits[ii] << ii);
  }
  
  cout << "Pulse gen activated at time "  
       << sc_time_stamp() 
       << " " 
       << c_bus_bits[0] 
       << c_bus_bits[1] 
       << c_bus_bits[2] 
       << c_bus_bits[3] 
       << c_bus_bits[4] 
       << c_bus_bits[5] 
       << c_bus_bits[6] 
       << c_bus_bits[7] 
       << endl;
  
  //create the individual phase pulses; these are summed to produce
  //the total pulse
  frac_pulse[0] = (c_bus == 0x87);
  frac_pulse[1] = (c_bus == 0xC3);
  frac_pulse[2] = (c_bus == 0xE1);
  frac_pulse[3] = (c_bus == 0xF0);
  frac_pulse[4] = (c_bus == 0x78);
  frac_pulse[5] = (c_bus == 0x3C);
  frac_pulse[6] = (c_bus == 0x1E);
  frac_pulse[7] = (c_bus == 0x0F);
  
  pulse.write(0);


  for(int ii=0; ii < 8; ii++){
    pulse.write(pulse.read() | (frac_pulse[ii] << ii));
  }
  
  
}

========================================================================================================================

 

When I run compile and run the simulation, only the test control module thread runs( m_test_control ) ( I traced this with gdb) and no other SC_THREADS or SC_METHODS from any other module gets called( or scheduled for execution.. The simulation ends when the thread from i_test_control exits... Can anyone help me figure out what's wrong with my code ???

 

Really appreciate the help !!! Raj

 

 

I have attached the tar ball for this code ...

Edited by rajatkmitra
Link to comment
Share on other sites

The main thing I notice is that in module 3, you have while(enable_clk.read());

At time zero enable_clk is false, so that while loop completes, and then the SC_THREAD never runs again as it has no infinite loop. Perhaps you need

void m_multi_phase_clock_gen::module_main(void)
{


  ////////////////////////////////////////////////////
  //Time 0 initialization !!!
  ////////////////////////////////////////////////////
  cout << "Clock Generator Initialized at time " << sc_time_stamp() << endl;
  clk.write(0);
  clk_45.write(0);
  clk_90.write(0);
  clk_135.write(0);
  clk_180.write(0);
  clk_225.write(0);
  clk_270.write(0);
  clk_315.write(0);
  
  wait(1.00, SC_NS);


  ////////////////////////////////////////////////////
  //Main Thread...
  ////////////////////////////////////////////////////
 while (true) {
  while(enable_clk.read()){
    
    //generate phase 0
    clk.write(!clk.read());
    wait(1.25, SC_NS);
    
    //generate phase 1
    clk_45.write(!clk_45.read());
    wait(1.25, SC_NS);
    
    //generate phase 2
    clk_90.write(!clk_90.read());      
    wait(1.25, SC_NS);
    
    //generate phase 3
    clk_135.write(!clk_135.read());
    wait(1.25, SC_NS);
    
    //generate phase 4
    clk_180.write(!clk_180.read());
    wait(1.25, SC_NS);
    
    //generate phase 5
    clk_225.write(!clk_225.read());
    wait(1.25, SC_NS);
    
    //generate phase 6
    clk_270.write(!clk_270.read());      
    wait(1.25, SC_NS);
    
    //generate phase 7
    clk_315.write(!clk_315.read());
    wait(1.25, SC_NS);
    
  }
  } // end while(true)
  
}

regards

Alan

Link to comment
Share on other sites

Hello Alan,

 That worked like a champ !!!! Thanks for the solution... so it seems like a template for writing an SC_THREAD process that is waiting on a signal is -

 

while(true) //infinite loop

 if(signal.read()){

  //do your thing

 }else{

  //do not lock up the simulator

  wait(1, SC_NS) //some very small amount of time 

 }

}

 

I guess this is what one would call a sampling thread...

 

Best,

Raj :)

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...