⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fplan.cpp

📁 两种btree算法
💻 CPP
字号:
// Project: B*-trees floorplanning
// Advisor: Yao-Wen Chang  <ywchang@cis.nctu.edu.tw>
// Authors: Jer-Ming Hsu   <barz@cis.nctu.edu.tw>
// 	    Hsun-Cheng Lee <gis88526@cis.nctu.edu.tw>
// Sponsor: Arcadia Inc.
// Date:    7/19/2000 ~

//---------------------------------------------------------------------------
#include <fstream>
#include <cstdio>
#include <cstring>
#include <climits>
#include <cassert>
#include <iostream>
#include <ctime>
using namespace std;
//#include <sys/time.h>
//#include <sys/resource.h>

#include "fplan.h"

//---------------------------------------------------------------------------
char line[100],t1[40],t2[40];
ifstream fs;

FPlan::FPlan(double calpha=1){
  norm_area= 1;
  norm_wire= 1;
  cost_alpha=calpha;
}

void FPlan::packing(){
  if(cost_alpha!=1)
     calcWireLength();
}

void FPlan::clear(){
  Area = 0; 
  WireLength = 0;
}

double FPlan::getCost()
{
  //if(cost_alpha==1)
  //   return cost_alpha*(Area/norm_area);
  //else if(cost_alpha < 1e-4)
  //   return (WireLength/norm_wire);
  //else
  //   return cost_alpha*(Area/norm_area)+(1-cost_alpha)*(WireLength/norm_wire);
 
  // outline cost

  double ar = getHeight()/getWidth();
  double ar_cost = ar - outline_ratio;
  ar_cost = ar_cost * ar_cost;
  if( outline_ratio <= 0 )
      ar_cost = 0;

  if( cost_alpha == 1 )
      return cost_alpha*(Area/norm_area) + ar_cost;


  return cost_alpha*(Area/norm_area) + (1-cost_alpha)*(WireLength/norm_wire) + k3*ar_cost;



}

double FPlan::getDeadSpace()
{
  return 100*(Area-TotalArea)/double(Area);
}

void FPlan::normalize_cost(int t)
{
  norm_area = norm_wire = 0;

  for(int i=0; i < t; i++)
  {
    perturb();
    packing();
    norm_area += Area;
    norm_wire += WireLength;
  }
  
  norm_area /= t;
  norm_wire /= t;
  printf("normalize area=%.6f, wire=%.0f\n", norm_area*1e-6, norm_wire);
}

//---------------------------------------------------------------------------
//   Read
//---------------------------------------------------------------------------

char* tail(char *str){
    str[strlen(str)-1]=0;
    return str;
}

void FPlan::read(char *file){
  filename = file; 
  fs.open(file);
  if(fs==NULL)
    error("unable to open file: %s",file);

  bool final=false;
  Module dummy_mod;
  for(int i=0; !fs.eof(); i++){
    // modules
    modules.push_back(dummy_mod);	// new module
    Module &mod = modules.back();
    mod.id = i;
    mod.pins.clear();
    mod.no_rotate = false;

    fs >> t1 >> t2;
    tail(t2);			// remove ";"
    strcpy(mod.name,t2);

    fs >> t1 >> t2;
    if(!strcmp(t2,"PARENT;"))
	final= true;
    
    // dimension
    read_dimension(mod);    
    read_IO_list(mod,final);

    // network
    if(final){
      read_network();
      break;
    }
  }

  root_module = modules.back();
  modules.pop_back();		// exclude the parent module
  modules_N = (int)modules.size();  
  modules_info.resize(modules_N);
  modules.resize(modules_N);

  create_network();

  TotalArea = 0;
  for(int i=0; i < modules_N; i++)
    TotalArea += modules[i].area;

}

void FPlan::read_dimension(Module &mod){
    fs >> t1;
    int min_x=INT_MAX,min_y=INT_MAX,max_x=INT_MIN,max_y=INT_MIN;
    int tx,ty;
    for(int i=0; i < 4;i++){
      fs >> tx >> ty; 
      min_x=min(min_x,tx); max_x=max(max_x,tx);
      min_y=min(min_y,ty); max_y=max(max_y,ty);
    }

    mod.x      = min_x;
    mod.y      = min_y;
    mod.width  = max_x - min_x;
    mod.height = max_y - min_y;
    mod.area   = mod.width * mod.height;
    fs >> t1 >> t2;
}

void FPlan::read_IO_list(Module &mod,bool parent=false){
    // IO list
    while(!fs.eof()){
      Pin p;
      fs.getline(line,100);
      if(strlen(line)==0) continue;
      sscanf(line,"%s %*s %d %d",t1,&p.x,&p.y);

      if(!strcmp(t1,"ENDIOLIST;"))
	break;

      if(parent){ // IO pad is network
       // make unique net id
        net_table.insert(make_pair(string(t1),net_table.size()));
        p.net = net_table[t1];
      }

      p.mod = mod.id;
      p.x -= mod.x;  p.y -= mod.y;	// shift to origin

      mod.pins.push_back(p);
    }
    fs.getline(line,100);
}

void FPlan::read_network(){
    while(!fs.eof()){
      bool end=false;
      int n=0;
      fs >> t1 >> t2;
      if(!strcmp(t1,"ENDNETWORK;"))
        break;
      // determine which module interconnection by name
      int m_id;
      for(m_id=0; m_id < modules.size(); m_id++)
        if(!strcmp(modules[m_id].name,t2))
   	  break;
      if(m_id== modules.size())
 	error("can't find suitable module name!");
        
      while(!fs.eof()){
        fs >> t1;
        if(t1[strlen(t1)-1]==';'){
 	  tail(t1);
          end=true;
        }

        // make unique net id
        net_table.insert(make_pair(string(t1),net_table.size()));
        modules[m_id].pins[n++].net = net_table[t1];
        if(end) break;
      }
    }
}









void FPlan::read_simple(char *file)
{
  filename = file; 
  fs.open(file);
  if(fs==NULL)
    error("unable to open file: %s",file);

  Module dummy_mod;
  for(int i=0; !fs.eof(); i++)
  {
    // modules
    modules.push_back(dummy_mod);	// new module
    Module &mod = modules.back();
    mod.id = i;
    mod.pins.clear();
    mod.no_rotate = false;

    fs >> t2;
    strcpy(mod.name, t2);

    fs >> t1 >> t2;
	mod.width = atoi( t1 );
	mod.height = atoi( t2 );
	mod.area = mod.width * mod.height;
  }

  root_module = modules.back();
  modules.pop_back();		// exclude the parent module
  modules_N = modules.size();  
  modules_info.resize(modules_N);
  modules.resize(modules_N);

  //create_network();

  TotalArea = 0;
  for(int i=0; i < modules_N; i++)
    TotalArea += modules[i].area;


}




//---------------------------------------------------------------------------
//   Wire Length Estimate
//---------------------------------------------------------------------------

void FPlan::create_network(){
  network.resize(net_table.size());

  for(int i=0; i < modules_N; i++){
    for(int j=0; j < modules[i].pins.size(); j++){
      Pin &p = modules[i].pins[j];
      network[p.net].push_back(&p);
    }
  }

  for(int j=0; j < root_module.pins.size(); j++){
    Pin &p = root_module.pins[j];
    network[p.net].push_back(&p);
  }

  connection.resize(modules_N+1);
  for(int i=0; i < modules_N+1; i++){
    connection[i].resize(modules_N+1);
    fill(connection[i].begin(), connection[i].end(), 0);
  }

  for(int i=0; i < network.size(); i++){
    for(int j=0; j < network[i].size()-1; j++){
      int p= network[i][j]->mod;
      for(int k=j+1 ; k < network[i].size(); k++){
        int q= network[i][k]->mod;
        connection[p][q]++;
        connection[q][p]++;   
      }
    }
  }
}


void FPlan::scaleIOPad(){
  double px = Width/double(root_module.width);
  double py = Height/double(root_module.height);
    
  for(int i=0; i < root_module.pins.size(); i++){
    Pin &p = root_module.pins[i];
    p.ax = int(px * p.x);
    p.ay = int(py * p.y);
    
  }      
}

double FPlan::calcWireLength(){

  scaleIOPad();
 
  WireLength=0;
  // compute absolute position
  for(int i=0; i < modules_N; i++){   
    int mx= modules_info[i].x, my= modules_info[i].y;
    bool rotate= modules_info[i].rotate;
    int w= modules[i].width;

    for(int j=0; j < modules[i].pins.size(); j++){
      Pin &p = modules[i].pins[j];

      if(!rotate){      
        p.ax= p.x+mx, p.ay= p.y+my;
      }
      else{ // Y' = W - X, X' = Y
	p.ax= p.y+mx, p.ay= (w-p.x)+my;
      } 
    }
  }

  for(int i=0; i < network.size(); i++){     
    int max_x= INT_MIN, max_y= INT_MIN;      
    int min_x= INT_MAX, min_y= INT_MAX;      

    assert(network[i].size() > 0);
    for(int j=0; j < network[i].size(); j++){
      Pin &p = *network[i][j];
      max_x= max(max_x, p.ax), max_y= max(max_y, p.ay);
      min_x= min(min_x, p.ax), min_y= min(min_y, p.ay);
    }
//    printf("%d %d %d %d\n",max_x,min_x,max_y,min_y);
    WireLength += (max_x-min_x)+(max_y-min_y);
  }
  return WireLength;
}

//---------------------------------------------------------------------------
//   Modules Information
//---------------------------------------------------------------------------

string query_map(map<string,int> M,int value){
  for(map<string,int>::iterator p=M.begin(); p != M.end(); p++){
    if(p->second == value)
      return p->first;
  }
  return "";
}

void FPlan::show_modules()
{
  for(int i=0; i < modules.size();i++){
    cout << "Module: " << modules[i].name << endl;
    cout << "  Width = " << modules[i].width;
    cout << "  Height= " << modules[i].height << endl;
    cout << "  Area  = " << modules[i].area << endl;
//    cout << modules[i].pins.size() << " Pins:\n";
//    for(int j=0; j < modules[i].pins.size(); j++){
//      cout << query_map(net_table,modules[i].pins[j].net) << " ";
//      cout << modules[i].pins[j].x << " " << modules[i].pins[j].y << endl;
//    }
  }
}

void FPlan::outDraw( const char* filename )
{

    FILE *fs = fopen( filename, "w" );
	for( int i=0; i<modules_N; i++ )
	{
		fprintf( fs,"RECT %s %d %d %d %d 0\n",
			modules[i].name,
			modules_info[i].x, 
			modules_info[i].y,
			modules_info[i].rx - modules_info[i].x,
			modules_info[i].ry - modules_info[i].y );
	}
    fclose(fs);
}

void FPlan::list_information(){

  string info = filename + ".info";   
  ofstream of(info.c_str());
  
  of << modules_N << " " << Width << " " << Height << endl;
  for(int i=0; i < modules_N; i++){
    of << modules_info[i].x  << " " << modules_info[i].rx  << " ";
    of << modules_info[i].y << " " << modules_info[i].ry << endl;
  }
  of << endl;

  calcWireLength(); 
  int x,y,rx,ry;
  for(int i=0; i < network.size(); i++){
    assert(network[i].size()>0);
    x = network[i][0]->ax;
    y = network[i][0]->ay;
    
    for(int j=1; j < network[i].size(); j++){
      rx = network[i][j]->ax;
      ry = network[i][j]->ay;
      of << x << " " << y << " " << rx << " " << ry << endl;
      x = rx, y = ry;
    }
  }

  cout << "Num of Module  = " << modules_N << endl;
  cout << "Total Area     = " << TotalArea*1e-6 << endl;
  cout << "Height         = " << Height*1e-3 << endl;
  cout << "Width          = " << Width*1e-3 << endl;
  cout << "Aspect Ratio   = " << getAR() << endl; 

  if( outline_ratio > 0 )
  {
      if( Height <= outline_height && Width <= outline_width )
      {
          printf( "Fit into the outline.\n" );
      }
  }

  cout << "\nArea           = " << Area*1e-6 << endl;
  cout << "Wire Length    = " << calcWireLength()*1e-3 << endl;
  printf( "Dead Space     = %.2f\n\n", getDeadSpace());

}



//---------------------------------------------------------------------------
//   Auxilliary Functions
//---------------------------------------------------------------------------

void error(char *msg,char *msg2/*=""*/)
{
  printf(msg,msg2);
  cout << endl;
  throw 1;
}

bool rand_bool()
{
	return bool( rand()%2 == 0 );
}

double rand_01()
{
  return double(rand()%10000)/10000;
}

double seconds()
{
	//rusage time;
	//getrusage(RUSAGE_SELF,&time);
	//return (double)(1.0*time.ru_utime.tv_sec+0.000001*time.ru_utime.tv_usec);
	return (double)clock()/CLOCKS_PER_SEC;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -