1 /*
2 Copyright 2010 Intel Corporation
3 
4 Use, modification and distribution are subject to the Boost Software License,
5 Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
6 http://www.boost.org/LICENSE_1_0.txt).
7 */
8 //extract_devices.hpp
9 #ifndef BOOST_POLYGON_TUTORIAL_EXTRACT_DEVICES_HPP
10 #define BOOST_POLYGON_TUTORIAL_EXTRACT_DEVICES_HPP
11 #include <string>
12 #include <iostream>
13 #include <fstream>
14 #include <vector>
15 #include "connectivity_database.hpp"
16 #include "device.hpp"
17 
18 typedef boost::polygon::connectivity_extraction_90<int> connectivity_extraction;
19 inline std::vector<std::set<int> >
extract_layer(connectivity_extraction & ce,std::vector<std::string> & net_ids,connectivity_database & connectivity,polygon_set & layout,std::string layer)20 extract_layer(connectivity_extraction& ce, std::vector<std::string>& net_ids,
21               connectivity_database& connectivity, polygon_set& layout,
22               std::string layer) {
23   for(connectivity_database::iterator itr = connectivity.begin(); itr != connectivity.end(); ++itr) {
24     net_ids.push_back((*itr).first);
25     ce.insert((*itr).second[layer]);
26   }
27   std::vector<polygon> polygons;
28   layout.get_polygons(polygons);
29   for(std::size_t i = 0; i < polygons.size(); ++i) {
30     ce.insert(polygons[i]);
31   }
32   std::vector<std::set<int> > graph(polygons.size() + net_ids.size(), std::set<int>());
33   ce.extract(graph);
34   return graph;
35 }
36 
extract_device_type(std::vector<device> & devices,connectivity_database & connectivity,polygon_set & layout,std::string type)37 inline void extract_device_type(std::vector<device>& devices, connectivity_database& connectivity,
38                                 polygon_set& layout, std::string type) {
39   //recall that P and NDIFF were merged into one DIFF layer in the connectivity database
40   //find the two nets on the DIFF layer that interact with each transistor
41   //and then find the net on the poly layer that interacts with each transistor
42   boost::polygon::connectivity_extraction_90<int> cediff;
43   std::vector<std::string> net_ids_diff;
44   std::vector<std::set<int> > graph_diff =
45     extract_layer(cediff, net_ids_diff, connectivity, layout, "DIFF");
46   boost::polygon::connectivity_extraction_90<int> cepoly;
47   std::vector<std::string> net_ids_poly;
48   std::vector<std::set<int> > graph_poly =
49     extract_layer(cepoly, net_ids_poly, connectivity, layout, "POLY");
50   std::vector<device> tmp_devices(graph_diff.size() - net_ids_poly.size());
51   for(std::size_t i = net_ids_poly.size(); i < graph_diff.size(); ++i) {
52     tmp_devices[i - net_ids_diff.size()].type = type;
53     tmp_devices[i - net_ids_diff.size()].terminals = std::vector<std::string>(3, std::string());
54     std::size_t j = 0;
55     for(std::set<int>::iterator itr = graph_diff[i].begin();
56         itr != graph_diff[i].end(); ++itr, ++j) {
57       if(j == 0) {
58         tmp_devices[i - net_ids_diff.size()].terminals[0] = net_ids_diff[*itr];
59       } else if(j == 1) {
60         tmp_devices[i - net_ids_diff.size()].terminals[2] = net_ids_diff[*itr];
61       } else {
62         //error, too many diff connections
63         tmp_devices[i - net_ids_diff.size()].terminals = std::vector<std::string>(3, std::string());
64       }
65     }
66     j = 0;
67     for(std::set<int>::iterator itr = graph_poly[i].begin();
68         itr != graph_poly[i].end(); ++itr, ++j) {
69       if(j == 0) {
70         tmp_devices[i - net_ids_diff.size()].terminals[1] = net_ids_poly[*itr];
71       } else {
72         //error, too many poly connections
73         tmp_devices[i - net_ids_poly.size()].terminals = std::vector<std::string>(3, std::string());
74       }
75     }
76   }
77 
78   devices.insert(devices.end(), tmp_devices.begin(), tmp_devices.end());
79 }
80 
81 //populates vector of devices based on connectivity and layout data
extract_devices(std::vector<device> & devices,connectivity_database & connectivity,layout_database & layout)82 inline void extract_devices(std::vector<device>& devices, connectivity_database& connectivity,
83                             layout_database& layout) {
84   using namespace boost::polygon::operators;
85   //p-type transistors are gate that interact with p diffusion and nwell
86   polygon_set ptransistors = layout["GATE"];
87   ptransistors.interact(layout["PDIFF"]);
88   ptransistors.interact(layout["NWELL"]);
89   //n-type transistors are gate that interact with n diffusion and not nwell
90   polygon_set ntransistors = layout["GATE"];
91   ntransistors.interact(layout["NDIFF"]);
92   polygon_set not_ntransistors = ntransistors;
93   not_ntransistors.interact(layout["NWELL"]);
94   ntransistors -= not_ntransistors;
95   extract_device_type(devices, connectivity, ptransistors, "PTRANS");
96   extract_device_type(devices, connectivity, ntransistors, "NTRANS");
97 }
98 
99 #endif
100