diff --git a/src/actions.c b/src/actions.c index 7a6f56e5..bb3f17be 100644 --- a/src/actions.c +++ b/src/actions.c @@ -1295,8 +1295,8 @@ void attach_labels_to_inst(int interactive) /* offloaded from callback.c 201710 int use_label_prefix; int found=0; - my_strdup(_ALLOC_ID_, &symname_pin, tcleval("rel_sym_path [find_file_first lab_pin.sym]")); - my_strdup(_ALLOC_ID_, &symname_wire, tcleval("rel_sym_path [find_file_first lab_wire.sym]")); + my_strdup(_ALLOC_ID_, &symname_pin, tcleval("find_file_first lab_pin.sym")); + my_strdup(_ALLOC_ID_, &symname_wire, tcleval("find_file_first lab_wire.sym")); if(symname_pin && symname_wire) { rebuild_selected_array(); k = xctx->lastsel; @@ -1451,10 +1451,10 @@ void delete_files(void) void place_net_label(int type) { if(type == 1) { - const char *lab = tcleval("rel_sym_path [find_file_first lab_pin.sym]"); + const char *lab = tcleval("find_file_first lab_pin.sym"); place_symbol(-1, lab, xctx->mousex_snap, xctx->mousey_snap, 0, 0, NULL, 4, 1, 1/*to_push_undo*/); } else { - const char *lab = tcleval("rel_sym_path [find_file_first lab_wire.sym]"); + const char *lab = tcleval("find_file_first lab_wire.sym"); place_symbol(-1, lab, xctx->mousex_snap, xctx->mousey_snap, 0, 0, NULL, 4, 1, 1/*to_push_undo*/); } move_objects(START,0,0,0); @@ -1482,7 +1482,7 @@ int place_symbol(int pos, const char *symbol_name, double x, double y, short rot tcleval("load_file_dialog {Choose symbol} *.\\{sym,tcl\\} INITIALINSTDIR"); my_strncpy(name1, tclresult(), S(name1)); } else { - my_strncpy(name1, trim_chars(symbol_name, " \t\n"), S(name1)); + my_strncpy(name1, abs_sym_path(trim_chars(symbol_name, " \t\n"), ""), S(name1)); } if(!name1[0]) return 0; dbg(1, "place_symbol(): 1: name1=%s first_call=%d\n",name1, first_call); diff --git a/src/spice.awk b/src/spice.awk index 5dc7b170..07bb05e7 100755 --- a/src/spice.awk +++ b/src/spice.awk @@ -275,7 +275,7 @@ function process( i,j, iprefix, saveinstr, savetype, saveanalysis) } else if( $1 ~ /^\*\.(ipin|opin|iopin)/ ) { num=split($2,name,",") for(i=1;i<=num;i++) print $1 " " name[i] - } else if( $1 ~ /\.subckt/) { + } else if( tolower($1) ~ /\.subckt/) { # remove m=.. from subcircuit definition since m= is a multiplier not a param sub(/ m=[0-9]+/," ",$0) gsub(","," ",$0) diff --git a/src/spice_netlist.c b/src/spice_netlist.c index 663a2a7d..359a0095 100644 --- a/src/spice_netlist.c +++ b/src/spice_netlist.c @@ -173,10 +173,9 @@ static int spice_netlist(FILE *fd, int spice_stop ) int err = 0; int i, flag = 0; const char *type; - int top_sub; + int top_sub = tclgetboolvar("lvs_netlist") || tclgetboolvar("top_is_subckt"); int lvs_ignore = tclgetboolvar("lvs_ignore"); - - top_sub = tclgetboolvar("lvs_netlist") || tclgetboolvar("top_is_subckt"); + if(!spice_stop) { dbg(1, "spice_netlist(): invoke prepare_netlist_structs for %s\n", xctx->current_name); xctx->prep_net_structs = 0; @@ -278,6 +277,7 @@ int global_spice_netlist(int global, int alert) /* netlister driver */ int found_top_symbol = 0; int npins = 0; /* top schematic number of i/o ports */ Sch_pin_record *pinnumber_list = NULL; /* list of top sch i/o ports ordered wrt sim_pinnumber attr */ + int uppercase_subckt = tclgetboolvar("uppercase_subckt"); exit_code = 0; /* reset exit code */ split_f = tclgetboolvar("split_files"); @@ -341,7 +341,10 @@ int global_spice_netlist(int global, int alert) /* netlister driver */ } top_sub = tclgetboolvar("lvs_netlist") || tclgetboolvar("top_is_subckt"); if(!top_sub) fprintf(fd,"**"); - fprintf(fd,".subckt %s", get_cell(xctx->sch[xctx->currsch], 0)); + if(uppercase_subckt) + fprintf(fd,".SUBCKT %s", get_cell(xctx->sch[xctx->currsch], 0)); + else + fprintf(fd,".subckt %s", get_cell(xctx->sch[xctx->currsch], 0)); pinnumber_list = sort_schematic_pins(&npins); /* sort pins according to sim_pinnumber attr */ /* print top subckt ipin/opins */ @@ -405,7 +408,10 @@ int global_spice_netlist(int global, int alert) /* netlister driver */ /* /20100217 */ if(!top_sub) fprintf(fd,"**"); - fprintf(fd, ".ends\n"); + if(uppercase_subckt) + fprintf(fd, ".ENDS\n"); + else + fprintf(fd, ".ends\n"); if(split_f) { @@ -572,7 +578,7 @@ int global_spice_netlist(int global, int alert) /* netlister driver */ /* 20150922 added split_files check */ - if(!split_f) fprintf(fd, ".end\n"); + if( !top_sub && !split_f) fprintf(fd, ".end\n"); dbg(1, "global_spice_netlist(): starting awk on netlist!\n"); @@ -612,7 +618,8 @@ int spice_block_netlist(FILE *fd, int i, int alert) char *sym_def = NULL; char *name = NULL; const char *default_schematic; - + int uppercase_subckt = tclgetboolvar("uppercase_subckt"); + split_f = tclgetboolvar("split_files"); if(!strboolcmp( get_tok_value(xctx->sym[i].prop_ptr,"spice_stop",0),"true") ) @@ -657,7 +664,10 @@ int spice_block_netlist(FILE *fd, int i, int alert) } else { const char *s = get_cell(sanitize(name), 0); fprintf(fd, "** sch_path: %s\n", sanitized_abs_sym_path(filename, "")); - fprintf(fd, ".subckt %s ", s); + if(uppercase_subckt) + fprintf(fd, ".SUBCKT %s ", s); + else + fprintf(fd, ".subckt %s ", s); print_spice_subckt_nodes(fd, i); my_strdup(_ALLOC_ID_, &extra, get_tok_value(xctx->sym[i].prop_ptr,"extra",0) ); @@ -680,7 +690,10 @@ int spice_block_netlist(FILE *fd, int i, int alert) fprintf(fd, "%s\n", xctx->schprop); fprintf(fd,"**** end user architecture code\n"); } - fprintf(fd, ".ends\n\n"); + if(uppercase_subckt) + fprintf(fd, ".ENDS\n\n"); + else + fprintf(fd, ".ends\n\n"); } if(split_f) { int save; diff --git a/src/xinit.c b/src/xinit.c index 8ffe0f5c..ff9e9835 100644 --- a/src/xinit.c +++ b/src/xinit.c @@ -1666,6 +1666,7 @@ static void create_new_window(int *window_count, const char *noconfirm, const ch tclvareval("set_bindings ", window_path[n], NULL); tclvareval("set_replace_key_binding ", window_path[n], NULL); tclvareval("save_ctx ", window_path[n], NULL); + tcleval("eval_user_startup_commands"); /* restore previous context, * because the Expose event after new window creation does a context switch prev win -> new win * @@ -2892,6 +2893,7 @@ int Tcl_AppInit(Tcl_Interp *inter) if(has_x) { tclsetintvar("tctx::max_new_windows", MAX_NEW_WINDOWS); tcleval("pack_widgets; set_bindings .drw"); + tcleval("eval_user_startup_commands"); } fs=tclgetintvar("fullscreen"); diff --git a/src/xschem.tcl b/src/xschem.tcl index 585a991b..122a0d75 100644 --- a/src/xschem.tcl +++ b/src/xschem.tcl @@ -3997,6 +3997,13 @@ proc is_xschem_file {f} { } else { fconfigure $fd -translation binary while { [gets $fd line] >=0 } { + + #### Can not use this. schematics may containg 8 bit extended characters + # if {[regexp {[^[:print:][:space:]]} $line]} { ;# line contains non ascii chars + # close $fd + # return 0 + # } + # this is a script. not an xschem file if { $nline == 0 && [regexp {^#!} $line] } { #### too dangerous executing an arbitrary script... @@ -4503,9 +4510,6 @@ proc load_file_dialog {{msg {}} {ext {}} {global_initdir {INITIALINSTDIR}} file_dialog_set_colors1 scrollbar .load.l.paneleft.yscroll -command ".load.l.paneleft.list yview" -takefocus 0 scrollbar .load.l.paneleft.xscroll -command ".load.l.paneleft.list xview" -orient horiz -takefocus 0 - pack .load.l.paneleft.yscroll -side right -fill y - pack .load.l.paneleft.xscroll -side bottom -fill x - pack .load.l.paneleft.list -fill both -expand true -padx 12 bind .load.l.paneleft.list <> { set file_dialog_sel [.load.l.paneleft.list curselection] if { $file_dialog_sel ne {} } { @@ -4551,9 +4555,6 @@ proc load_file_dialog {{msg {}} {ext {}} {global_initdir {INITIALINSTDIR}} -xscrollcommand ".load.l.paneright.f.xscroll set" -exportselection 0 scrollbar .load.l.paneright.f.yscroll -command ".load.l.paneright.f.list yview" -takefocus 0 scrollbar .load.l.paneright.f.xscroll -command ".load.l.paneright.f.list xview" -orient horiz -takefocus 0 - pack .load.l.paneright.f.yscroll -side right -fill y - pack .load.l.paneright.f.xscroll -side bottom -fill x - pack .load.l.paneright.f.list -side bottom -fill both -expand true if { $loadfile == 2} { .load.l add .load.l.recent @@ -4598,7 +4599,7 @@ proc load_file_dialog {{msg {}} {ext {}} {global_initdir {INITIALINSTDIR}} } label .load.buttons_bot.label -text { File:} entry .load.buttons_bot.entry -highlightcolor red -highlightthickness 2 \ - -highlightbackground [option get . background {}] + -highlightbackground [option get . background {}] -takefocus 0 entry_replace_selection .load.buttons_bot.entry label .load.buttons_bot.srclab -text { Search:} entry .load.buttons_bot.src -width 18 -highlightcolor red -highlightthickness 2 \ @@ -4652,19 +4653,28 @@ proc load_file_dialog {{msg {}} {ext {}} {global_initdir {INITIALINSTDIR}} file_dialog_set_colors1 .load.l.paneleft.list xview moveto 1 } + + pack .load.l -expand true -fill both + pack .load.l.paneleft.yscroll -side right -fill y + pack .load.l.paneleft.xscroll -side bottom -fill x + pack .load.l.paneleft.list -fill both -expand true -padx 12 + pack .load.buttons.home .load.buttons.up .load.buttons.pwd .load.buttons.path -side left pack .load.buttons.mkdirlab -side left pack .load.buttons.newdir -expand true -fill x -side left pack .load.buttons.rmdir .load.buttons.mkdir -side right - # pack .load.buttons_bot.all .load.buttons_bot.sym .load.buttons_bot.sch -side left pack .load.buttons_bot.srclab -side left pack .load.buttons_bot.src -side left pack .load.buttons_bot.label -side left pack .load.buttons_bot.entry -side left -fill x -expand true + + pack .load.l.paneright.f.yscroll -side right -fill y + pack .load.l.paneright.f.xscroll -side bottom -fill x + pack .load.l.paneright.f.list -side bottom -fill both -expand true + pack .load.buttons_bot.cancel .load.buttons_bot.ok -side left pack .load.buttons_bot -side bottom -fill x pack .load.buttons -side bottom -fill x - pack .load.l -expand true -fill both if { [info exists file_dialog_default_geometry]} { wm geometry .load "${file_dialog_default_geometry}" } @@ -4840,6 +4850,34 @@ proc insert_symbol_preview {{paths {}}} { } } } + +proc get_list_of_dirs_with_symbols {{paths {}} {levels -1} {level -1}} { + global pathlist + if {$level == -1} { set level 0} + if {$paths eq {}} {set paths $pathlist} + + foreach i $paths { + set filelist [glob -nocomplain -directory $i -type f *] + set there_are_symbols 0 + foreach f $filelist { + if {[regexp {\.(sch|sym|tcl)$} $f]} { + # if {[is_xschem_file $f] ne {0}} { } + set there_are_symbols 1 + break + } + } + if {$there_are_symbols} { + puts $i + } + + set dirlist [glob -nocomplain -directory $i -type d *] + if {$levels >=0 && $level + 1 > $levels} {return} + foreach d $dirlist { + get_list_of_dirs_with_symbols $d $levels [expr {$level + 1} ] + } + } +} + #### fill list of files matching pattern proc insert_symbol_filelist {paths {maxdepth -1}} { # puts "insert_symbol_filelist: paths=$paths" @@ -4922,8 +4960,10 @@ proc insert_symbol {{paths {}} {maxdepth -1} {ext {.*}}} { frame .ins.top -takefocus 0 frame .ins.top2 -takefocus 0 panedwindow .ins.center -orient horizontal -height 8c + frame .ins.center.leftdir -takefocus 0 frame .ins.center.left -takefocus 0 - frame .ins.center.right -width 300 -height 250 -bg white -takefocus 0 + frame .ins.center.right -width 250 -height 250 -bg white -takefocus 0 + .ins.center add .ins.center.leftdir .ins.center add .ins.center.left .ins.center add .ins.center.right frame .ins.bottom -takefocus 0 @@ -4931,13 +4971,26 @@ proc insert_symbol {{paths {}} {maxdepth -1} {ext {.*}}} { pack .ins.top2 -side top -fill x pack .ins.center -side top -expand 1 -fill both pack .ins.bottom -side top -fill x - listbox .ins.center.left.l -listvariable insert_symbol(list) -width 50 -height 20 \ + + listbox .ins.center.leftdir.l -listvariable insert_symbol(dirs) -width 20 -height 20 \ + -yscrollcommand ".ins.center.leftdir.s set" -highlightcolor red -highlightthickness 2 \ + -activestyle underline -highlightbackground [option get . background {}] \ + -exportselection 0 + + listbox .ins.center.left.l -listvariable insert_symbol(list) -width 40 -height 20 \ -yscrollcommand ".ins.center.left.s set" -highlightcolor red -highlightthickness 2 \ -activestyle underline -highlightbackground [option get . background {}] \ -exportselection 0 + + scrollbar .ins.center.leftdir.s -command ".ins.center.leftdir.l yview" -takefocus 0 scrollbar .ins.center.left.s -command ".ins.center.left.l yview" -takefocus 0 + pack .ins.center.left.l -expand 1 -fill both -side left pack .ins.center.left.s -fill y -side left + + pack .ins.center.leftdir.l -expand 1 -fill both -side left + pack .ins.center.leftdir.s -fill y -side left + label .ins.top2.dir_l -text {Full path:} entry .ins.top2.dir_e -width 60 -state readonly \ -readonlybackground [option get . background {}] -takefocus 0 @@ -7006,15 +7059,15 @@ proc rel_sym_path {symbol {paths {}} } { if { $paths eq {}} {set paths $pathlist} regsub {^~/} $symbol ${env(HOME)}/ symbol - if {$OS eq "Windows"} { - if {![regexp {^[A-Za-z]\:/} $symbol]} { - set symbol [pwd]/$symbol - } - } else { - if {![regexp {^/} $symbol]} { - set symbol [pwd]/$symbol - } - } + # if {$OS eq "Windows"} { + # if {![regexp {^[A-Za-z]\:/} $symbol]} { + # set symbol [pwd]/$symbol + # } + # } else { + # if {![regexp {^/} $symbol]} { + # set symbol [pwd]/$symbol + # } + # } set curr_dirname [pwd] set name {} foreach path_elem $paths { @@ -8143,8 +8196,9 @@ set tctx::global_list { svg_font_name sym_txt symbol symbol_width tabstop tclcmd_txt tclstop tctx::colors tctx::hsize tctx::rcode tctx::vsize text_line_default_geometry text_replace_selection text_tabs_setting textwindow_fileid textwindow_filename textwindow_w toolbar_horiz toolbar_list toolbar_visible - top_is_subckt transparent_svg undo_type unselect_partial_sel_wires use_cursor_for_selection - use_lab_wire use_label_prefix use_tclreadline user_wants_copy_cell verilog_2001 verilog_bitblast + top_is_subckt transparent_svg undo_type unselect_partial_sel_wires uppercase_subckt + use_cursor_for_selection use_lab_wire use_label_prefix use_tclreadline user_wants_copy_cell + verilog_2001 verilog_bitblast viewdata_fileid viewdata_filename viewdata_w xschem_libs xschem_listen_port zoom_full_center } @@ -9119,7 +9173,7 @@ proc build_widgets { {topwin {} } } { -selectcolor $selectcolor -variable auto_hilight_graph_nodes $topwin.menubar.simulation.graph add command -label {Add waveform graph} -command {xschem add_graph} $topwin.menubar.simulation.graph add command -label {Add waveform reload launcher} -command { - xschem place_symbol [rel_sym_path [find_file_first launcher.sym]] "name=h5\ndescr=\"load waves\" + xschem place_symbol [find_file_first launcher.sym] "name=h5\ndescr=\"load waves\" tclcommand=\"xschem raw_read \$netlist_dir/[file tail [file rootname [xschem get current_name]]].raw tran\" " } @@ -9149,7 +9203,8 @@ tclcommand=\"xschem raw_read \$netlist_dir/[file tail [file rootname [xschem get xschem set format {} } } - + $topwin.menubar.simulation.lvs add checkbutton -label "Upper case .SUBCKT and .ENDS" \ + -selectcolor $selectcolor -variable uppercase_subckt $topwin.menubar.simulation.lvs add checkbutton -label "Top level is a .subckt" \ -selectcolor $selectcolor -variable top_is_subckt @@ -9358,6 +9413,15 @@ proc source_user_tcl_files {} { } } +proc eval_user_startup_commands {} { + global user_startup_commands + if {[info exists user_startup_commands]} { + if {[catch {uplevel #0 $user_startup_commands} res]} { + puts "executing $user_startup_commands:\n\n$res" + } + } +} + proc eval_postinit_commands {} { global postinit_commands if {[info exists postinit_commands]} { @@ -9587,6 +9651,7 @@ set_ne local_netlist_dir 0 ;# if set use /simulation for netlist and si set_ne bus_replacement_char {} ;# use {<>} to replace [] with <> in bussed signals set_ne lvs_netlist 0 set_ne top_is_subckt 0 +set_ne uppercase_subckt 0 set_ne lvs_ignore 0 set_ne hide_empty_graphs 0 ;# if set to 1 waveform boxes will be hidden if no raw file loaded set_ne graph_use_ctrl_key 0;# if set forces to use Control key to operate on graphs diff --git a/src/xschemrc b/src/xschemrc index 6b90809f..ffdf2b1b 100644 --- a/src/xschemrc +++ b/src/xschemrc @@ -546,6 +546,17 @@ # } # } +########################################################################### +#### TCL COMMANDS TO BE EXECUTED AFTER ANY NEW WINDOW CREATION +########################################################################### +#### this hook is useful to execute user UI code (like event binding, +#### new buttons / menu entries etc). +# set user_startup_commands { +# bind [xschem get current_win_path] { +# puts Hello +# } +# } + ########################################################################### #### TCL COMMANDS TO BE EXECUTED AFTER GENERATING NETLIST ###########################################################################