-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrouter.h
266 lines (236 loc) · 7.82 KB
/
router.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
#pragma once
#include "lefParser.h"
#include "defParser.h"
#include <list>
#include <time.h>
struct GENRET
{
tuple<rect,rect> e;
int layer=-1; //-1代表布线成功
};
class via
{
public:
float x;
float y;
LEF::via v;
LEF::metal m;
via(float x,float y, LEF::via v, lefParser &lp) : x(x), y(y), v(v), m(lp.getMetal(v.m1)) {}
qstring getName() { return "via"+qstring::number(v.m1); }
qstring getPos()
{
return "( "+qstring::number(int(this->x))+" "+qstring::number(int(this->y))+" )";
}
};
class router
{
private:
optional<rect> checkLine(line l, pinRect* r1, pinRect* r2)
{
for(LEF::cell &c : this->allCell) //可以尝试只检测近邻的以剪枝
{
optional<rect> result=l.checkPinRect(c,r1,r2);
if(result.has_value())
return result;
result=l.checkOBS(c);
if(result.has_value())
return result;
}
rect lr=l.toRect();
for(vector<line> &allLine : this->allNetLine)
{
for(line &li : allLine) //剪枝同上
{
if(l.metal==li.metal)
{
rect lir=li.toRect();
if(lr.isIntersect(lir,l.metal.spacing,l.width))
return lir;
}
}
}
return optional<rect>();
}
tuple<LEF::metal,LEF::metal> switchMetal(LEF::metal m1, LEF::metal m2)
{
int maxNewMetal=max(m1.ID+2,m2.ID+2);
if(maxNewMetal>=this->lp.allMetal.size())
throw string("all Metal disabled");
//都上移两层(因为都是从下层开始的)
LEF::metal newM1=this->lp.getMetal(m1.ID+2);
LEF::metal newM2=this->lp.getMetal(m2.ID+2);
return make_tuple(newM1,newM2);
}
void connectPin(LEF::pin &p1, LEF::pin &p2, vector<line> &allLine, vector<via> &allVia);
bool connectPinRect(LEF::pin &p1, LEF::pin &p2, pinRect *r1, pinRect *r2,
vector<line> &allLine, vector<via> &allVia);
LEF::pin* findLEFPin(qstring instName, qstring pinName)
{
for(LEF::cell &c : this->allCell)
{
if(c.instName==instName)
{
for(LEF::pin &p : c.allPin)
{
if(p.name==pinName)
return &p;
}
}
}
throw string("LEF Pin not Found");
}
/*static tuple<pinRect*,pinRect*> randGetPin(LEF::pin &p1, LEF::pin &p2)
{
auto random=[](unsigned int n) {
float num;
static int i;
float random;
srand(((unsigned int)(time(NULL) + i)));
random = (rand() % n);
i += 311;
return int(random);
};
while(1)
{
pinRect* p1_rect=&p1.allRect[random(p1.allRect.size())];
pinRect* p2_rect=&p2.allRect[random(p2.allRect.size())];
if(!p1_rect->isOccupy && !p2_rect->isOccupy)
return make_tuple(p1_rect,p2_rect);
}
}*/
static tuple<pinRect*,pinRect*,float> getMinDistPinRect(LEF::pin &p1, LEF::pin &p2)
{
//rect中点
float mid_p1_x ;
float mid_p1_y ;
float mid_p2_x ;
float mid_p2_y ;
//rect差值
float div_x ;
float div_y ;
float div ;
//上次计算结果
float last;
int p1_rect_cnt_last=-1;
int p2_rect_cnt_last=-1;
pinRect* p1_rect;
pinRect* p2_rect;
//循环比较
for(int p1_rect_cnt=0;p1_rect_cnt<p1.allRect.size();p1_rect_cnt++)
{
p1_rect = &(p1.allRect[p1_rect_cnt]);
if(p1_rect->isOccupy)
continue;
for(int p2_rect_cnt=0;p2_rect_cnt<p2.allRect.size();p2_rect_cnt++)
{
p2_rect = &(p2.allRect[p2_rect_cnt]);
if(p2_rect->isOccupy)
continue;
tie(mid_p1_x,mid_p1_y)=p1_rect->getMidPos();
tie(mid_p2_x,mid_p2_y)=p2_rect->getMidPos();
div_x = mid_p1_x - mid_p2_x;
div_y = mid_p1_y - mid_p2_y;
div = fabs(div_x) + fabs(div_y);
if((p1_rect_cnt_last == -1) || (p2_rect_cnt_last == -1))
{
last = div ;
p1_rect_cnt_last = p1_rect_cnt;
p2_rect_cnt_last = p2_rect_cnt;
}
else if(div<last)
{
last = div;
p1_rect_cnt_last = p1_rect_cnt;
p2_rect_cnt_last = p2_rect_cnt;
}
}
}
if(p1_rect_cnt_last==-1)
p1_rect_cnt_last=0;
if(p2_rect_cnt_last==-1)
p2_rect_cnt_last=0;
p1_rect = &(p1.allRect[p1_rect_cnt_last]);
p2_rect = &(p2.allRect[p2_rect_cnt_last]);
return make_tuple(p1_rect,p2_rect,last);
}
vector<LEF::pin*> toLEFPinVec(const vector<DEF::pin> &allPin)
{
vector<LEF::pin*> result;
for(DEF::pin i : allPin)
{
LEF::pin* p=this->findLEFPin(i.instName,i.pinName);
result.push_back(p);
}
return result;
}
vector<LEF::pin*> sortAllPin(const vector<DEF::pin> &allPin)
{
vector<LEF::pin*> LEFallPin=this->toLEFPinVec(allPin);
float distance = 0;
float last_distance = 0;
int min_num = 0;
for (int i = 0; i < LEFallPin.size() - 2; i++)
{
for (int j = i + 1; j < LEFallPin.size() - 1; j++)
{
tie(ignore,ignore,distance) = this->getMinDistPinRect(*(LEFallPin[i]), *(LEFallPin[j]));
//在i后面找和i距离最小的
if ((i == 0) && (j == 1)) {
last_distance = distance;
min_num = j;
}
else if (distance < last_distance) {
last_distance = distance;
min_num = j;
}
}
LEF::pin* temp = LEFallPin[min_num];
LEFallPin[min_num] = LEFallPin[i+1];
LEFallPin[i+1] = temp;
}
return LEFallPin;
}
//genLine需要的
optional<rect> checkNewLine(list<line> &newLine, pinRect *r1, pinRect *r2);
optional<list<line>> fixConnect(line l,LEF::metal m1,LEF::metal realM2, pinRect *r1, pinRect *r2);
GENRET genLine(float p1x, float p1y, float p2x, float p2y,
LEF::metal m1, LEF::metal realM2, list<line> &alreadyLine, int layer,
pinRect *r1, pinRect *r2);
public:
defParser dp;
lefParser lp;
//vector<line> allLine; //将net转化为line
vector<vector<line>> allNetLine;
vector<vector<via>> allNetVia;
vector<LEF::cell> allCell; //版图中放置的所有cell(转换为版图坐标系)
router(defParser dp, lefParser lp) : dp(dp), lp(lp)
{
for(DEF::component &c : dp.allComponent)
{
LEF::cell lefC=lp.getCell(c.cellName);
lefC.instName=c.instName;
lefC.setToLayout(c.x,c.y,c.dire);
this->allCell.push_back(lefC);
}
this->connectAllNet();
}
void connectAllNet()
{
for(DEF::net &n : dp.allNet)
{
vector<line> allLine;
vector<via> allVia;
if(n.allPin.size()>1) //两个以上的才需要连
{
auto LEFallPin=this->sortAllPin(n.allPin);
for(int i=1;i<LEFallPin.size();i++)
{
this->connectPin(*(LEFallPin[i-1]),*(LEFallPin[i]),allLine,allVia);
}
}
//所有net按下标都对应一对他俩
this->allNetLine.push_back(allLine);
this->allNetVia.push_back(allVia);
}
}
};