degate  0.1.2
AutoNameGates.cc
Go to the documentation of this file.
00001 #include <AutoNameGates.h>
00002 #include <LogicModelHelper.h>
00003 #include <Layer.h>
00004 
00005 #include <boost/foreach.hpp>
00006 
00007 using namespace degate;
00008 
00009 bool compare_min_x(const Gate_shptr lhs, const Gate_shptr rhs) {
00010   return lhs->get_min_x() < rhs->get_min_x();
00011 }
00012 
00013 bool compare_min_y(const Gate_shptr lhs, const Gate_shptr rhs) {
00014   return lhs->get_min_y() < rhs->get_min_y();
00015 }
00016 
00017 AutoNameGates::AutoNameGates(LogicModel_shptr lmodel, ORIENTATION orientation) :
00018   _lmodel(lmodel),
00019   _orientation(orientation) {
00020   layer = get_first_logic_layer(lmodel);
00021 }
00022 
00023 void AutoNameGates::run() {
00024   std::vector<unsigned int> histogram(std::max(_lmodel->get_width(), 
00025                                                _lmodel->get_height()));
00026 
00027   fill_histogram(_lmodel, histogram, _orientation);
00028   std::list<int> scan_lines = scan_histogram(histogram);
00029   rename_gates(histogram, _orientation, scan_lines);
00030 }
00031 
00032 void AutoNameGates::rename_gates(std::vector<unsigned int> const & histogram, 
00033                                  ORIENTATION orientation,
00034                                  std::list<int> const& scan_lines) const {
00035   
00036   unsigned int col_num = 0;
00037   unsigned int row_num = 0;
00038 
00039   BOOST_FOREACH(int i, scan_lines) {
00040 
00041     // naming = along-rows => histogram along y-axis, following scanlines along x-axis
00042 
00043     
00044     // collect all gates placed along scanline
00045     
00046     std::list<Gate_shptr> gate_list;
00047     
00048     BoundingBox bbox(orientation == ALONG_ROWS ? 0 : i, 
00049                      orientation == ALONG_ROWS ? layer->get_width() - 1 : i, 
00050                      orientation == ALONG_COLS ? 0 : i, 
00051                      orientation == ALONG_COLS ? layer->get_height() - 1 : i);
00052     
00053     for(Layer::qt_region_iterator iter = layer->region_begin(bbox); 
00054         iter != layer->region_end(); ++iter) {
00055       if(Gate_shptr gate = std::dynamic_pointer_cast<Gate>(*iter))
00056         gate_list.push_back(gate);
00057     }
00058     
00059     // sort gate list according to their min_x or min_y
00060     if(orientation == ALONG_ROWS) gate_list.sort(compare_min_x);
00061     else gate_list.sort(compare_min_y);
00062     
00063     // rename gates
00064     BOOST_FOREACH(Gate_shptr gate, gate_list) {
00065       boost::format f("%1%.%2%");
00066       f % row_num % col_num;
00067       gate->set_name(f.str());
00068       
00069       // next row or col
00070       if(_orientation == ALONG_ROWS) col_num++;
00071       else row_num++;      
00072     }
00073     
00074     // next row or col
00075     if(_orientation == ALONG_ROWS) { row_num++; col_num = 0; }
00076     else { col_num++; row_num = 0; }
00077   }
00078 }
00079 
00080 void AutoNameGates::fill_histogram(LogicModel_shptr lmodel,
00081                                    std::vector<unsigned int> & histogram, 
00082                                    ORIENTATION orientation) const {
00083 
00084   int x, y;
00085 
00086   // iterate over gates
00087   for(LogicModel::gate_collection::iterator iter = lmodel->gates_begin();
00088       iter != lmodel->gates_end(); ++iter) {
00089     Gate_shptr gate = (*iter).second;
00090     assert(gate != NULL);
00091     
00092     if(_orientation == ALONG_COLS) 
00093       for(x = gate->get_min_x(); x < gate->get_max_x(); x++)
00094         histogram[x]++;
00095 
00096     if(_orientation == ALONG_ROWS) 
00097       for(y = gate->get_min_y(); y < gate->get_max_y(); y++)
00098         histogram[y]++;
00099   }
00100 }
00101 
00102 std::list<int> AutoNameGates::scan_histogram(std::vector<unsigned int> const & histogram) const {
00103 
00104   std::list<int> scan_lines;
00105 
00106   unsigned int from = 0;
00107   unsigned int i;
00108   for(i = 0; i < histogram.size(); i++) {
00109     if(histogram[i] > 0 && from == 0) from = i;
00110     if(histogram[i] == 0 && from > 0) {
00111       scan_lines.push_back(from + (i - from)/2);
00112       from = 0;
00113     }
00114   }
00115   return scan_lines;
00116 }
00117