-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathhotfloorplan.c
217 lines (194 loc) · 7.51 KB
/
hotfloorplan.c
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
/*
* HotFloorplan is a temperature-aware floorplanning tool
* that can be easily modified to optimize for any arbitrary
* metric. This program reads in a floorplan description
* file that has the area, aspect ratio and connectivity
* information of a set of functional blocks. It also reads
* in a file with the average power dissipation values for
* those blocks and outputs the best floorplan it can find
* that optimizes the specified metric.
*/
#include <stdio.h>
#include <string.h>
#ifdef _MSC_VER
#define strcasecmp _stricmp
#define strncasecmp _strnicmp
#else
#include <strings.h>
#endif
#include "flp.h"
#include "temperature.h"
#include "wire.h"
#include "util.h"
#include "hotfloorplan.h"
void usage(int argc, char **argv)
{
fprintf(stdout, "Usage: %s -f <file> -p <file> -o <file> [-c <file>] [-d <file>] [options]\n", argv[0]);
fprintf(stdout, "Finds a thermally-aware floorplan for the given functional blocks.\n");
fprintf(stdout, "Options:(may be specified in any order, within \"[]\" means optional)\n");
fprintf(stdout, " -f <file>\tfloorplan description input file (e.g. ev6.desc)\n");
fprintf(stdout, " -p <file>\tpower input file (e.g. avg.p)\n");
fprintf(stdout, " -o <file>\tfloorplan output file\n");
fprintf(stdout, " [-c <file>]\tinput configuration parameters from file (e.g. hotspot.config)\n");
fprintf(stdout, " [-d <file>]\toutput configuration parameters to file\n");
fprintf(stdout, " [options]\tzero or more options of the form \"-<name> <value>\",\n");
fprintf(stdout, " \toverride the options from config file\n");
}
/*
* parse a table of name-value string pairs and add the configuration
* parameters to 'config'
*/
void global_config_from_strs(global_config_t *config, str_pair *table, int size)
{
int idx;
if ((idx = get_str_index(table, size, "f")) >= 0) {
if(sscanf(table[idx].value, "%s", config->flp_desc) != 1)
fatal("invalid format for configuration parameter flp_desc\n");
} else {
fatal("required parameter flp_desc missing. check usage\n");
}
if ((idx = get_str_index(table, size, "p")) >= 0) {
if(sscanf(table[idx].value, "%s", config->power_in) != 1)
fatal("invalid format for configuration parameter power_in\n");
} else {
fatal("required parameter power_in missing. check usage\n");
}
if ((idx = get_str_index(table, size, "o")) >= 0) {
if(sscanf(table[idx].value, "%s", config->flp_out) != 1)
fatal("invalid format for configuration parameter flp_out\n");
} else {
fatal("required parameter flp_out missing. check usage\n");
}
if ((idx = get_str_index(table, size, "c")) >= 0) {
if(sscanf(table[idx].value, "%s", config->config) != 1)
fatal("invalid format for configuration parameter config\n");
} else {
strcpy(config->config, NULLFILE);
}
if ((idx = get_str_index(table, size, "d")) >= 0) {
if(sscanf(table[idx].value, "%s", config->dump_config) != 1)
fatal("invalid format for configuration parameter dump_config\n");
} else {
strcpy(config->dump_config, NULLFILE);
}
}
/*
* convert config into a table of name-value pairs. returns the no.
* of parameters converted
*/
int global_config_to_strs(global_config_t *config, str_pair *table, int max_entries)
{
if (max_entries < 5)
fatal("not enough entries in table\n");
sprintf(table[0].name, "f");
sprintf(table[1].name, "p");
sprintf(table[2].name, "o");
sprintf(table[3].name, "c");
sprintf(table[4].name, "d");
sprintf(table[0].value, "%s", config->flp_desc);
sprintf(table[1].value, "%s", config->power_in);
sprintf(table[2].value, "%s", config->flp_out);
sprintf(table[3].value, "%s", config->config);
sprintf(table[4].value, "%s", config->dump_config);
return 5;
}
void print_wire_delays(flp_t *flp, double frequency)
{
int i, j;
double delay_g, delay_i;
fprintf(stdout, "printing wire delay between blocks for global and intermediate metal layers:\n");
fprintf(stdout, "(in %.1f GHz cycles)\n", frequency / 1.0e9);
fprintf(stdout, "name1\tname2\tglobal\tintermediate\n");
for (i=0; i < flp->n_units-1; i++)
for (j=i+1; j < flp->n_units; j++)
if (flp->wire_density[i][j]) {
delay_g = wire_length2delay(get_manhattan_dist(flp, i, j), WIRE_GLOBAL);
delay_i = wire_length2delay(get_manhattan_dist(flp, i, j), WIRE_INTER);
fprintf(stdout, "%s\t%s\t%.3f\t%.3f\n", flp->units[i].name, flp->units[j].name,
frequency * delay_g, frequency * delay_i);
}
}
/* main function for the floorplanner */
int main(int argc, char **argv)
{
flp_desc_t *flp_desc;
flp_t *flp;
RC_model_t *model;
double *power;
thermal_config_t thermal_config;
flp_config_t flp_config;
global_config_t global_config;
str_pair table[MAX_ENTRIES];
int size, compacted;
if (!(argc >= 7 && argc % 2)) {
usage(argc, argv);
return 1;
}
size = parse_cmdline(table, MAX_ENTRIES, argc, argv);
global_config_from_strs(&global_config, table, size);
/* read configuration file */
if (strcmp(global_config.config, NULLFILE))
size += read_str_pairs(&table[size], MAX_ENTRIES, global_config.config);
/*
* in the str_pair 'table', earlier entries override later ones.
* so, command line options have priority over config file
*/
size = str_pairs_remove_duplicates(table, size);
/* get defaults */
thermal_config = default_thermal_config();
flp_config = default_flp_config();
/* modify according to command line / config file */
thermal_config_add_from_strs(&thermal_config, table, size);
flp_config_add_from_strs(&flp_config, table, size);
/* dump configuration if specified */
if (strcmp(global_config.dump_config, NULLFILE)) {
size = global_config_to_strs(&global_config, table, MAX_ENTRIES);
size += thermal_config_to_strs(&thermal_config, &table[size], MAX_ENTRIES-size);
size += flp_config_to_strs(&flp_config, &table[size], MAX_ENTRIES-size);
/* prefix the name of the variable with a '-' */
dump_str_pairs(table, size, global_config.dump_config, "-");
}
/* If the grid model is used, things could be really slow!
* Also make sure it is not in the 3-d chip mode (specified
* with the layer configuration file)
*/
if (!strcmp(thermal_config.model_type, GRID_MODEL_STR)) {
if (strcmp(thermal_config.grid_layer_file, NULLFILE))
fatal("lcf file specified with the grid model. 3-d chips not supported\n");
warning("grid model is used. HotFloorplan could be REALLY slow\n");
}
/* description of the functional blocks to be floorplanned */
flp_desc = read_flp_desc(global_config.flp_desc, &flp_config);
/*
* just an empty frame with blocks' names.
* block positions not known yet.
*/
flp = flp_placeholder(flp_desc);
/* temperature model */
model = alloc_RC_model(&thermal_config, flp, 0);
/* input power vector */
power = hotspot_vector(model);
read_power(model, power, global_config.power_in);
/* main floorplanning routine */
compacted = floorplan(flp, flp_desc, model, power);
/*
* print the finally selected floorplan in a format that can
* be understood by tofig.pl (which converts it to a FIG file)
*/
print_flp_fig(flp);
/* print the floorplan statistics */
if (flp_config.wrap_l2 &&
!strcasecmp(flp_desc->units[flp_desc->n_units-1].name, flp_config.l2_label))
print_flp_stats(flp, model, flp_config.l2_label,
global_config.power_in, global_config.flp_desc);
/* print the wire delays between blocks */
print_wire_delays(flp, thermal_config.base_proc_freq);
/* also output the floorplan to a file readable by hotspot */
dump_flp(flp, global_config.flp_out, FALSE);
free_flp_desc(flp_desc);
delete_RC_model(model);
free_dvector(power);
/* while deallocating, free the compacted blocks too */
free_flp(flp, compacted);
return 0;
}