preserve ordering in verilog/VHDL signal/wire/reg declarations for consistent netlist hashing/checking

This commit is contained in:
Stefan Frederik 2021-12-15 15:17:45 +01:00
parent 95ea920faf
commit ba15e21b24
7 changed files with 98 additions and 88 deletions

View File

@ -1045,7 +1045,9 @@ static void send_current_to_gaw(int simtype, const char *node)
my_free(1182, &t);
}
/* hilight_instances: if set == 1 hilight non pin/label symbols with "highlight=true" attribute set */
/* hilight/clear pin/label instances attached to hilight nets, or instances with "hilight=true"
* attr if en_hilight_conn_inst option is set
*/
void propagate_hilights(int set, int clear, int mode)
{
int i, hilight_connected_inst;
@ -1058,12 +1060,14 @@ void propagate_hilights(int set, int clear, int mode)
prepare_netlist_structs(0);
for(i = 0; i < xctx->instances; i++) {
if(xctx->inst[i].ptr < 0 ) {
dbg(0, "propagate_hilights(): .ptr < 0, unbound symbol: inst %d, name=%s\n", i, xctx->inst[i].instname);
dbg(0, "propagate_hilights(): .ptr<0, unbound symbol: inst %d, name=%s sch=%s\n",
i, xctx->inst[i].instname, xctx->current_name);
continue;
}
type = (xctx->inst[i].ptr+ xctx->sym)->type;
hilight_connected_inst = en_hi &&
( (xctx->inst[i].flags & 4) || ((xctx->inst[i].ptr+ xctx->sym)->flags & 4) );
/* hilight/clear instances with hilight=true attr set and en_hilight_conn_inst option is set ... */
if(hilight_connected_inst && type && !IS_LABEL_SH_OR_PIN(type)) {
int rects, j, nohilight_pins;
if( (rects = (xctx->inst[i].ptr+ xctx->sym)->rects[PINLAYER]) > 0 ) {
@ -1085,6 +1089,7 @@ void propagate_hilights(int set, int clear, int mode)
xctx->inst[i].color=-10000;
}
}
/* ... else hilight/clear pin/label instances attached to hilight nets */
} else if(type && xctx->inst[i].node && IS_LABEL_SH_OR_PIN(type) ) {
entry=bus_hilight_hash_lookup( xctx->inst[i].node[0], 0, XLOOKUP);
if(entry && set) xctx->inst[i].color = entry->value;

View File

@ -1137,7 +1137,7 @@ void load_schematic(int load_symbols, const char *filename, int reset_undo) /* 2
}
if(tclgetboolvar("autotrim_wires")) trim_wires();
update_conn_cues(0, 0);
if(xctx->hilight_nets) {
if(xctx->hilight_nets && load_symbols) {
propagate_hilights(1, 1, XINSERT_NOREPLACE);
}
}

View File

@ -38,6 +38,7 @@ BEGIN{
net_types["integer"]=1
net_types["time"]=1
net_types["real"]=1
net_types["signed"]=1
net_types["logic"]=1
net_types["bool"]=1
direction["input"]=1
@ -108,7 +109,8 @@ primitive==1{primitive_line=primitive_line " " $0; next }
# print signals/regs/variables
/---- end signal list/{
for(i in signal_basename) {
for(ii = 0 ; ii < signal_n; ii++) { # used to preserve order of signals
i = signal_num[ii] # used to preserve order of signals
n=signal_basename[i]
split(signal_index[i],tmp)
hsort(tmp,n)
@ -150,8 +152,7 @@ primitive==1{primitive_line=primitive_line " " $0; next }
# store signals
siglist==1 && ($1 in net_types) {
# 20070525 recognize "reg real" types and similar
# 20070525 recognize "reg real", "wire signed" types and similar
if($2 in net_types) {
if($3 ~ /^#/) basename=s_b($4)
else basename=s_b($3)
@ -166,20 +167,19 @@ siglist==1 && ($1 in net_types) {
sub(/;.*/,"",val)
signal_value[basename]=val
}
if(!(basename in signal_basename)) signal_num[signal_n++] = basename # used to preserve order of signals
signal_basename[basename]++
if($3 ~ /\[.*\]/) {
signal_index[basename]=signal_index[basename] " " s_i($3)
}
else signal_index[basename]="no_index"
}
# /20070525
# /20070525
else {
if($2 ~ /^#/) basename=s_b($3)
else basename=s_b($2)
signal_type[basename]=$1
if($2 ~ /^#/) {
if($2 ~ /^#/) { # handle declarations like: wire #20 w_tmp;
signal_delay[basename]=$2
$2=""; $0=$0;
}
@ -189,6 +189,7 @@ siglist==1 && ($1 in net_types) {
sub(/;.*/,"",val)
signal_value[basename]=val
}
if(!(basename in signal_basename)) signal_num[signal_n++] = basename # used to preserve order of signals
signal_basename[basename]++
if($2 ~ /\[.*\]/) {
signal_index[basename]=signal_index[basename] " " s_i($2)
@ -216,6 +217,8 @@ NF==3 && $3=="(" && $1=="module" {
delete signal_value
delete signal_type
delete signal_delay
delete signal_num # used to preserve order of signals
signal_n = 0 # used to preserve order of signals
}
begin_module && $1 ~/^\);$/ {

View File

@ -399,8 +399,6 @@ void verilog_block_netlist(FILE *fd, int i)
fprintf(fd, "// sym_path: %s\n", abs_sym_path(xctx->sym[i].name, ""));
fprintf(fd, "// sch_path: %s\n", filename);
verilog_stop? load_schematic(0,filename, 0) : load_schematic(1,filename, 0);
/* print verilog timescale and preprocessor directives 10102004 */
for(j=0;j<xctx->instances;j++)

View File

@ -207,6 +207,8 @@ primitive==1{primitive_line=primitive_line " " $0; next } # 20071217
/^[ \t]*architecture[ \t]+.*[ \t]+is[ \t]*$/{
arch_rep=$2
arch=$4
arch_signal_n = 0 # used to preserve order of signals
delete arch_signal_num # used to preserve order of signals
delete arch_signal_dir
delete arch_index_array
delete arch_sig_type_array
@ -250,6 +252,9 @@ primitive==1{primitive_line=primitive_line " " $0; next } # 20071217
sig_dir=" downto " # just to have a value
sig_class=$1
}
if(!(sig_basename in arch_signal_dir)) {
arch_signal_num[arch_signal_n++] = sig_basename # used to preserve order of signals
}
arch_signal_dir[sig_basename]=sig_dir
arch_signal_class[sig_basename]=sig_class
arch_sig_type_array[sig_basename]=sig_type
@ -276,75 +281,71 @@ primitive==1{primitive_line=primitive_line " " $0; next } # 20071217
if( user_declarations!="") print user_declarations
ttt[1]="constant"
ttt[2]="variable"
ttt[3]="signal"
for(tt=1;tt<=3;tt++)
for(i in arch_signal_dir)
if(arch_signal_class[i]==ttt[tt])
for(ii = 0; ii < arch_signal_n; ii++)
{
i = arch_signal_num[ii]
## 04062002 don't add _vector if user defined type
if(arch_sig_type_array[i] ~ /^(boolean|bit|real|std_logic|integer)$/)
vector_type=arch_sig_type_array[i] "_vector ("
else
vector_type=arch_sig_type_array[i] " ("
n=split(arch_index_array[i],tmp,",")
hsort(tmp, n)
if(n>1 || (arch_index_array[i] !~ /no_index/) ) #11092003 if not no_index treat as a bus
{
if(check(tmp,n))
{
if(arch_signal_dir[i] == " downto ")
{
## 04062002 don't add _vector if user defined type
if(arch_sig_type_array[i] ~ /^(boolean|bit|real|std_logic|integer)$/)
vector_type=arch_sig_type_array[i] "_vector ("
else
vector_type=arch_sig_type_array[i] " ("
n=split(arch_index_array[i],tmp,",")
hsort(tmp, n)
if(n>1 || (arch_index_array[i] !~ /no_index/) ) #11092003 if not no_index treat as a bus
{
if(check(tmp,n))
{
if(arch_signal_dir[i] == " downto ")
{
arch_sig_name[entity_name, i "[" tmp[1] ":" tmp[n] "]"]=i
printf "%s",arch_signal_class[i] " " i " : " vector_type tmp[1] " downto " tmp[n] ")" #04062002
}
else
{
arch_sig_name[entity_name, i "[" tmp[n] ":" tmp[1] "]"]=i
printf "%s",arch_signal_class[i] " " i " : " vector_type tmp[n] " to " tmp[1] ")" #04062002
}
}
else print "\n**** ERROR >>>> " i " non contigous bus ->" n, "|" arch_index_array[i] "|"
}
else
{
# we do not declare parametrized subranges as normally will result in redeclaration
# of a port signal
if( i ~ /\[.*\]/)
{
range = s_i(i)
basename=s_b(i) # on exactly matching ranges
arch_sig_name[entity_name, basename "[" range "]"]=i # used later in port maps to avoid specifying ranges
if( !(basename in entity_ports) ) #09112003, eror corrected, basename instead of i in
{ #arch_sig_name[entity_name,...
if(range ~ /0:/)
sub(/:/, " to ", range)
else
sub(/:/, " downto ", range)
range= range ")"
printf "%s",arch_signal_class[i] " " basename " : " vector_type range #04062002
}
else continue
}
else
printf "%s",arch_signal_class[i] " " i " : " arch_sig_type_array[i]
}
if(arch_value_array[i] != "") { #08112004 add quotes on values
if(tolower( arch_sig_type_array[i]) ~ /std_logic/ || # if not present
tolower(arch_sig_type_array[i]) ~ /bit/ ) { # for verilog/VHDL compatiblity
# if(tolower(arch_sig_type_array[i]) ~ /vector/) sep="\""
if(n>1 || (arch_index_array[i] !~ /no_index/) ) sep="\""
else sep = "'"
if( arch_value_array[i] !~ sep)
arch_value_array[i] = sep arch_value_array[i] sep
}
printf "%s"," := " arch_value_array[i]
}
printf " ;\n"
arch_sig_name[entity_name, i "[" tmp[1] ":" tmp[n] "]"]=i
printf "%s",arch_signal_class[i] " " i " : " vector_type tmp[1] " downto " tmp[n] ")" #04062002
}
else
{
arch_sig_name[entity_name, i "[" tmp[n] ":" tmp[1] "]"]=i
printf "%s",arch_signal_class[i] " " i " : " vector_type tmp[n] " to " tmp[1] ")" #04062002
}
}
else print "\n**** ERROR >>>> " i " non contigous bus ->" n, "|" arch_index_array[i] "|"
}
else
{
# we do not declare parametrized subranges as normally will result in redeclaration
# of a port signal
if( i ~ /\[.*\]/)
{
range = s_i(i)
basename=s_b(i) # on exactly matching ranges
arch_sig_name[entity_name, basename "[" range "]"]=i # used later in port maps to avoid specifying ranges
if( !(basename in entity_ports) ) #09112003, eror corrected, basename instead of i in
{ #arch_sig_name[entity_name,...
if(range ~ /0:/)
sub(/:/, " to ", range)
else
sub(/:/, " downto ", range)
range= range ")"
printf "%s",arch_signal_class[i] " " basename " : " vector_type range #04062002
}
else continue
}
else
printf "%s",arch_signal_class[i] " " i " : " arch_sig_type_array[i]
}
if(arch_value_array[i] != "") { #08112004 add quotes on values
if(tolower( arch_sig_type_array[i]) ~ /std_logic/ || # if not present
tolower(arch_sig_type_array[i]) ~ /bit/ ) { # for verilog/VHDL compatiblity
# if(tolower(arch_sig_type_array[i]) ~ /vector/) sep="\""
if(n>1 || (arch_index_array[i] !~ /no_index/) ) sep="\""
else sep = "'"
if( arch_value_array[i] !~ sep)
arch_value_array[i] = sep arch_value_array[i] sep
}
printf "%s"," := " arch_value_array[i]
}
printf " ;\n"
}
if(user_attributes!="") print user_attributes
@ -366,7 +367,7 @@ primitive==1{primitive_line=primitive_line " " $0; next } # 20071217
}
($1==");" && port_map==1){
nii=split(instance,ii,",")
nii=split(instance,inst_arr,",")
for(j=0;j<p;j++) {
if(j>=g) { # do not split generics 06042005
actual_port_mult=split(inst_actual_port[j],actual_port_array,",")
@ -378,7 +379,7 @@ primitive==1{primitive_line=primitive_line " " $0; next } # 20071217
ck2[j] = check2(actual_port_array,actual_port_mult)
}
for(i=1;i<=nii;i++) {
print ii[i] " : " cell
print inst_arr[i] " : " cell
if(g>0)
print "generic map ("
else
@ -400,7 +401,7 @@ primitive==1{primitive_line=primitive_line " " $0; next } # 20071217
if(inst_formal_port_mult[j]<0) {
parametrized_formal_range=1 # 20100408
inst_formal_port_mult[j] = actual_port_mult
inst_formal_up[j] = actual_port_mult -1 # 20100419 assume inst_formal_low=0 in case of parametrized vector port...
inst_formal_up[j] = actual_port_mult -1 #assume inst_formal_low=0 in case of parametrized vector port...
}
a=((i-1)*inst_formal_port_mult[j]) % actual_port_mult+1
@ -468,6 +469,7 @@ primitive==1{primitive_line=primitive_line " " $0; next } # 20071217
}
printf "\n);\n"
}
delete inst_arr
port_map=0
print_arch_definition=1
no_print=1

View File

@ -163,9 +163,9 @@ proc netlist_test {} {
global netlist_dir
foreach {f t h} {
rom8k.sch spice 1466291334
greycnt.sch verilog 389394682
greycnt.sch verilog 3391559642
autozero_comp.sch spice 2011673313
loading.sch vhdl 3704887277
loading.sch vhdl 2601437773
mos_power_ampli.sch spice 1186348644
LCC_instances.sch spice 824427889
simulate_ff.sch spice 1321596936
@ -176,10 +176,11 @@ proc netlist_test {} {
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 1] == $h } {
set netlist_hash [xschem hash_file $netlist_file 1]
if { $netlist_hash == $h } {
puts "$f netlist check OK"
} else {
puts "$f netlist check FAIL"
puts "$f netlist check, expected hash: ${h}, calculated hash: ${netlist_hash}, FAIL"
}
}
}

View File

@ -1,4 +1,4 @@
v {xschem version=2.9.7 file_version=1.2}
v {xschem version=3.0.0 file_version=1.2 }
G {process
begin
A<='0';
@ -76,11 +76,12 @@ wait for 10 ns;
wait;
end process;
}
K {}
V {integer n = 0;
initial begin
$dumpfile("dumpfile.vcd");
$dumpvars;
$dumpvars(0, testbench);
A=0;
B=0;
#1000;