Compare commits

...
19 Commits
Author SHA1 Message Date
Tim Edwards ad05d059c7 Merge branch 'master' into netgen-1.5 2020-07-31 03:00:27 -04:00
Tim Edwards 85eb34c01e Made several corrections to handling of proxy pins when matching
black-box circuits, especially those coming from verilog netlists
where a pin does not need to be declared and is implicitly floating.
This prevents the need to have an explicit black-box entry for any
verilog module that may have an instance that does not declare all
the pin connections.  Also corrected an error which causes mysterious
failures if a verilog netlist is read before a SPICE netlist,
because the former gets hashed case-sensitive and the latter changes
the hashing to case-insensitive.  Modified to force the SPICE
netlist to be treated case-sensitive, which may cause errors, but
is consistent with the reverse order handling, and doesn't cause
unexplained errors.
2020-07-30 22:51:34 -04:00
Tim Edwards 8a24c6c3ca Modified the ResolveAutomorphisms() routine once again, to break
symmetry of all elements in all symmetric partitions, rather than
(as previously done) all elements in each partition, before re-
running iterations to convergence.  This solves the problem of
having a very large number of partitions with a few elements each
taking a long time to run.
2020-07-30 14:48:08 -04:00
Tim Edwards 46cdf48bc4 Updated the version to force the tarball and github mirror. 2020-07-30 08:10:09 -04:00
Tim Edwards 9d542b92b0 Corrected one logical error in netcmp.c from the last commit,
discovered and fixed by Ahmed Ghazy.
2020-07-30 08:06:44 -04:00
Tim Edwards 1b2cd1497c Merge branch 'master' into netgen-1.5 2020-07-30 03:00:28 -04:00
Tim Edwards 71ad228d8d Modified the symmetry breaking routine that arbitrarily resolves
automorphisms so that it arbitrarily assigns all pairs from
circuit1 and circuit2 at once rather than assigning one pair at
a time and rerunning to convergence.  I'm not sure of the validity
of this, other than that I have never seen a circuit fail to match
after resolving automorphisms, leading me to believe that the way
the symmetry breaking is done is irrelevant.
2020-07-29 21:13:45 -04:00
Tim Edwards 339a0d5d4e Updated version to force the new tarball and github mirror. 2020-07-29 13:59:24 -04:00
Tim Edwards 9cebb76787 Corrected a problem in ResolveAutomorphsByProperty() that causes
long run-times even when there are no properties to check.  Corrected
a problem with SPICE and verilog netlist reading which arbitrarily
replaces file extensions even when a file extension is given,
resulting in reading the wrong file.
2020-07-29 13:57:08 -04:00
Tim Edwards d9d5a46c6e Merge branch 'master' into netgen-1.5 2020-07-25 03:00:09 -04:00
Tim Edwards 251622c8bc Corrected the routines DescendCountQueue and DescendCompareQueue
to include type CLASS_MODULE in the list of types to descend into,
since "module" (black-box) types need to be checked for pin
matching even if they have no contents.  This allows two verilog
netlists to be compared against each other.
2020-07-24 20:50:07 -04:00
Tim Edwards d73b711e3a Merge branch 'master' into netgen-1.5 2020-07-02 03:00:09 -04:00
Tim Edwards 18739235a9 Extended the code from the last commit to cover cases in which the
definition covers multiple lines;  this also is a general handler
of the backslash-newline continuation line.
2020-07-01 16:00:54 -04:00
Tim Edwards 07c493c796 Corrected the verilog parser's behavior with respect to string
definitions:  Now correctly parses everything from the definition
name to the end of line as the definition value.  Also:  The
search for definitions in the body of the text does not reject
non-alphanumerics "_" and "$" in the definition name, without
which definition names containing those characters will go
unrecongized.  Have not yet extended this to multi-line definition
values.
2020-07-01 14:28:00 -04:00
Tim Edwards cca0e4b3f3 Corrected an error in bundle assignment that failed to make a copy
of the root name of the LHS net, and so would use the last root
name copied, which might have belonged to something entirely
different, or nothing at all.
2020-07-01 13:11:37 -04:00
Tim Edwards 1428580109 Merge branch 'master' into netgen-1.5 2020-06-17 03:00:38 -04:00
Tim Edwards fb0e1d10b0 Added back a correction that did not get made in this code base
and so didn't make it into the commit.  Handles implicit pins in
verilog.
2020-06-16 17:16:30 -04:00
Tim Edwards 6f81e1d294 Removed a restriction on the "equate pins" command such that pins
are matched on circuits that have no elements.  This condition
does not necessarily indicate an error, and matching pins has no
adverse affect (while refusing to match them certainly can).
2020-06-16 15:56:59 -04:00
Tim Edwards cec6d89474 Corrected an uninitialized variable error in the verilog reading code
that produces a segfault condition.
2020-06-16 12:52:29 -04:00
9 changed files with 239 additions and 68 deletions
+1 -1
View File
@@ -1 +1 @@
1.5.147
1.5.152
+123 -35
View File
@@ -3145,7 +3145,9 @@ void DescendCountQueue(struct nlist *tc, int *level, int loclevel)
if (ob->type == FIRSTPIN) {
/* First check if there is a class equivalent */
tcsub = LookupCellFile(ob->model.class, tc->file);
if (!tcsub || (tcsub->class != CLASS_SUBCKT)) continue;
/* Module (black-box) class needs pin checking */
if (!tcsub || ((tcsub->class != CLASS_SUBCKT) &&
(tcsub->class != CLASS_MODULE))) continue;
else if (tcsub == tc) continue;
DescendCountQueue(tcsub, level, loclevel + 1);
}
@@ -3238,7 +3240,8 @@ void DescendCompareQueue(struct nlist *tc, struct nlist *tctop, int stoplevel,
tcsub = NULL;
if (ob->type == FIRSTPIN) {
tcsub = LookupCellFile(ob->model.class, tc->file);
if (!tcsub || (tcsub->class != CLASS_SUBCKT)) continue;
if (!tcsub || ((tcsub->class != CLASS_SUBCKT) &&
(tcsub->class != CLASS_MODULE))) continue;
else if (tcsub == tc) continue;
DescendCompareQueue(tcsub, tctop, stoplevel, loclevel + 1, flip);
}
@@ -5283,8 +5286,10 @@ PropertyMatch(struct objlist *ob1, struct objlist *ob2, int do_print,
obn1 = tp1;
for (tp2 = ob2->next; (tp2 != NULL) && tp2->type > FIRSTPIN; tp2 = tp2->next)
obn2 = tp2;
if (tp1 && (tp1->type == FIRSTPIN)) tp1 = NULL; /* tp1 had no properties */
if (tp2 && (tp2->type == FIRSTPIN)) tp2 = NULL; /* tp2 had no properties */
if (tp1 && ((tp1->type == FIRSTPIN) || (tp1->type == NODE)))
tp1 = NULL; /* tp1 had no properties */
if (tp2 && ((tp2->type == FIRSTPIN) || (tp2->type == NODE)))
tp2 = NULL; /* tp2 had no properties */
/* Check if there are any properties to match */
@@ -5685,21 +5690,20 @@ int ResolveAutomorphsByPin()
struct Node *N;
int C1, C2;
unsigned long newhash, orighash;
struct nlist *tc1, *tc2;
struct objlist *tob, *ob1, *ob2;
int portnum;
/* Diagnostic */
Fprintf(stdout, "Resolving automorphisms by pin name.\n");
for (NC = NodeClasses; NC != NULL; NC = NC->next) {
struct Node *N1, *N2;
C1 = C2 = 0;
N1 = N2 = NULL;
for (N = NC->nodes; N != NULL; N = N->next) {
if (N->graph == Circuit1->file) {
if (N->graph == Circuit1->file)
C1++;
}
else {
else
C2++;
}
}
if (C1 == C2 && C1 != 1) {
@@ -5711,7 +5715,6 @@ int ResolveAutomorphsByPin()
orighash = NC->nodes->hashval;
for (N1 = NC->nodes; N1 != NULL; N1 = N1->next) {
if (N1->hashval != orighash) continue;
ob1 = N1->object;
for (N2 = N1->next; N2 != NULL; N2 = N2->next) {
if ((N2->graph != N1->graph) &&
(*matchfunc)(N2->object->name, N1->object->name)) {
@@ -5749,6 +5752,9 @@ int ResolveAutomorphsByProperty()
int C1, C2, result, badmatch;
unsigned long orighash, newhash;
/* Diagnostic */
Fprintf(stdout, "Resolving automorphisms by property value.\n");
for (EC = ElementClasses; EC != NULL; EC = EC->next) {
struct Element *E1, *E2;
C1 = C2 = 0;
@@ -5785,7 +5791,6 @@ int ResolveAutomorphsByProperty()
badmatch = FALSE;
for (E2 = E1->next; E2 != NULL; E2 = E2->next) {
if (E2->hashval != orighash) continue;
if (E2->graph == E1->graph) continue;
if (E1->graph == Circuit1->file)
PropertyMatch(E1->object, E2->object, FALSE, FALSE, &result);
else
@@ -5836,21 +5841,20 @@ int ResolveAutomorphsByProperty()
/*
*-------------------------------------------------------------------------
*
* ResolveAutormorphisms --
* ResolveElementAutomorphisms --
*
* Arbitrarily equivalence one pair of elements within an automorphic class
* Apply arbitrary symmetry breaking to symmetric element lists, then
* iterate exhaustively to resolve all automorphisms.
*
* Return value is the same as VerifyMatching()
*
*-------------------------------------------------------------------------
*/
int ResolveAutomorphisms()
int ResolveElementAutomorphisms()
{
struct ElementClass *EC;
struct NodeClass *NC;
struct Element *E;
struct Node *N;
int C1, C2;
for (EC = ElementClasses; EC != NULL; EC = EC->next) {
@@ -5869,13 +5873,55 @@ int ResolveAutomorphisms()
}
if (C1 == C2 && C1 != 1) {
unsigned long newhash;
Magic(newhash);
E1->hashval = newhash;
E2->hashval = newhash;
goto converge;
/* Do all of them at once. */
/* NOTE: If this were to fail for some reason, it would */
/* probably be necessary to do this the original slow way */
/* which is to rehash one pair at a time and iterate to */
/* convergence, and repeat. */
E1 = E2 = EC->elements;
while (E1 != NULL && E2 != NULL) {
while (E1->graph != Circuit1->file) E1 = E1->next;
while (E2->graph != Circuit2->file) E2 = E2->next;
Magic(newhash);
E1->hashval = newhash;
E2->hashval = newhash;
E1 = E1->next;
E2 = E2->next;
}
}
}
FractureElementClass(&ElementClasses);
FractureNodeClass(&NodeClasses);
ExhaustiveSubdivision = 1;
while (!Iterate() && VerifyMatching() != -1);
return(VerifyMatching());
}
/*
*-------------------------------------------------------------------------
*
* ResolveNodeAutomorphisms --
*
* Apply arbitrary symmetry breaking to symmetric node lists, then iterate
* exhaustively to resolve all automorphisms. Normally, all automorphisms
* should be resolved by ResolveElementAutomorphisms(). It is likely true
* that this routine will never run, by definition.
*
* Return value is the same as VerifyMatching()
*
*-------------------------------------------------------------------------
*
*/
int ResolveNodeAutomorphisms()
{
struct Node *N;
struct NodeClass *NC;
int C1, C2;
for (NC = NodeClasses; NC != NULL; NC = NC->next) {
struct Node *N1, *N2;
C1 = C2 = 0;
@@ -5892,14 +5938,26 @@ int ResolveAutomorphisms()
}
if (C1 == C2 && C1 != 1) {
unsigned long newhash;
Magic(newhash);
N1->hashval = newhash;
N2->hashval = newhash;
goto converge;
/* Do all of them at once */
/* NOTE: If this were to fail for some reason, it would */
/* probably be necessary to do this the original slow way */
/* which is to rehash one pair at a time and iterate to */
/* convergence, and repeat. */
N1 = N2 = NC->nodes;
while (N1 != NULL && N2 != NULL) {
while (N1->graph != Circuit1->file) N1 = N1->next;
while (N2->graph != Circuit2->file) N2 = N2->next;
Magic(newhash);
N1->hashval = newhash;
N2->hashval = newhash;
N1 = N1->next;
N2 = N2->next;
}
}
}
converge:
FractureElementClass(&ElementClasses);
FractureNodeClass(&NodeClasses);
ExhaustiveSubdivision = 1;
@@ -5907,6 +5965,29 @@ int ResolveAutomorphisms()
return(VerifyMatching());
}
/*
*-------------------------------------------------------------------------
*
* ResolveAutormorphisms --
*
* Arbitrarily equivalence one pair of elements within an automorphic class
*
* Return value is the same as VerifyMatching()
*
*-------------------------------------------------------------------------
*/
int ResolveAutomorphisms()
{
int result;
result = ResolveElementAutomorphisms();
if (result != 0)
result = ResolveNodeAutomorphisms();
return result;
}
/*------------------------------------------------------*/
/* PermuteSetup -- */
/* Add an entry to a cell's "permutes" linked list. */
@@ -6611,7 +6692,7 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist)
struct NodeClass *NC;
struct Node *N1, *N2;
int i, j, k, m, a, b, swapped, numnodes, numorig;
int result = 1, haspins = 0;
int result = 1, haspins = 0, notempty = 0;
int hasproxy1 = 0, hasproxy2 = 0;
int needclean1 = 0, needclean2 = 0;
char *ostr;
@@ -6776,12 +6857,15 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist)
/* has been left orphaned after flattening. If */
/* disconnected, set its node number to -2. */
notempty = 0;
for (obt = ob1->next; obt; obt = obt->next) {
if (obt->type >= FIRSTPIN)
if (obt->type >= FIRSTPIN) {
notempty = 1;
if (obt->node == ob1->node)
break;
}
}
if (obt == NULL) {
if ((obt == NULL) && (notempty == 1)) {
ob1->node = -2; // Will run this through cleanuppins
needclean1 = 1;
}
@@ -6880,7 +6964,7 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist)
/* Find the end of the pin list in tc1, for adding proxy pins */
for (ob1 = tc1->cell; ob1 != NULL; ob1 = ob1->next) {
if (ob1 && ob1->next && ob1->next->type != PORT)
if (ob1 && ((ob1->next && ob1->next->type != PORT) || ob1->next == NULL))
break;
}
if (ob1 == NULL) ob1 = tc1->cell; /* No ports */
@@ -6923,12 +7007,15 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist)
/* flattening instances has left a port with a */
/* net number that doesn't connect to anything */
notempty = 0;
for (obt = ob2->next; obt; obt = obt->next) {
if (obt->type >= FIRSTPIN)
if (obt->type >= FIRSTPIN) {
notempty = 1;
if (obt->node == ob2->node)
break;
}
}
if (obt == NULL) {
if ((obt == NULL) && (notempty == 1)) {
ob2->node = -2; // Will run this through cleanuppins
needclean2 = 1;
continue;
@@ -6966,7 +7053,7 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist)
/* Find the end of the pin list in tc2, for adding proxy pins */
for (ob2 = tc2->cell; ob2 != NULL; ob2 = ob2->next) {
if (ob2 && ob2->next && ob2->next->type != PORT)
if (ob2 && ((ob2->next && ob2->next->type != PORT) || ob2->next == NULL))
break;
}
if (ob2 == NULL) ob2 = tc2->cell; /* No ports */
@@ -6997,7 +7084,8 @@ int MatchPins(struct nlist *tc1, struct nlist *tc2, int dolist)
if (obn == NULL) ob1->node = -1; /* Make disconnected */
}
if (ob1 == NULL || ob1->type != PORT || ob1->node >= 0) {
if (ob1 == NULL || ob1->type != PORT || ob1->node >= 0
|| (ob1->node < 0 && tc1->class == CLASS_MODULE)) {
/* Add a proxy pin to tc2 */
obn = (struct objlist *)CALLOC(1, sizeof(struct objlist));
@@ -7353,7 +7441,7 @@ int Compare(char *cell1, char *cell2)
/* arbitrarily resolve automorphisms */
Fprintf(stdout, "\n");
Fprintf(stdout, "Arbitrarily resolving automorphisms:\n");
Fprintf(stdout, "Resolving automorphisms by arbitrary symmetry breaking:\n");
while ((automorphisms = ResolveAutomorphisms()) > 0) ;
if (automorphisms == -1) {
MatchFail(cell1, cell2);
+41 -4
View File
@@ -289,6 +289,7 @@ int GetNextLineNoNewline(char *delimiter)
char *newbuf;
int testc;
int nested = 0;
int llen;
if (feof(infile)) return -1;
@@ -306,12 +307,25 @@ int GetNextLineNoNewline(char *delimiter)
linetok = (char *)MALLOC(linesize + 1);
}
fgets(line, linesize, infile);
while (strlen(line) == linesize - 1) {
/* Immediately resolve backslash-EOL */
llen = strlen(line);
while ((llen > 1) && (llen < linesize - 1) && *(line + llen - 2) == '\\') {
*(line + llen - 2) = '\n';
fgets(line + llen - 1, linesize - llen + 1, infile);
llen = strlen(line);
}
while (llen == linesize - 1) {
newbuf = (char *)MALLOC(linesize + 501);
strcpy(newbuf, line);
FREE(line);
line = newbuf;
fgets(line + linesize - 1, 501, infile);
llen = strlen(line);
while ((llen > 1) && (llen < linesize - 1) && *(line + llen - 2) == '\\') {
*(line + llen - 2) = '\n';
fgets(line + llen - 1, linesize - llen + 1, infile);
llen = strlen(line);
}
linesize += 500;
FREE(linetok);
linetok = (char *)MALLOC(linesize + 1);
@@ -329,7 +343,7 @@ int GetNextLineNoNewline(char *delimiter)
for (s = line; *s != '\0'; s++) {
if (*s == '`') {
w = s + 1;
while (isalnum(*w)) w++;
while (isalnum(*w) || (*w == '_') || (*w == '$')) w++;
e = *w;
*w = '\0';
kl = (struct property *)HashLookup(s + 1, definitions);
@@ -365,7 +379,7 @@ int GetNextLineNoNewline(char *delimiter)
for (s = line; *s != '\0'; s++) {
if (*s == '`') {
w = s + 1;
while (isalnum(*w)) w++;
while (isalnum(*w) || (*w == '_') || (*w == '$')) w++;
e = *w;
*w = '\0';
kl = (struct property *)HashLookup(s + 1, definitions);
@@ -496,6 +510,24 @@ void GetNextLine(char *delimiter)
} while (nexttok == NULL);
}
/*----------------------------------------------------------------------*/
/* Return a pointer to the line at the position of nexttok */
/* This is used only when returning the entire line, untokenized, and */
/* is only called by the verilog read routine when reading the value of */
/* a `define statement. */
/*----------------------------------------------------------------------*/
char *GetLineAtTok()
{
char *lpos;
if (nexttok == NULL) return NULL;
if (line == NULL) return NULL;
lpos = strstr(line, nexttok);
return lpos;
}
/*----------------------------------------------------------------------*/
/* if nexttok is already NULL, force scanner to read new line */
/*----------------------------------------------------------------------*/
@@ -766,7 +798,7 @@ int OpenParseFile(char *name, int fnum)
FILE *locfile;
struct filestack *newfile;
locfile = fopen(name,"r");
locfile = fopen(name, "r");
linenum = 0;
/* reset the token scanner */
nexttok = NULL;
@@ -851,7 +883,12 @@ char *ReadNetlist(char *fname, int *fnum)
{SPICE_EXTENSION, ReadSpice},
{SPICE_EXT2, ReadSpice},
{SPICE_EXT3, ReadSpice},
{SPICE_EXT4, ReadSpice},
{SPICE_EXT5, ReadSpice},
{SPICE_EXT6, ReadSpice},
{SPICE_EXT7, ReadSpice},
{VERILOG_EXTENSION, ReadVerilog},
{SYS_VERILOG_EXTENSION, ReadVerilog},
{NETGEN_EXTENSION, ReadNetgenFile},
{NULL, NULL}
};
+7 -1
View File
@@ -9,11 +9,16 @@
#define SIM_EXTENSION ".sim"
#define SPICE_EXTENSION ".spice"
#define SPICE_EXT2 ".spc"
#define SPICE_EXT3 ".fspc"
#define SPICE_EXT3 ".sp"
#define SPICE_EXT4 ".spi"
#define SPICE_EXT5 ".fspc"
#define SPICE_EXT6 ".cir"
#define SPICE_EXT7 ".ckt"
#define NETGEN_EXTENSION ".ntg"
#define CCODE_EXTENSION ".c.code"
#define ESACAP_EXTENSION ".esa"
#define VERILOG_EXTENSION ".v"
#define SYS_VERILOG_EXTENSION ".sv"
#define LINELENGTH 80
@@ -31,6 +36,7 @@ extern struct hashdict *definitions;
extern char *nexttok;
#define SKIPTO(a) do {SkipTok(NULL);} while (!match(nexttok,a))
extern char *strdtok(char *pstring, char *delim1, char *delim2);
extern char *GetLineAtTok();
extern void SkipTok(char *delimiter);
extern void SkipTokNoNewline(char *delimiter);
extern void SkipTokComments(char *delimiter);
+1 -1
View File
@@ -289,7 +289,7 @@ static struct hashdict cell_dict;
void InitCellHashTable(void)
{
hashfunc = hash;
matchfunc = match;
matchfunc = NULL;
matchintfunc = matchfile;
InitializeHashTable(&cell_dict, CELLHASHSIZE);
}
+1 -1
View File
@@ -1066,7 +1066,7 @@ void Query(void)
ActelLib();
break;
case 'S':
promptstring("Read SPICE (.ckt) file? ", repstr);
promptstring("Read SPICE (.spice) file? ", repstr);
ReadSpice(repstr, &filenum);
break;
case 'V':
+26 -10
View File
@@ -1883,20 +1883,36 @@ char *ReadSpiceTop(char *fname, int *fnum, int blackbox)
CurrentCell = NULL;
if ((filenum = OpenParseFile(fname, *fnum)) < 0) {
char name[100];
SetExtension(name, fname, SPICE_EXTENSION);
if ((filenum = OpenParseFile(name, *fnum)) < 0) {
Fprintf(stderr,"Error in SPICE file read: No file %s\n",name);
if (strrchr(fname, '.') == NULL) {
char name[1024];
SetExtension(name, fname, SPICE_EXTENSION);
if ((filenum = OpenParseFile(name, *fnum)) < 0) {
Fprintf(stderr, "Error in SPICE file read: No file %s\n", name);
*fnum = filenum;
return NULL;
}
}
else {
Fprintf(stderr, "Error in SPICE file read: No file %s\n", fname);
*fnum = filenum;
return NULL;
}
}
}
/* Make sure all SPICE file reading is case insensitive */
matchfunc = matchnocase;
matchintfunc = matchfilenocase;
hashfunc = hashnocase;
/* Make sure all SPICE file reading is case insensitive */
/* BUT if a verilog file was read before it, then it will */
/* be forced to be case sensitive, caveat end-user. */
if (matchfunc == match) {
Printf("Warning: A case-sensitive file has been read and so the "
"SPICE netlist must be treated case-sensitive to match.\n");
}
else {
matchfunc = matchnocase;
matchintfunc = matchfilenocase;
hashfunc = hashnocase;
}
InitializeHashTable(&spiceparams, OBJHASHSIZE);
@@ -1980,7 +1996,7 @@ void IncludeSpice(char *fname, int parent, struct cellstack **CellStackPtr,
/* helps, if the file didn't have an extension. But */
/* really, we're getting desperate at this point. */
if (strchr(fname, '.') == NULL) {
if (strrchr(fname, '.') == NULL) {
SetExtension(name, fname, SPICE_EXTENSION);
filenum = OpenParseFile(name, parent);
if (filenum < 0) {
+38 -13
View File
@@ -1115,10 +1115,17 @@ skip_endmodule:
kl->slop.dval = 0.01; // One percent default
}
else {
/* Treat the parameter as a string */
char *toks;
/* Treat the parameter as a string; BUT pull everything to */
/* EOL, not just the current token. */
toks = GetLineAtTok();
kl->type = PROP_STRING;
kl->pdefault.string = strsave(nexttok);
kl->pdefault.string = strsave(toks);
kl->slop.dval = 0.0;
SkipNewLine(VLOG_DELIMITERS);
}
if (kl) HashPtrInstall(kl->key, kl, &verilogdefs);
}
@@ -1218,9 +1225,11 @@ skip_endmodule:
lhs = LookupObject(nodename, CurrentCell);
*aptr = '[';
}
else strcpy(noderoot, nexttok);
}
else {
lhs = LookupObject(nexttok, CurrentCell);
strcpy(noderoot, nexttok);
}
SkipTokComments(VLOG_DELIMITERS);
if (lhs && ((!nexttok) || (!match(nexttok, "=")))) {
@@ -1786,7 +1795,7 @@ nextinst:
// Net is bit-sliced across array of instances.
if (wb.start > wb.end) {
char *bptr, *cptr = NULL, cchar, *netname;
char *bptr = NULL, *cptr = NULL, cchar, *netname;
unsigned char is_bundle = 0;
struct bus wbb;
@@ -1918,11 +1927,15 @@ nextinst:
scan = scan->next;
}
if (scan == NULL) {
Fprintf(stderr, "Error: No match in call for pin %s\n", obpinname);
break;
}
char localnet[100];
if (GetBus(scan->net, &wb) == 0) {
/* Assume an implicit unconnected pin */
sprintf(localnet, "_noconnect_%d_", localcount++);
Node(localnet);
join(localnet, obptr->name);
Fprintf(stderr, "Note: Implicit pin %s\n", obpinname);
}
else if (GetBus(scan->net, &wb) == 0) {
char *bptr2;
char *scanroot;
scanroot = strsave(scan->net);
@@ -2056,14 +2069,21 @@ char *ReadVerilogTop(char *fname, int *fnum, int blackbox)
CurrentCell = NULL;
if ((filenum = OpenParseFile(fname, *fnum)) < 0) {
char name[100];
SetExtension(name, fname, VERILOG_EXTENSION);
if ((filenum = OpenParseFile(name, *fnum)) < 0) {
Fprintf(stderr,"Error in Verilog file read: No file %s\n",name);
*fnum = filenum;
return NULL;
if (strchr(fname, '.') == NULL) {
char name[1024];
SetExtension(name, fname, VERILOG_EXTENSION);
if ((filenum = OpenParseFile(name, *fnum)) < 0) {
Fprintf(stderr, "Error in Verilog file read: No file %s\n", name);
*fnum = filenum;
return NULL;
}
}
else {
Fprintf(stderr, "Error in Verilog file read: No file %s\n", fname);
*fnum = filenum;
return NULL;
}
}
/* All Verilog file reading is case sensitive. However: if */
@@ -2074,6 +2094,11 @@ char *ReadVerilogTop(char *fname, int *fnum, int blackbox)
Printf("Warning: A case-insensitive file has been read and so the "
"verilog file must be treated case-insensitive to match.\n");
}
else {
matchfunc = match;
matchintfunc = matchfile;
hashfunc = hash;
}
InitializeHashTable(&verilogparams, OBJHASHSIZE);
InitializeHashTable(&verilogdefs, OBJHASHSIZE);
+1 -2
View File
@@ -2982,8 +2982,7 @@ _netcmp_equate(ClientData clientData,
else {
Fprintf(stdout, "Equate pins: cell %s and/or %s "
"has no elements.\n", name1, name2);
Tcl_SetObjResult(interp, Tcl_NewBooleanObj(0));
return TCL_OK;
/* This is not necessarily an error, so go ahead and match pins. */
}
}
if (ElementClasses == NULL) {