Browse Source

Fix a memory leak. Cleanup the code a bit. All-digital Pspice subckts with U* devices for most used gates/ff can be handled. More extensive test cases are necessary. Also, interfacing subckts with analog ports is not implemented.

pre-master-46
Brian Taylor 4 years ago
committed by Holger Vogt
parent
commit
7b5c780043
  1. 73
      src/frontend/inpcom.c
  2. 43
      src/frontend/udevices.c

73
src/frontend/inpcom.c

@ -8287,6 +8287,7 @@ static void rem_double_braces(struct card* newcard)
} }
#ifdef INTEGRATE_UDEVICES #ifdef INTEGRATE_UDEVICES
/*
static void list_the_cards(struct card *startcard, char *prefix) static void list_the_cards(struct card *startcard, char *prefix)
{ {
struct card *card; struct card *card;
@ -8296,6 +8297,7 @@ static void list_the_cards(struct card *startcard, char *prefix)
printf("%s %s\n", prefix, cut_line); printf("%s %s\n", prefix, cut_line);
} }
} }
*/
static struct card *the_last_card(struct card *startcard) static struct card *the_last_card(struct card *startcard)
{ {
@ -8305,6 +8307,19 @@ static struct card *the_last_card(struct card *startcard)
lastcard = card; lastcard = card;
} }
return lastcard; return lastcard;
}
static void remove_old_cards(struct card *first, struct card *stop)
{
struct card *x, *next = NULL;
if (!first || !stop || (first == stop)) { return; }
for (x = first; (x && (x != stop)); x = next) {
//printf("Remove %s\n", x->line);
if (x->line) { tfree(x->line); }
if (x->error) { tfree(x->error); }
next = x->nextcard;
tfree(x);
}
} }
static struct card *u_instances(struct card *startcard) static struct card *u_instances(struct card *startcard)
@ -8315,15 +8330,14 @@ static struct card *u_instances(struct card *startcard)
int models_ok = 0, models_not_ok = 0; int models_ok = 0, models_not_ok = 0;
int udev_ok = 0, udev_not_ok = 0; int udev_ok = 0, udev_not_ok = 0;
BOOL create_called = FALSE, repeat_pass = FALSE; BOOL create_called = FALSE, repeat_pass = FALSE;
BOOL skip_next = FALSE, verbose = FALSE;
char *tmp = NULL, *pos;
BOOL skip_next = FALSE;
char *tmp = NULL, *pos, *new_str = NULL;
card = startcard; card = startcard;
while (card) { while (card) {
char *cut_line = card->line; char *cut_line = card->line;
skip_next = FALSE; skip_next = FALSE;
if (verbose) printf("line: %s\n", cut_line);
if (ciprefix(".subckt", cut_line)) { if (ciprefix(".subckt", cut_line)) {
models_ok = models_not_ok = 0; models_ok = models_not_ok = 0;
udev_ok = udev_not_ok = 0; udev_ok = udev_not_ok = 0;
@ -8333,54 +8347,44 @@ static struct card *u_instances(struct card *startcard)
printf("Too many nesting levels\n"); printf("Too many nesting levels\n");
break; break;
} }
tmp = TMALLOC(char, strlen(cut_line) + 1);
(void) memcpy(tmp, cut_line, strlen(cut_line) + 1);
subcktcard = card; subcktcard = card;
if (verbose) printf("** subckt: %s\n", cut_line);
if (!repeat_pass) { if (!repeat_pass) {
if (create_called) { if (create_called) {
cleanup_udevice(); cleanup_udevice();
} }
initialize_udevice(); initialize_udevice();
create_called = TRUE; create_called = TRUE;
if (verbose) printf("Doing first pass\n");
} else { } else {
pos = strstr(tmp, "optional");
if (pos) {
*pos = '\0';
}
//printf(" %s\n", tmp);
if (verbose) printf("Doing second pass\n");
}
//tfree(tmp);
tmp = TMALLOC(char, strlen(cut_line) + 1);
(void) memcpy(tmp, cut_line, strlen(cut_line) + 1);
pos = strstr(tmp, "optional");
if (pos) {
*pos = '\0';
}
new_str = copy(tmp);
tfree(tmp);
}
} else if (ciprefix(".ends", cut_line)) { } else if (ciprefix(".ends", cut_line)) {
level--; level--;
if (verbose) printf("** ends: %s\n", cut_line);
if (repeat_pass) { if (repeat_pass) {
newcard = replacement_udevice_cards(); newcard = replacement_udevice_cards();
if (newcard) { if (newcard) {
remove_old_cards(subcktcard->nextcard, card);
subcktcard->nextcard = newcard; subcktcard->nextcard = newcard;
tfree(subcktcard->line); tfree(subcktcard->line);
subcktcard->line = tmp;
subcktcard->line = new_str;
//list_the_cards(newcard, "Replacement:"); //list_the_cards(newcard, "Replacement:");
last_newcard = the_last_card(newcard); last_newcard = the_last_card(newcard);
if (last_newcard) { if (last_newcard) {
last_newcard->nextcard = card; // the .ends card last_newcard->nextcard = card; // the .ends card
} }
} }
if (verbose) printf("Second pass ");
//printf(" %s\n", cut_line);
} else {
if (verbose) printf("First pass ");
} }
if (verbose) printf("udev_ok=%d udev_not_ok=%d models_ok=%d models_not_ok=%d\n",
udev_ok, udev_not_ok, models_ok, models_not_ok);
if (models_not_ok > 0 || udev_not_ok > 0) { if (models_not_ok > 0 || udev_not_ok > 0) {
repeat_pass = FALSE; repeat_pass = FALSE;
cleanup_udevice(); cleanup_udevice();
create_called = FALSE; create_called = FALSE;
} else if (udev_ok > 0) { } else if (udev_ok > 0) {
if (verbose) printf("Repeat subckt\n");
repeat_pass = TRUE; repeat_pass = TRUE;
card = subcktcard; card = subcktcard;
skip_next = TRUE; skip_next = TRUE;
@ -8392,9 +8396,7 @@ static struct card *u_instances(struct card *startcard)
subcktcard = NULL; subcktcard = NULL;
} else if (ciprefix(".model", cut_line)) { } else if (ciprefix(".model", cut_line)) {
if (subcktcard && !repeat_pass) { if (subcktcard && !repeat_pass) {
if (verbose) printf("** model: %s\n", cut_line);
if (!u_process_model_line(cut_line)) { if (!u_process_model_line(cut_line)) {
if (verbose) printf("Unable to convert model\n");
models_not_ok++; models_not_ok++;
} else { } else {
models_ok++; models_ok++;
@ -8402,19 +8404,15 @@ static struct card *u_instances(struct card *startcard)
} }
} else if (ciprefix("u", cut_line)) { } else if (ciprefix("u", cut_line)) {
if (subcktcard) { if (subcktcard) {
if (verbose) printf("** instance: %s\n", cut_line);
if (repeat_pass) { if (repeat_pass) {
if (!u_process_instance(cut_line)) { if (!u_process_instance(cut_line)) {
/* Bail out */ /* Bail out */
if (verbose) printf("Unable to convert instance\n");
break; break;
} }
} else { } else {
if (u_check_instance(cut_line)) { if (u_check_instance(cut_line)) {
if (verbose) printf("Instance can be converted\n");
udev_ok++; udev_ok++;
} else { } else {
if (verbose) printf("Instance can NOT be converted\n");
udev_not_ok++; udev_not_ok++;
} }
} }
@ -8478,16 +8476,6 @@ static struct card *pspice_compat(struct card *oldcard)
controlled_exit(1); controlled_exit(1);
} }
#ifdef INTEGRATE_UDEVICES
//list_the_cards(oldcard, "After AKO");
/* Here
{
struct card *ucard;
ucard = u_instances(oldcard);
}
*/
#endif
/* Process .distribution cards. */ /* Process .distribution cards. */
do_distribution(oldcard); do_distribution(oldcard);
@ -8522,13 +8510,10 @@ static struct card *pspice_compat(struct card *oldcard)
nextcard->nextcard = oldcard; nextcard->nextcard = oldcard;
#ifdef INTEGRATE_UDEVICES #ifdef INTEGRATE_UDEVICES
/* or here? */
{ {
struct card *ucard; struct card *ucard;
//ucard = u_instances(oldcard);
//ucard = u_instances(nextcard);
ucard = u_instances(newcard); ucard = u_instances(newcard);
list_the_cards(oldcard, "After udevices");
//list_the_cards(oldcard, "After udevices");
} }
#endif #endif

43
src/frontend/udevices.c

@ -30,10 +30,11 @@
functions for gates, tristate, flip-flops and latches. translate_...() functions for gates, tristate, flip-flops and latches. translate_...()
calls add_..._inout_timing_model() to parse the U* card, and then calls calls add_..._inout_timing_model() to parse the U* card, and then calls
gen_..._instance(). Creating new cards to replace the U* and .model gen_..._instance(). Creating new cards to replace the U* and .model
cards needs modifying where the output goes from processing an instance.
This will be added either to this file or to frontend/inpcom.c.
Finally, call cleanup_udevice() before repeating the sequence for
another subcircuit.
cards is done by calling replacement_udevice_cards(), which returns a
list of new cards. The list of cards is then to be inserted after the
.subckt card and before the .ends card. This occurs in the function
u_instances() in frontend/inpcom.c. Finally, call cleanup_udevice()
before repeating the sequence for another subcircuit.
*/ */
#include <stdio.h> #include <stdio.h>
@ -2126,6 +2127,7 @@ static char *get_delays_ugff(char *rem, char *d_name)
return delays; return delays;
} }
/*
static void print_delays(char *delays) static void print_delays(char *delays)
{ {
if (delays) { if (delays) {
@ -2135,26 +2137,22 @@ static void print_delays(char *delays)
} }
return; return;
} }
*/
static BOOL u_process_model(char *nline, char *original, static BOOL u_process_model(char *nline, char *original,
char *newname, char *xspice) char *newname, char *xspice)
{ {
char *tok, *remainder, *delays = NULL, *utype, *tmodel; char *tok, *remainder, *delays = NULL, *utype, *tmodel;
BOOL retval = TRUE, verbose = FALSE;
#ifdef TRACE
//verbose = TRUE;
#endif
BOOL retval = TRUE;
/* .model */ /* .model */
tok = strtok(nline, " \t"); tok = strtok(nline, " \t");
/* model name */ /* model name */
tok = strtok(NULL, " \t"); tok = strtok(NULL, " \t");
if (verbose) printf("\nmodel_name -> %s\n", tok);
tmodel = TMALLOC(char, strlen(tok) + 1); tmodel = TMALLOC(char, strlen(tok) + 1);
memcpy(tmodel, tok, strlen(tok) + 1); memcpy(tmodel, tok, strlen(tok) + 1);
/* model utype */ /* model utype */
tok = strtok(NULL, " \t("); tok = strtok(NULL, " \t(");
if (verbose) printf("model_utype -> %s\n", tok);
utype = TMALLOC(char, strlen(tok) + 1); utype = TMALLOC(char, strlen(tok) + 1);
memcpy(utype, tok, strlen(tok) + 1); memcpy(utype, tok, strlen(tok) + 1);
@ -2165,30 +2163,25 @@ static BOOL u_process_model(char *nline, char *original,
delays = get_delays_ugate(remainder, xspice); delays = get_delays_ugate(remainder, xspice);
add_delays_to_model_xlator((delays ? delays : ""), add_delays_to_model_xlator((delays ? delays : ""),
utype, "", tmodel); utype, "", tmodel);
if (verbose) print_delays(delays);
if (delays) { tfree(delays); } if (delays) { tfree(delays); }
} else if (strcmp(utype, "utgate") == 0) { } else if (strcmp(utype, "utgate") == 0) {
delays = get_delays_utgate(remainder, xspice); delays = get_delays_utgate(remainder, xspice);
add_delays_to_model_xlator((delays ? delays : ""), add_delays_to_model_xlator((delays ? delays : ""),
utype, "", tmodel); utype, "", tmodel);
if (verbose) print_delays(delays);
if (delays) { tfree(delays); } if (delays) { tfree(delays); }
} else if (strcmp(utype, "ueff") == 0) { } else if (strcmp(utype, "ueff") == 0) {
delays = get_delays_ueff(remainder, xspice); delays = get_delays_ueff(remainder, xspice);
add_delays_to_model_xlator((delays ? delays : ""), add_delays_to_model_xlator((delays ? delays : ""),
utype, "", tmodel); utype, "", tmodel);
if (verbose) print_delays(delays);
if (delays) { tfree(delays); } if (delays) { tfree(delays); }
} else if (strcmp(utype, "ugff") == 0) { } else if (strcmp(utype, "ugff") == 0) {
delays = get_delays_ugff(remainder, "d_dlatch"); delays = get_delays_ugff(remainder, "d_dlatch");
add_delays_to_model_xlator((delays ? delays : ""), add_delays_to_model_xlator((delays ? delays : ""),
utype, "d_dlatch", tmodel); utype, "d_dlatch", tmodel);
if (verbose) print_delays(delays);
if (delays) { tfree(delays); } if (delays) { tfree(delays); }
delays = get_delays_ugff(remainder, "d_srlatch"); delays = get_delays_ugff(remainder, "d_srlatch");
add_delays_to_model_xlator((delays ? delays : ""), add_delays_to_model_xlator((delays ? delays : ""),
utype, "d_srlatch", tmodel); utype, "d_srlatch", tmodel);
if (verbose) print_delays(delays);
if (delays) { tfree(delays); } if (delays) { tfree(delays); }
} else { } else {
retval = FALSE; retval = FALSE;
@ -2439,7 +2432,7 @@ static struct gate_instance *add_array_inout_timing_model(
struct instance_hdr *hdr, char *start) struct instance_hdr *hdr, char *start)
{ {
char *tok, *copyline, *itype = hdr->instance_type; char *tok, *copyline, *itype = hdr->instance_type;
BOOL first = TRUE, tristate = FALSE, verbose = FALSE;
BOOL first = TRUE, tristate = FALSE;
int i, j, k, n1 =hdr->num1, n2 = hdr->num2, inwidth, numgates; int i, j, k, n1 =hdr->num1, n2 = hdr->num2, inwidth, numgates;
struct gate_instance *gip = NULL; struct gate_instance *gip = NULL;
char **inarr = NULL, **outarr = NULL, *name; char **inarr = NULL, **outarr = NULL, *name;
@ -2475,10 +2468,6 @@ static struct gate_instance *add_array_inout_timing_model(
gip->num_outs = numgates; gip->num_outs = numgates;
copyline = TMALLOC(char, strlen(start) + 1); copyline = TMALLOC(char, strlen(start) + 1);
(void) memcpy(copyline, start, strlen(start) + 1); (void) memcpy(copyline, start, strlen(start) + 1);
if (verbose) {
printf("instance: %s itype: %s\n",
hdr->instance_name, hdr->instance_type);
}
/* /*
numgates gates, each gate has inwidth inputs and 1 output numgates gates, each gate has inwidth inputs and 1 output
inputs first inputs first
@ -2497,7 +2486,6 @@ static struct gate_instance *add_array_inout_timing_model(
name = TMALLOC(char, strlen(tok) + 1); name = TMALLOC(char, strlen(tok) + 1);
(void) memcpy(name, tok, strlen(tok) + 1); (void) memcpy(name, tok, strlen(tok) + 1);
inarr[k] = name; inarr[k] = name;
if (verbose) { printf(" gate %d input(%d): %s\n", i, j, tok); }
k++; k++;
} }
} }
@ -2507,7 +2495,6 @@ static struct gate_instance *add_array_inout_timing_model(
name = TMALLOC(char, strlen(tok) + 1); name = TMALLOC(char, strlen(tok) + 1);
(void) memcpy(name, tok, strlen(tok) + 1); (void) memcpy(name, tok, strlen(tok) + 1);
gip->enable = name; gip->enable = name;
if (verbose) { printf(" enable: %s\n", tok); }
} }
/* outputs next */ /* outputs next */
outarr = TMALLOC(char *, numgates); outarr = TMALLOC(char *, numgates);
@ -2517,14 +2504,12 @@ static struct gate_instance *add_array_inout_timing_model(
name = TMALLOC(char, strlen(tok) + 1); name = TMALLOC(char, strlen(tok) + 1);
(void) memcpy(name, tok, strlen(tok) + 1); (void) memcpy(name, tok, strlen(tok) + 1);
outarr[i] = name; outarr[i] = name;
if (verbose) { printf(" gate %d output: %s\n", i, tok); }
} }
/* timing model last */ /* timing model last */
tok = strtok(NULL, " \t"); tok = strtok(NULL, " \t");
name = TMALLOC(char, strlen(tok) + 1); name = TMALLOC(char, strlen(tok) + 1);
(void) memcpy(name, tok, strlen(tok) + 1); (void) memcpy(name, tok, strlen(tok) + 1);
gip->tmodel = name; gip->tmodel = name;
if (verbose) { printf(" tmodel: %s\n", tok); }
tfree(copyline); tfree(copyline);
return gip; return gip;
} }
@ -2534,7 +2519,7 @@ static struct gate_instance *add_gate_inout_timing_model(
{ {
char *tok, *copyline, *itype = hdr->instance_type; char *tok, *copyline, *itype = hdr->instance_type;
int i, n1 = hdr->num1, n2 = hdr->num2, inwidth; int i, n1 = hdr->num1, n2 = hdr->num2, inwidth;
BOOL first = TRUE, tristate = FALSE, verbose = FALSE;
BOOL first = TRUE, tristate = FALSE;
struct gate_instance *gip = NULL; struct gate_instance *gip = NULL;
char **inarr = NULL, **outarr = NULL, *name; char **inarr = NULL, **outarr = NULL, *name;
@ -2564,10 +2549,6 @@ static struct gate_instance *add_gate_inout_timing_model(
gip->num_outs = 1; gip->num_outs = 1;
copyline = TMALLOC(char, strlen(start) + 1); copyline = TMALLOC(char, strlen(start) + 1);
(void) memcpy(copyline, start, strlen(start) + 1); (void) memcpy(copyline, start, strlen(start) + 1);
if (verbose) {
printf("instance: %s itype: %s\n",
hdr->instance_name, hdr->instance_type);
}
/* inputs */ /* inputs */
inarr = TMALLOC(char *, gip->num_ins); inarr = TMALLOC(char *, gip->num_ins);
gip->inputs = inarr; gip->inputs = inarr;
@ -2581,7 +2562,6 @@ static struct gate_instance *add_gate_inout_timing_model(
name = TMALLOC(char, strlen(tok) + 1); name = TMALLOC(char, strlen(tok) + 1);
(void) memcpy(name, tok, strlen(tok) + 1); (void) memcpy(name, tok, strlen(tok) + 1);
inarr[i] = name; inarr[i] = name;
if (verbose) { printf(" input(%d): %s\n", i, tok); }
} }
/* enable for tristate */ /* enable for tristate */
if (tristate) { if (tristate) {
@ -2589,7 +2569,6 @@ static struct gate_instance *add_gate_inout_timing_model(
name = TMALLOC(char, strlen(tok) + 1); name = TMALLOC(char, strlen(tok) + 1);
(void) memcpy(name, tok, strlen(tok) + 1); (void) memcpy(name, tok, strlen(tok) + 1);
gip->enable = name; gip->enable = name;
if (verbose) { printf(" enable: %s\n", tok); }
} }
/* output */ /* output */
assert(gip->num_outs == 1); assert(gip->num_outs == 1);
@ -2599,13 +2578,11 @@ static struct gate_instance *add_gate_inout_timing_model(
name = TMALLOC(char, strlen(tok) + 1); name = TMALLOC(char, strlen(tok) + 1);
(void) memcpy(name, tok, strlen(tok) + 1); (void) memcpy(name, tok, strlen(tok) + 1);
outarr[0] = name; outarr[0] = name;
if (verbose) { printf(" output: %s\n", tok); }
/* timing model last */ /* timing model last */
tok = strtok(NULL, " \t"); tok = strtok(NULL, " \t");
name = TMALLOC(char, strlen(tok) + 1); name = TMALLOC(char, strlen(tok) + 1);
(void) memcpy(name, tok, strlen(tok) + 1); (void) memcpy(name, tok, strlen(tok) + 1);
gip->tmodel = name; gip->tmodel = name;
if (verbose) { printf(" tmodel: %s\n", tok); }
tfree(copyline); tfree(copyline);
return gip; return gip;
} }

Loading…
Cancel
Save