/src/manifold/models/iris/iris_srcs/components/genericRC.cc

https://gitlab.com/pranith/macsim · C++ · 544 lines · 457 code · 66 blank · 21 comment · 120 complexity · 8754e72d4f9732184628508f2e93b2ff MD5 · raw file

  1. #ifndef _genericaddressdecoder_cc_INC
  2. #define _genericaddressdecoder_cc_INC
  3. #include "genericRC.h"
  4. GenericRC::GenericRC()
  5. {
  6. srand(time(NULL));
  7. rc_method = RING_ROUTING;
  8. do_request_reply_network = false;
  9. }
  10. void GenericRC::init()
  11. {
  12. if( rc_method == XY_ROUTING || rc_method == XY_ROUTING_HETERO)
  13. {
  14. grid_xloc.resize(no_nodes);
  15. grid_yloc.resize(no_nodes);
  16. for( uint i = 0; i < no_nodes; i++ )
  17. {
  18. grid_xloc[i] = i % grid_size;
  19. grid_yloc[i] = i / grid_size;
  20. }
  21. // possible_out_vcs.push_back(0);
  22. }
  23. }
  24. uint
  25. GenericRC::route_x_y(uint dest)
  26. {
  27. uint oport = -1;
  28. uint myx=-1, destx=-1, myy =-1, desty=-1;
  29. myx = grid_xloc[node_id];
  30. myy = grid_yloc[node_id];
  31. destx = grid_xloc[ dest ];
  32. desty = grid_yloc[ dest ];
  33. if ( myx == destx && myy == desty )
  34. oport = 0;
  35. else if ( myx == destx )
  36. {
  37. if( desty < myy )
  38. oport = 3;
  39. else
  40. oport = 4;
  41. }
  42. else
  43. {
  44. if( destx < myx )
  45. oport = 1;
  46. else
  47. oport = 2;
  48. }
  49. return oport;
  50. }
  51. //want spinal routers to be flexible: prefer y traversal, but can use x if adjacent router is also spinal
  52. //FIXME only does X then Y for now, as GPU nodes only have lateral links - consider using MECS eventually?
  53. void
  54. GenericRC::route_x_y_hetero( HeadFlit* hf )
  55. {
  56. if ( hf->req->m_id == 458 )
  57. {
  58. cout << "node id " << node_id << "\n";
  59. cout << "routing: \n";
  60. }
  61. uint dest = hf->dst_node;
  62. uint myx=-1, destx=-1, myy =-1, desty=-1;
  63. myx = grid_xloc[node_id];
  64. myy = grid_yloc[node_id];
  65. destx = grid_xloc[ dest ];
  66. desty = grid_yloc[ dest ];
  67. if ( myx == destx && myy == desty )
  68. possible_out_ports.push_back(0);
  69. else if ( myx < 3 || myx > 4 )//case is gpu
  70. {
  71. if( destx < myx )
  72. possible_out_ports.push_back(1);
  73. else
  74. possible_out_ports.push_back(2);
  75. } //case is mc/l3
  76. else if ( myy != desty )
  77. {
  78. if( desty < myy )
  79. {
  80. possible_out_ports.push_back(3);
  81. // possible_out_vcs.push_back(5); //alternative to 3
  82. }
  83. else
  84. {
  85. possible_out_ports.push_back(4);
  86. // possible_out_vcs.push_back(6);
  87. }
  88. }else
  89. {
  90. if( destx < myx )
  91. possible_out_ports.push_back(1);
  92. else
  93. possible_out_ports.push_back(2);
  94. }
  95. return;
  96. }
  97. void
  98. GenericRC::route_torus(HeadFlit* hf)
  99. {
  100. uint myx = (int)(node_id%grid_size);
  101. uint destx = (int)(hf->dst_node%grid_size);
  102. uint myy = (int)(node_id/grid_size);
  103. uint desty = (int)(hf->dst_node/grid_size);
  104. if ( myx == destx && myy == desty )
  105. {
  106. possible_out_ports.push_back(0);
  107. if ( hf->mclass == MC_RESP)
  108. possible_out_vcs.push_back(1);
  109. else
  110. possible_out_vcs.push_back(0);
  111. return;
  112. }
  113. else if ( myx == destx ) /* reached row but not col */
  114. {
  115. /* Decide the port based on hops around the ring */
  116. if ( desty > myy )
  117. {
  118. if ((desty-myy)>grid_size/2)
  119. possible_out_ports.push_back(3);
  120. else
  121. possible_out_ports.push_back(4);
  122. }
  123. else
  124. {
  125. if ((myy - desty )>grid_size/2)
  126. possible_out_ports.push_back(4);
  127. else
  128. possible_out_ports.push_back(3);
  129. }
  130. /* Decide the vc */
  131. possible_out_vcs.resize(1);
  132. if( possible_out_ports[0] == 3)
  133. {
  134. desty = (grid_size-desty)%grid_size;
  135. myy= (grid_size-myy)%grid_size;
  136. }
  137. if ( desty > myy )
  138. {
  139. if ( hf->mclass == MC_RESP)
  140. possible_out_vcs[0] = 3;
  141. else
  142. possible_out_vcs[0] = 2;
  143. }
  144. else
  145. {
  146. if ( hf->mclass == MC_RESP)
  147. possible_out_vcs[0] = 1;
  148. else
  149. possible_out_vcs[0] = 0;
  150. }
  151. return;
  152. }
  153. /* both row and col dont match do x first. Y port is
  154. * adaptive in this case and can only be used with the adaptive vc */
  155. else
  156. {
  157. if ( destx > myx )
  158. {
  159. if ((destx - myx)>grid_size/2)
  160. possible_out_ports.push_back(1);
  161. else
  162. possible_out_ports.push_back(2);
  163. }
  164. else
  165. {
  166. if ((myx - destx )>grid_size/2)
  167. possible_out_ports.push_back(2);
  168. else
  169. possible_out_ports.push_back(1);
  170. }
  171. /* Decide the vc */
  172. possible_out_vcs.resize(1);
  173. if( possible_out_ports[0] == 1)
  174. {
  175. destx = (grid_size-destx)%grid_size;
  176. myx= (grid_size-myx)%grid_size;
  177. }
  178. if ( destx > myx )
  179. {
  180. if ( hf->mclass == MC_RESP)
  181. possible_out_vcs[0] = 3;
  182. else
  183. possible_out_vcs[0] = 2;
  184. }
  185. else
  186. {
  187. if ( hf->mclass == MC_RESP)
  188. possible_out_vcs[0] = 1;
  189. else
  190. possible_out_vcs[0] = 0;
  191. }
  192. return;
  193. }
  194. cout << "ERROR: dint return yet " << endl;
  195. return;
  196. }
  197. // this routes unidirectional
  198. void
  199. GenericRC::route_ring_uni(HeadFlit* hf)
  200. {
  201. grid_size = no_nodes;
  202. uint myx = node_id;
  203. uint destx = hf->dst_node;
  204. if ( myx == destx )
  205. {
  206. possible_out_ports.push_back(0);
  207. if ( hf->mclass== PROC_REQ)
  208. possible_out_vcs.push_back(0);
  209. else
  210. {
  211. possible_out_vcs.push_back(1);
  212. // should be able to add 0-4 vcs here but make sure vca can
  213. // handle multiple selections
  214. }
  215. return;
  216. }
  217. else
  218. {
  219. possible_out_ports.push_back(2);
  220. /* Decide the vc */
  221. possible_out_vcs.resize(1);
  222. possible_out_vcs[0] = rand() % 4;
  223. return;
  224. if ( destx > myx )
  225. {
  226. if ( hf->mclass == PROC_REQ )
  227. possible_out_vcs[0] = 2;
  228. else
  229. possible_out_vcs[0] = 3;
  230. }
  231. else
  232. {
  233. if ( hf->mclass == PROC_REQ)
  234. possible_out_vcs[0] = 0;
  235. else
  236. possible_out_vcs[0] = 1;
  237. }
  238. return;
  239. }
  240. cout << "ERROR: dint return yet " << endl;
  241. return;
  242. }
  243. void
  244. GenericRC::route_ring(HeadFlit* hf)
  245. {
  246. grid_size = no_nodes;
  247. uint myx = node_id;
  248. uint destx = hf->dst_node;
  249. if ( myx == destx )
  250. {
  251. possible_out_ports.push_back(0);
  252. if ( hf->mclass== PROC_REQ)
  253. possible_out_vcs.push_back(0);
  254. else
  255. {
  256. possible_out_vcs.push_back(1);
  257. // should be able to add 0-4 vcs here but make sure vca can
  258. // handle multiple selections
  259. }
  260. return;
  261. }
  262. else
  263. {
  264. if ( destx > myx)
  265. {
  266. if ( (destx - myx) > grid_size/2)
  267. possible_out_ports.push_back(1);
  268. else
  269. possible_out_ports.push_back(2);
  270. }
  271. else
  272. {
  273. if ( (myx - destx) > grid_size/2)
  274. possible_out_ports.push_back(2);
  275. else
  276. possible_out_ports.push_back(1);
  277. }
  278. /* Decide the vc */
  279. possible_out_vcs.resize(1);
  280. // possible_out_vcs[0] = rand() % 4;
  281. // return;
  282. if( possible_out_ports[0] == 1)
  283. {
  284. destx = (grid_size-destx)%grid_size;
  285. myx= (grid_size-myx)%grid_size;
  286. }
  287. if ( destx > myx )
  288. {
  289. if ( hf->mclass == PROC_REQ )
  290. {
  291. possible_out_vcs[0] = 2;//rand() % 2;
  292. }
  293. else
  294. {
  295. possible_out_vcs[0] = 3;// + rand() % 3;
  296. }
  297. }//*
  298. else
  299. {
  300. if ( hf->mclass == PROC_REQ)
  301. possible_out_vcs[0] = 0;
  302. else
  303. possible_out_vcs[0] = 1;
  304. }
  305. //*/
  306. return;
  307. }
  308. cout << "ERROR: dint return yet " << endl;
  309. return;
  310. }
  311. void
  312. GenericRC::route_twonode(HeadFlit* hf)
  313. {
  314. if ( node_id == 0 )
  315. {
  316. if ( hf->dst_node == 1)
  317. possible_out_ports.push_back(1);
  318. else
  319. possible_out_ports.push_back(0);
  320. }
  321. if ( node_id == 1 )
  322. {
  323. if ( hf->dst_node == 0)
  324. possible_out_ports.push_back(1);
  325. else
  326. possible_out_ports.push_back(0);
  327. }
  328. if ( hf->mclass == PROC_REQ )
  329. possible_out_vcs.push_back(0);
  330. else
  331. possible_out_vcs.push_back(1);
  332. return;
  333. }
  334. void
  335. GenericRC::push (Flit* f, uint ch )
  336. {
  337. if(ch > addresses.size())
  338. std::cout << "Invalid VC Exception " << std::endl;
  339. //Route the head
  340. if( f->type == HEAD )
  341. {
  342. HeadFlit* header = static_cast< HeadFlit* >( f );
  343. addresses[ch].last_adaptive_port = 0;
  344. addresses[ch].possible_out_ports.clear();
  345. addresses[ch].possible_out_vcs.clear();
  346. possible_out_ports.clear();
  347. possible_out_vcs.clear();
  348. addresses[ch].last_adaptive_port = 0;
  349. if( rc_method == RING_ROUTING)
  350. {
  351. possible_out_ports.clear();
  352. possible_out_vcs.clear();
  353. route_ring( header );
  354. addresses[ch].out_port = possible_out_ports.at(0);
  355. addresses[ch].possible_out_vcs.push_back(possible_out_vcs.at(0));
  356. addresses[ch].possible_out_ports.push_back(possible_out_ports.at(0));
  357. }
  358. if( rc_method == TWONODE_ROUTING)
  359. {
  360. possible_out_ports.clear();
  361. possible_out_vcs.clear();
  362. route_twonode( header );
  363. addresses[ch].out_port = possible_out_ports.at(0);
  364. addresses[ch].possible_out_vcs.push_back(possible_out_vcs.at(0));
  365. addresses[ch].possible_out_ports.push_back(possible_out_ports.at(0));
  366. }
  367. if( rc_method == XY_ROUTING)
  368. {
  369. addresses [ch].out_port = route_x_y(header->dst_node );
  370. addresses[ch].possible_out_vcs.push_back(0);
  371. addresses [ch].possible_out_ports.push_back(route_x_y(header->dst_node));
  372. }
  373. if( rc_method == XY_ROUTING_HETERO)
  374. {
  375. route_x_y_hetero(header);
  376. addresses [ch].out_port = possible_out_ports.at(0);
  377. addresses[ch].possible_out_vcs.push_back(0);
  378. addresses [ch].possible_out_ports.push_back(possible_out_ports.at(0));
  379. }
  380. if( rc_method == TORUS_ROUTING)
  381. {
  382. possible_out_ports.clear();
  383. possible_out_vcs.clear();
  384. route_torus( header );
  385. addresses[ch].out_port = possible_out_ports.at(0);
  386. addresses[ch].possible_out_vcs.push_back(possible_out_vcs.at(0));
  387. addresses[ch].possible_out_ports.push_back(possible_out_ports.at(0));
  388. assert ( possible_out_ports.size() == 1);
  389. assert ( possible_out_vcs.size() == 1);
  390. }
  391. addresses [ch].route_valid = true;
  392. }
  393. else if(f->type == TAIL)
  394. {
  395. if( !addresses[ch].route_valid)
  396. {
  397. printf("TAIL InvalidAddrException" );
  398. }
  399. addresses[ch].route_valid = false;
  400. addresses[ch].possible_out_ports.clear();
  401. addresses[ch].possible_out_vcs.clear();
  402. addresses[ch].last_adaptive_port = 0;
  403. possible_out_ports.clear();
  404. possible_out_vcs.clear();
  405. }
  406. else if (f->type == BODY)
  407. {
  408. if( !addresses[ch].route_valid)
  409. {
  410. printf("BODY InvalidAddrException" );
  411. }
  412. }
  413. else
  414. {
  415. printf(" InvalidFlitException fty: %d", f->type);
  416. }
  417. return ;
  418. } /* ----- end of method genericRC::push ----- */
  419. uint
  420. GenericRC::get_output_port ( uint ch)
  421. {
  422. uint oport = -1;
  423. if (addresses[ch].last_adaptive_port == addresses[ch].possible_out_ports.size())
  424. addresses[ch].last_adaptive_port = 0;
  425. oport = addresses[ch].possible_out_ports[addresses[ch].last_adaptive_port];
  426. addresses[ch].last_adaptive_port++;
  427. return oport;
  428. } /* ----- end of method genericRC::get_output_port ----- */
  429. uint
  430. GenericRC::no_adaptive_vcs( uint ch )
  431. {
  432. return addresses[ch].possible_out_vcs.size();
  433. }
  434. uint
  435. GenericRC::no_adaptive_ports( uint ch )
  436. {
  437. return addresses[ch].possible_out_ports.size();
  438. }
  439. uint
  440. GenericRC::get_virtual_channel ( uint ch )
  441. {
  442. uint och = -1;
  443. if (addresses[ch].last_vc == addresses[ch].possible_out_vcs.size())
  444. addresses[ch].last_vc = 0;
  445. och = addresses[ch].possible_out_vcs[addresses[ch].last_vc];
  446. addresses[ch].last_vc++;
  447. return och;
  448. } /* ----- end of method genericRC::get_vc ----- */
  449. void
  450. GenericRC::resize ( uint ch )
  451. {
  452. vcs = ch;
  453. addresses.resize(ch);
  454. for ( uint i = 0 ; i<ch ; i++ )
  455. {
  456. addresses[i].route_valid = false;
  457. addresses[i].last_vc = 0;
  458. }
  459. return ;
  460. } /* ----- end of method genericRC::set_no_channels ----- */
  461. bool
  462. GenericRC::is_empty ()
  463. {
  464. uint channels = addresses.size();
  465. for ( uint i=0 ; i<channels ; i++ )
  466. if(addresses[i].route_valid)
  467. return false;
  468. return true;
  469. } /* ----- end of method genericRC::is_empty ----- */
  470. std::string
  471. GenericRC::toString () const
  472. {
  473. std::stringstream str;
  474. str << "GenericRC"
  475. << "\tchannels: " << addresses.size();
  476. return str.str();
  477. } /* ----- end of function GenericRC::toString ----- */
  478. #endif /* ----- #ifndef _genericaddressdecoder_cc_INC ----- */