int bsg_set_tile_x_y() { // everybody stores to tile 0,0 bsg_remote_store(0,0,&bsg_x,0); bsg_remote_store(0,0,&bsg_y,0); // make sure memory ops above are not moved down bsg_compiler_memory_barrier(); // wait for my tile number to change bsg_wait_while((bsg_volatile_access(bsg_x) == -1) || (bsg_volatile_access(bsg_y) == -1)); // make sure memory ops below are not moved above bsg_compiler_memory_barrier(); // head of each column is responsible for // propagating to next column if ((bsg_x == 0) && ((bsg_y + 1) != bsg_tiles_Y) ) { bsg_remote_store(0,bsg_y+1,&bsg_x,bsg_x); bsg_remote_store(0,bsg_y+1,&bsg_y,bsg_y+1); } // propagate across each row if ((bsg_x+1) != bsg_tiles_X) { bsg_remote_store(bsg_x+1,bsg_y,&bsg_x,bsg_x+1); bsg_remote_store(bsg_x+1,bsg_y,&bsg_y,bsg_y); } }
int main() { bsg_remote_store_char(0,0,&t[3],3); bsg_remote_store_char(0,0,&t[2],2); bsg_remote_store_char(0,0,&t[1],1); bsg_remote_store_char(0,0,&t[0],0); bsg_wait_while(bsg_volatile_access(foo) != 0x03020100); bsg_finish(); }
void produce(int v) { // Wait until it's not full bsg_wait_while( (bsg_volatile_access(queue_head) - bsg_volatile_access(queue_tail) == 1) || (bsg_volatile_access(queue_tail) - bsg_volatile_access(queue_head) == PD_FIFO_SIZE - 1) ); // Store data to the remote consumer's queue bsg_remote_store(dest_x, dest_y, &local_queue[queue_tail], v); // Position update queue_tail++; if (queue_tail == PD_FIFO_SIZE) // circular queue condition queue_tail = 0; // Update consumer's tail position bsg_remote_store(dest_x, dest_y, &queue_tail, queue_tail); }
int main() { bsg_set_tile_x_y(); if (bsg_x == 1 && bsg_y == 1) { tmp = *bsg_remote_ptr(0, 1, 0xABCD0); bsg_remote_ptr_io_store(0, 0x2000, tmp); tmp = *bsg_remote_ptr(0, 1, 0xBCDE0); bsg_remote_ptr_io_store(0, 0x2000, tmp); } else if (bsg_x == 1 && bsg_y == 0) { tmp2 = 0xCDEF; tmp = tmp2; bsg_remote_ptr_io_store(0, 0x2000, tmp); } if ((bsg_x == bsg_tiles_X-1) && (bsg_y == bsg_tiles_Y-1)) bsg_finish(); bsg_wait_while(1); }
void barrier(int x, int y) { barrier_array[x][y] = ++barrier_count; if (x == BARRIER_CENTRAL_X && y == BARRIER_CENTRAL_Y) { // Case 1 (central node): wait until all are resolved while (1) { if (!is_still_barrier_waiting()) break; } // Wait until all stores are commit bsg_commit_stores_wait(); // Update its own barrier mincount barrier_central_count = barrier_count; } else { // Case 2 (non-central nodes): send barrier_count to the central node, // and wait until it is resolved by the propagation below bsg_remote_store(BARRIER_CENTRAL_X,BARRIER_CENTRAL_Y,&barrier_array[x][y],barrier_count); bsg_compiler_memory_barrier(); bsg_wait_while( (bsg_volatile_access(barrier_central_count) < barrier_count) ); } // propagate to next column if ((x == 0) && ((y + 1) != bsg_tiles_Y) ) { bsg_remote_store(0,y+1,&barrier_central_count,barrier_central_count); } // propagate across each row if ((x+1) != bsg_tiles_X) { bsg_remote_store(x+1,y,&barrier_central_count,barrier_central_count); } }
int consume() { int v; // Wait until it's not empty bsg_wait_while( (bsg_volatile_access(queue_head) == bsg_volatile_access(queue_tail)) ); // Read data v = local_queue[queue_head]; // Position update queue_head++; if (queue_head == PD_FIFO_SIZE) // circular queue condition queue_head = 0; // Update producer's head position bsg_remote_store(dest_x, dest_y, &queue_head, queue_head); return v; }