Jump to content
wsch

Out of bounds error. SystemC simulation with Modelsim

Recommended Posts

Hi

When I simulate my SystemC project in Modelsim I get this error:

Error: (vsim-6596) Out of bounds:
# In process: sc_main/hermes_2d/thread_p_2 @ 872800 ns
# ** Fatal: Fatal SystemC error detected, exiting...

From what I could ascertain according to the results collected, the logic is correct.

Heres is the code:

for(int i = 0; i < 16; ++i)
{
         sc_spawn(sc_bind(&hermes_with_pkt_codec_vhd_bfm::sender, this, i));
	  sc_spawn(sc_bind(&hermes_with_pkt_codec_vhd_bfm::receiver, this, i));
}





void receiver(unsigned int agent)
{
	 wait(reset);  sc_core::sc_lv<16> tx_re_s;
        sctg::BufferInterface* buffer = _confIf->getBufferIf(agent);
	 tgPacket* packet = 0;

 if(!buffer)
 {return;}  
 while(true)
 {

           sc_core::wait(clk_ip->posedge_event());
		packet = new tgPacket;

		do { sc_core::wait(clk_ip->posedge_event()); }
           while(tx_av.read()[agent] == sc_dt::SC_LOGIC_0);  

           packet->address = tx_data.read().range((agent+1)*32-1, agent*32).to_ulong();

		do { sc_core::wait(clk_ip->posedge_event()); }
          while(tx_av.read()[agent] == sc_dt::SC_LOGIC_1);		  

           unsigned int tam	=  tx_data.read().range((agent+1)*32-1, agent*32).to_uint();



		for(unsigned int i = 0; i < tam; i++)
		{  
			   do { sc_core::wait(clk_ip->posedge_event()); }
                  while(tx_free.read()[agent] == sc_dt::SC_LOGIC_0);  



			   packet->data = new unsigned char[sizeof(unsigned int)];
                  unsigned int data = tx_data.read().range((agent+1)*32-1, agent*32).to_uint();
                   *reinterpret_cast<unsigned int*>(packet->data) = data;

                 packet->size += 32/8;

			   do { sc_core::wait(clk_ip->posedge_event()); }
                 while(tx_free.read()[agent] == sc_dt::SC_LOGIC_1);

          }

           // Wait until packet fits to agent's buffer
           while(buffer->rxSpaceLeft() < packet->size)
           {
                   wait(*(buffer->rxGetReadEvent()));
            }

          buffer->rxPutPacket(packet);
          packet = 0;
          sc_core::wait(clk_ip->posedge_event());
     }
}

Thanks

Share this post


Link to post
Share on other sites

Who knows?

You need a stack backtrace to narrow down the location of the error.

regards

Alan

P.S. One thing looks odd - why is packet->address assigned using to_ulong(), and tam assigned using to_uint()?

Share this post


Link to post
Share on other sites

There are two issues that need to be tackled.

1. You are using sc_spawn == please ensure

that you use sc_join to force the simulator to

take care of dynamic threads after they have

completed their task. This is very important,

because otherwise threads get spawned, eat

up memory and then a crash.

2. Correct interfacing with ModelSim

Since it appears that you are trying to model

packets being read in/out (some network

device) why not stick to static threads only.

All buffers on all network devices(e.g., router)

have finite fixed memory and no matter what

algorithm one uses, the final constraint is

physical memory.

Share this post


Link to post
Share on other sites

Who knows?

You need a stack backtrace to narrow down the location of the error.

I agree with Alan here. Moreover, when you look at the backtrace, you'll most probably see that the problem is within the sender part:

Error: (vsim-6596) Out of bounds:
# In process: sc_main/hermes_2d/thread_p_2 @ 872800 ns
# ** Fatal: Fatal SystemC error detected, exiting...

The name thread_p_2 refers to the third dynamically created process in this module. Based on your loop above, this would be the second sender process. You didn't show the body of the sender.

That said, it is always a good idea to add explicit names to the design elements you create. Something like:

sc_spawn( sc_bind(&hermes_with_pkt_codec_vhd_bfm::sender, this, i), sc_core::sc_gen_unique_name("sender") );

Greetings from Oldenburg,

Philipp

Share this post


Link to post
Share on other sites

Hi

Here is the body of sender

void sender(unsigned int agent)
  {  
 wait(reset);
 sctg::BufferInterface* buffer = _confIf->getBufferIf(agent);
 if(!buffer)
 {return;}
 tgPacket* packet = 0;
 sc_core::sc_lv<16>  rx_av_s; 
 sc_core::sc_lv<16*32> rx_data_s;
	 sc_core::sc_lv<16>  rx_tx_len_s;
 sc_core::sc_lv<16> rx_we_s;
 while(true)
 {
 // Wait for packets to send
 if(!buffer->txPacketAvailable())
 {
    sc_core::wait(*(buffer->txGetPacketAvailableEvent()));
 }
 // Read packet from buffer
 packet = buffer->txGetPacket();		
 sc_core::wait(clk_ip->posedge_event());
	    //RX_AV = 1
 // Send address - set address valid
 rx_av_s = rx_av.get_new_value();
 rx_av_s[agent] = sc_dt::SC_LOGIC_1;
 rx_av = rx_av_s;		 

 // Put first data (is address) to bus //ENDEREƇO DO PE DESTINO
 rx_data_s = rx_data.get_new_value();
 rx_data_s.range((agent+1)*32-1, agent*32)
    = addr_gen(agent, packet->address);	
 rx_data = rx_data_s;		  
 // Set transfer length
 rx_tx_len_s = rx_tx_len.get_new_value();
 rx_tx_len_s.range((agent+1)*16-1, agent*16)
    = sc_dt::sc_uint<16>(packet->size/4);
 rx_tx_len = rx_tx_len_s;  
	    // Set write enable
 rx_we_s = rx_we.get_new_value();
 rx_we_s[agent] = sc_dt::SC_LOGIC_1;
 rx_we = rx_we_s;
 // Wait until NoC is ready to read
	    do { sc_core::wait(clk_ip->posedge_event()); }
 while(rx_full.read()[agent] == sc_dt::SC_LOGIC_1);
 // Negate address valid
 rx_av_s = rx_av.get_new_value();
 rx_av_s[agent] = sc_dt::SC_LOGIC_0;
 rx_av = rx_av_s;
 // Send data 
 for(unsigned int i = 0; i < packet->size/4; ++i)
 {
    // Set data to line
    rx_data_s = rx_data.get_new_value();
    if(i == 0)
    {
   // Send first byte actually, fill rest with dummy data
   rx_data_s.range((agent+1)*32-1, agent*32)
   = sc_dt::sc_uint<32>
   (*reinterpret_cast<int*>(packet->data)); //data_width_g = 4 bytes ou 32 bits
 // printf("\nDATA1:	    %d", (*reinterpret_cast<int*>(packet->data)));
    }
    else
    {
   rx_data_s.range((agent+1)*32-1, agent*32)
   = sc_dt::sc_uint<32>(agent);  //data_width_g = 4 bytes ou 32 bits
   //   printf("\nDATA2:	    %d", agent);

    }
		   //RX_DATA = DADOS
    rx_data = rx_data_s;
    // Wait clock cycle or more if NoC can't read it
    do { sc_core::wait(clk_ip->posedge_event()); }
    while(rx_full.read()[agent] == sc_dt::SC_LOGIC_1);
 }
	    //RX_WE = 0
 // Negate write enable
 rx_we_s = rx_we.get_new_value();
 rx_we_s[agent] = sc_dt::SC_LOGIC_0;
 rx_we = rx_we_s;
	    //RX_DATA = 0
 // Set data bus to zero (not necessary, for easier debugging in sim)
 rx_data_s = rx_data.get_new_value();
 rx_data_s.range((agent+1)*32-1, agent*32)
    = sc_dt::sc_uint<32>(0);
 rx_data = rx_data_s;
	    //RX_TX_LEN = 0 
 // Set tx len lines to zeros (not necessary)
 rx_tx_len_s = rx_tx_len.get_new_value();
 rx_tx_len_s.range((agent+1)*16-1, agent*16)
    = sc_dt::sc_uint<16>(0);
 rx_tx_len = rx_tx_len_s;
	    // Delete packet
 delete [] packet->data;
 delete packet; packet = 0;	 
 }
  }

Share this post


Link to post
Share on other sites

Thanks all!!!

I find out

Philipp is right, the problem was in sender function

I was using

    sc_core::sc_lv<16>  rx_tx_len_s;

instead

 sc_core::sc_lv<16*16>  rx_tx_len_s;

Best Regards

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

×