21 #define has_input_from_N(conn) (conn & 0b00000001)
22 #define has_input_from_E(conn) (conn & 0b00000010)
23 #define has_input_from_S(conn) (conn & 0b00000100)
24 #define has_input_from_W(conn) (conn & 0b00001000)
25 #define has_input_from_NW(conn) (conn & 0b00010000)
26 #define has_input_from_NE(conn) (conn & 0b00100000)
27 #define has_input_from_SE(conn) (conn & 0b01000000)
28 #define has_input_from_SW(conn) (conn & 0b10000000)
31 #define is_top_pe(r, c, rows, cols) (r == 0)
32 #define is_bot_pe(r, c, rows, cols) (r == rows-1)
33 #define is_leftmost_pe(r, c, rows, cols) (c == 0)
34 #define is_rightmost_pe(r, c, rows, cols) (c == cols-1)
37 #define mask_top_pe(conn) ((conn & 0b11001111) | 0b00000001) // Remove NE, NW connections, add N connection
38 #define mask_bot_pe(conn) ((conn & 0b00111111) | 0b00000100) // Remove SE, SW connections, add S connection
39 #define mask_leftmost_pe(conn) ((conn & 0b01101111) | 0b00001000) // Remove NW, SW connections, add W connection
40 #define mask_rightmost_pe(conn) ((conn & 0b10011111) | 0b00000010) // Remove NE, SE connections, add E connection
42 #define mask_top_pred(conn) ((conn & 0b11001111) | 0b00000001) // Remove NE, NW connections, add N connection
43 #define mask_bot_pred(conn) ((conn & 0b00111111) | 0b00000100) // Remove SE, SW connections, add S connection
44 #define mask_leftmost_pred(conn) ((conn & 0b01100111)) // Remove NW, SW connections, remove W connection
45 #define mask_rightmost_pred(conn) ((conn & 0b10011111) | 0b00000010) // Remove NE, SE connections, add E connection
46 #define mask_rightmost_pred_mem(conn) ((conn & 0b10011101)) // Remove NE, SE connections, remove E connection
48 #define mask_top_event_pred(conn) ((conn & 0b11001111) | 0b00000001) // Remove NE, NW connections, add N connection
53 return (((val << 2) & 0x0f) | (val >> 2));
57 int pe_conn_orig,
int rows,
int cols,
bool pred,
bool extra_mem =
false, std::string pred_scheme =
"") {
68 for (
int r = 0; r < rows; r++) {
69 for (
int c = 0; c < cols; c++) {
70 pcv[0][r][c] = pe_conn_orig;
76 lefthalf = (pe_conn_orig >> 4) & 0x0f;
77 righthalf = pe_conn_orig & 0x0f;
84 pe_conn_out = (lefthalf << 4) | righthalf;
87 for (
int r = 0; r < rows; r++) {
88 for (
int c = 0; c < cols; c++) {
89 pcv[1][r][c] = pe_conn_out;
94 for (
int r = 0; r < rows; r++) {
95 for (
int c = 0; c < cols; c++) {
99 if (pred_scheme.find(
"event") != std::string::npos) {
170 const unsigned int cols = args.
getInt(
"cols");
171 const unsigned int rows = args.
getInt(
"rows");
172 const int fu_II = args.
getInt(
"fu_II");
173 const int pe_conn = args.
getInt(
"pe_conn");
174 const int fu_latency = args.
getInt(
"fu_latency");
175 const int num_const_addresses = args.
getInt(
"num_const_addresses");
176 const bool pred = args.
getBool(
"pred");
177 const int II = args.
getInt(
"II");
178 const bool extra_mem = args.
getBool(
"extra_mem");
179 const std::string pred_scheme = args.
getString(
"pred_scheme");
186 double moduleW = 1.0/(cols+2);
187 double moduleH = 1.0/(rows+2);
190 const int SIZE = [&]() {
210 std::vector < std::vector < std::vector<int> > >
211 pe_conn_vec(2, std::vector< std::vector<int> >(rows, std::vector<int>(cols)));
213 std::vector < std::vector < std::vector<int> > >
214 pred_conn_vec(2, std::vector< std::vector<int> >(rows, std::vector<int>(cols)));
218 fillPEConnArray(pred_conn_vec, pe_conn, rows, cols, pred, extra_mem, pred_scheme);
219 auto cgra_storage = std::make_unique<CGRA>();
220 Module* result = &cgra_storage->getTopLevelModule();
226 for (
unsigned int c = 0; c < cols; c++) {
227 for (
unsigned int r = 0; r < rows; r++) {
232 pe_conn_vec[0][r][c],
233 pe_conn_vec[1][r][c],
234 pred_conn_vec[0][r][c],
235 pred_conn_vec[1][r][c],
241 result->
addSubModule(PE, (c+1.0)*moduleW, (r+1.0)*moduleH, moduleW, moduleH);
252 for (
unsigned int r = 0; r < rows; r++) {
254 auto mem_port =
new MemPort(
"mem_" +
std::to_string(r), loc, rows, SIZE, num_const_addresses, pred, II);
255 result->
addSubModule(mem_port, 0, (r+1.0)*moduleH, moduleW, moduleH);
264 for (
unsigned int c = 0; c < cols; c++) {
265 Location loc_bot = {c + 1, rows + 1};
268 auto io_bottom =
new IO(
"io_bottom_" +
std::to_string(c), loc_bot, SIZE, II);
269 result->
addSubModule(io_top, c/(cols+2.0), 0, moduleW, moduleH);
270 result->
addSubModule(io_bottom, c*moduleW, (rows+1.0)*moduleH, moduleW, moduleH);
281 for (
unsigned int r = 0; r < rows; r++) {
284 auto mem_port =
new MemPort(
"mem_right_" +
std::to_string(r), loc, rows, SIZE, num_const_addresses, pred, II);
285 result->
addSubModule(mem_port, 0, (r+1.0)*moduleH, moduleW, moduleH);
293 result->
addSubModule(io_right, (cols+1.0)*moduleW, (r+1.0)*moduleH, moduleW, moduleH);
304 for (
unsigned int c = 0; c < cols; c++) {
305 for (
unsigned int r = 0; r < rows; r++) {
309 std::string blk_n_c_r =
"pe_c" + currC +
"_r" + currR;
316 blk_n_c_r +
".in" + north);
319 "io_top_" + currC +
".in");
322 blk_n_c_r +
".in" + north);
331 blk_n_c_r +
".in" + east);
333 std::string _blk_prefix =
"pe_c" + currC +
"_r";
334 for (
int _r = 0; _r < rows; _r++) {
336 std::string _blk_n_c_r = _blk_prefix + _currR;
338 "mem_right_" + currR +
".in" + _currR);
342 blk_n_c_r +
".in" + east);
345 "io_right_" + currR +
".in");
349 blk_n_c_r +
".in" + east);
357 blk_n_c_r +
".in" + south);
360 "io_bottom_" + currC +
".in");
363 blk_n_c_r +
".in" + south);
371 blk_n_c_r +
".in" + west);
373 std::string _blk_prefix =
"pe_c" + currC +
"_r";
374 for (
int _r = 0; _r < rows; _r++) {
376 std::string _blk_n_c_r = _blk_prefix + _currR;
378 "mem_" + currR +
".in" + _currR);
382 blk_n_c_r +
".in" + west);
388 blk_n_c_r +
".in" + northWest);
393 blk_n_c_r +
".in" + northEast);
398 blk_n_c_r +
".in" + southEast);
403 blk_n_c_r +
".in" + southWest);
408 if (!pred)
return cgra_storage;
416 if (pred_scheme.find(
"event") != std::string::npos) {
420 result->
addConnection(
"event_mux.out",
"EventTransitionTable.current_event");
421 for (
int i = 0; i < cols; i++) {
425 }
else if (pred_scheme.find(
"partial") != std::string::npos) {
427 throw cgrame_error(
"Cannot recognize the predication scheme");
433 for (
unsigned int c = 0; c < cols; c++) {
434 Location loc_bot = {c + 1, rows + 1};
437 auto io_bottom =
new IO(
"io_bottom_pred_" +
std::to_string(c), loc_bot, 1, II);
438 result->
addSubModule(io_top, c/(cols+2.0), 0, moduleW, moduleH);
439 result->
addSubModule(io_bottom, c*moduleW, (rows+1.0)*moduleH, moduleW, moduleH);
446 for (
unsigned int r = 0; r < rows; r++) {
450 result->
addSubModule(io_right, (cols+1.0)*moduleW, (r+1.0)*moduleH, moduleW, moduleH);
459 for (
unsigned int c = 0; c < cols; c++) {
460 for (
unsigned int r = 0; r < rows; r++) {
463 std::string blk_n_c_r =
"pe_c" + currC +
"_r" + currR;
470 blk_n_c_r +
".in_pred" + north);
473 "io_top_pred_" + currC +
".in");
476 blk_n_c_r +
".in_pred" + north);
483 std::string _blk_prefix =
"pe_c" + currC +
"_r";
484 for (
int _r = 0; _r < rows; _r++) {
486 std::string _blk_n_c_r = _blk_prefix + _currR;
488 "mem_right_" + currR +
".pred" + _currR);
492 blk_n_c_r +
".in_pred" + east);
495 "io_right_pred_" + currR +
".in");
499 blk_n_c_r +
".in_pred" + east);
506 blk_n_c_r +
".in_pred" + south);
509 "io_bottom_pred_" + currC +
".in");
512 blk_n_c_r +
".in_pred" + south);
519 std::string _blk_prefix =
"pe_c" + currC +
"_r";
520 for (
int _r = 0; _r < rows; _r++) {
522 std::string _blk_n_c_r = _blk_prefix + _currR;
524 "mem_" + currR +
".pred" + _currR);
528 blk_n_c_r +
".in_pred" + west);
535 blk_n_c_r +
".in_pred" + northWest);
541 blk_n_c_r +
".in_pred" + northEast);
547 blk_n_c_r +
".in_pred" + southEast);
553 blk_n_c_r +
".in_pred" + southWest);