connectivity_database.hpp 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. /*
  2. Copyright 2010 Intel Corporation
  3. Use, modification and distribution are subject to the Boost Software License,
  4. Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
  5. http://www.boost.org/LICENSE_1_0.txt).
  6. */
  7. //connectivity_database.hpp
  8. #ifndef BOOST_POLYGON_TUTORIAL_CONNECTIVITY_DATABASE_HPP
  9. #define BOOST_POLYGON_TUTORIAL_CONNECTIVITY_DATABASE_HPP
  10. #include <boost/polygon/polygon.hpp>
  11. #include <map>
  12. #include <sstream>
  13. #include "layout_database.hpp"
  14. #include "layout_pin.hpp"
  15. typedef std::map<std::string, layout_database > connectivity_database;
  16. //map layout pin data type to boost::polygon::rectangle_concept
  17. namespace boost { namespace polygon{
  18. template <>
  19. struct rectangle_traits<layout_pin> {
  20. typedef int coordinate_type;
  21. typedef interval_data<int> interval_type;
  22. static inline interval_type get(const layout_pin& pin, orientation_2d orient) {
  23. if(orient == HORIZONTAL)
  24. return interval_type(pin.xl, pin.xh);
  25. return interval_type(pin.yl, pin.yh);
  26. }
  27. };
  28. template <>
  29. struct geometry_concept<layout_pin> { typedef rectangle_concept type; };
  30. }}
  31. typedef boost::polygon::polygon_90_data<int> polygon;
  32. typedef boost::polygon::polygon_90_set_data<int> polygon_set;
  33. inline void populate_connected_component
  34. (connectivity_database& connectivity, std::vector<polygon>& polygons,
  35. std::vector<int> polygon_color, std::vector<std::set<int> >& graph,
  36. std::size_t node_id, std::size_t polygon_id_offset, std::string& net,
  37. std::vector<std::string>& net_ids, std::string net_prefix,
  38. std::string& layout_layer) {
  39. if(polygon_color[node_id] == 1)
  40. return;
  41. polygon_color[node_id] = 1;
  42. if(node_id < polygon_id_offset && net_ids[node_id] != net) {
  43. //merge nets in connectivity database
  44. //if one of the nets is internal net merge it into the other
  45. std::string net1 = net_ids[node_id];
  46. std::string net2 = net;
  47. if(net.compare(0, net_prefix.length(), net_prefix) == 0) {
  48. net = net1;
  49. std::swap(net1, net2);
  50. } else {
  51. net_ids[node_id] = net;
  52. }
  53. connectivity_database::iterator itr = connectivity.find(net1);
  54. if(itr != connectivity.end()) {
  55. for(layout_database::iterator itr2 = (*itr).second.begin();
  56. itr2 != (*itr).second.end(); ++itr2) {
  57. connectivity[net2][(*itr2).first].insert((*itr2).second);
  58. }
  59. connectivity.erase(itr);
  60. }
  61. }
  62. if(node_id >= polygon_id_offset)
  63. connectivity[net][layout_layer].insert(polygons[node_id - polygon_id_offset]);
  64. for(std::set<int>::iterator itr = graph[node_id].begin();
  65. itr != graph[node_id].end(); ++itr) {
  66. populate_connected_component(connectivity, polygons, polygon_color, graph,
  67. *itr, polygon_id_offset, net, net_ids, net_prefix, layout_layer);
  68. }
  69. }
  70. inline void connect_layout_to_layer(connectivity_database& connectivity, polygon_set& layout, std::string layout_layer, std::string layer, std::string net_prefix, int& net_suffix) {
  71. if(layout_layer.empty())
  72. return;
  73. boost::polygon::connectivity_extraction_90<int> ce;
  74. std::vector<std::string> net_ids;
  75. for(connectivity_database::iterator itr = connectivity.begin(); itr != connectivity.end(); ++itr) {
  76. net_ids.push_back((*itr).first);
  77. ce.insert((*itr).second[layer]);
  78. }
  79. std::vector<polygon> polygons;
  80. layout.get_polygons(polygons);
  81. std::size_t polygon_id_offset = net_ids.size();
  82. for(std::size_t i = 0; i < polygons.size(); ++i) {
  83. ce.insert(polygons[i]);
  84. }
  85. std::vector<std::set<int> > graph(polygons.size() + net_ids.size(), std::set<int>());
  86. ce.extract(graph);
  87. std::vector<int> polygon_color(polygons.size() + net_ids.size(), 0);
  88. //for each net in net_ids populate connected component with net
  89. for(std::size_t node_id = 0; node_id < net_ids.size(); ++node_id) {
  90. populate_connected_component(connectivity, polygons, polygon_color, graph, node_id,
  91. polygon_id_offset, net_ids[node_id], net_ids,
  92. net_prefix, layout_layer);
  93. }
  94. //for each polygon_color that is zero populate connected compontent with net_prefix + net_suffix++
  95. for(std::size_t i = 0; i < polygons.size(); ++i) {
  96. if(polygon_color[i + polygon_id_offset] == 0) {
  97. std::stringstream ss(std::stringstream::in | std::stringstream::out);
  98. ss << net_prefix << net_suffix++;
  99. std::string internal_net;
  100. ss >> internal_net;
  101. populate_connected_component(connectivity, polygons, polygon_color, graph,
  102. i + polygon_id_offset,
  103. polygon_id_offset, internal_net, net_ids,
  104. net_prefix, layout_layer);
  105. }
  106. }
  107. }
  108. //given a layout_database we populate a connectivity database
  109. inline void populate_connectivity_database(connectivity_database& connectivity, std::vector<layout_pin>& pins, layout_database& layout) {
  110. using namespace boost::polygon;
  111. using namespace boost::polygon::operators;
  112. for(std::size_t i = 0; i < pins.size(); ++i) {
  113. connectivity[pins[i].net][pins[i].layer].insert(pins[i]);
  114. }
  115. int internal_net_suffix = 0;
  116. //connect metal1 layout to pins which were on metal1
  117. connect_layout_to_layer(connectivity, layout["METAL1"], "METAL1",
  118. "METAL1", "__internal_net_", internal_net_suffix);
  119. //connect via0 layout to metal1
  120. connect_layout_to_layer(connectivity, layout["VIA0"], "VIA0",
  121. "METAL1", "__internal_net_", internal_net_suffix);
  122. //poly needs to have gates subtracted from it to prevent shorting through transistors
  123. polygon_set poly_not_gate = layout["POLY"] - layout["GATE"];
  124. //connect poly minus gate to via0
  125. connect_layout_to_layer(connectivity, poly_not_gate, "POLY",
  126. "VIA0", "__internal_net_", internal_net_suffix);
  127. //we don't want to short signals through transistors so we subtract the gate regions
  128. //from the diffusions
  129. polygon_set diff_not_gate = (layout["PDIFF"] + layout["NDIFF"]) - layout["GATE"];
  130. //connect diffusion minus gate to poly
  131. //Note that I made up the DIFF layer name for combined P and NDIFF
  132. connect_layout_to_layer(connectivity, diff_not_gate, "DIFF",
  133. "POLY", "__internal_net_", internal_net_suffix);
  134. //connect gate to poly to make connections through gates on poly
  135. connect_layout_to_layer(connectivity, layout["GATE"], "GATE",
  136. "POLY", "__internal_net_", internal_net_suffix);
  137. //now we have traced connectivity of the layout down to the transistor level
  138. //any polygons not connected to pins have been assigned internal net names
  139. }
  140. #endif