Handle cases where logicexp has a timing model but no pindly. This is rare, only 22 tests from the digital libraries. Move digital examples, add missing .spiceint file.
This commit is contained in:
parent
de2280ca73
commit
44c69f5bf5
|
|
@ -0,0 +1 @@
|
|||
set ngbehavior=ltpsa
|
||||
|
|
@ -292,6 +292,32 @@ static char *lex_gate_name(int c, BOOL not)
|
|||
return buf;
|
||||
}
|
||||
|
||||
static char *tmodel_gate_name(int c, BOOL not)
|
||||
{
|
||||
/* Returns an XSPICE model name for the case where
|
||||
logicexp does not have a corresponding pindly
|
||||
but does have a UGATE timing model (not d0_gate).
|
||||
*/
|
||||
static char buf[32];
|
||||
switch (c) {
|
||||
case '&':
|
||||
if (not)
|
||||
sprintf(buf, "dxspice_dly_nand");
|
||||
else
|
||||
sprintf(buf, "dxspice_dly_and");
|
||||
break;
|
||||
case '|':
|
||||
if (not)
|
||||
sprintf(buf, "dxspice_dly_nor");
|
||||
else
|
||||
sprintf(buf, "dxspice_dly_or");
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
static int lex_gate_op(int c)
|
||||
{
|
||||
switch (c) {
|
||||
|
|
@ -584,6 +610,7 @@ static int adepth = 0;
|
|||
static int max_adepth = 0;
|
||||
static DSTRING d_curr_line;
|
||||
static int number_of_instances = 0;
|
||||
static BOOL use_tmodel_delays = FALSE;
|
||||
|
||||
static BOOL inverters_needed(void)
|
||||
{
|
||||
|
|
@ -888,7 +915,7 @@ static PTABLE optimize_gen_tab(PTABLE pt)
|
|||
{
|
||||
/* This function compacts the gen_tab, returning a new PTABLE.
|
||||
Aliases are transformed and removed as described below.
|
||||
Usually, optimized_gen_tab is called a second time on the
|
||||
Usually, optimize_gen_tab is called a second time on the
|
||||
PTABLE created by the first call. The algorithm here will
|
||||
only transform one level of aliases.
|
||||
*/
|
||||
|
|
@ -1131,7 +1158,7 @@ static void gen_gates(PTABLE gate_tab, SYM_TAB parser_symbols)
|
|||
tok_count = 0;
|
||||
gate_op = 0;
|
||||
in_count = 0;
|
||||
while (val != '\0') {
|
||||
while (val != '\0') { // while val loop
|
||||
tok_count++;
|
||||
if (val == LEX_ID) {
|
||||
idnum++;
|
||||
|
|
@ -1170,13 +1197,33 @@ static void gen_gates(PTABLE gate_tab, SYM_TAB parser_symbols)
|
|||
goto quick_return;
|
||||
}
|
||||
val = lexer_scan(lxr);
|
||||
}
|
||||
} // end while val loop
|
||||
|
||||
if (in_count == 1) { // buffer or inverter
|
||||
if (gate_op != 0) goto quick_return;
|
||||
ds_cat_str(&gate_name, lex_gate_name('~', found_tilde));
|
||||
} else if (in_count >= 2) { // AND, OR. XOR and inverses
|
||||
if (gate_op == 0) goto quick_return;
|
||||
ds_cat_str(&gate_name, lex_gate_name(gate_op, found_tilde));
|
||||
if (use_tmodel_delays) {
|
||||
/* This is the case when logicexp has a UGATE
|
||||
timing model (not d0_gate) and no pindly.
|
||||
*/
|
||||
SYM_TAB entry = NULL;
|
||||
char *nm1 = 0;
|
||||
entry = member_sym_tab(ds_get_buf(&out_name), parser_symbols);
|
||||
if (entry && (entry->attribute & SYM_OUTPUT)) {
|
||||
nm1 = tmodel_gate_name(gate_op, found_tilde);
|
||||
if (nm1) {
|
||||
ds_cat_str(&gate_name, nm1);
|
||||
}
|
||||
}
|
||||
if (!nm1) {
|
||||
nm1 = lex_gate_name(gate_op, found_tilde);
|
||||
ds_cat_str(&gate_name, nm1);
|
||||
}
|
||||
} else {
|
||||
ds_cat_str(&gate_name, lex_gate_name(gate_op, found_tilde));
|
||||
}
|
||||
} else {
|
||||
goto quick_return;
|
||||
}
|
||||
|
|
@ -1537,7 +1584,19 @@ BOOL f_logicexp(char *line)
|
|||
/* timing model */
|
||||
t = lex_scan();
|
||||
if (!expect_token(t, LEX_ID, NULL, TRUE, 12)) goto error_return;
|
||||
//printf("TMODEL: %s\n", parse_lexer->lexer_buf);
|
||||
if (!eq(parse_lexer->lexer_buf, "d0_gate")) {
|
||||
u_add_logicexp_model(parse_lexer->lexer_buf,
|
||||
"d_and", "dxspice_dly_and");
|
||||
u_add_logicexp_model(parse_lexer->lexer_buf,
|
||||
"d_nand", "dxspice_dly_nand");
|
||||
u_add_logicexp_model(parse_lexer->lexer_buf,
|
||||
"d_or", "dxspice_dly_or");
|
||||
u_add_logicexp_model(parse_lexer->lexer_buf,
|
||||
"d_nor", "dxspice_dly_nor");
|
||||
use_tmodel_delays = TRUE;
|
||||
} else {
|
||||
use_tmodel_delays = FALSE;
|
||||
}
|
||||
(void) add_sym_tab_entry(parse_lexer->lexer_buf,
|
||||
SYM_TMODEL, &parse_lexer->lexer_sym_tab);
|
||||
ret_val = bparse(line, FALSE);
|
||||
|
|
|
|||
|
|
@ -777,6 +777,19 @@ void u_add_instance(char *str)
|
|||
}
|
||||
}
|
||||
|
||||
static BOOL gen_timing_model(
|
||||
char *tmodel, char *utype, char *xspice, char *newname, Xlatorp xlp);
|
||||
|
||||
void u_add_logicexp_model(char *tmodel, char *xspice_gate, char *model_name)
|
||||
{
|
||||
Xlatorp xlp = NULL;
|
||||
xlp = create_xlator();
|
||||
if (gen_timing_model(tmodel, "ugate", xspice_gate, model_name, xlp)) {
|
||||
append_xlator(translated_p, xlp);
|
||||
}
|
||||
delete_xlator(xlp);
|
||||
}
|
||||
|
||||
void initialize_udevice(char *subckt_line)
|
||||
{
|
||||
Xlatep xdata;
|
||||
|
|
|
|||
|
|
@ -8,5 +8,6 @@ void initialize_udevice(char *subckt_line);
|
|||
struct card *replacement_udevice_cards(void);
|
||||
void cleanup_udevice(void);
|
||||
void u_add_instance(char *str);
|
||||
void u_add_logicexp_model(char *tmodel, char *xspice_gate, char *model_name);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Reference in New Issue