summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRuben Undheim <ruben.undheim@gmail.com>2016-04-13 20:34:28 +0200
committerRuben Undheim <ruben.undheim@gmail.com>2016-04-13 20:34:28 +0200
commit74357fe050d06744339b6c87ec6ff67d8d4eb261 (patch)
tree20325f6750a4e29b073f5e6668b000438357ac51 /src
parent5429619e812ec00cd0d816ef02401516a1ed847e (diff)
parentaacb52b78ac09d620ae4486a542c5015b96efcad (diff)
Merge tag '1.1.31' into upstream
Diffstat (limited to 'src')
-rw-r--r--src/Makefile3
-rw-r--r--src/Makefile.in1
-rw-r--r--src/blifFanout.c103
-rw-r--r--src/readliberty.c3
-rw-r--r--src/vesta.c2
5 files changed, 87 insertions, 25 deletions
diff --git a/src/Makefile b/src/Makefile
index 63bdb06..dca79aa 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -3,7 +3,7 @@
#
# Main compiler arguments
-CFLAGS = -g -O2
+CFLAGS = -g
DEFS = -DPACKAGE_NAME=\"\" -DPACKAGE_TARNAME=\"\" -DPACKAGE_VERSION=\"\" -DPACKAGE_STRING=\"\" -DPACKAGE_BUGREPORT=\"\" -DPACKAGE_URL=\"\" -DSTDC_HEADERS=1 -DHAVE_SETENV=1 -DHAVE_PUTENV=1 -DTCLSH_PATH=\"/bin/tclsh\" -DQFLOW_MAGIC_PATH=\"/usr/local/bin/magic\" -DQFLOW_QROUTER_PATH=\"/usr/local/bin/qrouter\" -DQFLOW_GRAYWOLF_PATH=\"/usr/local/bin/graywolf\" -DQFLOW_YOSYS_PATH=\"/usr/local/bin/yosys\"
LIBS =
LDFLAGS =
@@ -59,6 +59,7 @@ install: $(TARGETS)
(cd $(DESTDIR)${BININSTALL}; $(RM) -f magic; ln -s $(QFLOW_MAGIC_PATH) magic)
@if test "${HAVE_YOSYS}" = "1"; then \
(cd $(DESTDIR)${BININSTALL}; $(RM) -f yosys; ln -s $(QFLOW_YOSYS_PATH) yosys); \
+ (cd $(DESTDIR)${BININSTALL}; $(RM) -f yosys-abc; ln -s $(QFLOW_YOSYS_PATH)-abc yosys-abc); \
fi
uninstall:
diff --git a/src/Makefile.in b/src/Makefile.in
index 09e164d..03bc2fd 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -59,6 +59,7 @@ install: $(TARGETS)
(cd $(DESTDIR)${BININSTALL}; $(RM) -f magic; ln -s $(QFLOW_MAGIC_PATH) magic)
@if test "${HAVE_YOSYS}" = "1"; then \
(cd $(DESTDIR)${BININSTALL}; $(RM) -f yosys; ln -s $(QFLOW_YOSYS_PATH) yosys); \
+ (cd $(DESTDIR)${BININSTALL}; $(RM) -f yosys-abc; ln -s $(QFLOW_YOSYS_PATH)-abc yosys-abc); \
fi
uninstall:
diff --git a/src/blifFanout.c b/src/blifFanout.c
index c566ac6..d812aeb 100644
--- a/src/blifFanout.c
+++ b/src/blifFanout.c
@@ -95,11 +95,11 @@ double MaxOverload = 0.0;
int MaxFanout = 16; // Maximum fanout per node allowed without
// additional buffering.
-double MaxLatency = 100.0; // Maximum variable latency (ps) for which we
+double MaxLatency = 1000.0; // Maximum variable latency (ps) for which we
// are solving. Represents the largest delay
// allowed for any gate caused by total load
// capacitance. This is empirically derived.
-double MaxOutputCap = 18.0; // Maximum capacitance for an output node (fF).
+double MaxOutputCap = 30.0; // Maximum capacitance for an output node (fF).
// Outputs should be able to drive this much
// capacitance within MaxLatency time (ps).
double WireCap = 10.0; // Base capacitance for an output node, estimate
@@ -163,7 +163,7 @@ void showgatelist(void);
void helpmessage(void);
void registernode(char *nodename, int type, struct Gatelist *gl, char *pinname);
void shownodes(void);
-void write_output(FILE *infptr, FILE *outfptr);
+void write_output(int doLoadBalance, FILE *infptr, FILE *outfptr);
struct Gatelist *best_size(struct Gatelist *gl, double amount, char *overload);
void count_gatetype(struct Gatelist *gl, int num_in, int num_out);
@@ -201,6 +201,36 @@ char *find_suffix(char *gatename)
/*
*---------------------------------------------------------------------------
+ * Check if a liberty file function describes a buffer. Since this is the
+ * function of the output pin, it needs only be the input pin (e.g.,
+ * func(Q) = "A"). However, some liberty files repeat the output pin (e.g.,
+ * func(Q) = "Q = A"). Check for both styles.
+ *---------------------------------------------------------------------------
+ */
+
+int is_buffer_func(char *func_text, char *pin_in, char *pin_out) {
+ char *eqptr, esav, *tptr;
+
+ if (!strcmp(func_text, pin_in)) return 1;
+
+ else if ((eqptr = strchr(func_text, '=')) != NULL) {
+ tptr = eqptr + 1;
+ while (isspace(*tptr) && (*tptr != '\0')) tptr++;
+ while ((eqptr > func_text) && isspace(*(eqptr - 1))) eqptr--;
+ esav = *eqptr;
+ *eqptr = '\0';
+ if (!strcmp(func_text, pin_out) && (*tptr != '\0') &&
+ !strcmp(tptr, pin_in)) {
+ *eqptr = esav;
+ return 1;
+ }
+ *eqptr = esav;
+ }
+ return 0;
+}
+
+/*
+ *---------------------------------------------------------------------------
*---------------------------------------------------------------------------
*/
@@ -211,6 +241,8 @@ int main (int argc, char *argv[])
int inputcount;
int gateinputs;
int gatecount;
+ int doLoadBalance = 1;
+ int doFanout = 1;
char *pinname;
char *test;
char *s, *t;
@@ -233,7 +265,7 @@ int main (int argc, char *argv[])
InitializeHashTable(Drivehash);
InitializeHashTable(Gatehash);
- while ((i = getopt(argc, argv, "gnhvl:c:b:i:o:p:s:f:F:")) != EOF) {
+ while ((i = getopt(argc, argv, "fLgnhvl:c:b:i:o:p:s:I:F:")) != EOF) {
switch (i) {
case 'b':
Buffername = strdup(optarg);
@@ -247,7 +279,13 @@ int main (int argc, char *argv[])
case 'p':
Gatepath = strdup(optarg);
break;
- case 'f':
+ case 'f': // fanout only
+ doLoadBalance = 0;
+ break;
+ case 'L': // load balance only
+ doFanout = 0;
+ break;
+ case 'I':
Ignorepath = strdup(optarg);
break;
case 'F':
@@ -357,17 +395,21 @@ int main (int argc, char *argv[])
if (ctest->pins && ctest->pins->next && !ctest->pins->next->next) {
if (ctest->pins->type == PIN_INPUT &&
ctest->pins->next->type == PIN_OUTPUT) {
- if (!strcmp(ctest->function, ctest->pins->name)) {
+ if (is_buffer_func(ctest->function, ctest->pins->name,
+ ctest->pins->next->name)) {
fprintf(stdout, "Using cell \"%s\" for buffers.\n",
ctest->name);
+ Buffername = strdup(ctest->name);
break;
}
}
else if (ctest->pins->type == PIN_OUTPUT &&
ctest->pins->next->type == PIN_INPUT) {
- if (!strcmp(ctest->function, ctest->pins->next->name)) {
+ if (is_buffer_func(ctest->function, ctest->pins->next->name,
+ ctest->pins->name)) {
fprintf(stdout, "Using cell \"%s\" for buffers.\n",
ctest->name);
+ Buffername = strdup(ctest->name);
break;
}
}
@@ -379,7 +421,10 @@ int main (int argc, char *argv[])
gl = (struct Gatelist *)HashLookup(Buffername, Gatehash);
if (gl == NULL) {
- fprintf(stderr, "blifFanout: Buffer cell %s cannot be found.\n",
+ if (Buffername == NULL)
+ fprintf(stderr, "blifFanout: No suitable buffer cell in library.\n");
+ else
+ fprintf(stderr, "blifFanout: Buffer cell %s cannot be found.\n",
Buffername);
return -1;
}
@@ -388,7 +433,7 @@ int main (int argc, char *argv[])
if (buf_in_pin == NULL)
buf_in_pin = strdup(curpin->name);
}
- else if (curpin->type == PIN_INPUT) {
+ else if (curpin->type == PIN_OUTPUT) {
if (buf_out_pin == NULL)
buf_out_pin = strdup(curpin->name);
}
@@ -527,18 +572,20 @@ int main (int argc, char *argv[])
fflush(stdout);
fprintf(stderr, "Top internal fanout is %d (load %g) from node %s,\n"
- "driven by %s with strength %g\n",
+ "driven by %s with strength %g (fF driven at latency %g)\n",
Topfanout, Topload, nlmax->nodename,
nlmax->outputgate->gatename,
- nlmax->outputgatestrength);
+ nlmax->outputgatestrength,
+ MaxLatency);
- fprintf(stderr, "Top fanout load-to-strength ratio is %g\n", Topratio);
+ fprintf(stderr, "Top fanout load-to-strength ratio is %g (latency = %g ps)\n",
+ Topratio, MaxLatency * Topratio);
fprintf(stderr, "Top input node fanout is %d (load %g) from node %s.\n",
Inputfanout, Inputload, nlimax->nodename);
Buffer_count = 0;
- if ((Topfanout > MaxFanout) || (Inputfanout > MaxFanout)) {
+ if (doFanout && ((Topfanout > MaxFanout) || (Inputfanout > MaxFanout))) {
/* Insert buffer trees */
nl = (struct Nodelist *)HashFirst(Nodehash);
@@ -580,7 +627,7 @@ int main (int argc, char *argv[])
nl = (struct Nodelist *)HashNext(Nodehash);
}
}
- write_output(infptr, outfptr);
+ write_output(doLoadBalance, infptr, outfptr);
fprintf(stderr, "%d gates exceed specified minimum load.\n", stren_err_counter);
fprintf(stderr, "%d buffers were added.\n", Buffer_count);
@@ -689,6 +736,10 @@ int read_gate_file(char *gate_file_name)
/* substitutions (this does not include internal, constant */
/* delays in each gate). */
+ // (Diagnostic, for debug)
+ // fprintf(stderr, "Parsing cell \"%s\", \"%s\", function \"%s\"\n",
+ // gl->gatename, gl->gatecell->name, gl->gatecell->function);
+
gl->strength = MaxLatency / gl->delay;
HashPtrInstall(gl->gatename, gl, Gatehash);
gatecount++;
@@ -909,7 +960,7 @@ void shownodes(void)
nl = (struct Nodelist *)HashFirst(Nodehash);
while (nl != NULL) {
- printf("\n\nnode: %s with %d fanout and %g cap",
+ printf("\n\nnode: %s with %d fanout and %g fF cap",
nl->nodename, nl->num_inputs, nl->total_load);
printf("\ndriven by %s, with %g strength.\n",
nl->outputgate->gatename, nl->outputgatestrength);
@@ -922,7 +973,7 @@ void shownodes(void)
*---------------------------------------------------------------------------
*/
-void write_output(FILE *infptr, FILE *outfptr)
+void write_output(int doLoadBalance, FILE *infptr, FILE *outfptr)
{
char *s, *t;
char line[MAXLINE];
@@ -1109,7 +1160,7 @@ void write_output(FILE *infptr, FILE *outfptr)
if (VerboseFlag) printf("\nOutput node %s", t);
nl = (struct Nodelist *)HashLookup(t, Nodehash);
- if (nl != NULL) {
+ if (doLoadBalance && (nl != NULL)) {
if ((nl->ignore == FALSE) && (nl->ratio > 1.0)) {
if (VerboseFlag)
printf("\nGate should be %g times stronger", nl->ratio);
@@ -1128,10 +1179,12 @@ void write_output(FILE *infptr, FILE *outfptr)
glbest = best_size(gl, nl->total_load + MaxOutputCap
+ WireCap, NULL);
if (glbest && (glbest != gl)) {
- needscorrecting = TRUE;
- if (VerboseFlag)
- printf("\nOutput Gate changed from %s to %s\n",
+ if (doLoadBalance) {
+ needscorrecting = TRUE;
+ if (VerboseFlag)
+ printf("\nOutput Gate changed from %s to %s\n",
gl->gatename, glbest->gatename);
+ }
}
}
// Don't attempt to correct gates for which we cannot find a suffix
@@ -1210,7 +1263,7 @@ void write_output(FILE *infptr, FILE *outfptr)
bbest->gatename, buf_in_pin, s, buf_out_pin,
nl->nodename);
}
- if (gl != glbest) {
+ if ((gl != NULL) && (gl != glbest)) {
s = strstr(gateline, gl->gatename);
if (s) {
int glen = strlen(gl->gatename);
@@ -1358,6 +1411,8 @@ void helpmessage(void)
printf("Typically, it will be iterated until convergence (return value 0).\n\n");
printf("valid switches are:\n");
+ printf("\t-f\t\tRun gate fanout buffering only (no load balancing)\n");
+ printf("\t-L\t\tRun gate load balance optimization only (no fanout buffering)\n");
printf("\t-g\t\tDebug mode: parse and print the gate.cfg table\n");
printf("\t-n\t\tDebug mode: parse and print the node list\n");
printf("\t-v\t\tDebug mode: verbose output\n");
@@ -1366,11 +1421,13 @@ void helpmessage(void)
printf("\t-F value\tSet the maximum fanout per node (default %g)\n",
MaxFanout);
printf("\t-b buffername\tSet the name of a buffer gate\n");
+ printf("\t-i pin_name\tSet the name of the buffer gate input pin (used with -b)\n");
+ printf("\t-o pin_name\tSet the name of the buffer gate output pin (used with -b)\n");
printf("\t-s separator\tGate names have \"separator\" before drive strength\n");
- printf("\t-o value\tSet the maximum output capacitance (fF). (default %g)\n",
+ printf("\t-c value\tSet the maximum output capacitance (fF). (default %g)\n",
MaxOutputCap);
printf("\t-p filepath\tSpecify an alternate path and filename for gate.cfg\n");
- printf("\t-f filepath\tSpecify a path and filename for list of nets to ignore\n");
+ printf("\t-I filepath\tSpecify a path and filename for list of nets to ignore\n");
printf("\t-h\t\tprint this help message\n\n");
printf("This will not work at all for tristate gates.\n");
diff --git a/src/readliberty.c b/src/readliberty.c
index 37ee151..991a28f 100644
--- a/src/readliberty.c
+++ b/src/readliberty.c
@@ -529,6 +529,7 @@ read_liberty(char *libfile, char *pattern)
newtable->times = NULL;
newtable->caps = NULL;
newtable->next = tables;
+ newtable->invert = 0;
tables = newtable;
token = advancetoken(flib, 0);
@@ -800,7 +801,7 @@ read_liberty(char *libfile, char *pattern)
}
else if (!strcasecmp(token, "dont_use")) {
free(newcell->name);
- newcell->name == NULL;
+ newcell->name = NULL;
}
else if (!strcasecmp(token, "pin")) {
token = advancetoken(flib, 0); // Open parens
diff --git a/src/vesta.c b/src/vesta.c
index bac0c7f..65d7046 100644
--- a/src/vesta.c
+++ b/src/vesta.c
@@ -1426,6 +1426,8 @@ int find_clock_to_term_paths(connlistptr clockedlist, ddataptr *masterlist, netp
// Find the sources of the clock at the path end
destdir = (testinst->refcell->type & CLK_SENSE_MASK) ? FALLING : RISING;
testconn = find_register_clock(testinst);
+ // If testconn is NULL, this is not a register (latch, maybe?)
+ if (testconn == NULL) continue;
find_clock_source(testconn, &clock2list, destdir);
selecteddest = find_clock_transition(clock2list, testconn, destdir, ~minmax);