PageRenderTime 310ms CodeModel.GetById 20ms RepoModel.GetById 11ms app.codeStats 1ms

/src/common/scp_tab.cc

https://code.google.com/
C++ | 457 lines | 393 code | 37 blank | 27 comment | 88 complexity | ef6862719207df2c7d379da06c0398d6 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.1
  1. // Verilog Behavioral Simulator
  2. // Copyright (C) 2000-2001,2011 George Varughese, Jimen Ching
  3. //
  4. // With modifications from:
  5. // Jimen Ching <jimen.ching@gmail.com>
  6. //
  7. // This file is part of the Verilog Behavioral Simulator package.
  8. // See the file COPYRIGHT for copyright and disclaimer information.
  9. // See the file COPYING for the licensing terms and conditions.
  10. // See the file CONTRIBUTORS for a list of contributing authors.
  11. //
  12. // scp_tab.cc
  13. #include <cstring>
  14. #include "sym_tab.h"
  15. #include "st_inst.h"
  16. #include "st_net.h"
  17. #include "scp_tab.h"
  18. #include "vbs.h"
  19. extern "C" char *vbs_strdup(const char *);
  20. scope_table::scope_table()
  21. {
  22. _current_level = 0; // Top!
  23. // _hashtab[1] = "top"; // Top level!
  24. }
  25. scope_table::scope_table(net_list *n)
  26. {
  27. scope_table(n, 0);
  28. }
  29. scope_table::scope_table(net_list *n, int sc)
  30. {
  31. _dump_scope = sc;
  32. _instance_level = -1;
  33. _current_level = 0; // Top!
  34. }
  35. void
  36. scope_table::is_net(const bool yn)
  37. { _is_net = yn; }
  38. bool
  39. scope_table::is_net()
  40. { return _is_net; }
  41. char *
  42. scope_table::find(int i)
  43. {
  44. static char null_string[] = {0};
  45. hashtable_type::iterator itp = _hashtab.find(i);
  46. if (itp != _hashtab.end())
  47. return vbs_strdup((*itp).second.c_str());
  48. return null_string;
  49. }
  50. int
  51. scope_table::find(const str_type &n)
  52. {
  53. // This is costly!
  54. hashtable_type::iterator ibegin = _hashtab.begin();
  55. hashtable_type::iterator istop = _hashtab.end();
  56. for (; ibegin != istop; ++ibegin)
  57. {
  58. if (ibegin->second == n)
  59. return ibegin->first;
  60. }
  61. return -1;
  62. }
  63. scope_table::net_list
  64. scope_table::get_nets(int sc)
  65. {
  66. // Returns nets at scope sc
  67. symbol_table &symboltable = vbs_engine::symboltable();
  68. net_list n_list;
  69. size_type max = symboltable.size();
  70. for (size_type i = 0; i < max; ++i)
  71. {
  72. bucket_type::iterator item = symboltable.begin(i);
  73. bucket_type::iterator last = symboltable.end(i);
  74. for (; item != last; ++item)
  75. {
  76. st_net *n = item->get()->get_net();
  77. if (n != 0)
  78. {
  79. if (n->scope() == sc)
  80. n_list.insert(n_list.end(), n);
  81. }
  82. }
  83. }
  84. return n_list;
  85. }
  86. st_net *
  87. scope_table::get_net(const char *st)
  88. {
  89. symbol_table &symboltable = vbs_engine::symboltable();
  90. int sc;
  91. char *scp = get_scope(st);
  92. str_type net_name(st);
  93. int dot = net_name.find(".");
  94. if (dot == -1)
  95. sc = 1; // top
  96. else
  97. {
  98. if (scp == 0)
  99. sc = 1; // try top
  100. else
  101. sc = find(scp);
  102. if (sc == 0)
  103. sc = 1; // top level
  104. }
  105. free(scp);
  106. size_type max = symboltable.size();
  107. unsigned int last_dot_position = net_name.rfind(".");
  108. if (last_dot_position < net_name.length())
  109. net_name = net_name.substr(last_dot_position+1);
  110. for (size_type i = 0; i < max; ++i)
  111. {
  112. bucket_type::iterator item = symboltable.begin(i);
  113. bucket_type::iterator last = symboltable.end(i);
  114. for (; item != last; ++item)
  115. {
  116. st_net *n = item->get()->get_net();
  117. if (n != 0)
  118. {
  119. //if (n->name() == st && n->scope() == sc)
  120. if (n->name() == net_name && n->scope() == sc)
  121. return n;
  122. }
  123. }
  124. }
  125. return 0;
  126. }
  127. // Returns the scope name of full net name
  128. // Eg: a.n1 returns a
  129. char *
  130. scope_table::get_scope(const char *nin)
  131. {
  132. str_type nm = nin;
  133. str_type top = top_level();
  134. #if __GNUC__ == 2 && __GNUC_MINOR__ >= 95
  135. if (nm.compare(top, 0, top.size()) == 0)
  136. #else
  137. if (nm.compare(0, top.size(), top) == 0)
  138. #endif
  139. nm.replace(0,top.length()+1,"");
  140. const char * n = nm.c_str();
  141. size_t full, sub,diff;
  142. char * last_dot = strrchr(n,'.');
  143. char * ret = 0;
  144. if (last_dot != 0)
  145. {
  146. full = strlen(n);
  147. sub = strlen(last_dot);
  148. diff = full - sub;
  149. ret = new char [diff+1];
  150. strncpy(ret,n,diff);
  151. ret[diff] = '\0';
  152. }
  153. else
  154. {
  155. if (strlen(n) > 0)
  156. ret = vbs_strdup(n);
  157. }
  158. return ret;
  159. }
  160. scope_table::net_list
  161. scope_table::get_nets(int sc, int lvls)
  162. {
  163. net_list n_list;
  164. instantiation_list inst_list = get_instances(sc);
  165. if (inst_list.size() > 0)
  166. n_list = get_nets(inst_list,lvls);
  167. net_list tmp_n_list = get_nets(sc);
  168. // This level...
  169. n_list.insert(n_list.end(), tmp_n_list.begin(), tmp_n_list.end());
  170. return n_list;
  171. }
  172. scope_table::net_list
  173. scope_table::get_nets(const char *sc)
  174. {
  175. net_list lst;
  176. int scp = 1;
  177. if (strcmp(sc,top_level().c_str()))
  178. scp = find(sc); // Not top!
  179. if (scp == -1)
  180. return lst;
  181. lst = get_nets(scp);
  182. return lst;
  183. }
  184. scope_table::net_list
  185. scope_table::get_nets(const char *sc, int lvls)
  186. {
  187. net_list nlst;
  188. str_type nm = sc;
  189. str_type top = top_level();
  190. int scp = 1;
  191. if (nm != top)
  192. {
  193. // scope table is relative to top
  194. #if __GNUC__ == 2 && __GNUC_MINOR__ >= 95
  195. if (nm.compare(top, 0, top.size()) == 0)
  196. #else
  197. if (nm.compare(0, top.size(), top) == 0)
  198. #endif
  199. nm.replace(0, top.length()+1, "");
  200. is_net(false);
  201. scp = find(nm.c_str());
  202. }
  203. if (scp == -1)
  204. {
  205. // check if its a net
  206. st_net * net = get_net(nm.c_str());
  207. if (net == 0)
  208. {
  209. cout << "Warning : " << nm << " undefined instance or net." << endl;
  210. }
  211. else
  212. {
  213. is_net(true);
  214. nlst.insert(nlst.end(),net);
  215. }
  216. return nlst;
  217. }
  218. st_instantiation *cur_inst = get_instance(nm);
  219. if (cur_inst != 0) // get nets for cur_inst
  220. {
  221. dump_top_level = cur_inst->level();
  222. nlst = get_nets(scp,lvls);
  223. return nlst;
  224. }
  225. else // could be a net or top level
  226. {
  227. if (nm == top_level())
  228. {
  229. // Start from top!
  230. nlst = get_nets(1,lvls);
  231. }
  232. else
  233. {
  234. // FIXME: should not reach here after the second
  235. // setup pass...
  236. cout << "Warning : " << nm << " undefined instance or net." << endl;
  237. }
  238. return nlst;
  239. }
  240. }
  241. scope_table::net_list
  242. scope_table::get_nets(instantiation_list & inst_list, int lvls)
  243. {
  244. // Returns nets lvls levels below inst_list level.
  245. net_list tmp_net_list;
  246. instantiation_list tmp_inst_list;
  247. // It is inefficient to traverse the full symbol table, but...
  248. instantiation_list::iterator itp = inst_list.begin();
  249. instantiation_list::iterator stop = inst_list.end();
  250. for (; itp != stop; ++itp)
  251. {
  252. st_instantiation *inst = *itp;
  253. int inst_scope = inst->instance_scope();
  254. int cur_rel_level = inst->level() - dump_top_level;
  255. if ((cur_rel_level < lvls) || ( lvls == 0))
  256. {
  257. net_list nt;
  258. instantiation_list child_inst_list;
  259. child_inst_list = get_instances(inst_scope);
  260. nt = get_nets(child_inst_list,lvls);
  261. tmp_net_list.insert(tmp_net_list.end(), nt.begin(), nt.end());
  262. nt = get_nets(inst_scope);
  263. tmp_net_list.insert(tmp_net_list.end(), nt.begin(), nt.end());
  264. }
  265. }
  266. return tmp_net_list;
  267. }
  268. st_instantiation *
  269. scope_table::get_instance(str_type &nam)
  270. {
  271. symbol_table &symboltable = vbs_engine::symboltable();
  272. int sc = find(nam);
  273. size_type max = symboltable.size();
  274. for (size_type i = 0; i < max; ++i)
  275. {
  276. bucket_type::iterator item = symboltable.begin(i);
  277. bucket_type::iterator last = symboltable.end(i);
  278. for (; item != last; ++item)
  279. {
  280. st_instantiation *n = item->get()->get_instantiation();
  281. if (n != 0)
  282. {
  283. if (n->instance_scope() == sc)
  284. return n;
  285. }
  286. }
  287. }
  288. return 0;
  289. }
  290. scope_table::instantiation_list
  291. scope_table::get_instances(int sc)
  292. {
  293. // Returns instances at scope sc.
  294. symbol_table &symboltable = vbs_engine::symboltable();
  295. instantiation_list inst_lst;
  296. size_type max = symboltable.size();
  297. for (size_type i = 0; i < max ; ++i)
  298. {
  299. bucket_type::iterator item = symboltable.begin(i);
  300. bucket_type::iterator last = symboltable.end(i);
  301. for (; item != last; ++item)
  302. {
  303. st_instantiation *n = item->get()->get_instantiation();
  304. if (n != 0)
  305. {
  306. if (n->scope() == sc)
  307. inst_lst.insert(inst_lst.end(), n);
  308. }
  309. }
  310. }
  311. return inst_lst;
  312. }
  313. scope_table::instantiation_list
  314. scope_table::get_instances(const char *sc)
  315. {
  316. int i = find(sc);
  317. return get_instances(i);
  318. }
  319. scope_table::instantiation_list
  320. scope_table::get_instances(char *sc, net_list *n_lst)
  321. {
  322. net_list nets;
  323. nets = get_nets(sc);
  324. n_lst->insert(n_lst->end(), nets.begin(), nets.end());
  325. return get_instances(sc);
  326. }
  327. scope_table::net_list *
  328. scope_table::get_dump_list()
  329. { return &_dump_list; }
  330. void
  331. scope_table::clear_dump_list()
  332. { _dump_list.clear(); }
  333. int
  334. scope_table::push_level()
  335. { return ++_current_level; }
  336. int
  337. scope_table::pop_level()
  338. { return --_current_level; }
  339. int
  340. scope_table::level()
  341. { return _current_level; }
  342. scope_table::str_type
  343. scope_table::scope_string()
  344. {
  345. str_type sc("");
  346. str_list::iterator itp(_scope_string.begin());
  347. str_list::iterator stop(_scope_string.end());
  348. if (itp != stop && itp->size() > 0)
  349. sc = *itp;
  350. else
  351. return sc;
  352. for (++itp; itp != stop; ++itp)
  353. {
  354. sc += ".";
  355. sc += *itp;
  356. }
  357. return sc;
  358. }
  359. void
  360. scope_table::push_scope(const str_type &s)
  361. {
  362. _scope_string.insert(_scope_string.end(), s);
  363. }
  364. void
  365. scope_table::pop_scope()
  366. {
  367. if (_scope_string.size() > 0)
  368. {
  369. str_list::iterator stop = _scope_string.end();
  370. --stop;
  371. _scope_string.erase(stop);
  372. }
  373. }
  374. void
  375. scope_table::insert(const int i)
  376. {
  377. str_list::iterator itp = _scope_string.begin();
  378. str_list::iterator stop = _scope_string.end();
  379. str_type this_scope;
  380. this_scope = (*itp);
  381. ++itp;
  382. for (; itp != stop; ++itp)
  383. {
  384. this_scope += ".";
  385. this_scope += (*itp);
  386. }
  387. _hashtab[i] = this_scope;
  388. }
  389. void
  390. scope_table::insert(int i, const str_type &s)
  391. {
  392. _hashtab[i] = s;
  393. }
  394. void
  395. scope_table::add(net_list &n)
  396. {
  397. net_list::iterator b(n.begin());
  398. net_list::iterator e(n.end());
  399. if (b != e)
  400. _dump_list.insert(_dump_list.end(), b, e);
  401. }
  402. bool
  403. scope_table::net_list_added()
  404. { return _net_list_added; }
  405. void
  406. scope_table::net_list_added(bool n)
  407. {
  408. _net_list_added = n;
  409. }
  410. const scope_table::str_type &
  411. scope_table::top_level()
  412. {
  413. return _top_level;
  414. }
  415. void
  416. scope_table::top_level(const str_type &t)
  417. {
  418. _hashtab[1] = t; // Top level!
  419. _top_level = t;
  420. }