From 4bac92056425aab8c2a9e0976b3a198fc98b17c8 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Sat, 31 Dec 2022 14:50:07 +0100 Subject: [PATCH 01/17] Add PREDICTOR to Cygwin build --- compile_cyg_make_short_check_64.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compile_cyg_make_short_check_64.sh b/compile_cyg_make_short_check_64.sh index 1f77f265a..54d0868d2 100644 --- a/compile_cyg_make_short_check_64.sh +++ b/compile_cyg_make_short_check_64.sh @@ -38,7 +38,7 @@ cd release64_cyg if [ $? -ne 0 ]; then echo "cd release64_cyg failed"; exit 1 ; fi echo # You may add --enable-adms to the following command for adding adms generated devices -../configure --with-x=yes --with-readline=yes --disable-debug --enable-cider --enable-openmp --enable-xspice --enable-osdi --enable-shortcheck CFLAGS="-O2 -m64" LDFLAGS="-s -m64" +../configure --with-x=yes --with-readline=yes --disable-debug --enable-cider --enable-openmp --enable-xspice --enable-osdi --enable-predictor --enable-shortcheck CFLAGS="-O2 -m64" LDFLAGS="-s -m64" #../configure --with-x=no --with-readline=yes --disable-debug --enable-xspice --enable-cider --enable-openmp if [ $? -ne 0 ]; then echo "../configure failed"; exit 1 ; fi From 3ca9f037bdd20d22750b18c660c5fb0ed102c754 Mon Sep 17 00:00:00 2001 From: Brian Taylor Date: Sat, 24 Dec 2022 12:27:57 -0800 Subject: [PATCH 02/17] Add more error checks for f_logicexp and f_pindly. --- src/frontend/logicexp.c | 59 ++++++++++++++++++++++++++--------------- 1 file changed, 38 insertions(+), 21 deletions(-) diff --git a/src/frontend/logicexp.c b/src/frontend/logicexp.c index 26b4b53b0..7acc9bd08 100644 --- a/src/frontend/logicexp.c +++ b/src/frontend/logicexp.c @@ -1100,7 +1100,7 @@ quick_return: return new_gen; } -static void gen_gates(PTABLE gate_tab, SYM_TAB parser_symbols) +static BOOL gen_gates(PTABLE gate_tab, SYM_TAB parser_symbols) { /* gen_gates is called with PTABLE gate_tab being the final PTABLE produced by optimize_gen_tab(,..) calls. @@ -1122,11 +1122,11 @@ static void gen_gates(PTABLE gate_tab, SYM_TAB parser_symbols) ds_free(&in_names); ds_free(&gate_name); ds_free(&instance); - return; + return FALSE; } t = gate_tab->first; lxr = new_lexer(t->line); - while (t) { + while (t) { // while t loop ds_clear(&out_name); ds_clear(&in_names); ds_clear(&gate_name); @@ -1160,25 +1160,25 @@ static void gen_gates(PTABLE gate_tab, SYM_TAB parser_symbols) } } else if (val == '~') { found_tilde = TRUE; - if (tok_count != 3) goto quick_return; + if (tok_count != 3) goto gen_error; } else if (val == '=') { - if (tok_count != 2) goto quick_return; + if (tok_count != 2) goto gen_error; } else if (lex_gate_op(val)) { if (gate_op != 0) { - if (val != gate_op) goto quick_return; + if (val != gate_op) goto gen_error; } gate_op = val; } else { - goto quick_return; + goto gen_error; } val = lexer_scan(lxr); } // end while val loop if (in_count == 1) { // buffer or inverter - if (gate_op != 0) goto quick_return; + if (gate_op != 0) goto gen_error; 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; + if (gate_op == 0) goto gen_error; if (use_tmodel_delays) { /* This is the case when logicexp has a UGATE timing model (not d0_gate) and no pindly. @@ -1200,7 +1200,7 @@ static void gen_gates(PTABLE gate_tab, SYM_TAB parser_symbols) ds_cat_str(&gate_name, lex_gate_name(gate_op, found_tilde)); } } else { - goto quick_return; + goto gen_error; } ds_cat_printf(&instance, "%s ", get_inst_name()); if (in_count == 1) { @@ -1217,10 +1217,10 @@ static void gen_gates(PTABLE gate_tab, SYM_TAB parser_symbols) ds_get_buf(&out_name)); ent = member_sym_tab(tail, parser_symbols); if (!ent) { - goto quick_return; + goto gen_error; } if ((ent->attribute & SYM_INVERTER) == 0) { - goto quick_return; + goto gen_error; } ent->ref_count--; } else { @@ -1241,15 +1241,22 @@ static void gen_gates(PTABLE gate_tab, SYM_TAB parser_symbols) if (ds_get_length(&instance) > 0) { u_add_instance(ds_get_buf(&instance)); } - } + } // end while t loop -quick_return: delete_lexer(lxr); ds_free(&out_name); ds_free(&in_names); ds_free(&gate_name); ds_free(&instance); - return; + return TRUE; + +gen_error: + delete_lexer(lxr); + ds_free(&out_name); + ds_free(&in_names); + ds_free(&gate_name); + ds_free(&instance); + return FALSE; } /* @@ -1387,7 +1394,7 @@ static BOOL bparse(char *line, BOOL new_lexer) lookahead = lex_scan(); // "logic" lookahead = lex_scan(); // ':' lookahead = lex_scan(); - while (lookahead != '\0') { + while (lookahead != '\0') { // while lookahead loop unsigned int last_count = 0, curr_count = 0; init_parse_tables(); adepth = max_adepth = 0; @@ -1411,7 +1418,10 @@ static BOOL bparse(char *line, BOOL new_lexer) } last_count = gen_tab->entry_count; if (last_count == 1) { - gen_gates(gen_tab, lx->lexer_sym_tab); + ret_val = gen_gates(gen_tab, lx->lexer_sym_tab); + if (!ret_val) { + printf("ERROR generating gates for logicexp\n"); + } } else if (last_count > 1) { opt_tab1 = optimize_gen_tab(gen_tab); if (prit) { @@ -1437,7 +1447,10 @@ static BOOL bparse(char *line, BOOL new_lexer) curr_count = opt_tab2->entry_count; } if (opt_tab2) { - gen_gates(opt_tab2, lx->lexer_sym_tab); + ret_val = gen_gates(opt_tab2, lx->lexer_sym_tab); + if (!ret_val) { + printf("ERROR generating gates for logicexp\n"); + } delete_parse_table(opt_tab2); } } else { @@ -1450,7 +1463,7 @@ static BOOL bparse(char *line, BOOL new_lexer) if (!ret_val) { break; } - } + } // end while lookahead loop ds_free(&d_curr_line); gen_models(); @@ -1579,6 +1592,10 @@ BOOL f_logicexp(char *line) ret_val = bparse(line, FALSE); current_lexer = NULL; + if (!ret_val) { + printf("ERROR parsing logicexp\n"); + printf("ERROR in \"%s\"\n", line); + } return ret_val; error_return: @@ -1720,7 +1737,7 @@ static void print_pindly_table(PINTABLE pint) static PLINE nth_pindly_entry(PINTABLE pint, int n) { - /* Entries ore from 0 to num_entries - 1 */ + /* Entries are from 0 to num_entries - 1 */ PLINE p, next; int count = 0; if (n < 0) return NULL; @@ -2099,7 +2116,6 @@ static BOOL new_gen_output_models(LEXER lx) return TRUE; err_return: - printf("ERROR in new_gen_output_models\n"); ds_free(&enable_name); ds_free(&last_enable); tfree(pline_arr); @@ -2195,6 +2211,7 @@ BOOL f_pindly(char *line) } if (!new_gen_output_models(lxr)) { + printf("ERROR generating models for pindly\n"); printf("ERROR in \"%s\"\n", line); goto error_return;; } From de1c835edd8f36dfe0d2b6bad0912930b051781a Mon Sep 17 00:00:00 2001 From: Brian Taylor Date: Mon, 26 Dec 2022 21:47:38 -0800 Subject: [PATCH 03/17] Return errors from f_logicexp and f_pindly without calling exit. --- src/frontend/logicexp.c | 118 ++++++++++++++++++++++++++++------------ src/frontend/udevices.c | 13 ++++- 2 files changed, 94 insertions(+), 37 deletions(-) diff --git a/src/frontend/logicexp.c b/src/frontend/logicexp.c index 7acc9bd08..479dbceb9 100644 --- a/src/frontend/logicexp.c +++ b/src/frontend/logicexp.c @@ -606,9 +606,9 @@ static void ptable_print(PTABLE pt) static char *get_inst_name(void); static char *get_inverter_output_name(char *input); static void aerror(char *s); -static void amatch(int t); -static void bexpr(void); -static void bfactor(void); +static BOOL amatch(int t); +static BOOL bexpr(void); +static BOOL bfactor(void); static BOOL bparse(char *line, BOOL new_lexer); static int lookahead = 0; @@ -618,6 +618,13 @@ static DSTRING d_curr_line; static int number_of_instances = 0; static BOOL use_tmodel_delays = FALSE; +static void cleanup_parser(void) +{ + delete_lexer(parse_lexer); + parse_lexer = NULL; + delete_parse_gen_tables(); +} + static char *get_inst_name(void) { static char name[64]; @@ -714,7 +721,7 @@ static void aerror(char *s) { LEXER lx = parse_lexer; printf("%s [%s]\n", s, lx->lexer_line + lx->lexer_pos); - exit(1); + cleanup_parser(); } char *get_temp_name(void) @@ -726,19 +733,28 @@ char *get_temp_name(void) return name; } -static void amatch(int t) +static BOOL amatch(int t) { LEXER lx = parse_lexer; if (lookahead == t) { lookahead = lex_scan(); } else { - printf("t = '%c' [%d] lookahead = '%c' [%d] lexer_buf %s\n", + printf("expect = '%c' [%d] lookahead = '%c' [%d] lexer_buf %s\n", t, t, lookahead, lookahead, lx->lexer_buf); aerror("amatch: syntax error"); + return FALSE; } + return TRUE; } -static void bfactor(void) +#define AMATCH_BFACTOR(n) \ +{ \ + if (!amatch((n))) { \ + return FALSE; \ + } \ +} + +static BOOL bfactor(void) { /* factor is : ['~'] rest where rest is: input_name_id | '(' expr ')' | error @@ -789,7 +805,10 @@ static void bfactor(void) ds_clear(&d_curr_line); lookahead = lex_scan(); - bexpr(); + if (!bexpr()) { + cleanup_parser(); + return FALSE; + } (void) ptab_add_line(ds_get_buf(&d_curr_line), TRUE); ds_clear(&d_curr_line); @@ -799,44 +818,62 @@ static void bfactor(void) (void) ptab_add_line(ds_get_buf(&d_curr_line), TRUE); ds_clear(&d_curr_line); - amatch(')'); ds_free(&tmpnam); + AMATCH_BFACTOR(')'); } else { aerror("bfactor: syntax error"); + return FALSE; } adepth--; + return TRUE; } -static void bexpr(void) +static BOOL bexpr(void) { /* expr is: factor { gate_op factor }+ where {}+ means 0 or more times. */ - bfactor(); + if (!bfactor()) { + cleanup_parser(); + return FALSE; + } while (lex_gate_op(lookahead)) { ds_cat_printf(&d_curr_line, "%c ", lookahead); lookahead = lex_scan(); - bfactor(); + if (!bfactor()) { + cleanup_parser(); + return FALSE; + } } + return TRUE; } -static void bstmt(void) +#define AMATCH_BSTMT(n) \ +{ \ + if (!amatch((n))) { \ + ds_free(&tname); ds_free(&assign); \ + return FALSE; \ + } \ +} + +static BOOL bstmt(void) { /* A stmt is: output_name_id = '{' expr '}' */ BOOL verbose = PRINT_ALL; int end_pos = 0, start_pos = 0; SYM_TAB entry = NULL; - LEXER lx = parse_lexer; DS_CREATE(tname, 64); DS_CREATE(assign, LEX_BUF_SZ); if (lookahead == LEX_ID) { - entry = add_sym_tab_entry(lx->lexer_buf, SYM_ID, &lx->lexer_sym_tab); + entry = add_sym_tab_entry(parse_lexer->lexer_buf, SYM_ID, + &parse_lexer->lexer_sym_tab); } else { aerror("bstmt: syntax error"); + return FALSE; } adepth++; @@ -844,18 +881,18 @@ static void bstmt(void) max_adepth = adepth; if (verbose) { - start_pos = lx->lexer_pos; - printf("* %s", lx->lexer_buf); + start_pos = parse_lexer->lexer_pos; + printf("* %s", parse_lexer->lexer_buf); } - amatch(LEX_ID); - amatch('='); + AMATCH_BSTMT(LEX_ID); + AMATCH_BSTMT('='); ds_clear(&assign); ds_cat_printf(&assign, "%s =", entry->name); (void) ptab_add_line(ds_get_buf(&assign), TRUE); - amatch('{'); + AMATCH_BSTMT('{'); ds_clear(&tname); ds_cat_str(&tname, get_temp_name()); @@ -863,7 +900,12 @@ static void bstmt(void) (void) ptab_add_line(ds_get_buf(&d_curr_line), TRUE); ds_clear(&d_curr_line); - bexpr(); + if (!bexpr()) { + cleanup_parser(); + ds_free(&assign); + ds_free(&tname); + return FALSE; + } if (ds_get_length(&d_curr_line) > 0) { (void) ptab_add_line(ds_get_buf(&d_curr_line), TRUE); @@ -875,19 +917,19 @@ static void bstmt(void) if (verbose) { DS_CREATE(stmt_str, 128); - end_pos = lx->lexer_pos; - ds_cat_mem(&stmt_str, &lx->lexer_line[start_pos], + end_pos = parse_lexer->lexer_pos; + ds_cat_mem(&stmt_str, &parse_lexer->lexer_line[start_pos], (size_t) (end_pos - start_pos)); printf("%s\n", ds_get_buf(&stmt_str)); ds_free(&stmt_str); } - amatch('}'); + AMATCH_BSTMT('}'); ds_free(&assign); ds_free(&tname); adepth--; - return; + return TRUE; } static PTABLE optimize_gen_tab(PTABLE pt) @@ -1374,7 +1416,6 @@ static BOOL bparse(char *line, BOOL new_lexer) { int stmt_num = 0; BOOL ret_val = TRUE, prit = PRINT_ALL; - LEXER lx; PTABLE opt_tab1 = NULL, opt_tab2 = NULL; DS_CREATE(stmt, LEX_BUF_SZ); char *seed_buf; @@ -1389,7 +1430,6 @@ static BOOL bparse(char *line, BOOL new_lexer) if (new_lexer) lex_init(line); if (!parse_lexer) return FALSE; - lx = parse_lexer; lookahead = lex_set_start("logic:"); lookahead = lex_scan(); // "logic" lookahead = lex_scan(); // ':' @@ -1400,8 +1440,12 @@ static BOOL bparse(char *line, BOOL new_lexer) adepth = max_adepth = 0; stmt_num++; ds_clear(&stmt); - ds_cat_str(&stmt, lx->lexer_buf); - bstmt(); + ds_cat_str(&stmt, parse_lexer->lexer_buf); + if (!bstmt()) { + cleanup_parser(); + ret_val= FALSE; + break; + } if (prit) { printf("START parse_tab\n"); @@ -1418,7 +1462,7 @@ static BOOL bparse(char *line, BOOL new_lexer) } last_count = gen_tab->entry_count; if (last_count == 1) { - ret_val = gen_gates(gen_tab, lx->lexer_sym_tab); + ret_val = gen_gates(gen_tab, parse_lexer->lexer_sym_tab); if (!ret_val) { printf("ERROR generating gates for logicexp\n"); } @@ -1447,9 +1491,10 @@ static BOOL bparse(char *line, BOOL new_lexer) curr_count = opt_tab2->entry_count; } if (opt_tab2) { - ret_val = gen_gates(opt_tab2, lx->lexer_sym_tab); + ret_val = gen_gates(opt_tab2, parse_lexer->lexer_sym_tab); if (!ret_val) { - printf("ERROR generating gates for logicexp\n"); + printf( + "ERROR generating gates for logicexp\n"); } delete_parse_table(opt_tab2); } @@ -1466,9 +1511,10 @@ static BOOL bparse(char *line, BOOL new_lexer) } // end while lookahead loop ds_free(&d_curr_line); - gen_models(); + if (ret_val) + gen_models(); ds_free(&stmt); - delete_lexer(lx); + cleanup_parser(); return ret_val; } /* End of logicexp parser */ @@ -1487,7 +1533,8 @@ static BOOL expect_token( { if (tok != expected_tok) { if (msg) { - printf("ERROR expect_token failed tok %d expected_tok %d loc %d\n", + printf( + "ERROR expect_token failed tok %d expected_tok %d loc %d\n", tok, expected_tok, loc); } return FALSE; @@ -1595,6 +1642,7 @@ BOOL f_logicexp(char *line) if (!ret_val) { printf("ERROR parsing logicexp\n"); printf("ERROR in \"%s\"\n", line); + cleanup_parser(); } return ret_val; diff --git a/src/frontend/udevices.c b/src/frontend/udevices.c index 6d9992df7..cc570c245 100644 --- a/src/frontend/udevices.c +++ b/src/frontend/udevices.c @@ -3612,16 +3612,25 @@ BOOL u_process_instance(char *nline) char *p1, *itype, *xspice; struct instance_hdr *hdr = create_instance_header(nline); Xlatorp xp = NULL; + BOOL behav_ret = TRUE; itype = hdr->instance_type; xspice = find_xspice_for_delay(itype); if (!xspice) { if (eq(itype, "logicexp")) { delete_instance_hdr(hdr); - return f_logicexp(nline); + behav_ret = f_logicexp(nline); + if (!behav_ret && current_subckt && ps_udevice_msgs >= 1) { + printf("ERROR in %s\n", current_subckt); + } + return behav_ret; } else if (eq(itype, "pindly")) { delete_instance_hdr(hdr); - return f_pindly(nline); + behav_ret = f_pindly(nline); + if (!behav_ret && current_subckt && ps_udevice_msgs >= 1) { + printf("ERROR in %s\n", current_subckt); + } + return behav_ret; } else if (eq(itype, "constraint")) { delete_instance_hdr(hdr); return TRUE; From 9acee01604778fc7b3bd78161cea4b3fb5014f1b Mon Sep 17 00:00:00 2001 From: Brian Taylor Date: Tue, 27 Dec 2022 14:42:23 -0800 Subject: [PATCH 04/17] Add variable ps_udevice_exit. If set non-zero, ngspice will exit if there is an error processing f_logicexp or f_pindly. --- src/frontend/udevices.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/frontend/udevices.c b/src/frontend/udevices.c index cc570c245..a9ae798fb 100644 --- a/src/frontend/udevices.c +++ b/src/frontend/udevices.c @@ -292,6 +292,10 @@ static void print_name_list(NAME_ENTRY nelist) */ static int ps_port_directions = 0; // If non-zero list subckt port directions static int ps_udevice_msgs = 0; // Controls the verbosity of U* warnings +/* + If ps_udevice_exit is non-zero then exit when u_process_instance fails +*/ +static int ps_udevice_exit = 0; static NAME_ENTRY new_names_list = NULL; static NAME_ENTRY input_names_list = NULL; static NAME_ENTRY output_names_list = NULL; @@ -819,6 +823,12 @@ void initialize_udevice(char *subckt_line) if (!cp_getvar("ps_udevice_msgs", CP_NUM, &ps_udevice_msgs, 0)) { ps_udevice_msgs = 0; } + /* + If ps_udevice_exit is non-zero then exit when u_process_instance fails + */ + if (!cp_getvar("ps_udevice_exit", CP_NUM, &ps_udevice_exit, 0)) { + ps_udevice_exit = 0; + } if (subckt_line && strncmp(subckt_line, ".subckt", 7) == 0) { add_all_port_names(subckt_line); current_subckt = TMALLOC(char, strlen(subckt_line) + 1); @@ -3623,6 +3633,10 @@ BOOL u_process_instance(char *nline) if (!behav_ret && current_subckt && ps_udevice_msgs >= 1) { printf("ERROR in %s\n", current_subckt); } + if (!behav_ret && ps_udevice_exit) { + fprintf(stderr, "ERROR bad syntax in logicexp\n"); + controlled_exit(EXIT_FAILURE); + } return behav_ret; } else if (eq(itype, "pindly")) { delete_instance_hdr(hdr); @@ -3630,6 +3644,10 @@ BOOL u_process_instance(char *nline) if (!behav_ret && current_subckt && ps_udevice_msgs >= 1) { printf("ERROR in %s\n", current_subckt); } + if (!behav_ret && ps_udevice_exit) { + fprintf(stderr, "ERROR bad syntax in pindly\n"); + controlled_exit(EXIT_FAILURE); + } return behav_ret; } else if (eq(itype, "constraint")) { delete_instance_hdr(hdr); @@ -3657,6 +3675,10 @@ BOOL u_process_instance(char *nline) xp = translate_pull(hdr, p1); } else { delete_instance_hdr(hdr); + if (ps_udevice_exit) { + fprintf(stderr, "ERROR unknown U* device\n"); + controlled_exit(EXIT_FAILURE); + } return FALSE; } if (xp) { @@ -3664,6 +3686,10 @@ BOOL u_process_instance(char *nline) delete_xlator(xp); return TRUE; } else { + if (ps_udevice_exit) { + fprintf(stderr, "ERROR U* device syntax error\n"); + controlled_exit(EXIT_FAILURE); + } return FALSE; } } From 0d74a0731601af49d3d7a14ffa80100c0f3b84a3 Mon Sep 17 00:00:00 2001 From: Brian Taylor Date: Tue, 27 Dec 2022 20:48:53 -0800 Subject: [PATCH 05/17] Ensure that amatch output is not binary data. --- src/frontend/logicexp.c | 6 +++--- src/frontend/udevices.c | 16 +++++++++++++--- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/src/frontend/logicexp.c b/src/frontend/logicexp.c index 479dbceb9..d611ba851 100644 --- a/src/frontend/logicexp.c +++ b/src/frontend/logicexp.c @@ -721,6 +721,7 @@ static void aerror(char *s) { LEXER lx = parse_lexer; printf("%s [%s]\n", s, lx->lexer_line + lx->lexer_pos); + fflush(stdout); cleanup_parser(); } @@ -735,12 +736,11 @@ char *get_temp_name(void) static BOOL amatch(int t) { - LEXER lx = parse_lexer; if (lookahead == t) { lookahead = lex_scan(); } else { - printf("expect = '%c' [%d] lookahead = '%c' [%d] lexer_buf %s\n", - t, t, lookahead, lookahead, lx->lexer_buf); + printf("expect = %d lookahead = %d lexer_buf \"%s\"\n", + t, lookahead, parse_lexer->lexer_buf); aerror("amatch: syntax error"); return FALSE; } diff --git a/src/frontend/udevices.c b/src/frontend/udevices.c index a9ae798fb..da5ceb19f 100644 --- a/src/frontend/udevices.c +++ b/src/frontend/udevices.c @@ -3593,7 +3593,7 @@ BOOL u_check_instance(char *line) } if (ps_udevice_msgs >= 1) { if (current_subckt && subckt_msg_count == 0) { - printf("%s\n", current_subckt); + printf("\nWARNING in %s\n", current_subckt); } subckt_msg_count++; printf("WARNING "); @@ -3630,22 +3630,24 @@ BOOL u_process_instance(char *nline) if (eq(itype, "logicexp")) { delete_instance_hdr(hdr); behav_ret = f_logicexp(nline); - if (!behav_ret && current_subckt && ps_udevice_msgs >= 1) { + if (!behav_ret && current_subckt) { printf("ERROR in %s\n", current_subckt); } if (!behav_ret && ps_udevice_exit) { fprintf(stderr, "ERROR bad syntax in logicexp\n"); + fflush(stdout); controlled_exit(EXIT_FAILURE); } return behav_ret; } else if (eq(itype, "pindly")) { delete_instance_hdr(hdr); behav_ret = f_pindly(nline); - if (!behav_ret && current_subckt && ps_udevice_msgs >= 1) { + if (!behav_ret && current_subckt) { printf("ERROR in %s\n", current_subckt); } if (!behav_ret && ps_udevice_exit) { fprintf(stderr, "ERROR bad syntax in pindly\n"); + fflush(stdout); controlled_exit(EXIT_FAILURE); } return behav_ret; @@ -3676,7 +3678,11 @@ BOOL u_process_instance(char *nline) } else { delete_instance_hdr(hdr); if (ps_udevice_exit) { + if (current_subckt) { + printf("ERROR in %s\n", current_subckt); + } fprintf(stderr, "ERROR unknown U* device\n"); + fflush(stdout); controlled_exit(EXIT_FAILURE); } return FALSE; @@ -3687,7 +3693,11 @@ BOOL u_process_instance(char *nline) return TRUE; } else { if (ps_udevice_exit) { + if (current_subckt) { + printf("ERROR in %s\n", current_subckt); + } fprintf(stderr, "ERROR U* device syntax error\n"); + fflush(stdout); controlled_exit(EXIT_FAILURE); } return FALSE; From b0000c6eda39b167e974a75df83328c044cac5d2 Mon Sep 17 00:00:00 2001 From: Brian Taylor Date: Fri, 30 Dec 2022 19:12:39 -0800 Subject: [PATCH 06/17] Add example for 74f524. --- .../digital/digital_devices/74f524-cp.stim | 11 + .../digital/digital_devices/74f524-csi.stim | 9 + .../digital/digital_devices/74f524-io.stim | 9 + .../digital/digital_devices/74f524-s0s1.stim | 7 + .../digital/digital_devices/74f524-sem.stim | 10 + examples/digital/digital_devices/74f524.cir | 223 ++++++++++++++++++ 6 files changed, 269 insertions(+) create mode 100644 examples/digital/digital_devices/74f524-cp.stim create mode 100644 examples/digital/digital_devices/74f524-csi.stim create mode 100644 examples/digital/digital_devices/74f524-io.stim create mode 100644 examples/digital/digital_devices/74f524-s0s1.stim create mode 100644 examples/digital/digital_devices/74f524-sem.stim create mode 100644 examples/digital/digital_devices/74f524.cir diff --git a/examples/digital/digital_devices/74f524-cp.stim b/examples/digital/digital_devices/74f524-cp.stim new file mode 100644 index 000000000..1042719a6 --- /dev/null +++ b/examples/digital/digital_devices/74f524-cp.stim @@ -0,0 +1,11 @@ +* t c +* i p +* m +* e +0ns 0s +100ns 1s +150ns 0s +600ns 1s +650ns 0s +1.10us 1s +1.15us 0s diff --git a/examples/digital/digital_devices/74f524-csi.stim b/examples/digital/digital_devices/74f524-csi.stim new file mode 100644 index 000000000..aee0fa048 --- /dev/null +++ b/examples/digital/digital_devices/74f524-csi.stim @@ -0,0 +1,9 @@ +* t c +* i s +* m i +* e +10ns 1s +220ns 0s +270ns 1s +620ns 0s +700ns 1s diff --git a/examples/digital/digital_devices/74f524-io.stim b/examples/digital/digital_devices/74f524-io.stim new file mode 100644 index 000000000..286808af1 --- /dev/null +++ b/examples/digital/digital_devices/74f524-io.stim @@ -0,0 +1,9 @@ +* t i i i i i i i i +* i o o o o o o o o +* m 7 6 5 4 3 2 1 0 +* e +20ns 1s 0s 0s 0s 0s 0s 1s 1s +250ns 0s 0s 1s 0s 0s 1s 1s 0s +350ns 1s 0s 0s 0s 0s 0s 1s 1s +450ns 1s 1s 0s 0s 0s 1s 1s 0s +850ns Uz Uz Uz Uz Uz Uz Uz Uz diff --git a/examples/digital/digital_devices/74f524-s0s1.stim b/examples/digital/digital_devices/74f524-s0s1.stim new file mode 100644 index 000000000..228fe9a09 --- /dev/null +++ b/examples/digital/digital_devices/74f524-s0s1.stim @@ -0,0 +1,7 @@ +* t s s +* i 0 1 +* m +* e +15ns 1s 1s +215ns 0s 0s +1us 0s 1s diff --git a/examples/digital/digital_devices/74f524-sem.stim b/examples/digital/digital_devices/74f524-sem.stim new file mode 100644 index 000000000..e944d3c7d --- /dev/null +++ b/examples/digital/digital_devices/74f524-sem.stim @@ -0,0 +1,10 @@ +* t s m +* i e +* m b +* e +15ns 1s 0s +215ns 0s 0s +300ns 0s 1s +640ns 1s 1s +800ns 0s 1s +900ns 0s 0s diff --git a/examples/digital/digital_devices/74f524.cir b/examples/digital/digital_devices/74f524.cir new file mode 100644 index 000000000..90f072ad5 --- /dev/null +++ b/examples/digital/digital_devices/74f524.cir @@ -0,0 +1,223 @@ +Test 74f524.cir + +*-------------------------------------------------------------74F524----------- + +* 8 Bit Register Comparator (Open Collector and Tri-State) +* Philips FAST Logic Databook, 1992, pages 506 to 513 +* jat 7/11/96 + +.SUBCKT 74F524 S0 S1 SEBAR C/SI I/O0 I/O1 I/O2 I/O3 I/O4 I/O5 I/O6 I/O7 ++ CP M C/SO EQ GT LT ++ OPTIONAL: DPWR=$G_DPWR DGND=$G_DGND ++ PARAMS: MNTYMXDLY=0 IO_LEVEL=0 + +U1 LOGICEXP(22,13) DPWR DGND ++ S0 S1 SEBAR C/SI CP M I/O0 I/O1 I/O2 I/O3 I/O4 I/O5 I/O6 I/O7 ++ Q0 Q1 Q2 Q3 Q4 Q5 Q6 Q7 ++ C/SOO EQO GTO LTO ENAB D0 D1 D2 D3 D4 D5 D6 D7 ++ D0_GATE IO_F MNTYMXDLY={MNTYMXDLY} IO_LEVEL={IO_LEVEL} ++ LOGIC: ++ ENAB = {S1 & ~S0} ++ LOAD = {S0 & S1} ++ SHIFT = {~S1 & S0} ++ D0 = {(Q0 & ~S0) | (I/O0 & LOAD) | (SHIFT & Q1)} ++ D1 = {(Q1 & ~S0) | (I/O1 & LOAD) | (SHIFT & Q2)} ++ D2 = {(Q2 & ~S0) | (I/O2 & LOAD) | (SHIFT & Q3)} ++ D3 = {(Q3 & ~S0) | (I/O3 & LOAD) | (SHIFT & Q4)} ++ D4 = {(Q4 & ~S0) | (I/O4 & LOAD) | (SHIFT & Q5)} ++ D5 = {(Q5 & ~S0) | (I/O5 & LOAD) | (SHIFT & Q6)} ++ D6 = {(Q6 & ~S0) | (I/O6 & LOAD) | (SHIFT & Q7)} ++ D7 = {(Q7 & ~S0) | (I/O7 & LOAD) | (SHIFT & C/SI)} ++ NOR0 = {~(~I/O0 | Q0)} ++ XOR0 = {Q0 ^ ~I/O0} ++ AND0 = {Q0 & ~I/O0} ++ NOR1 = {~(~I/O1 | Q1)} ++ XOR1 = {Q1 ^ ~I/O1} ++ AND1 = {Q1 & ~I/O1} ++ NOR2 = {~(~I/O2 | Q2)} ++ XOR2 = {Q2 ^ ~I/O2} ++ AND2 = {Q2 & ~I/O2} ++ NOR3 = {~(~I/O3 | Q3)} ++ XOR3 = {Q3 ^ ~I/O3} ++ AND3 = {Q3 & ~I/O3} ++ NOR4 = {~(~I/O4 | Q4)} ++ XOR4 = {Q4 ^ ~I/O4} ++ AND4 = {Q4 & ~I/O4} ++ NOR5 = {~(~I/O5 | Q5)} ++ XOR5 = {Q5 ^ ~I/O5} ++ AND5 = {Q5 & ~I/O5} ++ NOR6 = {~(~I/O6 | Q6)} ++ XOR6 = {Q6 ^ ~I/O6} ++ AND6 = {Q6 & ~I/O6} ++ NOR7 = {~((~(~I/O7 ^ ~M)) | (~(Q7 ^ ~M)))} ++ XOR7 = {(~(~I/O7 ^ ~M)) ^ (~(Q7 ^ ~M))} ++ AND7 = {(~(~I/O7 ^ ~M)) & (~(Q7 ^ ~M))} ++ ORA = {(NOR0 & XOR1 & XOR2 & XOR3) | (NOR1 & XOR2 & XOR3) | (XOR3 & NOR2) | NOR3} ++ ORB = {(AND0 & XOR1 & XOR2 & XOR3) | (AND1 & XOR2 & XOR3) | (XOR3 & AND2) | AND3} ++ ORC = {(AND4 & XOR5 & XOR6 & XOR7) | (AND5 & XOR6 & XOR7) | (XOR7 & AND6) | AND7} ++ ORD = {(NOR4 & XOR5 & XOR6 & XOR7) | (NOR5 & XOR6 & XOR7) | (XOR7 & NOR6) | NOR7} ++ NANDLT = {~(XOR4 & XOR7 & XOR5 & XOR6)} ++ ANDDOWN = {C/SI & ~SEBAR} ++ LTO = {(~NANDLT & ORA) | ORD | ~ANDDOWN} ++ GTO = {ORC | ~ANDDOWN | (~NANDLT & ORB)} ++ EQO = {SEBAR | (~NANDLT & (XOR1 & XOR0 & XOR2 & XOR3))} ++ C/SOO = {(SHIFT & Q0) | (~SHIFT & (C/SI & ~NANDLT & XOR0 & XOR1 & XOR2 & XOR3))} + +U2 DFF(8) DPWR DGND ++ $D_HI $D_HI CP ++ D0 D1 D2 D3 D4 D5 D6 D7 ++ Q0 Q1 Q2 Q3 Q4 Q5 Q6 Q7 ++ $D_NC $D_NC $D_NC $D_NC $D_NC $D_NC $D_NC $D_NC ++ D0_EFF IO_F MNTYMXDLY={MNTYMXDLY} IO_LEVEL={IO_LEVEL} + +U3 PINDLY(9,1,12) DPWR DGND ++ Q0 Q1 Q2 Q3 Q4 Q5 Q6 Q7 C/SOO ++ ENAB ++ I/O0 I/O1 I/O2 I/O3 I/O4 I/O5 I/O6 I/O7 CP C/SI S0 S1 ++ I/O0 I/O1 I/O2 I/O3 I/O4 I/O5 I/O6 I/O7 C/SO ++ IO_F MNTYMXDLY={MNTYMXDLY} IO_LEVEL={IO_LEVEL} ++ BOOLEAN: ++ DATA = {CHANGED(I/O0,0) | CHANGED(I/O1,0) | CHANGED(I/O2,0) | CHANGED(I/O3,0) | ++ CHANGED(I/O4,0) | CHANGED(I/O5,0) | CHANGED(I/O6,0) | CHANGED(I/O7,0)} ++ EDGE = {CHANGED_LH(CP,0)} ++ CSI = {CHANGED(C/SI,0)} ++ SS = {CHANGED(S0,0) | CHANGED(S1,0)} ++ TRISTATE: ++ ENABLE HI = ENAB ++ I/O0 I/O1 I/O2 I/O3 I/O4 I/O5 I/O6 I/O7 = { ++ CASE( ++ TRN_ZH, DELAY(4.5NS,7NS,13NS), ++ TRN_ZL, DELAY(5.5NS,9NS,15NS), ++ TRN_HZ, DELAY(3NS,5NS,12NS), ++ TRN_LZ, DELAY(4.5NS,8NS,12.5NS), ++ DELAY(6.5NS,10NS,16NS))} ++ PINDLY: ++ C/SO = { ++ CASE( ++ SS & TRN_LH, DELAY(6.5NS,8NS,14.5NS), ++ SS & TRN_HL, DELAY(5.5NS,10NS,17NS), ++ EDGE & (S1 == '1 & S0 == '1) & TRN_LH, DELAY(10NS,16NS,20NS), ++ EDGE & (S1 == '0 & S0 == '1) & TRN_LH, DELAY(5NS,10NS,13NS), ++ EDGE & (S1 == '0 & S0 == '1) & TRN_HL, DELAY(4.5NS,9NS,11.5NS), ++ DATA & TRN_LH, DELAY(7NS,13NS,16NS), ++ DATA & TRN_HL, DELAY(6.5NS,9NS,14NS), ++ CSI & TRN_LH, DELAY(4NS,7NS,11NS), ++ CSI & TRN_HL, DELAY(4NS,7NS,11NS), ++ DELAY(11NS,17NS,21NS))} + +U4 PINDLY(3,0,12) DPWR DGND ++ EQO LTO GTO ++ I/O0 I/O1 I/O2 I/O3 I/O4 I/O5 I/O6 I/O7 CP C/SI SEBAR M ++ EQ LT GT ++ IO_F_OC MNTYMXDLY={MNTYMXDLY} IO_LEVEL={IO_LEVEL} ++ BOOLEAN: ++ DATA = {CHANGED(I/O0,0) | CHANGED(I/O1,0) | CHANGED(I/O2,0) | CHANGED(I/O3,0) | ++ CHANGED(I/O4,0) | CHANGED(I/O5,0) | CHANGED(I/O6,0) | CHANGED(I/O7,0)} ++ EDGE = {CHANGED_LH(CP,0)} ++ CSI = {CHANGED(C/SI,0)} ++ SE = {CHANGED(SEBAR,0)} ++ MM = {CHANGED(M,0)} ++ PINDLY: ++ EQ = { ++ CASE( ++ SE & TRN_LH, DELAY(3.5NS,7NS,10.5NS), ++ SE & TRN_HL, DELAY(2.5NS,4.5NS,8NS), ++ EDGE & TRN_LH, DELAY(11NS,17NS,22NS), ++ EDGE & TRN_HL, DELAY(4NS,8NS,14NS), ++ DATA & TRN_LH, DELAY(9NS,11.5NS,17NS), ++ DATA & TRN_HL, DELAY(4.5NS,7.5NS,11NS), ++ DELAY(12NS,18NS,23NS))} ++ GT = { ++ CASE( ++ SE & TRN_LH, DELAY(6NS,8NS,13NS), ++ SE & TRN_HL, DELAY(3.5NS,5NS,8NS), ++ MM & TRN_LH, DELAY(8NS,13NS,18NS), ++ MM & TRN_HL, DELAY(8NS,10NS,15.5NS), ++ EDGE & TRN_LH, DELAY(11NS,16NS,20NS), ++ EDGE & TRN_HL, DELAY(10NS,16.5NS,21NS), ++ DATA & TRN_LH, DELAY(8.5NS,11NS,17NS), ++ DATA & TRN_HL, DELAY(6.5NS,9.5NS,15.5NS), ++ CSI & TRN_LH, DELAY(8NS,10.5NS,16NS), ++ CSI & TRN_HL, DELAY(3NS,4.5NS,8.5NS), ++ DELAY(12NS,17NS,21NS))} ++ LT = { ++ CASE( ++ SE & TRN_LH, DELAY(5NS,8NS,12NS), ++ SE & TRN_HL, DELAY(3.5NS,5.5NS,8NS), ++ MM & TRN_LH, DELAY(10NS,15NS,20NS), ++ MM & TRN_HL, DELAY(6NS,8NS,12NS), ++ EDGE & TRN_LH, DELAY(11NS,16NS,23NS), ++ EDGE & TRN_HL, DELAY(8NS,14NS,18NS), ++ DATA & TRN_LH, DELAY(8NS,11NS,17NS), ++ DATA & TRN_HL, DELAY(6NS,10.5NS,14NS), ++ CSI & TRN_LH, DELAY(8NS,10.5NS,17NS), ++ CSI & TRN_HL, DELAY(3NS,6NS,8.5NS), ++ DELAY(12NS,17NS,24NS))} + + +U5 CONSTRAINT(12) DPWR DGND ++ I/O0 I/O1 I/O2 I/O3 I/O4 I/O5 I/O6 I/O7 CP S0 S1 C/SI ++ IO_F IO_LEVEL={IO_LEVEL} ++ FREQ: ++ NODE = CP ++ MAXFREQ = 65MEG ++ WIDTH: ++ NODE = CP ++ MIN_HI = 5NS ++ MIN_LO = 10NS ++ SETUP_HOLD: ++ CLOCK LH = CP ++ DATA(8) = I/O0 I/O1 I/O2 I/O3 I/O4 I/O5 I/O6 I/O7 ++ SETUPTIME = 6NS ++ SETUP_HOLD: ++ CLOCK LH = CP ++ DATA(2) = S0 S1 ++ SETUPTIME_HI = 13.5NS ++ SETUPTIME_LO = 10NS ++ SETUP_HOLD: ++ CLOCK LH = CP ++ DATA(1) = C/SI ++ SETUPTIME = 7NS + +.ENDS 74F524 + +* .SUBCKT 74F524 S0 S1 SEBAR C/SI I/O0 I/O1 I/O2 I/O3 I/O4 I/O5 I/O6 I/O7 +* + CP M C/SO EQ GT LT +X86 i_s0 i_s1 i_sebar csi io0 io1 io2 io3 io4 io5 io6 io7 cp i_m o_cso o_eq o_gt o_lt 74f524 + +a1 [cp] in_vec1 +.model in_vec1 d_source(input_file="74f524-cp.stim") +a2 [io7 io6 io5 io4 io3 io2 io1 io0] in_vec2 +.model in_vec2 d_source(input_file="74f524-io.stim") +a3 [i_sebar i_m] in_vec3 +.model in_vec3 d_source(input_file="74f524-sem.stim") +a4 [i_s0 i_s1] in_vec4 +.model in_vec4 d_source(input_file="74f524-s0s1.stim") +a5 [csi] in_vec5 +.model in_vec5 d_source(input_file="74f524-csi.stim") + +.tran 1ns 2us +.control +run +listing +*edisplay +eprint io0 io1 io2 io3 io4 io5 io6 io7 +eprint cp i_s0 i_s1 csi i_sebar i_m +eprint o_cso o_eq o_gt o_lt + +* save data to input directory +cd $inputdir +eprvcd io0 io1 io2 io3 io4 io5 io6 io7 cp i_s0 i_s1 csi i_sebar i_m o_cso o_eq o_gt o_lt > 74f524.vcd +* plotting the vcd file with GTKWave +if $oscompiled = 1 | $oscompiled = 8 ; MS Windows + shell start gtkwave 74f524.vcd --script nggtk.tcl +else + if $oscompiled = 7 ; macOS, manual tweaking required (mark, insert, Zoom Fit) + shell open -a gtkwave 74f524.vcd + else ; Linux and others + shell gtkwave 74f524.vcd --script nggtk.tcl & + end +end +quit +.endc +.end From b6f5e5b5a80fb1eaa6760f04d56f9b789c1ff655 Mon Sep 17 00:00:00 2001 From: dwarning Date: Mon, 2 Jan 2023 14:48:37 +0100 Subject: [PATCH 07/17] special ngbehavior needed --- examples/optran/.spiceinit | 1 + 1 file changed, 1 insertion(+) create mode 100644 examples/optran/.spiceinit diff --git a/examples/optran/.spiceinit b/examples/optran/.spiceinit new file mode 100644 index 000000000..aeee13ea7 --- /dev/null +++ b/examples/optran/.spiceinit @@ -0,0 +1 @@ +set ngbehavior=ltpsa From 1a50ca33cd52bf5ef54129de311f193f19a8edb7 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Wed, 4 Jan 2023 15:35:21 +0100 Subject: [PATCH 08/17] enable 'off', 'print', 'save' being part of a node name. Only plain 'off' (case of bipolar), or 'print', 'save' (in case of CIDER) will not be allowed. --- src/frontend/inpcom.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/frontend/inpcom.c b/src/frontend/inpcom.c index 413cccff5..fc2637b1a 100644 --- a/src/frontend/inpcom.c +++ b/src/frontend/inpcom.c @@ -4672,10 +4672,10 @@ int get_number_terminals(char *c) while ((i < 12) && (*cc != '\0')) { char* comma; name[i] = gettok_instance(&cc); - if (strstr(name[i], "off") || strchr(name[i], '=')) + if (search_plain_identifier(name[i], "off") || strchr(name[i], '=')) j++; #ifdef CIDER - if (strstr(name[i], "save") || strstr(name[i], "print")) + if (search_plain_identifier(name[i], "save") || search_plain_identifier(name[i], "print")) j++; #endif /* If we have IC=VBE, VCE instead of IC=VBE,VCE we need to inc From e8eae7aa859e7eccc3100c7ac6997b2e79bb2fff Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Wed, 4 Jan 2023 22:44:16 +0100 Subject: [PATCH 09/17] Update to fcn tprint: allow multiple printouts in a single simulation run, without overwriting the previous printout. --- src/frontend/inpcom.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/frontend/inpcom.c b/src/frontend/inpcom.c index fc2637b1a..b22900a99 100644 --- a/src/frontend/inpcom.c +++ b/src/frontend/inpcom.c @@ -7006,9 +7006,12 @@ static void inp_poly_err(struct card *card) void tprint(struct card *t) { struct card *tmp; - + static int npr; + char outfile[100]; + sprintf(outfile, "tprint-out%d.txt", npr); + npr++; /*debug: print into file*/ - FILE *fd = fopen("tprint-out.txt", "w"); + FILE *fd = fopen(outfile, "w"); for (tmp = t; tmp; tmp = tmp->nextcard) if (*(tmp->line) != '*') fprintf(fd, "%6d %6d %s\n", tmp->linenum_orig, tmp->linenum, From b1a806c35d8f5084c66e3d9ea93e6a77a1faae23 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Fri, 6 Jan 2023 11:50:45 +0100 Subject: [PATCH 10/17] A preliminary fix to bug report 612 Don't set series voltage sources when flag probe_alli_nox is set in .spiceinit --- src/frontend/inpc_probe.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/frontend/inpc_probe.c b/src/frontend/inpc_probe.c index e43bd2256..f18c60510 100644 --- a/src/frontend/inpc_probe.c +++ b/src/frontend/inpc_probe.c @@ -238,6 +238,17 @@ void inp_probe(struct card* deck) if (strchr("ehvk", *instname)) continue; + /* exclude a devices (code models may have special characters in their instance line. + digital nodes should not get V sources in series anyway.) */ + if ('a' == *instname) + continue; + + /* exclude x devices (Subcircuits may contain digital a devices, + and digital nodes should not get V sources in series anyway.), + when probe_alli_nox is set in .spiceinit. */ + if ('x' == *instname && cp_getvar("probe_alli_nox", CP_BOOL, NULL, 0)) + continue; + /* special treatment for controlled current sources and switches: We have three or four tokens until model name, but only the first 2 are relevant nodes. */ if (strchr("fgsw", *instname)) From 864e722f4ab0cb3ff0d223c4da26162acd369376 Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Fri, 6 Jan 2023 17:28:39 +0100 Subject: [PATCH 11/17] For memcpy in PREDICTOR --- src/spicelib/devices/cktaccept.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/spicelib/devices/cktaccept.c b/src/spicelib/devices/cktaccept.c index 817f939ca..9f9227b47 100644 --- a/src/spicelib/devices/cktaccept.c +++ b/src/spicelib/devices/cktaccept.c @@ -8,6 +8,8 @@ Author: 1985 Thomas L. Quarles * this is a driver program to iterate through all the various accept * functions provided for the circuit elements in the given circuit */ +#include + #include "ngspice/config.h" #include "ngspice/devdefs.h" #include "ngspice/sperror.h" From 440761409466d1cb701b31d1a565392f91c0d818 Mon Sep 17 00:00:00 2001 From: Francesco Lannutti Date: Fri, 6 Jan 2023 18:00:48 +0100 Subject: [PATCH 12/17] OSDI: fix const declaration, unused variables --- src/osdi/osdi.h | 2 +- src/osdi/osdiload.c | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/osdi/osdi.h b/src/osdi/osdi.h index 6f633b037..d58676215 100644 --- a/src/osdi/osdi.h +++ b/src/osdi/osdi.h @@ -189,7 +189,7 @@ typedef struct OsdiDescriptor { double temperature, uint32_t num_terminals, OsdiSimParas *sim_params, OsdiInitInfo *res); - uint32_t (*eval)(void *handle, void *inst, void *model, const OsdiSimInfo *info); + uint32_t (*eval)(void *handle, void *inst, const void *model, const OsdiSimInfo *info); void (*load_noise)(void *inst, void *model, double freq, double *noise_dens, double *ln_noise_dens); void (*load_residual_resist)(void *inst, void* model, double *dst); diff --git a/src/osdi/osdiload.c b/src/osdi/osdiload.c index e00c40efb..6612323d4 100644 --- a/src/osdi/osdiload.c +++ b/src/osdi/osdiload.c @@ -60,6 +60,9 @@ static void eval(const OsdiDescriptor *descr, const GENinstance *gen_inst, static void load(CKTcircuit *ckt, const GENinstance *gen_inst, void *model, void *inst, OsdiExtraInstData *extra_inst_data, bool is_tran, bool is_init_tran, const OsdiDescriptor *descr) { + + NG_IGNORE(extra_inst_data); + double dump; if (is_tran) { /* load dc matrix and capacitances (charge derivative multiplied with @@ -113,10 +116,8 @@ static void load(CKTcircuit *ckt, const GENinstance *gen_inst, void *model, } extern int OSDIload(GENmodel *inModel, CKTcircuit *ckt) { - OsdiNgspiceHandle handle; GENmodel *gen_model; GENinstance *gen_inst; - double dump; bool is_init_smsig = ckt->CKTmode & MODEINITSMSIG; bool is_sweep = ckt->CKTmode & MODEDCTRANCURVE; From 0e30430506afe9b3e88ee26e11acc1f0d185507c Mon Sep 17 00:00:00 2001 From: Francesco Lannutti Date: Fri, 6 Jan 2023 18:01:48 +0100 Subject: [PATCH 13/17] enable compiling without XSPICE on specific OSs --- src/Makefile.am | 6 +++--- src/osdi/Makefile.am | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index c25b7b3db..3988837e3 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -167,7 +167,7 @@ ngspice_LDADD += \ xspice/ipc/libipcxsp.la \ xspice/idn/libidnxsp.la endif -ngspice_LDADD += @XSPICEDLLIBS@ +ngspice_LDADD += $(XSPICEDLLIBS) ngspice_LDADD += \ frontend/parser/libparser.la \ @@ -453,7 +453,7 @@ libspice_la_LIBADD += \ xspice/ipc/libipcxsp.la \ xspice/idn/libidnxsp.la endif -libspice_la_LIBADD += @XSPICEDLLIBS@ +libspice_la_LIBADD += $(XSPICEDLLIBS) libspice_la_LIBADD += \ frontend/parser/libparser.la \ @@ -577,7 +577,7 @@ libngspice_la_LIBADD += \ xspice/ipc/libipcxsp.la \ xspice/idn/libidnxsp.la endif -libngspice_la_LIBADD += @XSPICEDLLIBS@ +libngspice_la_LIBADD += $(XSPICEDLLIBS) libngspice_la_LIBADD += \ frontend/parser/libparser.la \ diff --git a/src/osdi/Makefile.am b/src/osdi/Makefile.am index f23a7b8eb..9cdd27fed 100644 --- a/src/osdi/Makefile.am +++ b/src/osdi/Makefile.am @@ -18,7 +18,7 @@ libosdi_la_SOURCES = \ osdicallbacks.c - +libosdi_la_LIBADD = $(XSPICEDLLIBS) AM_CPPFLAGS = @AM_CPPFLAGS@ -I$(top_srcdir)/src/include AM_CFLAGS = $(STATIC) From 2bba40f2c5ed5b1a95290fce0bb547dde6c7bc7d Mon Sep 17 00:00:00 2001 From: Brian Taylor Date: Sat, 31 Dec 2022 11:18:29 -0800 Subject: [PATCH 14/17] Add serial load to 74f524 example. --- .../digital/digital_devices/74f524-cp.stim | 26 +++++++++++++++++-- .../digital/digital_devices/74f524-csi.stim | 13 ++++++++++ .../digital/digital_devices/74f524-io.stim | 4 +++ .../digital/digital_devices/74f524-s0s1.stim | 11 +++++++- .../digital/digital_devices/74f524-sem.stim | 7 +++++ examples/digital/digital_devices/74f524.cir | 2 +- 6 files changed, 59 insertions(+), 4 deletions(-) diff --git a/examples/digital/digital_devices/74f524-cp.stim b/examples/digital/digital_devices/74f524-cp.stim index 1042719a6..6ffbe10aa 100644 --- a/examples/digital/digital_devices/74f524-cp.stim +++ b/examples/digital/digital_devices/74f524-cp.stim @@ -7,5 +7,27 @@ 150ns 0s 600ns 1s 650ns 0s -1.10us 1s -1.15us 0s +1100ns 1s +1150ns 0s +* shift sequence +1200ns 1s +1250ns 0s +1300ns 1s +1350ns 0s +1400ns 1s +1450ns 0s +1500ns 1s +1550ns 0s +1600ns 1s +1650ns 0s +1700ns 1s +1750ns 0s +1800ns 1s +1850ns 0s +1900ns 1s +1950ns 0s +* +2500ns 1s +2550ns 0s +2600ns 1s +2650ns 0s diff --git a/examples/digital/digital_devices/74f524-csi.stim b/examples/digital/digital_devices/74f524-csi.stim index aee0fa048..d381ef2c1 100644 --- a/examples/digital/digital_devices/74f524-csi.stim +++ b/examples/digital/digital_devices/74f524-csi.stim @@ -2,8 +2,21 @@ * i s * m i * e +* csi is used with seb as status truth table entries in hold mode 10ns 1s 220ns 0s 270ns 1s 620ns 0s 700ns 1s +* shift - serial load data +1170ns 0s +1270ns 0s +1370ns 1s +1470ns 1s +1570ns 0s +1670ns 1s +1770ns 0s +1870ns 1s +* +2040ns 0s +2240ns 1s diff --git a/examples/digital/digital_devices/74f524-io.stim b/examples/digital/digital_devices/74f524-io.stim index 286808af1..d444c620d 100644 --- a/examples/digital/digital_devices/74f524-io.stim +++ b/examples/digital/digital_devices/74f524-io.stim @@ -6,4 +6,8 @@ 250ns 0s 0s 1s 0s 0s 1s 1s 0s 350ns 1s 0s 0s 0s 0s 0s 1s 1s 450ns 1s 1s 0s 0s 0s 1s 1s 0s +* float ios before read mode 850ns Uz Uz Uz Uz Uz Uz Uz Uz +1340ns 0s 0s 0s 0s 0s 0s 1s 1s +* float ios before read mode +2300ns Uz Uz Uz Uz Uz Uz Uz Uz diff --git a/examples/digital/digital_devices/74f524-s0s1.stim b/examples/digital/digital_devices/74f524-s0s1.stim index 228fe9a09..7b2f17f97 100644 --- a/examples/digital/digital_devices/74f524-s0s1.stim +++ b/examples/digital/digital_devices/74f524-s0s1.stim @@ -2,6 +2,15 @@ * i 0 1 * m * e +* load 15ns 1s 1s +* hold 215ns 0s 0s -1us 0s 1s +* read +1000ns 0s 1s +* shift +1160ns 1s 0s +* hold +2000ns 0s 0s +* read +2400ns 0s 1s diff --git a/examples/digital/digital_devices/74f524-sem.stim b/examples/digital/digital_devices/74f524-sem.stim index e944d3c7d..6778d6535 100644 --- a/examples/digital/digital_devices/74f524-sem.stim +++ b/examples/digital/digital_devices/74f524-sem.stim @@ -2,9 +2,16 @@ * i e * m b * e +* seb and csi are status truth table entries in hold mode +* m = 0 magnitude compare +* m = 1 twos-complement compare 15ns 1s 0s 215ns 0s 0s 300ns 0s 1s 640ns 1s 1s 800ns 0s 1s 900ns 0s 0s +1160ns 1s 0s +2000ns 0s 0s +2100ns 0s 1s +2200ns 0s 0s diff --git a/examples/digital/digital_devices/74f524.cir b/examples/digital/digital_devices/74f524.cir index 90f072ad5..5e3ba3de1 100644 --- a/examples/digital/digital_devices/74f524.cir +++ b/examples/digital/digital_devices/74f524.cir @@ -196,7 +196,7 @@ a4 [i_s0 i_s1] in_vec4 a5 [csi] in_vec5 .model in_vec5 d_source(input_file="74f524-csi.stim") -.tran 1ns 2us +.tran 1ns 3us .control run listing From a6b4f779fb609252b7c86530fe67ba01a2c9a650 Mon Sep 17 00:00:00 2001 From: Brian Taylor Date: Tue, 3 Jan 2023 09:38:57 -0800 Subject: [PATCH 15/17] Fix some comments. --- src/frontend/logicexp.c | 17 +++++++++++++---- src/frontend/udevices.c | 7 +++++-- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/frontend/logicexp.c b/src/frontend/logicexp.c index d611ba851..35c0f903b 100644 --- a/src/frontend/logicexp.c +++ b/src/frontend/logicexp.c @@ -2,7 +2,8 @@ logicexp.c Convert PSpice LOGICEXP logic expressions into XSPICE gates. - Extract timing delay estimates from PINDLY statements. + Extract typical timing delay estimates from PINDLY statements and + insert buffers and tristates with these delays. Reference: PSpice A/D Reference Guide version 16.6 */ @@ -1521,10 +1522,17 @@ static BOOL bparse(char *line, BOOL new_lexer) /* Start of f_logicexp which is called from udevices.c See the PSpice reference which describes the LOGICEXP statement syntax. - Combinational gates are generated and usually have zero delays. + + NOTE: Combinational gates are generated and usually have zero delays. + In XSPICE, the shortest delays are 1.0e-12 secs, not actually zero. + + Timing delays for LOGICEXP come from an associated PINDLY instance + when the timing model is d0_gate. Otherwise the timing model is used + for the delay estimates (see f_logicexp). + The PINDLY statements generate buffers and tristate buffers which drive the primary outputs from the LOGICEXP outputs. - These buffers have their delays set. + These buffers and tristates have estimated typical delays. */ static LEXER current_lexer = NULL; @@ -1654,7 +1662,8 @@ error_return: /* Start of f_pindly which is called from udevices.c See the PSpice reference which describes the PINDLY statement syntax. - Note that only two sections, PINDLY: and TRISTATE:, are considered. + + NOTE that only two sections, PINDLY: and TRISTATE:, are considered. Typical delays are estimated from the DELAY(...) functions. XSPICE does not have the variety of delays that PSpice supports. Output buffers and tristate buffers are generated. diff --git a/src/frontend/udevices.c b/src/frontend/udevices.c index da5ceb19f..c2b665e35 100644 --- a/src/frontend/udevices.c +++ b/src/frontend/udevices.c @@ -10,12 +10,15 @@ using the previously stored delays. Some limitations are: - No support for logicexp, pindly, and constraint behavioral primitives. + No support for DLYLINE, CONSTRAINT, RAM, ROM, STIM, PLAs. Approximations to the Pspice timing delays. Typical values for delays are estimated. Pspice has a rich set of timing simulation features, such as checks for setup/hold violations, minimum pulse width, and - hazard detection. + hazard detection. These timing simulation features are not available + in Xspice. Only the common logic gates, flip-flops, and latches are supported. + LOGICEXP and PINDLY are supported in logicexp.c through the functions + f_logicexp and f_pindly. First pass through a subcircuit. Call initialize_udevice() and read the .model cards by calling u_process_model_line() (or similar) for each card, From 111ec29e6121c2ccb97b3f9321253de169bb8a1c Mon Sep 17 00:00:00 2001 From: Holger Vogt Date: Mon, 9 Jan 2023 16:14:25 +0100 Subject: [PATCH 16/17] Rename example file --- examples/numparam/{example.cir => param-example.cir} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename examples/numparam/{example.cir => param-example.cir} (100%) diff --git a/examples/numparam/example.cir b/examples/numparam/param-example.cir similarity index 100% rename from examples/numparam/example.cir rename to examples/numparam/param-example.cir From 803168bdf2e4a327e8f9fb2048204ec388820936 Mon Sep 17 00:00:00 2001 From: Giles Atkinson <“gatk555@gmail.com”> Date: Sun, 8 Jan 2023 15:21:34 +0000 Subject: [PATCH 17/17] Add a simple example of using string-valued parameters. --- examples/numparam/strings.cir | 42 +++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 examples/numparam/strings.cir diff --git a/examples/numparam/strings.cir b/examples/numparam/strings.cir new file mode 100644 index 000000000..8495080fa --- /dev/null +++ b/examples/numparam/strings.cir @@ -0,0 +1,42 @@ +Example of string-valued parameters for XSPICE LUT + +.param and="0001" or="0111" + +* Simple AND gate via parameter. + +.model l_and d_lut table_values=and +aand [ d1 d2 ] o_and l_and + +* More usefully, strings may be passed as sub-circuit parameters + +xor d1 d2 o_or pgate table=or + +.subckt pgate 1 2 out table="0000" +.model poly d_lut table_values=table +ap [ 1 2 ] out poly +.ends + +* Strings can be concatenated by .param, but not in .subckt lines or instances. + +.param both=or{and} +xboth d1 d2 d3 o_both pgate3 table=both + +.subckt pgate3 1 2 3 out table="00000000" +.model poly3 d_lut table_values=table +ap3 [ 1 2 3 ] out poly3 +.ends + +* Verify the above with a simple transient simulation. + +v1 a1 0 pulse 1 0 0 1n 1n 0.5u 1u +v2 a2 0 pulse 1 0 0 1n 1n 1u 2u +v3 a3 0 pulse 1 0 0 1n 1n 2u 4u +aadc [ a1 a2 a3 ] [ d1 d2 d3 ] adc +.model adc adc_bridge in_low=0.5 in_high=0.5 + +.control +tran 0.1u 4.1u +plot d1 d2 d3 o_and o_or o_both digitop +.endc +.end +