Пример #1
0
void init()
{
	// Init core enumerations
	me.coreID  = e_get_coreid();
	e_coords_from_coreid(me.coreID, &me.row, &me.col);
	me.row     = me.row - E_FIRST_CORE_ROW;
	me.col     = me.col - E_FIRST_CORE_COL;
	me.corenum = me.row * E_COLS_IN_CHIP + me.col;
	me.coreIDh = me.coreID;
	e_neighbor_id((e_coreid_t *) &me.coreIDh, E_PREV_CORE, E_ROW_WRAP);
	me.coreIDv = me.coreID;
	e_neighbor_id((e_coreid_t *) &me.coreIDv, E_PREV_CORE, E_COL_WRAP);
	me.coreIDn = me.coreID;
	e_neighbor_id((e_coreid_t *) &me.coreIDn, E_NEXT_CORE, E_CHIP_WRAP);

	// Initialize the mailbox shared buffer pointers
	Mailbox.pBase = (void *) SHARED_DRAM;
	Mailbox.pA    = Mailbox.pBase + offsetof(shared_buf_t, A[0]);
	Mailbox.pB    = Mailbox.pBase + offsetof(shared_buf_t, B[0]);
	Mailbox.pC    = Mailbox.pBase + offsetof(shared_buf_t, C[0]);
	Mailbox.pCore = Mailbox.pBase + offsetof(shared_buf_t, core);

	// Initialize per-core parameters - core data structure
	
	// Initialize pointers to the operand matrices ping-pong arrays
	me.bank[_BankA][_PING] = (void *) &(AA[0][0][0]);
	me.bank[_BankA][_PONG] = (void *) &(AA[1][0][0]);
	me.bank[_BankB][_PING] = (void *) &(BB[0][0][0]);
	me.bank[_BankB][_PONG] = (void *) &(BB[1][0][0]);
	me.bank[_BankC][_PING] = (void *) &(CC   [0][0]);

	// Initialize the pointer addresses of the arrays in the horizontal and vertical target
	// cores, where the submatrices data will be swapped, and the inter-core sync signals.
	me.tgt_bk[_BankA][_PING] = _gptr(me.coreIDh, me.bank[_BankA][_PONG]);
	me.tgt_bk[_BankA][_PONG] = _gptr(me.coreIDh, me.bank[_BankA][_PING]);
	me.tgt_synch             = _gptr(me.coreIDh, (&(me.synch)));
	
	me.tgt_bk[_BankB][_PING] = _gptr(me.coreIDv, me.bank[_BankB][_PONG]);
	me.tgt_bk[_BankB][_PONG] = _gptr(me.coreIDv, me.bank[_BankB][_PING]);
	me.tgt_syncv             = _gptr(me.coreIDv, (&(me.syncv)));

	me.tgt_go_sync  = _gptr(me.coreIDn, (&(me.go_sync)));
	me.tgt_dma_sync = _gptr(me.coreIDn, (&(me.dma_sync)));

	me.pingpong = _PING;

	// Clear the inter-core sync signals
	me.synch = 0;
	me.syncv = 0;
	me.go_sync = 0;
	me.dma_sync = (me.corenum == 0) ? 1 : 0;
	// Init the host-accelerator sync signals
	Mailbox.pCore->go[me.corenum] = 0;
	if (me.corenum == 0)
		Mailbox.pCore->ready = 1;
	
	me.count = 0;

	return;
}
Пример #2
0
void init()
{
	// Init core enumerations
	me.coreID  = e_get_coreid();
	e_coords_from_coreid(me.coreID, &me.row, &me.col);
	me.row     = me.row - E_FIRST_CORE_ROW;
	me.col     = me.col - E_FIRST_CORE_COL;
	me.corenum = me.row * E_COLS_IN_CHIP + me.col;
	me.coreIDn = me.coreID;
	e_neighbor_id((e_coreid_t *) &me.coreIDn, E_NEXT_CORE, E_CHIP_WRAP);

	// Initialize the mailbox shared buffer pointers
	Mailbox.pBase = (void *)  MAILBOX_ADDRESS;
	Mailbox.pGo = Mailbox.pBase + offsetof(mbox_t, go[0]);
	Mailbox.pReady = Mailbox.pBase + offsetof(mbox_t, ready[0]);
	Mailbox.pClocks = Mailbox.pBase + offsetof(mbox_t, clocks);

#if 0
	Mailbox.pOutputBuffer = Mailbox.pBase + offsetof(mbox_t, output_buffer[0]);
	Mailbox.pOutputReady = Mailbox.pBase + offsetof(mbox_t, output_ready);
#endif

	Mailbox.pTimer0 = Mailbox.pBase + offsetof(mbox_t, timer0);
	Mailbox.pTimer1 = Mailbox.pBase + offsetof(mbox_t, timer1);

	// Init the ports
	init_input_port(&X);

	// Set the port pointer, the address must be global
	scale.X = (me.coreID << 20) | (int) &X;

#ifdef FULL
	init_output_port(&Y);
	scale.Y = (me.coreID << 20) | (int) &Y;
#endif

	scale.coreID = me.coreID;

	// Set the global actor pointer(don't forget to use global address)
	actors.scale = (me.coreID << 20) | (int) &scale;
	

	me.count = 0;

	// Coefficients
	W0[0] = 2048;	W0[1] = 2676;	W0[2] = 2841;	W0[3] = 1609;
	
	W1[0] = 2048;	W1[1] = 1108;	W1[2] = 565;	W1[3] = 2408;

	ww0 = W0[0];
	ww1 = 2048;

	index0 = 0;

	// Init the host-accelerator sync signals
	Mailbox.pReady[me.corenum] = &me.mystate;
	
	return;
}
int main(void)
{
	unsigned mesh_reg;
	unsigned mesh_reg_modify;
	unsigned time_c, time_p;
	unsigned time;
	unsigned tran,k,i,j,h,m,n,q;
	unsigned *mailbox, *mode;
	unsigned *commander;
	unsigned *counter;
	unsigned *master, *slave, *p;
	unsigned *row, *col;
	unsigned *n_row, *n_col;
	unsigned *neighbour0, *neighbour1, *neighbour2, *neighbour3;
	
	row = (unsigned *)0x5000;
	col = (unsigned *)0x5004;
	n_row = (unsigned *)0x5008;
	n_col = (unsigned *)0x500c;
	master = (unsigned *)0x2000;
	p =(unsigned *) 0x2000;
	slave = (unsigned *) e_get_global_address(*row, *col, p);
	commander = (unsigned *)0x5100;
	p = (unsigned *) 0x5300;
	counter = (unsigned *) e_get_global_address(*row, *col, p);
	mailbox = (unsigned *)0x6000;
	mode = (unsigned *)0x5400;
	tran = 2048;
	
	// Core number 
	k = (e_group_config.core_row)*e_group_config.group_cols + (e_group_config.core_col);
	
	// Broadcast to all the other neighbours
	p = (unsigned *)0x5100;
	e_neighbor_id(E_PREV_CORE, E_ROW_WRAP, n_row, n_col);
	neighbour0 = (unsigned *) e_get_global_address(*n_row, *n_col, p) ;
	
	e_neighbor_id(E_NEXT_CORE, E_ROW_WRAP, n_row, n_col);
	neighbour1 = (unsigned *) e_get_global_address(*n_row, *n_col, p) ;
	
	e_neighbor_id(E_PREV_CORE, E_COL_WRAP, n_row, n_col);
	neighbour2 = (unsigned *) e_get_global_address(*n_row, *n_col, p) ;
	
	e_neighbor_id(E_NEXT_CORE, E_COL_WRAP, n_row, n_col);
	neighbour3 = (unsigned *) e_get_global_address(*n_row, *n_col, p) ;
	
	// Initialize master and slave
	for(i=0; i<tran; i++)
	{
		master[i] = 0xdeadbee9;
		slave[i] = 0x00000000;
	}
	
	while(1)
	{
		//Clear the mode box
		mode[0] = 0xdeadbeef;	

		// Clear the start commander 
		commander[0] = 0x00000000;
		
		// Wait for the mesh event
		while(mode[0] == 0xdeadbeef)
		{};
		
		q = mode[0];
		mesh_reg = e_reg_read(E_REG_MESH_CONFIG);
		mesh_reg_modify = mesh_reg & 0xffffff0f;
		mesh_reg_modify = mesh_reg_modify |mesh_type[1][q]; 
		e_reg_write(E_REG_MESH_CONFIG, mesh_reg_modify);
		
		// Set the ctimer
		e_ctimer_set(E_CTIMER_0, E_CTIMER_MAX) ;		
		
		// Waiting for the signal to start transfering
		while(commander[0] != 0xdeadbeef)
		{};
		
		// Start the ctimer and select the time type
		time_p = e_ctimer_start(E_CTIMER_0, E_CTIMER_MESH_0);
	
		// Broadcast to all the other neighbours
		neighbour0[0] = 0xdeadbeef;
		neighbour1[0] = 0xdeadbeef;
		neighbour2[0] = 0xdeadbeef;
		neighbour3[0] = 0xdeadbeef;
		
		e_dma_copy(slave, master, 0x2000);	
		
		// Wait for transfer finishing
		while(slave[2047] != 0xdeadbee9 )
		{};
		counter[k] = 1;
	
		// Get the time now
		time_c = e_ctimer_get(E_CTIMER_0);
	
		time = time_p - time_c;		
		
		// Output the result
		mailbox[q] = time;
		
		// Load the original value of E_REG_MESH_CONFIG
		e_reg_write(E_REG_MESH_CONFIG, mesh_reg);
	
		// Check if all the mesh events have been through
		if(q == 12)
		{
			break;
		}
	}
	return 0;
}
Пример #4
0
int main(void)
{
	unsigned time_c, time_p;
	unsigned time;
	unsigned i,j,q,h,m,n,k;
	unsigned *commander;
	unsigned *counter;
	unsigned *mailbox;
	unsigned *n_row, *n_col;
	unsigned *neighbour0, *neighbour1, *neighbour2, *neighbour3, *p;
	
	commander = (unsigned *)0x6100;
	counter = (unsigned *)0x6300;
	mailbox = (unsigned *)0x5000;
	n_row = (unsigned *)0x5100;
	n_col = (unsigned *)0x5200;
	p = (unsigned *)0x6100;
	
	// Broadcast to all neighbours
	e_neighbor_id(E_PREV_CORE, E_ROW_WRAP, n_row, n_col);
	neighbour0 = (unsigned *) e_get_global_address(*n_row, *n_col, p) ;
	
	e_neighbor_id(E_NEXT_CORE, E_ROW_WRAP, n_row, n_col);
	neighbour1 = (unsigned *) e_get_global_address(*n_row, *n_col, p) ;
	
	e_neighbor_id(E_PREV_CORE, E_COL_WRAP, n_row, n_col);
	neighbour2 = (unsigned *) e_get_global_address(*n_row, *n_col, p) ;
	
	e_neighbor_id(E_NEXT_CORE, E_COL_WRAP, n_row, n_col);
	neighbour3 = (unsigned *) e_get_global_address(*n_row, *n_col, p) ;
	
	// Get core information
	k = e_group_config.core_row * e_group_config.group_cols + e_group_config.core_col;
	
	// Clear the counter of finishing transfering
	for(i=0; i<(e_group_config.group_rows*e_group_config.group_cols); i++)
	{
		counter[i] = 0;
	}
	
	// Initialize the commander and counter for the specific core
	counter[k] = 1;
	commander[0] = 0x00000000;
	
	
	// Set the ctimer
	e_ctimer_set(E_CTIMER_0, E_CTIMER_MAX) ;
			
	// Waiting for the signal of starting transfering
	while(commander[0] != (unsigned)0xdeadbeef)
	{};
	
	// Broadcast the signal to neighbours
	neighbour0[0] = 0xdeadbeef;
	neighbour1[0] = 0xdeadbeef;
	neighbour2[0] = 0xdeadbeef;
	neighbour3[0] = 0xdeadbeef;
	
	// Start the ctimer and select the time type
	time_p = e_ctimer_start(E_CTIMER_0, E_CTIMER_CLK);
	
	while(1)
	{
		if((counter[0]&counter[1]&counter[2]&counter[3]&counter[4]&counter[5]
		   &counter[6]&counter[7]&counter[8]&counter[9]&counter[10]&counter[11]
		   &counter[12]&counter[13]&counter[14]&counter[15]) != 0)
		{
			time_c = e_ctimer_get(E_CTIMER_0);
			break;
		}	
	}
	
	time = time_p - time_c;	
	mailbox[0] = time;
	
	return 0;
}
Пример #5
0
int main(void)
{
	unsigned time_c, time_p;
	unsigned time;
	unsigned tran,k,i,j,q,h,m,n;
	unsigned *commander;
	unsigned *n_row, *n_col, *p, *nei_row, *nei_col;
	unsigned *neighbour, *neighbour0;
	unsigned *master;
	unsigned *counter;
	
	// Define the mailbox
	master = (unsigned *)0x2000;
	n_row = (unsigned *)0x6000;
	n_col = (unsigned *)0x6004;
	neighbour0 = (unsigned *)0x6008;
	nei_row = (unsigned *) 0x600c;
	nei_col = (unsigned *) 0x6010;
	p =(unsigned *) 0x2000;
	commander = (unsigned *)0x6100;
	counter = (unsigned *)0x80806300;
	tran = 2048;
	
	// Get the neighbour global address
	e_neighbor_id(E_PREV_CORE, E_ROW_WRAP, n_row, n_col);
	neighbour = (unsigned *) e_get_global_address(*n_row, *n_col, p) ;
	k = (*n_row)*e_group_config.group_cols + (*n_col);
	
	commander[0] = 0x00000000;
	
	// Broadcast to the next core
	p = (unsigned *)0x6100;
	e_neighbor_id(E_NEXT_CORE, E_COL_WRAP, nei_row, nei_col);
	neighbour0 = (unsigned *) e_get_global_address(*nei_row, *nei_col, p) ;
	
	// Initialize master and slave
	for(i=0; i<tran; i++)
	{
		master[i] = 0xdeadbee1;
		neighbour[i] = 0x00000000;
	}
			
	// Waiting for the signal to start transfering
	while(commander[0] != (unsigned) 0xdeadbeef)
	{};
	
	// Broadcast the signal to neighbour
	neighbour0[0] = 0xdeadbeef;
	
	// Write to all neighbour cores
	e_dma_copy(neighbour, master, 0x2000);	
	
	while(1)
	{
		if(neighbour[2047] == 0xdeadbee1)
		{
			counter[e_group_config.core_row * (e_group_config.group_cols/2) + e_group_config.core_col] = 1;
			break;
		}
	}
		
	return 0;
}
Пример #6
0
int main(void)
{
	unsigned k,i,j;
	e_dma_desc_t dma_desc[4];
	unsigned *dst, *src, *dst1, *src1, *dst2, *src2;
	unsigned tran;
	unsigned tran1;
	unsigned index[3];
	unsigned neighbour_core;
	unsigned *n_row, *n_col, *p;
	unsigned *mailbox, *mailbox1, *mailbox2, *mailbox3;
	n_row = (unsigned *)0x00006400;
	n_col = (unsigned *)0x00006404;
	tran = 128;
	p = 0x0000;
	
	// Get the core id of neighbour core
	e_neighbor_id(E_NEXT_CORE, E_ROW_WRAP, n_row, n_col);

	neighbour_core = (unsigned) e_get_global_address(*n_row, *n_col, p);

	// Define the mailbox
	mailbox = (unsigned *)0x6000;
	mailbox1 = (unsigned *)0x6100;
	mailbox2 = (unsigned *)0x6200;
	mailbox3 = (unsigned *)0x6300;

	// Initialize the buffer address for dma chain test
	src = (int *)0x2000;
	dst = (int *)(neighbour_core + (unsigned)0x2000);
	src1 = (int *)0x2300;
	dst1 = (int *)(neighbour_core + (unsigned)0x2500);
	src2 = (int *)0x2600;
	dst2 = (int *)(neighbour_core + (unsigned)0x2a00);

	// Test for word size
 	// Initialize the source and destination buffer
	for (i=0; i<tran; i++)
	{ 
		src[i]  = 0xaaaaaaaa;
		src1[i] = 0xbbbbbbbb;
		src2[i] = 0xcccccccc;
	}

	for (i=0; i<tran*6; i++)
	{
		dst[i] = 0x00000000;
	}
	

	// Prepare for the descriptor for 2d dma 
	
	e_dma_set_desc(E_DMA_0,(E_DMA_ENABLE|E_DMA_MASTER|E_DMA_WORD), 0x0000,
	0x0004, 0x0004,
	0x0080, 0x0003,
	0x0104 , 0x0304,
	(void *)src,(void *)dst, &dma_desc[0]);
	
	// Start transaction
	e_dma_start(&dma_desc[0], E_DMA_0);
	
	// Wait
	e_dma_wait(E_DMA_0);		
	
	// Check the destination buffer value
	index[0] = checkbuffer(dst,  (unsigned)0xaaaaaaaa, tran);
	index[1] = checkbuffer(dst1, (unsigned)0xbbbbbbbb, tran);
	index[2] = checkbuffer(dst2, (unsigned)0xcccccccc, tran);

	if((index[0]|index[1]|index[2]) == 0)
	{
		mailbox[0] = 0xffffffff;
	}else
	{
		mailbox[0] = 0x00000000;
	}

	// Test for doubleword size
 	// Initialize the source and destination buffer
	for (i=0; i<tran; i++)
	{ 
		src[i]  = 0xaaaaaaaa;
		src1[i] = 0xbbbbbbbb;
		src2[i] = 0xcccccccc;
	}

	for (i=0; i<tran*6; i++)
	{
		dst[i] = 0x00000000;
	}
	
	

	// Prepare for the descriptor for 2d dma 
	
	e_dma_set_desc(E_DMA_0,(E_DMA_ENABLE|E_DMA_MASTER|E_DMA_DWORD), 0x0000,
	0x0008, 0x0008,
	0x0040, 0x0003,
	0x0108 , 0x0308,
	(void *)src,(void *)dst, &dma_desc[0]);
	
	// Start transaction
	e_dma_start(&dma_desc[0], E_DMA_0);
	
	// Wait 
	e_dma_wait(E_DMA_0);	

	// Check the destination buffer value
	index[0] = checkbuffer(dst,  (unsigned)0xaaaaaaaa, tran);
	index[1] = checkbuffer(dst1, (unsigned)0xbbbbbbbb, tran);
	index[2] = checkbuffer(dst2, (unsigned)0xcccccccc, tran);

	if((index[0]|index[1]|index[2]) == 0)
	{
		mailbox1[0] = 0xffffffff;
	}else
	{
		mailbox1[0] = 0x00000000;
	}

	// Test for half size
 	// Initialize the source and destination buffer
	for (i=0; i<tran; i++)
	{ 
		src[i]  = 0xaaaaaaaa;
		src1[i] = 0xbbbbbbbb;
		src2[i] = 0xcccccccc;
	}

	for (i=0; i<tran*6; i++)
	{
		dst[i] = 0x00000000;
	}
	
	

	// Prepare for the descriptor for 2d dma 
	
	e_dma_set_desc(E_DMA_0,(E_DMA_ENABLE|E_DMA_MASTER|E_DMA_HWORD), 0x0000,
	0x0002, 0x0002,
	0x0100, 0x0003,
	0x0102 , 0x0302,
	(void *)src,(void *)dst, &dma_desc[0]);
	
	// Start transaction
	e_dma_start(&dma_desc[0], E_DMA_0);
	
	// Wait 
	e_dma_wait(E_DMA_0);		

	// Check the destination buffer value
	index[0] = checkbuffer(dst,  (unsigned)0xaaaaaaaa, tran);
	index[1] = checkbuffer(dst1, (unsigned)0xbbbbbbbb, tran);
	index[2] = checkbuffer(dst2, (unsigned)0xcccccccc, tran);

	if((index[0]|index[1]|index[2]) == 0)
	{
		mailbox2[0] = 0xffffffff;
	}else
	{
		mailbox2[0] = 0x00000000;
	}

	// Test for byte size
 	// Initialize the source and destination buffer
	for (i=0; i<tran; i++)
	{ 
		src[i]  = 0xaaaaaaaa;
		src1[i] = 0xbbbbbbbb;
		src2[i] = 0xcccccccc;
	}

	for (i=0; i<tran*6; i++)
	{
		dst[i] = 0x00000000;
	}
	

	// Prepare for the descriptor for 2d dma 
	
	e_dma_set_desc(E_DMA_0,(E_DMA_ENABLE|E_DMA_MASTER|E_DMA_BYTE), 0x0000,
	0x0001, 0x0001,
	0x0200, 0x0003,
	0x0101 , 0x0301,
	(void *)src,(void *)dst, &dma_desc[0]);
	
	// Start transaction
	e_dma_start(&dma_desc[0], E_DMA_0);
	
	// Wait 
	e_dma_wait(E_DMA_0);	
	
	// Check the destination buffer value
	index[0] = checkbuffer(dst,  (unsigned)0xaaaaaaaa, tran);
	index[1] = checkbuffer(dst1, (unsigned)0xbbbbbbbb, tran);
	index[2] = checkbuffer(dst2, (unsigned)0xcccccccc, tran);

	if((index[0]|index[1]|index[2]) == 0)
	{
		mailbox3[0] = 0xffffffff;
	}else
	{
		mailbox3[0] = 0x00000000;
	}
	return 0;
}
int main(void)
{
	unsigned time_c, time_p;
	unsigned time;
	unsigned tran,k,i,j,q,h,m,n;
	unsigned *box;
	unsigned *n_row, *n_col, *p;
	unsigned *neighbour_n;
	unsigned *neighbour_s;
	unsigned *neighbour_w;
	unsigned *neighbour_e;
	unsigned *master;
	
	// Define the mailbox
	master = (unsigned *)0x2000;
	box = (unsigned *) 0x5000;
	n_row = (unsigned *)0x6000;
	n_col = (unsigned *)0x6004;
	tran = 2048;
	p =(unsigned *) 0x2000;

	// Get the neighbour global address
	e_neighbor_id(E_NEXT_CORE, E_ROW_WRAP, n_row, n_col);
	neighbour_e = (unsigned *) e_get_global_address(*n_row, *n_col, p) ;
	
	e_neighbor_id(E_PREV_CORE, E_ROW_WRAP, n_row, n_col);
	neighbour_w = (unsigned *) e_get_global_address(*n_row, *n_col, p) ;
	
	e_neighbor_id(E_NEXT_CORE, E_COL_WRAP, n_row, n_col);
	neighbour_s = (unsigned *) e_get_global_address(*n_row, *n_col, p) ;
	
	e_neighbor_id(E_PREV_CORE, E_COL_WRAP, n_row, n_col);
	neighbour_n = (unsigned *) e_get_global_address(*n_row, *n_col, p) ;	
	
	// Test the writing bandwidth	
	// Initialize master and slave
	for(i=0; i<tran; i++)
	{
		master[i] = 0xdeadbeef;
		neighbour_e[i] = 0x00000000;
		neighbour_w[i] = 0x00000000;
		neighbour_s[i] = 0x00000000;
		neighbour_n[i] = 0x00000000;
	}
			
	
	// Set the ctimer
	e_ctimer_set(E_CTIMER_0, E_CTIMER_MAX) ;
	
	// Start the ctimer and select the time type
	time_p = e_ctimer_start(E_CTIMER_0, E_CTIMER_CLK);
	
	// Write to all neighbour cores
	e_dma_copy(neighbour_e, master, 0x2000);	
	e_dma_copy(neighbour_w, master, 0x2000);
	e_dma_copy(neighbour_s, master, 0x2000);
	e_dma_copy(neighbour_n, master, 0x2000);
		
	// Get the time now
	time_c = e_ctimer_get(E_CTIMER_0);	
		
	time = time_p - time_c;
		
	// Output the result
	box[0] = time;	

	// Test the reading bandwidth
	// Initialize master and slave
	for(i=0; i<tran; i++)
	{
		master[i] = 0x00000000;
		neighbour_e[i] = 0xdeadbee1;
		neighbour_w[i] = 0xdeadbee2;
		neighbour_s[i] = 0xdeadbee3;
		neighbour_n[i] = 0xdeadbee4;
	}
			
	
	// Set the ctimer
	e_ctimer_set(E_CTIMER_0, E_CTIMER_MAX) ;
	
	// Start the ctimer and select the time type
	time_p = e_ctimer_start(E_CTIMER_0, E_CTIMER_CLK);
	
	// Read from all neighbour cores
	e_dma_copy(master, neighbour_e, 0x2000);	
	e_dma_copy(master, neighbour_w, 0x2000);
	e_dma_copy(master, neighbour_s, 0x2000);
	e_dma_copy(master, neighbour_n, 0x2000);
		
	// Get the time now
	time_c = e_ctimer_get(E_CTIMER_0);	
		
	time = time_p - time_c;
		
	// Output the result
	box[1] = time;	
	return 0;
}
int main(void)
{
    unsigned mesh_reg;
    unsigned mesh_reg_modify;
    unsigned time_c, time_p;
    unsigned time;
    unsigned time_c1, time_p1;
    unsigned time1;
    unsigned i,j,q,m,n,k;
    unsigned *commander;
    unsigned *counter;
    unsigned *mailbox,*mode;
    unsigned *n_row, *n_col;
    unsigned *neighbour0, *neighbour1, *neighbour2, *neighbour3, *p;

    commander = (unsigned *)0x5100;
    counter = (unsigned *)0x5300;
    mailbox = (unsigned *)0x6000;
    mode = (unsigned *)0x5400;
    n_row = (unsigned *)0x5008;
    n_col = (unsigned *)0x500c;
    p = (unsigned *)0x5100;

    // Broadcast to neighbours
    e_neighbor_id(E_PREV_CORE, E_ROW_WRAP, n_row, n_col);
    neighbour0 = (unsigned *) e_get_global_address(*n_row, *n_col, p) ;

    e_neighbor_id(E_NEXT_CORE, E_ROW_WRAP, n_row, n_col);
    neighbour1 = (unsigned *) e_get_global_address(*n_row, *n_col, p) ;

    e_neighbor_id(E_PREV_CORE, E_COL_WRAP, n_row, n_col);
    neighbour2 = (unsigned *) e_get_global_address(*n_row, *n_col, p) ;

    e_neighbor_id(E_NEXT_CORE, E_COL_WRAP, n_row, n_col);
    neighbour3 = (unsigned *) e_get_global_address(*n_row, *n_col, p) ;

    // Get core information
    k = e_group_config.core_row * e_group_config.group_cols + e_group_config.core_col;

    while(1)
    {
        // Clear the counter of finishing transfering
        for(m=0; m<(e_group_config.group_rows*e_group_config.group_cols); m++)
        {
            counter[m] = 0;
        }

        // Initialize the commander and counter
        counter[k] = 1;

        //Clear the mode box
        mode[0] = 0xdeadbeef;

        // Clear the start commander
        commander[0] = 0x00000000;

        // Wait for the mesh event
        while(mode[0] == 0xdeadbeef)
        {};

        q = mode[0];

        mesh_reg = e_reg_read(E_REG_MESH_CONFIG);
        mesh_reg_modify = mesh_reg & 0xffffff0f;
        mesh_reg_modify = mesh_reg_modify |mesh_type[1][q];
        e_reg_write(E_REG_MESH_CONFIG, mesh_reg_modify);

        // Set the ctimer
        e_ctimer_set(E_CTIMER_0, E_CTIMER_MAX) ;

        // Waiting for the signal to start transfering
        while(commander[0] != 0xdeadbeef)
        {};

        // Start the ctimer and select the time type
        time_p = e_ctimer_start(E_CTIMER_0, E_CTIMER_MESH_0);

        // Broadcast to all the other neighbours
        neighbour0[0] = 0xdeadbeef;
        neighbour1[0] = 0xdeadbeef;
        neighbour2[0] = 0xdeadbeef;
        neighbour3[0] = 0xdeadbeef;


        while((counter[0]&counter[1]&counter[2]&counter[3]&counter[4]&counter[5]&counter[6]
                &counter[7]&counter[8]&counter[9]&counter[10]&counter[11]&counter[12]&counter[13]
                &counter[14]&counter[15]) == 0) {};

        time_c = e_ctimer_get(E_CTIMER_0);

        time = time_p - time_c;
        mailbox[(*mode)] = time;

        // Load the original value to E_REG_MESH_CONFIG system register
        e_reg_write(E_REG_MESH_CONFIG, mesh_reg);

        if(mode[0] == 12)
        {
            break;
        }
    }
    return 0;
}