summaryrefslogtreecommitdiffstats
path: root/src/phys/place/place_test.c
diff options
context:
space:
mode:
authorAlan Mishchenko <alanmi@berkeley.edu>2008-01-30 20:01:00 -0800
committerAlan Mishchenko <alanmi@berkeley.edu>2008-01-30 20:01:00 -0800
commit0c6505a26a537dc911b6566f82d759521e527c08 (patch)
treef2687995efd4943fe3b1307fce7ef5942d0a57b3 /src/phys/place/place_test.c
parent4d30a1e4f1edecff86d5066ce4653a370e59e5e1 (diff)
downloadabc-0c6505a26a537dc911b6566f82d759521e527c08.tar.gz
abc-0c6505a26a537dc911b6566f82d759521e527c08.tar.bz2
abc-0c6505a26a537dc911b6566f82d759521e527c08.zip
Version abc80130_2
Diffstat (limited to 'src/phys/place/place_test.c')
-rw-r--r--src/phys/place/place_test.c360
1 files changed, 360 insertions, 0 deletions
diff --git a/src/phys/place/place_test.c b/src/phys/place/place_test.c
new file mode 100644
index 00000000..ea706a09
--- /dev/null
+++ b/src/phys/place/place_test.c
@@ -0,0 +1,360 @@
+/*===================================================================*/
+//
+// place_test.c
+//
+// Aaron P. Hurst, 2003-2007
+// ahurst@eecs.berkeley.edu
+//
+/*===================================================================*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include "place_base.h"
+
+
+// --------------------------------------------------------------------
+// Hash type/functions
+//
+// --------------------------------------------------------------------
+
+struct hash_element {
+ ConcreteCell *obj;
+ struct hash_element *next;
+} hash_element;
+
+int hash_string(int hash_max, const char *str) {
+ unsigned int hash = 0;
+ int p;
+ for(p = 0; p<strlen(str); p++)
+ hash += str[p]*p;
+ return hash % hash_max;
+}
+
+void hash_add(struct hash_element **hash, int hash_max,
+ ConcreteCell *cell) {
+ int key = hash_string(hash_max, cell->m_label);
+ // printf("adding %s key = %d\n", cell->m_label, key);
+ struct hash_element *element = malloc(sizeof(struct hash_element));
+ assert(element);
+ element->obj = cell;
+ element->next = hash[key];
+ hash[key] = element;
+}
+
+ConcreteCell *hash_find(struct hash_element **hash, int hash_max, const char *str) {
+ int key = hash_string(hash_max, str);
+ // printf("looking for %s key = %d\n", str, key);
+ struct hash_element *next = hash[key];
+ while(next) {
+ if (!strcmp(str, next->obj->m_label))
+ return next->obj;
+ next = next->next;
+ }
+ return 0;
+}
+
+// --------------------------------------------------------------------
+// Global variables
+//
+// --------------------------------------------------------------------
+
+struct hash_element **hash_cellname;
+
+int numCells = 0, numNets = 0;
+
+AbstractCell *abstractCells;
+ConcreteCell *concreteCells;
+ConcreteNet *concreteNets;
+
+// --------------------------------------------------------------------
+// Function implementations
+//
+// --------------------------------------------------------------------
+
+void readBookshelfNets(char *filename) {
+ char *tok;
+ char buf[1024];
+ const char *DELIMITERS = " \n\t:";
+ int id = 0;
+ int t;
+ ConcreteCell *cell;
+
+ FILE *netsFile = fopen(filename, "r");
+ if (!netsFile) {
+ printf("ERROR: Could not open .nets file\n");
+ exit(1);
+ }
+
+ // line 1 : version
+ while (fgets(buf, 1024, netsFile) && (buf[0] == '\n' || buf[0] == '#'));
+
+ // line 2 : number of nets
+ while (fgets(buf, 1024, netsFile) && (buf[0] == '\n' || buf[0] == '#'));
+ tok = strtok(buf, DELIMITERS);
+ tok = strtok(NULL, DELIMITERS);
+ numNets = atoi(tok);
+ printf("READ-20 : number of nets = %d\n", numNets);
+ concreteNets = malloc(sizeof(ConcreteNet)*numNets);
+
+ // line 3 : number of pins
+ while (fgets(buf, 1024, netsFile) && (buf[0] == '\n' || buf[0] == '#'));
+
+ // line XXX : net definitions
+ while(fgets(buf, 1024, netsFile)) {
+ if (buf[0] == '\n' || buf[0] == '#') continue;
+
+ concreteNets[id].m_id = id;
+ concreteNets[id].m_weight = 1.0;
+
+ tok = strtok(buf, DELIMITERS);
+ if (!!strcmp(tok, "NetDegree")) {
+ printf("%s\n",buf);
+ printf("ERROR: Incorrect format in .nets file\n");
+ exit(1);
+ }
+
+ tok = strtok(NULL, DELIMITERS);
+ concreteNets[id].m_numTerms = atoi(tok);
+ if (concreteNets[id].m_numTerms < 0 ||
+ concreteNets[id].m_numTerms > 100000) {
+ printf("ERROR: Bad net degree\n");
+ exit(1);
+ }
+ concreteNets[id].m_terms = malloc(sizeof(ConcreteCell*)*
+ concreteNets[id].m_numTerms);
+
+ // read terms
+ t = 0;
+ while(t < concreteNets[id].m_numTerms &&
+ fgets(buf, 1024, netsFile)) {
+ if (buf[0] == '\n' || buf[0] == '#') continue;
+
+ // cell name
+ tok = strtok(buf, DELIMITERS);
+ cell = hash_find(hash_cellname, numCells, tok);
+ if (!cell) {
+ printf("ERROR: Could not find cell %s in .nodes file\n", tok);
+ exit(1);
+ }
+ concreteNets[id].m_terms[t] = cell;
+ t++;
+ }
+
+ // add!
+ addConcreteNet(&(concreteNets[id]));
+
+ id++;
+ }
+
+ fclose(netsFile);
+}
+
+void readBookshelfNodes(char *filename) {
+ char *tok;
+ char buf[1024];
+ const char *DELIMITERS = " \n\t:";
+ int id = 0;
+
+ FILE *nodesFile = fopen(filename, "r");
+ if (!nodesFile) {
+ printf("ERROR: Could not open .nodes file\n");
+ exit(1);
+ }
+
+ // line 1 : version
+ while (fgets(buf, 1024, nodesFile) && (buf[0] == '\n' || buf[0] == '#'));
+
+ // line 2 : num nodes
+ while (fgets(buf, 1024, nodesFile) && (buf[0] == '\n' || buf[0] == '#'));
+ tok = strtok(buf, DELIMITERS);
+ tok = strtok(NULL, DELIMITERS);
+ numCells = atoi(tok);
+ printf("READ-10 : number of cells = %d\n", numCells);
+ concreteCells = malloc(sizeof(ConcreteCell)*numCells);
+ abstractCells = malloc(sizeof(AbstractCell)*numCells);
+ hash_cellname = calloc(numCells, sizeof(struct hash_element*));
+
+ // line 3 : num terminals
+ while (fgets(buf, 1024, nodesFile) && (buf[0] == '\n' || buf[0] == '#'));
+
+ // line XXX : cell definitions
+ while(fgets(buf, 1024, nodesFile)) {
+ if (buf[0] == '\n' || buf[0] == '#') continue;
+
+ tok = strtok(buf, DELIMITERS);
+ concreteCells[id].m_id = id;;
+
+ // label
+ concreteCells[id].m_parent = &(abstractCells[id]);
+ concreteCells[id].m_label = malloc(sizeof(char)*strlen(tok)+1);
+ strcpy(concreteCells[id].m_label, tok);
+ abstractCells[id].m_label = concreteCells[id].m_label;
+ hash_add(hash_cellname, numCells,
+ &(concreteCells[id]));
+
+ // dimensions
+ tok = strtok(NULL, DELIMITERS);
+ abstractCells[id].m_width = atof(tok);
+ tok = strtok(NULL, DELIMITERS);
+ abstractCells[id].m_height = atof(tok);
+ tok = strtok(NULL, DELIMITERS);
+ // terminal
+ abstractCells[id].m_pad = tok && !strcmp(tok, "terminal");
+
+ // add!
+ addConcreteCell(&(concreteCells[id]));
+
+ // DEBUG
+ /*
+ printf("\"%s\" : %f x %f\n", concreteCells[id].m_label,
+ abstractCells[id].m_width,
+ abstractCells[id].m_height);
+ */
+ id++;
+ }
+
+ fclose(nodesFile);
+}
+
+void readBookshelfPlacement(char *filename) {
+ char *tok;
+ char buf[1024];
+ const char *DELIMITERS = " \n\t:";
+ ConcreteCell *cell;
+
+ FILE *plFile = fopen(filename, "r");
+ FILE *netsFile = fopen(filename, "r");
+ if (!plFile) {
+ printf("ERROR: Could not open .pl file\n");
+ exit(1);
+ }
+ if (!netsFile) {
+ printf("ERROR: Could not open .nets file\n");
+ exit(1);
+ }
+
+ // line 1 : version
+ while (fgets(buf, 1024, plFile) && (buf[0] == '\n' || buf[0] == '#'));
+
+ // line XXX : placement definitions
+ while(fgets(buf, 1024, plFile)) {
+ if (buf[0] == '\n' || buf[0] == '#') continue;
+
+ tok = strtok(buf, DELIMITERS);
+
+ // cell name
+ cell = hash_find(hash_cellname, numCells, tok);
+ if (!cell) {
+ printf("ERROR: Could not find cell %s in .nodes file\n",tok);
+ exit(1);
+ }
+
+ // position
+ tok = strtok(NULL, DELIMITERS);
+ cell->m_x = atof(tok);
+ tok = strtok(NULL, DELIMITERS);
+ cell->m_y = atof(tok);
+
+ // hfixed
+ cell->m_fixed = strtok(NULL, DELIMITERS) &&
+ (tok = strtok(NULL, DELIMITERS)) &&
+ !strcmp(tok, "\\FIXED");
+ }
+
+ fclose(plFile);
+}
+
+void writeBookshelfPlacement(char *filename) {
+ int c = 0;
+
+ FILE *plFile = fopen(filename, "w");
+ if (!plFile) {
+ printf("ERROR: Could not open .pl file\n");
+ exit(1);
+ }
+
+ fprintf(plFile, "UCLA pl 1.0\n");
+ for(c=0; c<numCells; c++) {
+ fprintf(plFile, "%s %f %f : N %s\n",
+ concreteCells[c].m_label,
+ concreteCells[c].m_x,
+ concreteCells[c].m_y,
+ (concreteCells[c].m_fixed ? "\\FIXED" : ""));
+ }
+
+ fclose(plFile);
+}
+
+// deletes all connections to a cell
+void delNetConnections(ConcreteCell *cell) {
+ int n, t, t2, count = 0;
+ ConcreteCell **old = malloc(sizeof(ConcreteCell*)*g_place_numCells);
+
+ for(n=0; n<g_place_numNets; n++) if (g_place_concreteNets[n]) {
+ ConcreteNet *net = g_place_concreteNets[n];
+ count = 0;
+ for(t=0; t<net->m_numTerms; t++)
+ if (net->m_terms[t] == cell) count++;
+ if (count) {
+ memcpy(old, net->m_terms, sizeof(ConcreteCell*)*net->m_numTerms);
+ net->m_terms = realloc(net->m_terms,
+ sizeof(ConcreteCell*)*(net->m_numTerms-count));
+ t2 = 0;
+ for(t=0; t<net->m_numTerms; t++)
+ if (old[t] != cell) net->m_terms[t2++] = old[t];
+ net->m_numTerms -= count;
+ }
+ }
+ free(old);
+}
+
+int main(int argc, char **argv) {
+
+ if (argc != 4) {
+ printf("Usage: %s [nodes] [nets] [pl]\n", argv[0]);
+ exit(1);
+ }
+
+ readBookshelfNodes(argv[1]);
+ readBookshelfNets(argv[2]);
+ readBookshelfPlacement(argv[3]);
+
+ globalPreplace(0.8);
+ globalPlace();
+
+ // DEBUG net/cell removal/addition
+ /*
+ int i;
+ for(i=1000; i<2000; i++) {
+ delConcreteNet(g_place_concreteNets[i]);
+ delNetConnections(g_place_concreteCells[i]);
+ delConcreteCell(g_place_concreteCells[i]);
+ }
+
+ ConcreteCell newCell[2];
+ newCell[0].m_id = g_place_numCells+1;
+ newCell[0].m_x = 1000;
+ newCell[0].m_y = 1000;
+ newCell[0].m_fixed = false;
+ newCell[0].m_parent = &(abstractCells[1000]);
+ newCell[0].m_label = " ";
+ addConcreteCell(&newCell[0]);
+ newCell[1].m_id = g_place_numCells+3;
+ newCell[1].m_x = 1000;
+ newCell[1].m_y = 1000;
+ newCell[1].m_fixed = false;
+ newCell[1].m_parent = &(abstractCells[1000]);
+ newCell[1].m_label = " ";
+ addConcreteCell(&newCell[1]);
+ */
+
+ globalIncremental();
+
+ writeBookshelfPlacement(argv[3]);
+
+ free(hash_cellname);
+
+ return 0;
+}