more modularized xschemtest, use stdlib file functions for hash_file()

This commit is contained in:
Stefan Frederik 2021-12-10 13:17:21 +01:00
parent 5270d41d8d
commit 5a3ea573cd
2 changed files with 125 additions and 94 deletions

View File

@ -31,20 +31,23 @@ void here(int i)
}
/* super simple 32 bit hashing function for files
* It is suppoded to be used on text files.
* Calculates the same hash on windows (crlf) and unix (lf) text files.
* If you want high collision resistance and
* avoid 'birthday problem' collisions use a better hash function, like md5sum
* or sha256sum
*/
unsigned int hash_file(const char *f)
{
int fd;
FILE *fd;
int n, i;
int cr = 0;
unsigned int h=5381;
unsigned char line[4096];
fd = open(f, O_RDONLY);
if(fd >= 0) {
while( (n = read(fd, line, sizeof(line))) ) {
char line[4096];
fd = fopen(f, fopen_read_mode); /* "r" on linux, "rb" on windows */
if(fd) {
while( fgets(line, sizeof(line), fd) ) {
n = strlen(line);
for(i = 0; i < n; i++) {
/* skip CRs so hashes will match on unix / windows */
if(line[i] == '\r') {
@ -56,11 +59,11 @@ unsigned int hash_file(const char *f)
cr = 0;
h += (h << 5) + '\r';
}
h += (h << 5) + line[i];
h += (h << 5) + (unsigned char)line[i];
}
}
if(cr) h += (h << 5) + '\r'; /* file ends with \r not followed by \n: keep it */
close(fd);
fclose(fd);
return h;
} else {
fprintf(stderr, "Can not open file %s\n", f);

View File

@ -17,24 +17,44 @@
## allows to see differences in number of function calls / time spent.
## move schematic and redraw in a loop.
proc drawtest {} {
set increment 5.0
set a [time {
for { set i 0 } { $i < 100 } { incr i} {
set x [xschem get xorigin]
set y [xschem get yorigin]
set x [expr {$x +$increment}]
set y [expr {$y +$increment}]
xschem origin $x $y
xschem redraw
}
}]
set a [lindex $a 0]
set fps [expr {100.0 / $a * 1e6} ] ;# calculate drawing frames per second
puts "[rel_sym_path [xschem get schname]]: draw speed: $fps fps"
proc draw_test {} {
global show_pin_net_names
set show_pin_net_names 1
foreach f {
rom8k.sch
greycnt.sch
autozero_comp.sch
loading.sch
mos_power_ampli.sch
LCC_instances.sch
simulate_ff.sch
} {
xschem load [abs_sym_path $f]
xschem search regex 1 lab . ;# select all nets
xschem hilight ;# hilight all selected nets and labels
xschem unselect_all
set increment 5.0
set a [time {
for { set i 0 } { $i < 100 } { incr i} {
set x [xschem get xorigin]
set y [xschem get yorigin]
set x [expr {$x +$increment}]
set y [expr {$y +$increment}]
xschem origin $x $y
xschem redraw
}
}]
set a [lindex $a 0]
set fps [expr {100.0 / $a * 1e6} ] ;# calculate drawing frames per second
puts "$f: draw speed: $fps fps"
}
set show_pin_net_names 0
}
proc copy_paste_test {} {
## select all loaded schematic and paste 32 times in different places,
## check if number of elements after paste matches.
proc copy_paste_test {{f mos_power_ampli.sch}} {
xschem load [abs_sym_path $f]
xschem zoom_box -18000 -18000 18000 18000
xschem select_all
set n [xschem get lastsel]
@ -89,8 +109,79 @@ proc draw_trim_wiregrid {} {
set n [xschem get lastsel]
xschem unselect_all
## if all wires trimmed correctly we should have 129*128*2 = 33024 segments.
if {$n == 33024} { puts "trim wire test: $n segments, OK"} else { puts "trim wire test FAIL"}
after 200 { xschem clear force}
if {$n == 33024} { puts "Trim wire test: $n segments, OK"} else { puts "Trim wire test FAIL"}
xschem clear force
}
## test print files. Exact file content depend on window size and conversion tool,
## so we simply check if existing and size > 0.
## view parameter allows to view print file (works on linux)
proc print_test {{view 0}} {
global OS
foreach {f t} {
autozero_comp.sch png
mos_power_ampli.sch svg
simulate_ff.sch pdf
} {
set filepath [abs_sym_path $f]
set printfile [file rootname $f].$t
xschem load $filepath
puts "Printing: $printfile in $t format"
xschem print $t $printfile
if {$view && $OS ne {Windows}} {
execute 0 xdg-open $printfile
alert_ "Opening print file. Check if $printfile print file looks fine"
}
if {[file exists $printfile] && [file size $printfile] > 0} {
puts "Print file $printfile exists. [file size $printfile] bytes. OK"
} else {
puts "Print file $printfile not existing or empty. FAIL"
}
file delete $printfile
}
xschem clear force
}
## test xschem's own simulation engine
## there is no built in testing, just see if it works.
proc test_xschem_simulation {{f simulate_ff.sch}} {
global tclstop
xschem load [abs_sym_path $f]
## search element with tclcommand attribute
xschem search regex 1 tclcommand {}
## join transform a list element {foo} into a plain string foo
set instname [join [xschem selected_set]]
## run tcl testbench
eval [xschem getprop instance $instname tclcommand]
puts "Xschem simulation test done. OK"
}
## netlist some files in various formats and check netlist with known gold hashes
## hashes should be calculated in same way on windows and linux.
proc netlist_test {} {
global netlist_dir
foreach {f t h} {
rom8k.sch spice 2198713988
greycnt.sch verilog 389394682
autozero_comp.sch spice 2011673313
loading.sch vhdl 3834408538
mos_power_ampli.sch spice 1186348644
LCC_instances.sch spice 3918341865
simulate_ff.sch spice 1321596936
} {
xschem set netlist_type $t
xschem load [abs_sym_path $f]
xschem netlist
if {$t eq {verilog}} { set t v}
set netlist_file $netlist_dir/[file rootname $f].$t
## check netlist hashes, compare with gold hashes
if { [xschem hash_file $netlist_file] == $h } {
puts "$f netlist check OK"
} else {
puts "$f netlist check FAIL"
}
}
}
proc xschemtest {{view 0}} {
@ -99,78 +190,15 @@ proc xschemtest {{view 0}} {
## make sure ERC window wil not pop up above schematic while doing tests
wm deiconify .infotext
lower .infotext
for {set n 0} {$n < 7} {incr n} {
set show_pin_net_names 0
if {$n % 7 == 1} {
xschem set netlist_type verilog
xschem load [abs_sym_path greycnt.sch]
} elseif {$n % 7 == 2} {
xschem set netlist_type spice
xschem load [abs_sym_path autozero_comp.sch]
xschem print png autozero_comp.png
} elseif {$n % 7 == 3} {
xschem set netlist_type vhdl
xschem load [abs_sym_path loading.sch]
} elseif {$n % 7 == 4} {
xschem set netlist_type spice
set show_pin_net_names 1
xschem load [abs_sym_path mos_power_ampli.sch]
xschem print svg mos_power_ampli.svg
} elseif {$n % 7 == 5} {
xschem set netlist_type spice
xschem load [abs_sym_path LCC_instances.sch]
} elseif {$n % 7 == 6} {
xschem set netlist_type spice
xschem load [abs_sym_path simulate_ff.sch]
xschem print pdf simulate_ff.pdf
eval [xschem getprop instance h3 tclcommand]
} else {
xschem set netlist_type spice
xschem load [abs_sym_path rom8k.sch]
}
xschem search regex 1 lab . ;# select all nets
xschem hilight ;# hilight all selected nets and labels
xschem unselect_all
xschem netlist
drawtest
if { $n == 4} { copy_paste_test }
}
xschem clear force
netlist_test
print_test $view
draw_test
copy_paste_test mos_power_ampli.sch
draw_trim_wiregrid
## check netlist hashes, compare with gold hashes
foreach {f h} {
greycnt.v 389394682
mos_power_ampli.spice 1186348644
autozero_comp.spice 2011673313
loading.vhdl 3834408538
LCC_instances.spice 3918341865
simulate_ff.spice 1321596936
rom8k.spice 2198713988
} {
if { [xschem hash_file $netlist_dir/$f] == $h } {
puts "$f netlist check OK"
} else {
puts "$f netlist check FAIL"
}
}
## test print files. Exact file content depend on window size and conversion tool,
## so we simply check if existing and size > 0.
foreach i {autozero_comp.png mos_power_ampli.svg simulate_ff.pdf} {
if {$view && $OS ne {Windows}} {
execute 0 xdg-open $i
alert_ "Check if $i print file look fine"
}
if {[file exists $i] && [file size $i] > 0} {
puts "print file $i exists. OK"
} else {
puts "print file $i not existing or empty. FAIL"
}
file delete $i
}
test_xschem_simulation simulate_ff.sch
}]
puts $t
puts "Test time: [lindex $t 0] microseconds"
}
## this is the test to run from xschem console after sourcing this file