Jump to content

Out of bounds error. SystemC simulation with Modelsim


Recommended Posts

Posted

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

Posted

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()?

Posted

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.

Posted

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

Posted

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;	 
 }
  }

Posted

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

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...