/* Copyright 2010 Intel Corporation Use, modification and distribution are subject to the Boost Software License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt). */ //extract_devices.hpp #ifndef BOOST_POLYGON_TUTORIAL_EXTRACT_DEVICES_HPP #define BOOST_POLYGON_TUTORIAL_EXTRACT_DEVICES_HPP #include #include #include #include #include "connectivity_database.hpp" #include "device.hpp" typedef boost::polygon::connectivity_extraction_90 connectivity_extraction; inline std::vector > extract_layer(connectivity_extraction& ce, std::vector& net_ids, connectivity_database& connectivity, polygon_set& layout, std::string layer) { for(connectivity_database::iterator itr = connectivity.begin(); itr != connectivity.end(); ++itr) { net_ids.push_back((*itr).first); ce.insert((*itr).second[layer]); } std::vector polygons; layout.get_polygons(polygons); for(std::size_t i = 0; i < polygons.size(); ++i) { ce.insert(polygons[i]); } std::vector > graph(polygons.size() + net_ids.size(), std::set()); ce.extract(graph); return graph; } inline void extract_device_type(std::vector& devices, connectivity_database& connectivity, polygon_set& layout, std::string type) { //recall that P and NDIFF were merged into one DIFF layer in the connectivity database //find the two nets on the DIFF layer that interact with each transistor //and then find the net on the poly layer that interacts with each transistor boost::polygon::connectivity_extraction_90 cediff; std::vector net_ids_diff; std::vector > graph_diff = extract_layer(cediff, net_ids_diff, connectivity, layout, "DIFF"); boost::polygon::connectivity_extraction_90 cepoly; std::vector net_ids_poly; std::vector > graph_poly = extract_layer(cepoly, net_ids_poly, connectivity, layout, "POLY"); std::vector tmp_devices(graph_diff.size() - net_ids_poly.size()); for(std::size_t i = net_ids_poly.size(); i < graph_diff.size(); ++i) { tmp_devices[i - net_ids_diff.size()].type = type; tmp_devices[i - net_ids_diff.size()].terminals = std::vector(3, std::string()); std::size_t j = 0; for(std::set::iterator itr = graph_diff[i].begin(); itr != graph_diff[i].end(); ++itr, ++j) { if(j == 0) { tmp_devices[i - net_ids_diff.size()].terminals[0] = net_ids_diff[*itr]; } else if(j == 1) { tmp_devices[i - net_ids_diff.size()].terminals[2] = net_ids_diff[*itr]; } else { //error, too many diff connections tmp_devices[i - net_ids_diff.size()].terminals = std::vector(3, std::string()); } } j = 0; for(std::set::iterator itr = graph_poly[i].begin(); itr != graph_poly[i].end(); ++itr, ++j) { if(j == 0) { tmp_devices[i - net_ids_diff.size()].terminals[1] = net_ids_poly[*itr]; } else { //error, too many poly connections tmp_devices[i - net_ids_poly.size()].terminals = std::vector(3, std::string()); } } } devices.insert(devices.end(), tmp_devices.begin(), tmp_devices.end()); } //populates vector of devices based on connectivity and layout data inline void extract_devices(std::vector& devices, connectivity_database& connectivity, layout_database& layout) { using namespace boost::polygon::operators; //p-type transistors are gate that interact with p diffusion and nwell polygon_set ptransistors = layout["GATE"]; ptransistors.interact(layout["PDIFF"]); ptransistors.interact(layout["NWELL"]); //n-type transistors are gate that interact with n diffusion and not nwell polygon_set ntransistors = layout["GATE"]; ntransistors.interact(layout["NDIFF"]); polygon_set not_ntransistors = ntransistors; not_ntransistors.interact(layout["NWELL"]); ntransistors -= not_ntransistors; extract_device_type(devices, connectivity, ptransistors, "PTRANS"); extract_device_type(devices, connectivity, ntransistors, "NTRANS"); } #endif