added vhdl_sym_def, spice_sym_def, verilog_sym_def attributes for symbols. If defined and not empty the corresponding netlister will insert the content of the attribute instead of the subcircuit schematic implementation. Typically used to include a definition file. Updated documentation

This commit is contained in:
Stefan Frederik 2022-09-29 11:59:43 +02:00
parent ae4b74f2d8
commit b7c7c336dd
7 changed files with 334 additions and 308 deletions

View File

@ -145,10 +145,12 @@ type=nmos
<li><kbd>vhdl_ignore</kbd></li>
<li><kbd>spice_ignore</kbd></li>
<li><kbd>verilog_ignore</kbd></li>
<li><kbd>tedax_ignore</kbd></li>
<p>These 3 attributes tell XSCHEM to ignore completely the symbol in the respective netlist formats.</p>
<li><kbd>vhdl_stop</kbd></li>
<li><kbd>spice_stop</kbd></li>
<li><kbd>verilog_stop</kbd></li>
<li><kbd>tedax_stop</kbd></li>
<p> These 3 attributes will avoid XSCHEM to descend into the schematic representation of the symbol
(if there is one) when building the respective netlist format. For example, if an analog block
has a schematic (.sch) file describing the circuit that is meaningless when doing a VHDL netlist,
@ -162,6 +164,28 @@ type=nmos
<p> same as above <kbd>_stop</kbd> attributes, but in this case the schematic subcircuit is completely ignored,
only the 'format' string is dumped to netlist. No component/entity is generated in vhdl netlist,
no module declaration in verilog, no .subckt in spice, no schematic global attributes are exported to netlist.</p>
<li><kbd>spice_sym_def</kbd></li>
<li><kbd>verilog_sym_def</kbd></li>
<li><kbd>vhdl_sym_def</kbd></li>
<p> If any of these attributes are present and not empty the corresponding netlister will ignore the schematic subcircuit
and dump into the netlist the content of this attribute. The typical usage is to include a file, example:<br>
<pre class="code">
verilog_sym_def="tcleval(`include \"[abs_sym_path verilog_include_file.v]\")"
</pre>
</p>
<p>
In this example a <kbd>verilog_include_file.v</kbd> is included using the verilog <kbd>`include</kbd> directive.
In order to generate a full path for it the <kbd>abs_sym_path</kbd> TCL function is used that searches for this file
in any of the <kbd>XCHEM_LIBRARY_PATH</kbd> directories. Since TCL is used the attribute is wrappend into a tcleval(...),<br>
The following will appear in the generated netlist:
<pre class="code">
// expanding symbol: verilog_include.sym # of pins=3
// sym_path: /home/schippes/.xschem/xschem_library/verilog_include.sym
`include "/home/schippes/.xschem/xschem_library/verilog_include_file.v"
</pre>
</p>
<li><kbd>highlight</kbd></li>
<p>If set to <kbd>true</kbd> the symbol will be highlighted when one of the nets attached to its pins are highlighted.</p>
<li><kbd>net_name</kbd></li>

View File

@ -482,6 +482,7 @@ void spice_block_netlist(FILE *fd, int i)
/* int multip; */
char *extra=NULL;
int split_f;
const char *sym_def;
split_f = tclgetboolvar("split_files");
@ -500,31 +501,36 @@ void spice_block_netlist(FILE *fd, int i)
fprintf(fd, "\n* expanding symbol: %s # of pins=%d\n",
xctx->sym[i].name,xctx->sym[i].rects[PINLAYER] );
fprintf(fd, "** sym_path: %s\n", abs_sym_path(xctx->sym[i].name, ""));
fprintf(fd, "** sch_path: %s\n", filename);
fprintf(fd, ".subckt %s",skip_dir(xctx->sym[i].name));
print_spice_subckt(fd, i);
my_strdup(387, &extra, get_tok_value(xctx->sym[i].prop_ptr,"extra",0) );
/* this is now done in print_spice_subckt */
/*
* fprintf(fd, "%s ", extra ? extra : "" );
*/
/* 20081206 new get_sym_template does not return token=value pairs where token listed in extra */
fprintf(fd, "%s", get_sym_template(xctx->sym[i].templ, extra));
my_free(950, &extra);
fprintf(fd, "\n");
spice_stop ? load_schematic(0,filename, 0) : load_schematic(1,filename, 0);
spice_netlist(fd, spice_stop); /* 20111113 added spice_stop */
xctx->netlist_count++;
if(xctx->schprop && xctx->schprop[0]) {
fprintf(fd,"**** begin user architecture code\n");
fprintf(fd, "%s\n", xctx->schprop);
fprintf(fd,"**** end user architecture code\n");
sym_def = get_tok_value(xctx->sym[i].prop_ptr,"spice_sym_def",0);
if(sym_def[0]) {
fprintf(fd, "%s\n", sym_def);
} else {
fprintf(fd, "** sch_path: %s\n", filename);
fprintf(fd, ".subckt %s",skip_dir(xctx->sym[i].name));
print_spice_subckt(fd, i);
my_strdup(387, &extra, get_tok_value(xctx->sym[i].prop_ptr,"extra",0) );
/* this is now done in print_spice_subckt */
/*
* fprintf(fd, "%s ", extra ? extra : "" );
*/
/* 20081206 new get_sym_template does not return token=value pairs where token listed in extra */
fprintf(fd, "%s", get_sym_template(xctx->sym[i].templ, extra));
my_free(950, &extra);
fprintf(fd, "\n");
spice_stop ? load_schematic(0,filename, 0) : load_schematic(1,filename, 0);
spice_netlist(fd, spice_stop); /* 20111113 added spice_stop */
if(xctx->schprop && xctx->schprop[0]) {
fprintf(fd,"**** begin user architecture code\n");
fprintf(fd, "%s\n", xctx->schprop);
fprintf(fd,"**** end user architecture code\n");
}
fprintf(fd, ".ends\n\n");
}
fprintf(fd, ".ends\n\n");
if(split_f) {
int save;
fclose(fd);
@ -537,6 +543,7 @@ void spice_block_netlist(FILE *fd, int i)
set_tcl_netlist_type();
if(debug_var==0) xunlink(netl_filename);
}
xctx->netlist_count++;
}
/* GENERIC PURPOSE HASH TABLE */

View File

@ -2430,21 +2430,16 @@ static void print_verilog_primitive(FILE *fd, int inst) /* netlist switch level
{ /* and node number: m1 n1 m2 n2 .... */
for(i=0;i<no_of_pins;i++)
{
char *prop = (xctx->inst[inst].ptr + xctx->sym)->rect[PINLAYER][i].prop_ptr;
if(strcmp(get_tok_value(prop, "verilog_ignore",0), "true")) {
str_ptr = net_name(inst,i, &multip, 0, 1);
fprintf(fd, "----pin(%s) ", str_ptr);
}
str_ptr = net_name(inst,i, &multip, 0, 1);
fprintf(fd, "----pin(%s) ", str_ptr);
}
}
else if(token[0]=='@' && token[1]=='@') { /* recognize single pins 15112003 */
for(i=0;i<no_of_pins;i++) {
char *prop = (xctx->inst[inst].ptr + xctx->sym)->rect[PINLAYER][i].prop_ptr;
if(!strcmp( get_tok_value(prop,"name",0), token+2)) {
if(strcmp(get_tok_value(prop, "verilog_ignore",0), "true")) {
str_ptr = net_name(inst,i, &multip, 0, 1);
fprintf(fd, "----pin(%s) ", str_ptr);
}
str_ptr = net_name(inst,i, &multip, 0, 1);
fprintf(fd, "----pin(%s)", str_ptr);
break;
}
}
@ -2453,13 +2448,8 @@ static void print_verilog_primitive(FILE *fd, int inst) /* netlist switch level
else if(token[0]=='@' && token[1]=='#') {
int pin_number = atoi(token+2);
if(pin_number < no_of_pins) {
const char *vi;
char *prop = (xctx->inst[inst].ptr + xctx->sym)->rect[PINLAYER][pin_number].prop_ptr;
vi = get_tok_value(prop,"verilog_ignore",0);
if(strcmp(vi, "true")) {
str_ptr = net_name(inst,pin_number, &multip, 0, 1);
fprintf(fd, "----pin(%s) ", str_ptr);
}
str_ptr = net_name(inst,pin_number, &multip, 0, 1);
fprintf(fd, "----pin(%s) ", str_ptr);
}
}
else if(!strncmp(token,"@tcleval", 8)) {

View File

@ -59,6 +59,7 @@ BEGIN{
/^---- end primitive/{
primitive=0
$0 = primitive_line
split(primitive_line, primitive_line_sep, /[^ \n\t]+/)
gsub(/----pin\(/, " ----pin(",$0)
gsub(/----name\(/, " ----name(",$0)
for(j=1;j<= primitive_mult; j++) {
@ -89,13 +90,14 @@ BEGIN{
printf "%s", prefix prim_field_array[s]
if(s<pport_mult) printf ","
}
printf "} "
printf "}%s", primitive_line_sep[i+1]
}
}
else
# 20060919 end
printf "%s ", prim_field_array[1+(j-1) % pport_mult] # 20140401 1+(j-1) % pport_mult instead of j
printf "%s", prim_field_array[1+(j-1) % pport_mult] # 20140401 1+(j-1) % pport_mult instead of j
printf "%s", primitive_line_sep[i+1]
}
else if($i ~ /^----name\(.*\)/) {
sub(/----name\(/,"",prim_field)
@ -104,9 +106,9 @@ BEGIN{
split(prim_field, prim_field_array,/,/)
sub(/\[/,"_", prim_field_array[j])
sub(/\]/,"", prim_field_array[j])
printf "%s ", prefix prim_field_array[j]
printf "%s%s", prefix prim_field_array[j], primitive_line_sep[i+1]
}
else printf "%s ", prim_field
else printf "%s%s", prim_field, primitive_line_sep[i+1]
prefix=""
} # end for i
printf "\n"
@ -114,7 +116,7 @@ BEGIN{
next
}
primitive==1{primitive_line=primitive_line " " $0; next }
primitive==1{primitive_line=primitive_line "\n" $0; next }
# print signals/regs/variables
/---- end signal list/{
@ -148,7 +150,7 @@ primitive==1{primitive_line=primitive_line " " $0; next }
}
printf "%s ", i
if(i in signal_value) printf " = %s ", signal_value[i]
printf " ;\n"
printf ";\n"
}
}
# /20161118

View File

@ -423,6 +423,7 @@ void verilog_block_netlist(FILE *fd, int i)
char cellname[PATH_MAX];
const char *str_tmp, *fmt_attr = NULL;
int split_f;
const char *sym_def;
split_f = tclgetboolvar("split_files");
if(!strcmp( get_tok_value(xctx->sym[i].prop_ptr,"verilog_stop",0),"true") )
@ -438,110 +439,113 @@ void verilog_block_netlist(FILE *fd, int i)
my_snprintf(cellname, S(cellname), "%s.v", skip_dir(xctx->sym[i].name) );
}
dbg(1, "verilog_block_netlist(): expanding %s\n", xctx->sym[i].name);
fprintf(fd, "\n// expanding symbol: %s # of pins=%d\n",
xctx->sym[i].name,xctx->sym[i].rects[PINLAYER] );
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 */
fmt_attr = xctx->format ? xctx->format : "verilog_format";
for(j=0;j<xctx->instances;j++)
{
if( strcmp(get_tok_value(xctx->inst[j].prop_ptr,"verilog_ignore",0),"true")==0 ) continue;
if(xctx->inst[j].ptr<0) continue;
if(!strcmp(get_tok_value( (xctx->inst[j].ptr+ xctx->sym)->prop_ptr, "verilog_ignore",0 ), "true") ) {
continue;
}
my_strdup(544, &type,(xctx->inst[j].ptr+ xctx->sym)->type);
if( type && ( strcmp(type,"timescale")==0 || strcmp(type,"verilog_preprocessor")==0) )
{
str_tmp = get_tok_value( (xctx->inst[j].ptr+ xctx->sym)->prop_ptr, fmt_attr, 2);
my_strdup(545, &tmp_string, str_tmp);
fprintf(fd, "%s\n", str_tmp ? translate(j, tmp_string) : "(NULL)");
}
}
fprintf(fd, "module %s (\n", skip_dir(xctx->sym[i].name));
/*print_generic(fd, "entity", i); */
dbg(1, "verilog_block_netlist(): entity ports\n");
/* print ports directions */
tmp=0;
for(j=0;j<xctx->sym[i].rects[PINLAYER];j++)
{
if(strcmp(get_tok_value(xctx->sym[i].rect[PINLAYER][j].prop_ptr,"verilog_ignore",0), "true")) {
str_tmp = get_tok_value(xctx->sym[i].rect[PINLAYER][j].prop_ptr,"name",0);
if(tmp) fprintf(fd, " ,\n");
tmp++;
fprintf(fd," %s", str_tmp ? str_tmp : "<NULL>");
sym_def = get_tok_value(xctx->sym[i].prop_ptr,"verilog_sym_def",0);
if(sym_def[0]) {
fprintf(fd, "%s\n", sym_def);
} else {
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 */
fmt_attr = xctx->format ? xctx->format : "verilog_format";
for(j=0;j<xctx->instances;j++)
{
if( strcmp(get_tok_value(xctx->inst[j].prop_ptr,"verilog_ignore",0),"true")==0 ) continue;
if(xctx->inst[j].ptr<0) continue;
if(!strcmp(get_tok_value( (xctx->inst[j].ptr+ xctx->sym)->prop_ptr, "verilog_ignore",0 ), "true") ) {
continue;
}
my_strdup(544, &type,(xctx->inst[j].ptr+ xctx->sym)->type);
if( type && ( strcmp(type,"timescale")==0 || strcmp(type,"verilog_preprocessor")==0) )
{
str_tmp = get_tok_value( (xctx->inst[j].ptr+ xctx->sym)->prop_ptr, fmt_attr, 2);
my_strdup(545, &tmp_string, str_tmp);
fprintf(fd, "%s\n", str_tmp ? translate(j, tmp_string) : "(NULL)");
}
}
}
fprintf(fd, "\n);\n");
dbg(1, "verilog_block_netlist(): entity generics\n");
/* print module default parameters */
print_verilog_param(fd,i);
/* print port types */
tmp=0;
for(j=0;j<xctx->sym[i].rects[PINLAYER];j++)
{
if(strcmp(get_tok_value(xctx->sym[i].rect[PINLAYER][j].prop_ptr,"verilog_ignore",0), "true")) {
my_strdup(564, &sig_type,get_tok_value(
xctx->sym[i].rect[PINLAYER][j].prop_ptr,"verilog_type",0));
my_strdup(565, &port_value,
get_tok_value(xctx->sym[i].rect[PINLAYER][j].prop_ptr,"value", 0) );
my_strdup(566, &dir_tmp, get_tok_value(xctx->sym[i].rect[PINLAYER][j].prop_ptr,"dir",0) );
if(strcmp(dir_tmp,"in")){
if(!sig_type || sig_type[0]=='\0') my_strdup(567, &sig_type,"wire"); /* 20070720 changed reg to wire */
} else {
if(!sig_type || sig_type[0]=='\0') my_strdup(568, &sig_type,"wire");
fprintf(fd, "module %s (\n", skip_dir(xctx->sym[i].name));
/*print_generic(fd, "entity", i); */
dbg(1, "verilog_block_netlist(): entity ports\n");
/* print ports directions */
tmp=0;
for(j=0;j<xctx->sym[i].rects[PINLAYER];j++)
{
if(strcmp(get_tok_value(xctx->sym[i].rect[PINLAYER][j].prop_ptr,"verilog_ignore",0), "true")) {
str_tmp = get_tok_value(xctx->sym[i].rect[PINLAYER][j].prop_ptr,"name",0);
if(tmp) fprintf(fd, " ,\n");
tmp++;
fprintf(fd," %s", str_tmp ? str_tmp : "<NULL>");
}
str_tmp = get_tok_value(xctx->sym[i].rect[PINLAYER][j].prop_ptr,"name",0);
fprintf(fd," %s %s ;\n",
strcmp(dir_tmp,"in")? ( strcmp(dir_tmp,"out")? "inout" :"output" ) : "input",
str_tmp ? str_tmp : "<NULL>");
fprintf(fd," %s %s",
sig_type,
str_tmp ? str_tmp : "<NULL>");
if(port_value &&port_value[0])
fprintf(fd," = %s", port_value);
fprintf(fd," ;\n");
}
}
dbg(1, "verilog_block_netlist(): netlisting %s\n", skip_dir( xctx->sch[xctx->currsch]));
verilog_netlist(fd, verilog_stop);
xctx->netlist_count++;
fprintf(fd,"---- begin user architecture code\n");
for(l=0;l<xctx->instances;l++) {
if( strcmp(get_tok_value(xctx->inst[l].prop_ptr,"verilog_ignore",0),"true")==0 ) continue;
if(xctx->inst[l].ptr<0) continue;
if(!strcmp(get_tok_value( (xctx->inst[l].ptr+ xctx->sym)->prop_ptr, "verilog_ignore",0 ), "true") ) {
continue;
fprintf(fd, "\n);\n");
dbg(1, "verilog_block_netlist(): entity generics\n");
/* print module default parameters */
print_verilog_param(fd,i);
/* print port types */
tmp=0;
for(j=0;j<xctx->sym[i].rects[PINLAYER];j++)
{
if(strcmp(get_tok_value(xctx->sym[i].rect[PINLAYER][j].prop_ptr,"verilog_ignore",0), "true")) {
my_strdup(564, &sig_type,get_tok_value(
xctx->sym[i].rect[PINLAYER][j].prop_ptr,"verilog_type",0));
my_strdup(565, &port_value,
get_tok_value(xctx->sym[i].rect[PINLAYER][j].prop_ptr,"value", 0) );
my_strdup(566, &dir_tmp, get_tok_value(xctx->sym[i].rect[PINLAYER][j].prop_ptr,"dir",0) );
if(strcmp(dir_tmp,"in")){
if(!sig_type || sig_type[0]=='\0') my_strdup(567, &sig_type,"wire"); /* 20070720 changed reg to wire */
} else {
if(!sig_type || sig_type[0]=='\0') my_strdup(568, &sig_type,"wire");
}
str_tmp = get_tok_value(xctx->sym[i].rect[PINLAYER][j].prop_ptr,"name",0);
fprintf(fd," %s %s ;\n",
strcmp(dir_tmp,"in")? ( strcmp(dir_tmp,"out")? "inout" :"output" ) : "input",
str_tmp ? str_tmp : "<NULL>");
fprintf(fd," %s %s",
sig_type,
str_tmp ? str_tmp : "<NULL>");
if(port_value &&port_value[0])
fprintf(fd," = %s", port_value);
fprintf(fd," ;\n");
}
}
if(xctx->netlist_count &&
!strcmp(get_tok_value(xctx->inst[l].prop_ptr, "only_toplevel", 0), "true")) continue;
my_strdup(569, &type,(xctx->inst[l].ptr+ xctx->sym)->type);
if(type && !strcmp(type,"netlist_commands")) {
fprintf(fd, "%s\n", get_tok_value(xctx->inst[l].prop_ptr,"value", 0));
dbg(1, "verilog_block_netlist(): netlisting %s\n", skip_dir( xctx->sch[xctx->currsch]));
verilog_netlist(fd, verilog_stop);
fprintf(fd,"---- begin user architecture code\n");
for(l=0;l<xctx->instances;l++) {
if( strcmp(get_tok_value(xctx->inst[l].prop_ptr,"verilog_ignore",0),"true")==0 ) continue;
if(xctx->inst[l].ptr<0) continue;
if(!strcmp(get_tok_value( (xctx->inst[l].ptr+ xctx->sym)->prop_ptr, "verilog_ignore",0 ), "true") ) {
continue;
}
if(xctx->netlist_count &&
!strcmp(get_tok_value(xctx->inst[l].prop_ptr, "only_toplevel", 0), "true")) continue;
my_strdup(569, &type,(xctx->inst[l].ptr+ xctx->sym)->type);
if(type && !strcmp(type,"netlist_commands")) {
fprintf(fd, "%s\n", get_tok_value(xctx->inst[l].prop_ptr,"value", 0));
}
}
}
if(xctx->schverilogprop && xctx->schverilogprop[0]) {
fprintf(fd, "%s\n", xctx->schverilogprop);
}
fprintf(fd,"---- end user architecture code\n");
fprintf(fd, "endmodule\n");
if(xctx->schverilogprop && xctx->schverilogprop[0]) {
fprintf(fd, "%s\n", xctx->schverilogprop);
}
fprintf(fd,"---- end user architecture code\n");
fprintf(fd, "endmodule\n");
my_free(1079, &dir_tmp);
my_free(1080, &sig_type);
my_free(1081, &port_value);
my_free(1082, &type);
my_free(1083, &tmp_string);
} /* if(!sym_def[0]) */
if(split_f) {
int save;
fclose(fd);
@ -554,10 +558,6 @@ void verilog_block_netlist(FILE *fd, int i)
set_tcl_netlist_type();
if(debug_var==0) xunlink(netl_filename);
}
my_free(1079, &dir_tmp);
my_free(1080, &sig_type);
my_free(1081, &port_value);
my_free(1082, &type);
my_free(1083, &tmp_string);
xctx->netlist_count++;
}

View File

@ -515,6 +515,7 @@ void vhdl_block_netlist(FILE *fd, int i)
char *abs_path = NULL;
const char *str_tmp;
int split_f;
const char *sym_def;
split_f = tclgetboolvar("split_files");
if(!strcmp( get_tok_value(xctx->sym[i].prop_ptr,"vhdl_stop",0),"true") )
@ -534,170 +535,175 @@ void vhdl_block_netlist(FILE *fd, int i)
fprintf(fd, "\n-- expanding symbol: %s # of pins=%d\n",
xctx->sym[i].name,xctx->sym[i].rects[PINLAYER] );
fprintf(fd, "-- sym_path: %s\n", abs_sym_path(xctx->sym[i].name, ""));
fprintf(fd, "-- sch_path: %s\n", filename);
load_schematic(1,filename, 0);
dbg(1, "vhdl_block_netlist(): packages\n");
for(l=0;l<xctx->instances;l++)
{
if(!(xctx->inst[l].ptr+ xctx->sym)->type) continue;
if( strcmp(get_tok_value(xctx->inst[l].prop_ptr,"vhdl_ignore",0),"true")==0 ) continue;
if(xctx->inst[l].ptr<0) continue;
if(!strcmp(get_tok_value( (xctx->inst[l].ptr+ xctx->sym)->prop_ptr, "vhdl_ignore",0 ), "true") ) {
continue;
}
if( !strcmp((xctx->inst[l].ptr+ xctx->sym)->type, "package") )
fprintf(fd, "%s\n", xctx->inst[l].prop_ptr);
}
dbg(1, "vhdl_block_netlist(): use statements\n");
for(l=0;l<xctx->instances;l++)
{
if( strcmp(get_tok_value(xctx->inst[l].prop_ptr,"vhdl_ignore",0),"true")==0 ) continue;
if(xctx->inst[l].ptr<0) continue;
if(!(xctx->inst[l].ptr+ xctx->sym)->type) continue;
if(!strcmp(get_tok_value( (xctx->inst[l].ptr+ xctx->sym)->prop_ptr, "vhdl_ignore",0 ), "true") ) {
continue;
}
if( !strcmp((xctx->inst[l].ptr+ xctx->sym)->type, "use") )
fprintf(fd, "%s\n", xctx->inst[l].prop_ptr);
}
dbg(1, "vhdl_block_netlist(): entity generics\n");
/* print entity generics */
print_generic(fd, "entity", i);
dbg(1, "vhdl_block_netlist(): entity ports\n");
/* print entity ports */
tmp=0;
for(j=0;j<xctx->sym[i].rects[PINLAYER];j++)
{
if(strcmp(get_tok_value(xctx->sym[i].rect[PINLAYER][j].prop_ptr,"vhdl_ignore",0), "true")) {
my_strdup(592, &sig_type,
get_tok_value(xctx->sym[i].rect[PINLAYER][j].prop_ptr,"sig_type",0));
my_strdup(593, &port_value,
get_tok_value(xctx->sym[i].rect[PINLAYER][j].prop_ptr,"value", 0) );
if(!sig_type || sig_type[0]=='\0') my_strdup(594, &sig_type,"std_logic");
my_strdup(595, &dir_tmp, get_tok_value(xctx->sym[i].rect[PINLAYER][j].prop_ptr,"dir",0) );
str_tmp = get_tok_value(xctx->sym[i].rect[PINLAYER][j].prop_ptr,"name",0);
if(tmp) fprintf(fd, " ;\n");
if(!tmp) fprintf(fd,"port (\n");
fprintf(fd," %s : %s %s",str_tmp ? str_tmp : "<NULL>",
dir_tmp ? dir_tmp : "<NULL>", sig_type);
my_free(1092, &dir_tmp);
if(port_value &&port_value[0])
fprintf(fd," := %s", port_value);
tmp=1;
}
}
if(tmp) fprintf(fd, "\n);\n");
dbg(1, "vhdl_block_netlist(): port attributes\n");
for(l=0;l<xctx->instances;l++)
{
if( strcmp(get_tok_value(xctx->inst[l].prop_ptr,"vhdl_ignore",0),"true")==0 ) continue;
if(xctx->inst[l].ptr<0) continue;
if(!strcmp(get_tok_value( (xctx->inst[l].ptr+ xctx->sym)->prop_ptr, "vhdl_ignore",0 ), "true") ) {
continue;
}
my_strdup(596, &type,(xctx->inst[l].ptr+ xctx->sym)->type);
if( type && (strcmp(type,"port_attributes"))==0)
{
if(xctx->inst[l].prop_ptr) fprintf(fd, "%s\n", xctx->inst[l].prop_ptr);
}
}
fprintf(fd,"end %s ;\n\n", skip_dir(xctx->sym[i].name) );
dbg(1, "vhdl_block_netlist(): architecture\n");
fprintf(fd,"architecture arch_%s of %s is\n\n",
skip_dir(xctx->sym[i].name), skip_dir(xctx->sym[i].name) );
/* skip_dir( xctx->sch[xctx->currsch]), skip_dir( xctx->sch[xctx->currsch])); */
/* load current schematic to print used components */
dbg(1, "vhdl_block_netlist(): used components\n");
/* print all components */
if(!vhdl_stop) {
for(j=0;j<xctx->symbols;j++)
sym_def = get_tok_value(xctx->sym[i].prop_ptr,"vhdl_sym_def",0);
if(sym_def[0]) {
fprintf(fd, "%s\n", sym_def);
} else {
fprintf(fd, "-- sch_path: %s\n", filename);
load_schematic(1,filename, 0);
dbg(1, "vhdl_block_netlist(): packages\n");
for(l=0;l<xctx->instances;l++)
{
if( strcmp(get_tok_value(xctx->sym[j].prop_ptr,"vhdl_primitive",0),"true")==0 ) continue;
if(!xctx->sym[j].type || (strcmp(xctx->sym[j].type,"primitive")!=0 &&
strcmp(xctx->sym[j].type,"subcircuit")!=0))
continue;
my_strdup2(1238, &abs_path, abs_sym_path(xctx->sym[i].name, ""));
if(( strcmp(xctx->sym[j].type,"subcircuit")==0 || strcmp(xctx->sym[j].type,"primitive")==0) &&
check_lib(1, abs_path)
) {
/* only print component declaration if used in current subcircuit */
found=0;
for(l=0;l<xctx->instances;l++)
{
if( strcmp(get_tok_value(xctx->inst[l].prop_ptr,"vhdl_ignore",0),"true")==0 ) continue;
if(xctx->inst[l].ptr<0) continue;
if(!strcmp(get_tok_value( (xctx->inst[l].ptr+ xctx->sym)->prop_ptr, "vhdl_ignore",0 ), "true") ) {
continue;
}
if(!xctx->x_strcmp(xctx->sym[j].name,xctx->inst[l].name))
{
found=1; break;
}
}
if(!found) continue;
/* component generics */
print_generic(fd, "component",j);
if(!(xctx->inst[l].ptr+ xctx->sym)->type) continue;
if( strcmp(get_tok_value(xctx->inst[l].prop_ptr,"vhdl_ignore",0),"true")==0 ) continue;
if(xctx->inst[l].ptr<0) continue;
if(!strcmp(get_tok_value( (xctx->inst[l].ptr+ xctx->sym)->prop_ptr, "vhdl_ignore",0 ), "true") ) {
continue;
}
if( !strcmp((xctx->inst[l].ptr+ xctx->sym)->type, "package") )
fprintf(fd, "%s\n", xctx->inst[l].prop_ptr);
}
/* component ports */
tmp=0;
for(k=0;k<xctx->sym[j].rects[PINLAYER];k++)
{
if(strcmp(get_tok_value(xctx->sym[j].rect[PINLAYER][k].prop_ptr,"vhdl_ignore",0), "true")) {
my_strdup(597, &sig_type,get_tok_value(
xctx->sym[j].rect[PINLAYER][k].prop_ptr,"sig_type",0));
my_strdup(598, &port_value,
get_tok_value(xctx->sym[j].rect[PINLAYER][k].prop_ptr,"value", 0) );
if(!sig_type || sig_type[0]=='\0') my_strdup(599, &sig_type,"std_logic");
my_strdup(600, &dir_tmp, get_tok_value(xctx->sym[j].rect[PINLAYER][k].prop_ptr,"dir",0) );
str_tmp = get_tok_value(xctx->sym[j].rect[PINLAYER][k].prop_ptr,"name",0);
if(!tmp) fprintf(fd, "port (\n");
if(tmp) fprintf(fd, " ;\n");
fprintf(fd," %s : %s %s",str_tmp ? str_tmp : "<NULL>",
dir_tmp ? dir_tmp : "<NULL>", sig_type);
my_free(1093, &dir_tmp);
if(port_value &&port_value[0])
fprintf(fd," := %s", port_value);
tmp=1;
}
}
if(tmp) fprintf(fd, "\n);\n");
fprintf(fd, "end component ;\n\n");
dbg(1, "vhdl_block_netlist(): use statements\n");
for(l=0;l<xctx->instances;l++)
{
if( strcmp(get_tok_value(xctx->inst[l].prop_ptr,"vhdl_ignore",0),"true")==0 ) continue;
if(xctx->inst[l].ptr<0) continue;
if(!(xctx->inst[l].ptr+ xctx->sym)->type) continue;
if(!strcmp(get_tok_value( (xctx->inst[l].ptr+ xctx->sym)->prop_ptr, "vhdl_ignore",0 ), "true") ) {
continue;
}
if( !strcmp((xctx->inst[l].ptr+ xctx->sym)->type, "use") )
fprintf(fd, "%s\n", xctx->inst[l].prop_ptr);
}
dbg(1, "vhdl_block_netlist(): entity generics\n");
/* print entity generics */
print_generic(fd, "entity", i);
dbg(1, "vhdl_block_netlist(): entity ports\n");
/* print entity ports */
tmp=0;
for(j=0;j<xctx->sym[i].rects[PINLAYER];j++)
{
if(strcmp(get_tok_value(xctx->sym[i].rect[PINLAYER][j].prop_ptr,"vhdl_ignore",0), "true")) {
my_strdup(592, &sig_type,
get_tok_value(xctx->sym[i].rect[PINLAYER][j].prop_ptr,"sig_type",0));
my_strdup(593, &port_value,
get_tok_value(xctx->sym[i].rect[PINLAYER][j].prop_ptr,"value", 0) );
if(!sig_type || sig_type[0]=='\0') my_strdup(594, &sig_type,"std_logic");
my_strdup(595, &dir_tmp, get_tok_value(xctx->sym[i].rect[PINLAYER][j].prop_ptr,"dir",0) );
str_tmp = get_tok_value(xctx->sym[i].rect[PINLAYER][j].prop_ptr,"name",0);
if(tmp) fprintf(fd, " ;\n");
if(!tmp) fprintf(fd,"port (\n");
fprintf(fd," %s : %s %s",str_tmp ? str_tmp : "<NULL>",
dir_tmp ? dir_tmp : "<NULL>", sig_type);
my_free(1092, &dir_tmp);
if(port_value &&port_value[0])
fprintf(fd," := %s", port_value);
tmp=1;
}
} /* for(j...) */
} /* if(!vhdl_stop) */
my_free(1239, &abs_path);
dbg(1, "vhdl_block_netlist(): netlisting %s\n", skip_dir( xctx->sch[xctx->currsch]));
vhdl_netlist(fd, vhdl_stop);
fprintf(fd,"//// begin user architecture code\n");
for(l=0;l<xctx->instances;l++) {
if( strcmp(get_tok_value(xctx->inst[l].prop_ptr,"vhdl_ignore",0),"true")==0 ) continue;
if(xctx->inst[l].ptr<0) continue;
if(!strcmp(get_tok_value( (xctx->inst[l].ptr+ xctx->sym)->prop_ptr, "vhdl_ignore",0 ), "true") ) {
continue;
}
if(xctx->netlist_count &&
!strcmp(get_tok_value(xctx->inst[l].prop_ptr, "only_toplevel", 0), "true")) continue;
my_strdup(601, &type,(xctx->inst[l].ptr+ xctx->sym)->type);
if(type && !strcmp(type,"netlist_commands")) {
fprintf(fd, "%s\n", get_tok_value(xctx->inst[l].prop_ptr,"value", 0));
if(tmp) fprintf(fd, "\n);\n");
dbg(1, "vhdl_block_netlist(): port attributes\n");
for(l=0;l<xctx->instances;l++)
{
if( strcmp(get_tok_value(xctx->inst[l].prop_ptr,"vhdl_ignore",0),"true")==0 ) continue;
if(xctx->inst[l].ptr<0) continue;
if(!strcmp(get_tok_value( (xctx->inst[l].ptr+ xctx->sym)->prop_ptr, "vhdl_ignore",0 ), "true") ) {
continue;
}
my_strdup(596, &type,(xctx->inst[l].ptr+ xctx->sym)->type);
if( type && (strcmp(type,"port_attributes"))==0)
{
if(xctx->inst[l].prop_ptr) fprintf(fd, "%s\n", xctx->inst[l].prop_ptr);
}
}
}
if(xctx->schvhdlprop && xctx->schvhdlprop[0]) fprintf(fd, "%s\n", xctx->schvhdlprop);
fprintf(fd, "end arch_%s ;\n\n", skip_dir(xctx->sym[i].name) ); /* skip_dir( xctx->sch[xctx->currsch]) ); */
fprintf(fd,"end %s ;\n\n", skip_dir(xctx->sym[i].name) );
dbg(1, "vhdl_block_netlist(): architecture\n");
fprintf(fd,"architecture arch_%s of %s is\n\n",
skip_dir(xctx->sym[i].name), skip_dir(xctx->sym[i].name) );
/* skip_dir( xctx->sch[xctx->currsch]), skip_dir( xctx->sch[xctx->currsch])); */
/* load current schematic to print used components */
dbg(1, "vhdl_block_netlist(): used components\n");
/* print all components */
if(!vhdl_stop) {
for(j=0;j<xctx->symbols;j++)
{
if( strcmp(get_tok_value(xctx->sym[j].prop_ptr,"vhdl_primitive",0),"true")==0 ) continue;
if(!xctx->sym[j].type || (strcmp(xctx->sym[j].type,"primitive")!=0 &&
strcmp(xctx->sym[j].type,"subcircuit")!=0))
continue;
my_strdup2(1238, &abs_path, abs_sym_path(xctx->sym[i].name, ""));
if(( strcmp(xctx->sym[j].type,"subcircuit")==0 || strcmp(xctx->sym[j].type,"primitive")==0) &&
check_lib(1, abs_path)
) {
/* only print component declaration if used in current subcircuit */
found=0;
for(l=0;l<xctx->instances;l++)
{
if( strcmp(get_tok_value(xctx->inst[l].prop_ptr,"vhdl_ignore",0),"true")==0 ) continue;
if(xctx->inst[l].ptr<0) continue;
if(!strcmp(get_tok_value( (xctx->inst[l].ptr+ xctx->sym)->prop_ptr, "vhdl_ignore",0 ), "true") ) {
continue;
}
if(!xctx->x_strcmp(xctx->sym[j].name,xctx->inst[l].name))
{
found=1; break;
}
}
if(!found) continue;
/* component generics */
print_generic(fd, "component",j);
/* component ports */
tmp=0;
for(k=0;k<xctx->sym[j].rects[PINLAYER];k++)
{
if(strcmp(get_tok_value(xctx->sym[j].rect[PINLAYER][k].prop_ptr,"vhdl_ignore",0), "true")) {
my_strdup(597, &sig_type,get_tok_value(
xctx->sym[j].rect[PINLAYER][k].prop_ptr,"sig_type",0));
my_strdup(598, &port_value,
get_tok_value(xctx->sym[j].rect[PINLAYER][k].prop_ptr,"value", 0) );
if(!sig_type || sig_type[0]=='\0') my_strdup(599, &sig_type,"std_logic");
my_strdup(600, &dir_tmp, get_tok_value(xctx->sym[j].rect[PINLAYER][k].prop_ptr,"dir",0) );
str_tmp = get_tok_value(xctx->sym[j].rect[PINLAYER][k].prop_ptr,"name",0);
if(!tmp) fprintf(fd, "port (\n");
if(tmp) fprintf(fd, " ;\n");
fprintf(fd," %s : %s %s",str_tmp ? str_tmp : "<NULL>",
dir_tmp ? dir_tmp : "<NULL>", sig_type);
my_free(1093, &dir_tmp);
if(port_value &&port_value[0])
fprintf(fd," := %s", port_value);
tmp=1;
}
}
if(tmp) fprintf(fd, "\n);\n");
fprintf(fd, "end component ;\n\n");
}
} /* for(j...) */
} /* if(!vhdl_stop) */
my_free(1239, &abs_path);
dbg(1, "vhdl_block_netlist(): netlisting %s\n", skip_dir( xctx->sch[xctx->currsch]));
vhdl_netlist(fd, vhdl_stop);
fprintf(fd,"//// begin user architecture code\n");
for(l=0;l<xctx->instances;l++) {
if( strcmp(get_tok_value(xctx->inst[l].prop_ptr,"vhdl_ignore",0),"true")==0 ) continue;
if(xctx->inst[l].ptr<0) continue;
if(!strcmp(get_tok_value( (xctx->inst[l].ptr+ xctx->sym)->prop_ptr, "vhdl_ignore",0 ), "true") ) {
continue;
}
if(xctx->netlist_count &&
!strcmp(get_tok_value(xctx->inst[l].prop_ptr, "only_toplevel", 0), "true")) continue;
my_strdup(601, &type,(xctx->inst[l].ptr+ xctx->sym)->type);
if(type && !strcmp(type,"netlist_commands")) {
fprintf(fd, "%s\n", get_tok_value(xctx->inst[l].prop_ptr,"value", 0));
}
}
if(xctx->schvhdlprop && xctx->schvhdlprop[0]) fprintf(fd, "%s\n", xctx->schvhdlprop);
fprintf(fd, "end arch_%s ;\n\n", skip_dir(xctx->sym[i].name) ); /* skip_dir( xctx->sch[xctx->currsch]) ); */
my_free(1094, &sig_type);
my_free(1095, &port_value);
my_free(1096, &type);
} /* if(!sym_def[0]) */
if(split_f) {
int save;
fclose(fd);
@ -711,8 +717,5 @@ void vhdl_block_netlist(FILE *fd, int i)
if(debug_var==0) xunlink(netl_filename);
}
xctx->netlist_count++;
my_free(1094, &sig_type);
my_free(1095, &port_value);
my_free(1096, &type);
}

View File

@ -191,7 +191,7 @@ proc netlist_test {} {
global netlist_dir
foreach {f t h} {
rom8k.sch spice 2922365852
greycnt.sch verilog 3378316826
greycnt.sch verilog 3822198138
autozero_comp.sch spice 2275498269
loading.sch vhdl 584526899
mos_power_ampli.sch spice 1004049459