By default, use the shortest typical delay estimate. This makes the digi_74LS90_74LS42.cir testcase for bug641 behave almost the same as MicroCap 12. In ngspice and MicroCap, the only signal with a glitch is not_y8. The other not_* signals look the same. Setting ps_use_mntymx in .spiceinit will change the delay estimates. See the function set_u_devices_info in src/frontend/udevices.c for the various settings of ps_use_mntymx.
This commit is contained in:
parent
7a646c0a12
commit
492bb64d92
|
|
@ -1912,7 +1912,38 @@ static char *get_typ_estimate(char *min, char *typ, char *max, DSTRING *pds)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *typical_estimate(char *delay_str, DSTRING *pds)
|
static char *get_one_estimate(char *s, DSTRING *pds)
|
||||||
|
{
|
||||||
|
ds_clear(pds);
|
||||||
|
if (s && strlen(s) > 0 && s[0] != '-') {
|
||||||
|
ds_cat_str(pds, s);
|
||||||
|
return ds_get_buf(pds);
|
||||||
|
} else {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *get_delay_estimate(char *min, char *typ, char *max, DSTRING *pds)
|
||||||
|
{
|
||||||
|
char *one = NULL;
|
||||||
|
struct udevices_info info = u_get_udevices_info();
|
||||||
|
int delay_type = info.mntymx;
|
||||||
|
if (delay_type == 1) { // min
|
||||||
|
one = get_one_estimate(min, pds);
|
||||||
|
if (one) {
|
||||||
|
return one;
|
||||||
|
}
|
||||||
|
} else if (delay_type == 2) { // max
|
||||||
|
one = get_one_estimate(max, pds);
|
||||||
|
if (one) {
|
||||||
|
return one;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// typ
|
||||||
|
return get_typ_estimate(min, typ, max, pds);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *mntymx_estimate(char *delay_str, DSTRING *pds)
|
||||||
{
|
{
|
||||||
/* Input string (t1,t2,t2) */
|
/* Input string (t1,t2,t2) */
|
||||||
int which = 0;
|
int which = 0;
|
||||||
|
|
@ -1945,7 +1976,7 @@ static char *typical_estimate(char *delay_str, DSTRING *pds)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s = get_typ_estimate(ds_get_buf(&dmin), ds_get_buf(&dtyp),
|
s = get_delay_estimate(ds_get_buf(&dmin), ds_get_buf(&dtyp),
|
||||||
ds_get_buf(&dmax), pds);
|
ds_get_buf(&dmax), pds);
|
||||||
ds_free(&dmin);
|
ds_free(&dmin);
|
||||||
ds_free(&dtyp);
|
ds_free(&dtyp);
|
||||||
|
|
@ -1967,22 +1998,25 @@ static BOOL extract_delay(
|
||||||
BOOL in_delay = FALSE, ret_val = TRUE;
|
BOOL in_delay = FALSE, ret_val = TRUE;
|
||||||
int i;
|
int i;
|
||||||
BOOL prit = PRINT_ALL;
|
BOOL prit = PRINT_ALL;
|
||||||
float typ_max_val = 0.0, typ_val = 0.0;
|
BOOL shorter = FALSE, update_val = FALSE;
|
||||||
|
struct udevices_info info = u_get_udevices_info();
|
||||||
|
float del_max_val = 0.0, del_val = 0.0, del_min_val = FLT_MAX;
|
||||||
char *units;
|
char *units;
|
||||||
|
shorter = info.shorter_delays;
|
||||||
DS_CREATE(dly, 64);
|
DS_CREATE(dly, 64);
|
||||||
DS_CREATE(dtyp_max_str, 16);
|
DS_CREATE(ddel_str, 16);
|
||||||
DS_CREATE(tmp_ds, 128);
|
DS_CREATE(tmp_ds, 128);
|
||||||
|
|
||||||
if (val != '=') {
|
if (val != '=') {
|
||||||
ds_free(&dly);
|
ds_free(&dly);
|
||||||
ds_free(&dtyp_max_str);
|
ds_free(&ddel_str);
|
||||||
ds_free(&tmp_ds);
|
ds_free(&tmp_ds);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
val = lexer_scan(lx);
|
val = lexer_scan(lx);
|
||||||
if (val != '{') {
|
if (val != '{') {
|
||||||
ds_free(&dly);
|
ds_free(&dly);
|
||||||
ds_free(&dtyp_max_str);
|
ds_free(&ddel_str);
|
||||||
ds_free(&tmp_ds);
|
ds_free(&tmp_ds);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
@ -2005,7 +2039,7 @@ static BOOL extract_delay(
|
||||||
char *tmps;
|
char *tmps;
|
||||||
ds_clear(&tmp_ds);
|
ds_clear(&tmp_ds);
|
||||||
in_delay = FALSE;
|
in_delay = FALSE;
|
||||||
tmps = typical_estimate(ds_get_buf(&dly), &tmp_ds);
|
tmps = mntymx_estimate(ds_get_buf(&dly), &tmp_ds);
|
||||||
if (!tmps) {
|
if (!tmps) {
|
||||||
ret_val = FALSE;
|
ret_val = FALSE;
|
||||||
ds_clear(&tmp_ds);
|
ds_clear(&tmp_ds);
|
||||||
|
|
@ -2015,22 +2049,34 @@ static BOOL extract_delay(
|
||||||
printf("%s\n", ds_get_buf(&dly));
|
printf("%s\n", ds_get_buf(&dly));
|
||||||
printf("estimate \"%s\"\n", tmps);
|
printf("estimate \"%s\"\n", tmps);
|
||||||
}
|
}
|
||||||
typ_val = strtof(tmps, &units);
|
del_val = strtof(tmps, &units);
|
||||||
if (typ_val > typ_max_val) {
|
update_val = FALSE;
|
||||||
|
if (shorter) {
|
||||||
|
if (del_val < del_min_val) {
|
||||||
|
update_val = TRUE;
|
||||||
|
}
|
||||||
|
} else if (del_val > del_max_val) {
|
||||||
|
update_val = TRUE;
|
||||||
|
}
|
||||||
|
if (update_val) {
|
||||||
ds_clear(&delay_string);
|
ds_clear(&delay_string);
|
||||||
ds_clear(&dtyp_max_str);
|
ds_clear(&ddel_str);
|
||||||
ds_cat_str(&dtyp_max_str, tmps);
|
ds_cat_str(&ddel_str, tmps);
|
||||||
typ_max_val = typ_val;
|
if (shorter) {
|
||||||
if (ds_get_length(&dtyp_max_str) > 0) {
|
del_min_val = del_val;
|
||||||
|
} else {
|
||||||
|
del_max_val = del_val;
|
||||||
|
}
|
||||||
|
if (ds_get_length(&ddel_str) > 0) {
|
||||||
if (tri) {
|
if (tri) {
|
||||||
ds_cat_printf(&delay_string,
|
ds_cat_printf(&delay_string,
|
||||||
"(inertial_delay=true delay=%s)",
|
"(inertial_delay=true delay=%s)",
|
||||||
ds_get_buf(&dtyp_max_str));
|
ds_get_buf(&ddel_str));
|
||||||
} else {
|
} else {
|
||||||
ds_cat_printf(&delay_string,
|
ds_cat_printf(&delay_string,
|
||||||
"(inertial_delay=true rise_delay=%s fall_delay=%s)",
|
"(inertial_delay=true rise_delay=%s fall_delay=%s)",
|
||||||
ds_get_buf(&dtyp_max_str),
|
ds_get_buf(&ddel_str),
|
||||||
ds_get_buf(&dtyp_max_str));
|
ds_get_buf(&ddel_str));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
printf("WARNING pindly DELAY not found\n");
|
printf("WARNING pindly DELAY not found\n");
|
||||||
|
|
@ -2055,7 +2101,7 @@ static BOOL extract_delay(
|
||||||
val = lexer_scan(lx);
|
val = lexer_scan(lx);
|
||||||
} // end while != '}'
|
} // end while != '}'
|
||||||
ds_free(&dly);
|
ds_free(&dly);
|
||||||
ds_free(&dtyp_max_str);
|
ds_free(&ddel_str);
|
||||||
ds_free(&tmp_ds);
|
ds_free(&tmp_ds);
|
||||||
return ret_val;
|
return ret_val;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -307,6 +307,10 @@ static int ps_udevice_exit = 0;
|
||||||
static int ps_tpz_delays = 0; // For tristate delays
|
static int ps_tpz_delays = 0; // For tristate delays
|
||||||
static int ps_with_inverters = 0; // For ff/latch control inputs
|
static int ps_with_inverters = 0; // For ff/latch control inputs
|
||||||
static int ps_with_tri_inverters = 0; // For inv3/inv3a data inputs
|
static int ps_with_tri_inverters = 0; // For inv3/inv3a data inputs
|
||||||
|
|
||||||
|
static int ps_use_mntymx = 0;
|
||||||
|
static struct udevices_info mntymx_shorter = {0, FALSE};
|
||||||
|
|
||||||
static NAME_ENTRY new_names_list = NULL;
|
static NAME_ENTRY new_names_list = NULL;
|
||||||
static NAME_ENTRY input_names_list = NULL;
|
static NAME_ENTRY input_names_list = NULL;
|
||||||
static NAME_ENTRY output_names_list = NULL;
|
static NAME_ENTRY output_names_list = NULL;
|
||||||
|
|
@ -319,6 +323,46 @@ static BOOL add_drive_hilo = FALSE;
|
||||||
static char *current_subckt = NULL;
|
static char *current_subckt = NULL;
|
||||||
static unsigned int subckt_msg_count = 0;
|
static unsigned int subckt_msg_count = 0;
|
||||||
|
|
||||||
|
static void set_u_devices_info(int mntymx_duration)
|
||||||
|
{
|
||||||
|
switch (mntymx_duration) {
|
||||||
|
case 0: // typ + longer delays
|
||||||
|
mntymx_shorter.mntymx = 0;
|
||||||
|
mntymx_shorter.shorter_delays = FALSE;
|
||||||
|
break;
|
||||||
|
case 1: // min + longer delays
|
||||||
|
mntymx_shorter.mntymx = 1;
|
||||||
|
mntymx_shorter.shorter_delays = FALSE;
|
||||||
|
break;
|
||||||
|
case 2: // max + longer delays
|
||||||
|
mntymx_shorter.mntymx = 2;
|
||||||
|
mntymx_shorter.shorter_delays = FALSE;
|
||||||
|
break;
|
||||||
|
case 4: // typ + shorter delays
|
||||||
|
mntymx_shorter.mntymx = 0;
|
||||||
|
mntymx_shorter.shorter_delays = TRUE;
|
||||||
|
break;
|
||||||
|
case 5: // min + shorter delays
|
||||||
|
mntymx_shorter.mntymx = 1;
|
||||||
|
mntymx_shorter.shorter_delays = TRUE;
|
||||||
|
break;
|
||||||
|
case 6: // max + shorter delays
|
||||||
|
mntymx_shorter.mntymx = 2;
|
||||||
|
mntymx_shorter.shorter_delays = TRUE;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
mntymx_shorter.mntymx = 0;
|
||||||
|
mntymx_shorter.shorter_delays = FALSE;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct udevices_info u_get_udevices_info(void)
|
||||||
|
{
|
||||||
|
return mntymx_shorter;
|
||||||
|
}
|
||||||
|
|
||||||
static void check_name_unused(char *name)
|
static void check_name_unused(char *name)
|
||||||
{
|
{
|
||||||
if (find_name_entry(name, new_names_list)) {
|
if (find_name_entry(name, new_names_list)) {
|
||||||
|
|
@ -897,7 +941,7 @@ void initialize_udevice(char *subckt_line)
|
||||||
if they are the only delays.
|
if they are the only delays.
|
||||||
*/
|
*/
|
||||||
if (!cp_getvar("ps_tpz_delays", CP_NUM, &ps_tpz_delays, 0)) {
|
if (!cp_getvar("ps_tpz_delays", CP_NUM, &ps_tpz_delays, 0)) {
|
||||||
ps_tpz_delays = 0;
|
ps_tpz_delays = 1; // default: use tpz... delays if necessary
|
||||||
}
|
}
|
||||||
/* If non-zero use inverters with ff/latch control inputs */
|
/* If non-zero use inverters with ff/latch control inputs */
|
||||||
if (!cp_getvar("ps_with_inverters", CP_NUM, &ps_with_inverters, 0)) {
|
if (!cp_getvar("ps_with_inverters", CP_NUM, &ps_with_inverters, 0)) {
|
||||||
|
|
@ -907,6 +951,11 @@ void initialize_udevice(char *subckt_line)
|
||||||
if (!cp_getvar("ps_with_tri_inverters", CP_NUM, &ps_with_tri_inverters, 0)) {
|
if (!cp_getvar("ps_with_tri_inverters", CP_NUM, &ps_with_tri_inverters, 0)) {
|
||||||
ps_with_tri_inverters = 0;
|
ps_with_tri_inverters = 0;
|
||||||
}
|
}
|
||||||
|
if (!cp_getvar("ps_use_mntymx", CP_NUM, &ps_use_mntymx, 0)) {
|
||||||
|
ps_use_mntymx = 4; // default: typ + shorter delays
|
||||||
|
}
|
||||||
|
set_u_devices_info(ps_use_mntymx);
|
||||||
|
|
||||||
if (subckt_line && strncmp(subckt_line, ".subckt", 7) == 0) {
|
if (subckt_line && strncmp(subckt_line, ".subckt", 7) == 0) {
|
||||||
add_all_port_names(subckt_line);
|
add_all_port_names(subckt_line);
|
||||||
current_subckt = TMALLOC(char, strlen(subckt_line) + 1);
|
current_subckt = TMALLOC(char, strlen(subckt_line) + 1);
|
||||||
|
|
@ -2759,10 +2808,32 @@ static void estimate_typ(struct timing_data *tdp)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void estimate_delay(struct timing_data *tdp)
|
||||||
|
{
|
||||||
|
char *del = NULL;
|
||||||
|
if (!tdp) { return; }
|
||||||
|
if (mntymx_shorter.mntymx == 1) { // use min delay
|
||||||
|
del = tdp->min;
|
||||||
|
if (del && strlen(del) > 0 && del[0] != '-') {
|
||||||
|
tdp->estimate = EST_MIN;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else if (mntymx_shorter.mntymx == 2) { // use max delay
|
||||||
|
del = tdp->max;
|
||||||
|
if (del && strlen(del) > 0 && del[0] != '-') {
|
||||||
|
tdp->estimate = EST_MAX;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// use typ delay
|
||||||
|
estimate_typ(tdp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
static char *get_estimate(struct timing_data *tdp)
|
static char *get_estimate(struct timing_data *tdp)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Call after estimate_typ.
|
Call after estimate_delay.
|
||||||
Don't call delete_timing_data until you have copied
|
Don't call delete_timing_data until you have copied
|
||||||
or finished with this return value.
|
or finished with this return value.
|
||||||
*/
|
*/
|
||||||
|
|
@ -2777,8 +2848,11 @@ static char *get_estimate(struct timing_data *tdp)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *larger_delay(char *delay1, char *delay2)
|
static char *select_delay(char *delay1, char *delay2)
|
||||||
{
|
{
|
||||||
|
/* Return the shorter or longer delay
|
||||||
|
depending on the mntymx_shorter.shorter_delays setting
|
||||||
|
*/
|
||||||
float val1, val2;
|
float val1, val2;
|
||||||
char *units1, *units2;
|
char *units1, *units2;
|
||||||
|
|
||||||
|
|
@ -2787,11 +2861,16 @@ static char *larger_delay(char *delay1, char *delay2)
|
||||||
if (!eq(units1, units2)) {
|
if (!eq(units1, units2)) {
|
||||||
printf("WARNING units do not match\n");
|
printf("WARNING units do not match\n");
|
||||||
}
|
}
|
||||||
if (val1 >= val2) {
|
if (mntymx_shorter.shorter_delays) {
|
||||||
return delay1;
|
if (val1 <= val2) {
|
||||||
|
return delay1;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return delay2;
|
if (val1 >= val2) {
|
||||||
|
return delay1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
return delay2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* NOTE
|
/* NOTE
|
||||||
|
|
@ -2813,10 +2892,10 @@ static char *get_delays_ugate(char *rem)
|
||||||
BOOL has_rising = FALSE, has_falling = FALSE;
|
BOOL has_rising = FALSE, has_falling = FALSE;
|
||||||
|
|
||||||
tdp1 = create_min_typ_max("tplh", rem);
|
tdp1 = create_min_typ_max("tplh", rem);
|
||||||
estimate_typ(tdp1);
|
estimate_delay(tdp1);
|
||||||
rising = get_estimate(tdp1);
|
rising = get_estimate(tdp1);
|
||||||
tdp2 = create_min_typ_max("tphl", rem);
|
tdp2 = create_min_typ_max("tphl", rem);
|
||||||
estimate_typ(tdp2);
|
estimate_delay(tdp2);
|
||||||
falling = get_estimate(tdp2);
|
falling = get_estimate(tdp2);
|
||||||
has_rising = (rising && strlen(rising) > 0);
|
has_rising = (rising && strlen(rising) > 0);
|
||||||
has_falling = (falling && strlen(falling) > 0);
|
has_falling = (falling && strlen(falling) > 0);
|
||||||
|
|
@ -2845,7 +2924,7 @@ static char *get_delays_udly(char *rem)
|
||||||
struct timing_data *tdp1;
|
struct timing_data *tdp1;
|
||||||
|
|
||||||
tdp1 = create_min_typ_max("dly", rem);
|
tdp1 = create_min_typ_max("dly", rem);
|
||||||
estimate_typ(tdp1);
|
estimate_delay(tdp1);
|
||||||
udelay = get_estimate(tdp1);
|
udelay = get_estimate(tdp1);
|
||||||
if (udelay) {
|
if (udelay) {
|
||||||
delays = tprintf(
|
delays = tprintf(
|
||||||
|
|
@ -2865,22 +2944,22 @@ static char *get_delays_utgate(char *rem)
|
||||||
char *rising, *falling, *delays = NULL;
|
char *rising, *falling, *delays = NULL;
|
||||||
struct timing_data *tdp1, *tdp2;
|
struct timing_data *tdp1, *tdp2;
|
||||||
struct timing_data *tdp3, *tdp4, *tdp5, *tdp6;
|
struct timing_data *tdp3, *tdp4, *tdp5, *tdp6;
|
||||||
char *tplz, *tphz, *tpzl, *tpzh, *larger, *larger1, *larger2, *larger3;
|
char *tplz, *tphz, *tpzl, *tpzh, *select0, *select1, *select2, *select3;
|
||||||
BOOL use_zdelays = FALSE;
|
BOOL use_zdelays = FALSE;
|
||||||
BOOL has_rising = FALSE, has_falling = FALSE;
|
BOOL has_rising = FALSE, has_falling = FALSE;
|
||||||
|
|
||||||
tdp1 = create_min_typ_max("tplh", rem);
|
tdp1 = create_min_typ_max("tplh", rem);
|
||||||
estimate_typ(tdp1);
|
estimate_delay(tdp1);
|
||||||
rising = get_estimate(tdp1);
|
rising = get_estimate(tdp1);
|
||||||
tdp2 = create_min_typ_max("tphl", rem);
|
tdp2 = create_min_typ_max("tphl", rem);
|
||||||
estimate_typ(tdp2);
|
estimate_delay(tdp2);
|
||||||
falling = get_estimate(tdp2);
|
falling = get_estimate(tdp2);
|
||||||
has_rising = (rising && strlen(rising) > 0);
|
has_rising = (rising && strlen(rising) > 0);
|
||||||
has_falling = (falling && strlen(falling) > 0);
|
has_falling = (falling && strlen(falling) > 0);
|
||||||
if (has_rising) {
|
if (has_rising) {
|
||||||
if (has_falling) {
|
if (has_falling) {
|
||||||
larger = larger_delay(rising, falling);
|
select0 = select_delay(rising, falling);
|
||||||
delays = tprintf("(inertial_delay=true delay = %s)", larger);
|
delays = tprintf("(inertial_delay=true delay = %s)", select0);
|
||||||
} else {
|
} else {
|
||||||
delays = tprintf("(inertial_delay=true delay = %s)", rising);
|
delays = tprintf("(inertial_delay=true delay = %s)", rising);
|
||||||
}
|
}
|
||||||
|
|
@ -2889,49 +2968,49 @@ static char *get_delays_utgate(char *rem)
|
||||||
} else if (use_zdelays || (ps_tpz_delays & 1)) {
|
} else if (use_zdelays || (ps_tpz_delays & 1)) {
|
||||||
/* No lh/hl delays, so try the largest lz/hz/zl/zh delay */
|
/* No lh/hl delays, so try the largest lz/hz/zl/zh delay */
|
||||||
tdp3 = create_min_typ_max("tplz", rem);
|
tdp3 = create_min_typ_max("tplz", rem);
|
||||||
estimate_typ(tdp3);
|
estimate_delay(tdp3);
|
||||||
tplz = get_estimate(tdp3);
|
tplz = get_estimate(tdp3);
|
||||||
tdp4 = create_min_typ_max("tphz", rem);
|
tdp4 = create_min_typ_max("tphz", rem);
|
||||||
estimate_typ(tdp4);
|
estimate_delay(tdp4);
|
||||||
tphz = get_estimate(tdp4);
|
tphz = get_estimate(tdp4);
|
||||||
larger1 = NULL;
|
select1 = NULL;
|
||||||
if (tplz && strlen(tplz) > 0) {
|
if (tplz && strlen(tplz) > 0) {
|
||||||
if (tphz && strlen(tphz) > 0) {
|
if (tphz && strlen(tphz) > 0) {
|
||||||
larger1 = larger_delay(tplz, tphz);
|
select1 = select_delay(tplz, tphz);
|
||||||
} else {
|
} else {
|
||||||
larger1 = tplz;
|
select1 = tplz;
|
||||||
}
|
}
|
||||||
} else if (tphz && strlen(tphz) > 0) {
|
} else if (tphz && strlen(tphz) > 0) {
|
||||||
larger1 = tphz;
|
select1 = tphz;
|
||||||
}
|
}
|
||||||
tdp5 = create_min_typ_max("tpzl", rem);
|
tdp5 = create_min_typ_max("tpzl", rem);
|
||||||
estimate_typ(tdp5);
|
estimate_delay(tdp5);
|
||||||
tpzl = get_estimate(tdp5);
|
tpzl = get_estimate(tdp5);
|
||||||
tdp6 = create_min_typ_max("tpzh", rem);
|
tdp6 = create_min_typ_max("tpzh", rem);
|
||||||
estimate_typ(tdp6);
|
estimate_delay(tdp6);
|
||||||
tpzh = get_estimate(tdp6);
|
tpzh = get_estimate(tdp6);
|
||||||
larger2 = NULL;
|
select2 = NULL;
|
||||||
if (tpzl && strlen(tpzl) > 0) {
|
if (tpzl && strlen(tpzl) > 0) {
|
||||||
if (tpzh && strlen(tpzh) > 0) {
|
if (tpzh && strlen(tpzh) > 0) {
|
||||||
larger2 = larger_delay(tpzl, tpzh);
|
select2 = select_delay(tpzl, tpzh);
|
||||||
} else {
|
} else {
|
||||||
larger2 = tpzl;
|
select2 = tpzl;
|
||||||
}
|
}
|
||||||
} else if (tpzh && strlen(tpzh) > 0) {
|
} else if (tpzh && strlen(tpzh) > 0) {
|
||||||
larger2 = tpzh;
|
select2 = tpzh;
|
||||||
}
|
}
|
||||||
larger3 = NULL;
|
select3 = NULL;
|
||||||
if (larger1) {
|
if (select1) {
|
||||||
if (larger2) {
|
if (select2) {
|
||||||
larger3 = larger_delay(larger1, larger2);
|
select3 = select_delay(select1, select2);
|
||||||
} else {
|
} else {
|
||||||
larger3 = larger1;
|
select3 = select1;
|
||||||
}
|
}
|
||||||
} else if (larger2) {
|
} else if (select2) {
|
||||||
larger3 = larger2;
|
select3 = select2;
|
||||||
}
|
}
|
||||||
if (larger3) {
|
if (select3) {
|
||||||
delays = tprintf("(inertial_delay=true delay = %s)", larger3);
|
delays = tprintf("(inertial_delay=true delay = %s)", select3);
|
||||||
} else {
|
} else {
|
||||||
delays = tprintf("(inertial_delay=true delay=1.0e-12)");
|
delays = tprintf("(inertial_delay=true delay=1.0e-12)");
|
||||||
}
|
}
|
||||||
|
|
@ -2951,26 +3030,26 @@ static char *get_delays_ueff(char *rem)
|
||||||
{
|
{
|
||||||
char *delays = NULL;
|
char *delays = NULL;
|
||||||
char *clkqrise, *clkqfall, *pcqrise, *pcqfall;
|
char *clkqrise, *clkqfall, *pcqrise, *pcqfall;
|
||||||
char *clkd, *setd, *resetd, *larger;
|
char *clkd, *setd, *resetd, *select;
|
||||||
struct timing_data *tdp1, *tdp2, *tdp3, *tdp4;
|
struct timing_data *tdp1, *tdp2, *tdp3, *tdp4;
|
||||||
|
|
||||||
tdp1 = create_min_typ_max("tpclkqlh", rem);
|
tdp1 = create_min_typ_max("tpclkqlh", rem);
|
||||||
estimate_typ(tdp1);
|
estimate_delay(tdp1);
|
||||||
clkqrise = get_estimate(tdp1);
|
clkqrise = get_estimate(tdp1);
|
||||||
tdp2 = create_min_typ_max("tpclkqhl", rem);
|
tdp2 = create_min_typ_max("tpclkqhl", rem);
|
||||||
estimate_typ(tdp2);
|
estimate_delay(tdp2);
|
||||||
clkqfall = get_estimate(tdp2);
|
clkqfall = get_estimate(tdp2);
|
||||||
tdp3 = create_min_typ_max("tppcqlh", rem);
|
tdp3 = create_min_typ_max("tppcqlh", rem);
|
||||||
estimate_typ(tdp3);
|
estimate_delay(tdp3);
|
||||||
pcqrise = get_estimate(tdp3);
|
pcqrise = get_estimate(tdp3);
|
||||||
tdp4 = create_min_typ_max("tppcqhl", rem);
|
tdp4 = create_min_typ_max("tppcqhl", rem);
|
||||||
estimate_typ(tdp4);
|
estimate_delay(tdp4);
|
||||||
pcqfall = get_estimate(tdp4);
|
pcqfall = get_estimate(tdp4);
|
||||||
clkd = NULL;
|
clkd = NULL;
|
||||||
if (clkqrise && strlen(clkqrise) > 0) {
|
if (clkqrise && strlen(clkqrise) > 0) {
|
||||||
if (clkqfall && strlen(clkqfall) > 0) {
|
if (clkqfall && strlen(clkqfall) > 0) {
|
||||||
larger = larger_delay(clkqrise, clkqfall);
|
select = select_delay(clkqrise, clkqfall);
|
||||||
clkd = larger;
|
clkd = select;
|
||||||
} else {
|
} else {
|
||||||
clkd = clkqrise;
|
clkd = clkqrise;
|
||||||
}
|
}
|
||||||
|
|
@ -3018,7 +3097,7 @@ static char *get_delays_ugff(char *rem, char *d_name)
|
||||||
char *delays = NULL, *dname;
|
char *delays = NULL, *dname;
|
||||||
char *tpdqlh, *tpdqhl, *tpgqlh, *tpgqhl, *tppcqlh, *tppcqhl;
|
char *tpdqlh, *tpdqhl, *tpgqlh, *tpgqhl, *tppcqlh, *tppcqhl;
|
||||||
char *d_delay, *enab, *setd, *resetd;
|
char *d_delay, *enab, *setd, *resetd;
|
||||||
char *s1, *s2, *larger;
|
char *s1, *s2, *select;
|
||||||
struct timing_data *tdp1, *tdp2, *tdp3, *tdp4, *tdp5, *tdp6;
|
struct timing_data *tdp1, *tdp2, *tdp3, *tdp4, *tdp5, *tdp6;
|
||||||
|
|
||||||
if (eq(d_name, "d_dlatch")) {
|
if (eq(d_name, "d_dlatch")) {
|
||||||
|
|
@ -3029,28 +3108,28 @@ static char *get_delays_ugff(char *rem, char *d_name)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
tdp1 = create_min_typ_max("tpdqlh", rem);
|
tdp1 = create_min_typ_max("tpdqlh", rem);
|
||||||
estimate_typ(tdp1);
|
estimate_delay(tdp1);
|
||||||
tpdqlh = get_estimate(tdp1);
|
tpdqlh = get_estimate(tdp1);
|
||||||
tdp2 = create_min_typ_max("tpdqhl", rem);
|
tdp2 = create_min_typ_max("tpdqhl", rem);
|
||||||
estimate_typ(tdp2);
|
estimate_delay(tdp2);
|
||||||
tpdqhl = get_estimate(tdp2);
|
tpdqhl = get_estimate(tdp2);
|
||||||
tdp3 = create_min_typ_max("tpgqlh", rem);
|
tdp3 = create_min_typ_max("tpgqlh", rem);
|
||||||
estimate_typ(tdp3);
|
estimate_delay(tdp3);
|
||||||
tpgqlh = get_estimate(tdp3);
|
tpgqlh = get_estimate(tdp3);
|
||||||
tdp4 = create_min_typ_max("tpgqhl", rem);
|
tdp4 = create_min_typ_max("tpgqhl", rem);
|
||||||
estimate_typ(tdp4);
|
estimate_delay(tdp4);
|
||||||
tpgqhl = get_estimate(tdp4);
|
tpgqhl = get_estimate(tdp4);
|
||||||
tdp5 = create_min_typ_max("tppcqlh", rem);
|
tdp5 = create_min_typ_max("tppcqlh", rem);
|
||||||
estimate_typ(tdp5);
|
estimate_delay(tdp5);
|
||||||
tppcqlh = get_estimate(tdp5);
|
tppcqlh = get_estimate(tdp5);
|
||||||
tdp6 = create_min_typ_max("tppcqhl", rem);
|
tdp6 = create_min_typ_max("tppcqhl", rem);
|
||||||
estimate_typ(tdp6);
|
estimate_delay(tdp6);
|
||||||
tppcqhl = get_estimate(tdp6);
|
tppcqhl = get_estimate(tdp6);
|
||||||
d_delay = NULL;
|
d_delay = NULL;
|
||||||
if (tpdqlh && strlen(tpdqlh) > 0) {
|
if (tpdqlh && strlen(tpdqlh) > 0) {
|
||||||
if (tpdqhl && strlen(tpdqhl) > 0) {
|
if (tpdqhl && strlen(tpdqhl) > 0) {
|
||||||
larger = larger_delay(tpdqlh, tpdqhl);
|
select = select_delay(tpdqlh, tpdqhl);
|
||||||
d_delay = larger;
|
d_delay = select;
|
||||||
} else {
|
} else {
|
||||||
d_delay = tpdqlh;
|
d_delay = tpdqlh;
|
||||||
}
|
}
|
||||||
|
|
@ -3060,8 +3139,8 @@ static char *get_delays_ugff(char *rem, char *d_name)
|
||||||
enab = NULL;
|
enab = NULL;
|
||||||
if (tpgqlh && strlen(tpgqlh) > 0) {
|
if (tpgqlh && strlen(tpgqlh) > 0) {
|
||||||
if (tpgqhl && strlen(tpgqhl) > 0) {
|
if (tpgqhl && strlen(tpgqhl) > 0) {
|
||||||
larger = larger_delay(tpgqlh, tpgqhl);
|
select = select_delay(tpgqlh, tpgqhl);
|
||||||
enab = larger;
|
enab = select;
|
||||||
} else {
|
} else {
|
||||||
enab = tpgqlh;
|
enab = tpgqlh;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,11 @@
|
||||||
#ifndef INCLUDED_UDEVICES
|
#ifndef INCLUDED_UDEVICES
|
||||||
#define INCLUDED_UDEVICES
|
#define INCLUDED_UDEVICES
|
||||||
|
|
||||||
|
struct udevices_info {
|
||||||
|
int mntymx;
|
||||||
|
BOOL shorter_delays;
|
||||||
|
};
|
||||||
|
|
||||||
BOOL u_process_instance(char *line);
|
BOOL u_process_instance(char *line);
|
||||||
BOOL u_process_model_line(char *line);
|
BOOL u_process_model_line(char *line);
|
||||||
BOOL u_check_instance(char *line);
|
BOOL u_check_instance(char *line);
|
||||||
|
|
@ -10,5 +15,6 @@ void cleanup_udevice(void);
|
||||||
void u_add_instance(char *str);
|
void u_add_instance(char *str);
|
||||||
void u_add_logicexp_model(char *tmodel, char *xspice_gate, char *model_name);
|
void u_add_logicexp_model(char *tmodel, char *xspice_gate, char *model_name);
|
||||||
void u_remember_pin(char *name, int type);
|
void u_remember_pin(char *name, int type);
|
||||||
|
struct udevices_info u_get_udevices_info(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue