Jump to content
ankitpatnaik

How to forward simulation time in SC_METHOD.

Recommended Posts

Good Day All,

I am a complete noob in SystemC. I am however, working on a simulator which utilizes a few concepts from SystemC. 
 

Kernel is picking up on either the Sc_Method or the Sc_Thread. I am aware of the wait command. It can only be used in the sc_thread. But in my code, (excerpt) I am currently using SC_thread and sc_method simultaneously. I wanted to introduce a delay in simulation time in the sc_thread (using the wait command). 

Is there a way to forward the simulation time in SC_METHOD that is analogous to wait() in SC_Thread. I did change one of the functions to SC_Thread, and the other to SC_Method. But, on simulation, if the kernel picks up on the SC_Method, it continues to stay in SC_Method and not go on to SC_thread.
 

 

Here is the code for SC_Method: (code for SC_THREAD is given after this code)

 

void NoximRouter::rxProcess_local()
{
  cout<<"rxProcess_local";
          // Clear outputs and indexes of transmitting protocol
            ResetTable();
            current_level_rx_local = 0;        
    } 
    else
    {//cout<<req_rx_local.read()<<" "<<current_level_rx_local<<endl;
        if((req_rx_local.read()== 1- current_level_rx_local) && !buffer_snd.IsFull())
        {
            //current_level_rx = 1 + current_level_rx;
            NoximPacket received_packet =  flit_rx_local.read();
           //cout<<"Inside NoximRouter::rxProcess_local:"<<received_packet<<endl;
            buffer_snd.Push(received_packet);
           // cout<<"receiver"<<endl;
            if (NoximGlobalParams::verbose_mode > VERBOSE_OFF)
            {
            cout << sc_time_stamp().to_double() /
       1000 << ": Router[" << local_id << "], Received packet from PE: " << received_packet << endl;
            }
            current_level_rx_local = 1 - current_level_rx_local;
         }
         ack_rx_local.write(current_level_rx_local);
 
THIS IS PART OF THE CODE FOR SC_THREAD:
 
void NoximRouter::txProcess_mode()
{
  cout<<"txProcess_mode";
     while( buffer_snd.Size()!=0) //Going with just one buffer(may be corresponding to the router,... but actually for the processing element)
      {
                        NoximPacket packet =  buffer_snd.Front();
                        NoximRouteData route_data;
                        route_data.current_id = local_id;
               route_data.src_id = packet.src_id;
               route_data.dst_id = packet.dst_id;
                        const vector < vector<int> > o = Route(route_data);
                        //stats.power.Arbitration(o.size());
                            int src= packet.src_id;
                            vector <int> path;
                            int col =0;
                  // checking in the global table the channels which are free and writhing to the respective channels  
                  path.push_back(src);
                packet.dir=checkdir(o);  
                if(checkmode1(path,o,src,col,packet)==1)
                  {
                    buffer_snd.Pop();
              
                   cout<<"Mode1\n";
                    packet.seq_no=path;
                    packet.mode_tx=1;
                    flit_tx.write(packet);
                    mode1_traffic++;
                  
                    stats.pkthist.push_back(makePacketHist(packet));
                    for(int i=0;i<path.size();i++)
                    {
                    
 

Share this post


Link to post
Share on other sites

You can use next_trigger() in an SC_METHOD to modify the sensitivity of the following call to the SC_METHOD. The details of next_trigger() are in the LRM.

 

It's important to realise that next_trigger() is non-blocking. The SC_METHOD will still run to the end and return, but the sensitivity of the immediately following invocation is modified by the last call to next_trigger() in the function,

 

regards

Alan

Share this post


Link to post
Share on other sites

Hi,

 

I am not sure if the exerpt of your code is incomplete or if it is missing in your design, but teh SC_THREAD requires an infinite loop.

 

SC_METHOD:

The according function (argument of SC_METHOD macro) is called whenever an event from the sensitivity list is triggered. Then it runs to completion (until the function call returns). With next_trigger, you are able to change sensitivity dynamically. You can use next_trigger with a time argument as well. This results in sensitivity to an 'imaginary event' that is triggered automatically when the time has passed. Time advances in between two triggers. Assume an event at 2 ns and an event at 4 ns, then, the method will run at 2 ns once and at 4 ns a second time.

 

SC_©THREAD:

The according function is called only once and should contain an infinite loop and at least one wait statement. When the function completes (function call returns), this thread is dead and will not wake up anymore (only exception for this is 'reset').

The function runs to the first wait statement and returns controll to the simulation kernel, but the function does not complete actually. When an event this thread is sensitive to is triggered, the execution of the thread continues from that wait statement to the next wait statement.

 

Hope this helps a bit.

 

Greetings

Ralph

Share this post


Link to post
Share on other sites

Allan and Ralph,

First off, thank you both for such a swift response. I will definitely look into the next_trigger() option. I hadn't considered it earlier. 

Also, Ralph, the code is incomplete. I didnt want to copy paste the entire thread since i thought it would be quite cumbersome to go through every bit. I have used the wait () option a few times, and also used the infinite loop for SC_thread.

Entire code for SC_Thread:
 

void NoximRouter::txProcess_mode()
{
     while( buffer_snd.Size()!=0) //Going with just one buffer(may be corresponding to the router,... but actually for the processing element)
      {
                        NoximPacket packet =  buffer_snd.Front();
                        NoximRouteData route_data;
                        route_data.current_id = local_id;
               route_data.src_id = packet.src_id;
               route_data.dst_id = packet.dst_id;
                        const vector < vector<int> > o = Route(route_data);
                        //stats.power.Arbitration(o.size());
                            int src= packet.src_id;
                            vector <int> path;
                            int col =0;
                  // checking in the global table the channels which are free and writhing to the respective channels  
                  path.push_back(src);
                packet.dir=checkdir(o);  
                if(checkmode1(path,o,src,col,packet)==1)
                  {
                    buffer_snd.Pop();
              
                   cout<<"Mode1\n";
                    packet.seq_no=path;
                    packet.mode_tx=1;
                    flit_tx.write(packet);
                    mode1_traffic++;
                  
                    stats.pkthist.push_back(makePacketHist(packet));
                    for(int i=0;i<path.size();i++)
                    {
                    
                    MappingTable[path].channel_status_neighbor.available =0; // for all tiles from source to destination.finally udates when all the tiles are full.
           }
 
                wait (1, SC_NS);
              }
                else if(checkmode2(path,o,src,col,packet)==1)
                  {
                  buffer_snd.Pop(); 
                   
                    //cout<<"Mode2\n";
                    packet.seq_no=path;
                    packet.mode_tx=2;
                    flit_tx_1.write(packet);
                    mode2_traffic++;
                    //cout <<"In Mode 2"<<endl;
                    stats.pkthist.push_back(makePacketHist(packet));
                    for(int i=0;i<path.size();i++)
                    {
                      MappingTable[path].channel_status_neighbor_1.available =0;
                    }
                    wait (1, SC_NS);
                  }
                  else if (checkmode3(path,o,src,col,packet)==1)
                  {
                  buffer_snd.Pop();
                    
                    //cout<<"Mode3\n";
                    packet.seq_no=path;
                    packet.mode_tx=3;
                    flit_tx_2.write(packet);
                    mode3_traffic++;
                    // cout <<"In Mode 3"<<endl;
                    stats.pkthist.push_back(makePacketHist(packet));
                    for(int i=0;i<path.size();i++)
                    {
                    MappingTable[path].channel_status_neighbor_2.available =0;
                    }
                    
                    wait (1, SC_NS);
             }
 
                      else if (checkmode4(path,o,src,col,packet)==1)
                  {
                  buffer_snd.Pop();
                    checkdir(o);  
                    //cout<<"Mode4\n";
                    packet.seq_no=path;
                    packet.mode_tx=4;
                    flit_tx_3.write(packet);
                    mode4_traffic++;
                    // cout <<"In Mode 4"<<endl;
                    stats.pkthist.push_back(makePacketHist(packet));  //making stat packet
                    for(int i=0;i<path.size();i++)
 
                    { 
                    MappingTable[path].channel_status_neighbor_3.available =0;
                       }
 
                wait (1, SC_NS);
 
                        
                  }// end of if
 
                  SC_THREAD(txProcess_mode);
 
         }void NoximRouter::txProcess_mode()
{
     while( buffer_snd.Size()!=0) //Going with just one buffer(may be corresponding to the router,... but actually for the processing element)
      {
                        NoximPacket packet =  buffer_snd.Front();
                        NoximRouteData route_data;
                        route_data.current_id = local_id;
               route_data.src_id = packet.src_id;
               route_data.dst_id = packet.dst_id;
                        const vector < vector<int> > o = Route(route_data);
                        //stats.power.Arbitration(o.size());
                            int src= packet.src_id;
                            vector <int> path;
                            int col =0;
                  // checking in the global table the channels which are free and writhing to the respective channels  
                  path.push_back(src);
                packet.dir=checkdir(o);  
                if(checkmode1(path,o,src,col,packet)==1)
                  {
                    buffer_snd.Pop();
              
                   cout<<"Mode1\n";
                    packet.seq_no=path;
                    packet.mode_tx=1;
                    flit_tx.write(packet);
                    mode1_traffic++;
                  
                    stats.pkthist.push_back(makePacketHist(packet));
                    for(int i=0;i<path.size();i++)
                    {
                    
                    MappingTable[path].channel_status_neighbor.available =0; // for all tiles from source to destination.finally udates when all the tiles are full.
           }
 
                wait (1, SC_NS);
              }
                else if(checkmode2(path,o,src,col,packet)==1)
                  {
                  buffer_snd.Pop(); 
                   
                    //cout<<"Mode2\n";
                    packet.seq_no=path;
                    packet.mode_tx=2;
                    flit_tx_1.write(packet);
                    mode2_traffic++;
                    //cout <<"In Mode 2"<<endl;
                    stats.pkthist.push_back(makePacketHist(packet));
                    for(int i=0;i<path.size();i++)
                    {
                      MappingTable[path].channel_status_neighbor_1.available =0;
                    }
                    wait (1, SC_NS);
                  }
                  else if (checkmode3(path,o,src,col,packet)==1)
                  {
                  buffer_snd.Pop();
                    
                    //cout<<"Mode3\n";
                    packet.seq_no=path;
                    packet.mode_tx=3;
                    flit_tx_2.write(packet);
                    mode3_traffic++;
                    // cout <<"In Mode 3"<<endl;
                    stats.pkthist.push_back(makePacketHist(packet));
                    for(int i=0;i<path.size();i++)
                    {
                    MappingTable[path].channel_status_neighbor_2.available =0;
                    }
                    
                    wait (1, SC_NS);
             }
 
                      else if (checkmode4(path,o,src,col,packet)==1)
                  {
                  buffer_snd.Pop();
                    checkdir(o);  
                    //cout<<"Mode4\n";
                    packet.seq_no=path;
                    packet.mode_tx=4;
                    flit_tx_3.write(packet);
                    mode4_traffic++;
                    // cout <<"In Mode 4"<<endl;
                    stats.pkthist.push_back(makePacketHist(packet));  //making stat packet
                    for(int i=0;i<path.size();i++)
 
                    { 
                    MappingTable[path].channel_status_neighbor_3.available =0;
                       }
 
                wait (1, SC_NS);
 
                        
                  }// end of if
 
                  SC_THREAD(txProcess_mode);
 
         }

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×