diff --git a/examples/p-to-n-examples/behav-tristate.cir b/examples/p-to-n-examples/behav-tristate.cir new file mode 100644 index 000000000..b796c9616 --- /dev/null +++ b/examples/p-to-n-examples/behav-tristate.cir @@ -0,0 +1,69 @@ +Test behav-tristate.cir + +* -----------------------------------------------------------74HCT125------ +*** This is not quad +* Quad Buffer/Line Driver; Tri-State +* Philips High Speed CMOS Logic Family, 1994, pages 243 to 247 +* jat 9/4/96 + +.SUBCKT 74HCT125 1A 1Y 1OEBAR ++ OPTIONAL: DPWR=$G_DPWR DGND=$G_DGND ++ PARAMS: MNTYMXDLY=0 IO_LEVEL=0 + +U1 PINDLY(1,1,0) DPWR DGND ++ 1A ++ 1OEBAR ++ 1Y ++ IO_HCT MNTYMXDLY={MNTYMXDLY} IO_LEVEL={IO_LEVEL} ++ TRISTATE: ++ ENABLE LO = 1OEBAR ++ 1Y = { ++ CASE( ++ TRN_Z$,DELAY(-1,15NS,28NS), ++ TRN_$Z, DELAY(-1,15NS,25NS), ++ (TRN_LH | TRN_HL), DELAY(-1,15NS,25NS), ++ DELAY(-1,16NS,29NS))} + +.ENDS 74HCT125 +* -----------------------------------------------------------74HC126A------ +*** This is not quad +* Quad Tri-State Noninverting Buffers +* Motorola High-Speed CMOS Data, 1993, pages 5-106 to 5-109 +* jat 9/4/96 + +.SUBCKT 74HC126A A1 Y1 OE1 ++ OPTIONAL: DPWR=$G_DPWR DGND=$G_DGND ++ PARAMS: MNTYMXDLY=0 IO_LEVEL=0 + +U1 PINDLY(1,1,0) DPWR DGND ++ A1 ++ OE1 ++ Y1 ++ IO_HC MNTYMXDLY={MNTYMXDLY} IO_LEVEL={IO_LEVEL} ++ TRISTATE: ++ ENABLE HI = OE1 ++ Y1 = { ++ CASE( ++ TRN_Z$,DELAY(-1,-1,18NS), ++ TRN_$Z, DELAY(-1,-1,24NS), ++ (TRN_LH | TRN_HL), DELAY(-1,-1,18NS), ++ DELAY(-1,-1,25NS))} + +.ENDS 74HC126A + +* .SUBCKT 74HCT125 1A 1Y 1OEBAR +x1 1a 1y oebar 74hct125 +* .SUBCKT 74HC126A A1 Y1 OE1 +x1 a1 y1 oe 74hc126a +a_1 [ 1a oebar a1 oe ] input_vec1 +.model input_vec1 d_source(input_file = "behav-tristate.stim") + +.tran 0.01ns 1us +.control +run +listing +edisplay +eprint 1a oebar 1y a1 oe y1 +quit +.endc +.end diff --git a/examples/p-to-n-examples/behav-tristate.stim b/examples/p-to-n-examples/behav-tristate.stim new file mode 100644 index 000000000..4b3dd558d --- /dev/null +++ b/examples/p-to-n-examples/behav-tristate.stim @@ -0,0 +1,13 @@ +* T 1 o a o +* i a e 1 e +* m b +* e a +* r + +0ns 1s 1s 1s 0s +100ns 1s 0s 1s 1s +200ns 0s 0s 0s 1s +300ns 0s 1s 0s 0s +400ns 1s 1s 1s 0s +500ns 1s 0s 1s 1s +600ns 0s 0s 0s 1s diff --git a/src/frontend/logicexp.c b/src/frontend/logicexp.c index 335f0294b..f7fae0842 100644 --- a/src/frontend/logicexp.c +++ b/src/frontend/logicexp.c @@ -560,7 +560,7 @@ static void aerror(char *s); static void amatch(int t); static void bexpr(void); static void bfactor(void); -static void bparse(char *line, BOOL new_lexer); +static BOOL bparse(char *line, BOOL new_lexer); static int lookahead = 0; static int adepth = 0; @@ -891,9 +891,13 @@ static PTABLE optimize_gen_tab(PTABLE pt) } } else if (val == '~') { found_tilde = TRUE; - if (tok_count != 3) goto quick_return; + if (tok_count != 3) { + goto quick_return; + } } else if (val == '=') { - if (tok_count != 2) goto quick_return; + if (tok_count != 2) { + goto quick_return; + } } val = lexer_scan(lxr); } @@ -1250,9 +1254,10 @@ static void beval_order(void) return; } -static void bparse(char *line, BOOL new_lexer) +static BOOL bparse(char *line, BOOL new_lexer) { int stmt_num = 0; + BOOL ret_val = TRUE; LEXER lx; PTABLE opt_tab1 = NULL, opt_tab2 = NULL; DS_CREATE(stmt, LEX_BUF_SZ); @@ -1267,7 +1272,7 @@ static void bparse(char *line, BOOL new_lexer) if (new_lexer) lex_init(line); - if (!parse_lexer) return; + if (!parse_lexer) return FALSE; lx = parse_lexer; lookahead = lex_set_start("logic:"); lookahead = lex_scan(); // "logic" @@ -1290,10 +1295,15 @@ static void bparse(char *line, BOOL new_lexer) if (opt_tab2) { gen_gates(opt_tab2, lx->lexer_sym_tab); } + } else { + ret_val = FALSE; } delete_parse_table(opt_tab1); delete_parse_table(opt_tab2); delete_parse_gen_tables(); + if (!ret_val) { + break; + } } ds_free(&d_curr_line); @@ -1301,7 +1311,7 @@ static void bparse(char *line, BOOL new_lexer) gen_models(); ds_free(&stmt); delete_lexer(lx); - return; + return ret_val; } /* End of logicexp parser */ @@ -1348,6 +1358,7 @@ BOOL f_logicexp(char *line) { int t, num_ins = 0, num_outs = 0, i; char *endp; + BOOL ret_val = TRUE; lex_init(line); current_lexer = parse_lexer; @@ -1404,10 +1415,10 @@ BOOL f_logicexp(char *line) //printf("TMODEL: %s\n", parse_lexer->lexer_buf); (void) add_sym_tab_entry(parse_lexer->lexer_buf, SYM_TMODEL, &parse_lexer->lexer_sym_tab); - bparse(line, FALSE); + ret_val = bparse(line, FALSE); current_lexer = NULL; - return TRUE; + return ret_val; error_return: delete_lexer(parse_lexer); @@ -1737,12 +1748,16 @@ static BOOL new_gen_output_models(LEXER lx) in_pindly = TRUE; in_tristate = FALSE; val = lexer_scan(lx); - if (val != ':') goto err_return; + if (val != ':') { + goto err_return; + } } else if (eq(lx->lexer_buf, "tristate")) { in_pindly = FALSE; in_tristate = TRUE; val = lexer_scan(lx); - if (val != ':') goto err_return; + if (val != ':') { + goto err_return; + } } else if (eq(lx->lexer_buf, "setup_hold") || eq(lx->lexer_buf, "width") || eq(lx->lexer_buf, "freq") @@ -1755,16 +1770,21 @@ static BOOL new_gen_output_models(LEXER lx) while (val == LEX_ID) { if (prit) printf("pindly out \"%s\"\n", lx->lexer_buf); pline = find_pindly_out_name(pindly_tab, lx->lexer_buf); - if (pline) + if (pline) { pline_arr[idx++] = pline; - else + } else { goto err_return; + } val = lexer_scan(lx); } typ_max_val = 0.0; - if (val != '=') goto err_return; + if (val != '=') { + goto err_return; + } val = lexer_scan(lx); - if (val != '{') goto err_return; + if (val != '{') { + goto err_return; + } val = lexer_scan(lx); while (val != '}') { if (val == LEX_ID) { @@ -1788,7 +1808,9 @@ static BOOL new_gen_output_models(LEXER lx) if (prit) printf("estimate \"%s\"\n", typical_estimate(ds_get_buf(&dly))); tmps = typical_estimate(ds_get_buf(&dly)); - if (!tmps) goto err_return; + if (!tmps) { + goto err_return; + } typ_val = strtof(tmps, &units); if (typ_val > typ_max_val) { ds_clear(&delay_string); @@ -1831,9 +1853,13 @@ static BOOL new_gen_output_models(LEXER lx) invert = TRUE; if (prit) printf("tristate enable %s ", lx->lexer_buf); val = lexer_scan(lx); - if (val != '=') goto err_return; + if (val != '=') { + goto err_return; + } val = lexer_scan(lx); - if (val != LEX_ID) goto err_return; + if (val != LEX_ID) { + goto err_return; + } if (prit) printf("ena \"%s\"\n", lx->lexer_buf); ds_clear(&enable_name); if (invert) @@ -1845,7 +1871,9 @@ static BOOL new_gen_output_models(LEXER lx) ds_clear(&last_enable); ds_cat_ds(&last_enable, &enable_name); val = lexer_scan(lx); - if (val != LEX_ID) goto err_return; + if (val != LEX_ID) { + goto err_return; + } } else if (ds_get_length(&last_enable) > 0) { ds_clear(&enable_name); ds_cat_ds(&enable_name, &last_enable); @@ -1864,9 +1892,13 @@ static BOOL new_gen_output_models(LEXER lx) val = lexer_scan(lx); } typ_max_val = 0.0; - if (val != '=') goto err_return; + if (val != '=') { + goto err_return; + } val = lexer_scan(lx); - if (val != '{') goto err_return; + if (val != '{') { + goto err_return; + } val = lexer_scan(lx); while (val != '}') { if (val == LEX_ID) { @@ -1890,7 +1922,9 @@ static BOOL new_gen_output_models(LEXER lx) if (prit) printf("estimate \"%s\"\n", typical_estimate(ds_get_buf(&dly))); tmps = typical_estimate(ds_get_buf(&dly)); - if (!tmps) goto err_return; + if (!tmps) { + goto err_return; + } typ_val = strtof(tmps, &units); if (typ_val > typ_max_val) { ds_clear(&delay_string);