Browse Source

Do not generate netlist lines that use non-existent libraries.

To support that, give global scope to  function inp_pathresolve()
in inpcom.c.  Update internal documentation (long comment).
pre-master-46
Giles Atkinson 3 years ago
committed by Holger Vogt
parent
commit
5aa48cab0b
  1. 3
      src/frontend/inpcom.c
  2. 2
      src/frontend/inpcom.h
  3. 113
      src/xspice/evt/evtcheck_nodes.c

3
src/frontend/inpcom.c

@ -169,7 +169,6 @@ static void inp_check_syntax(struct card *deck);
static char *inp_spawn_brace(char *s);
static char *inp_pathresolve(const char *name);
static char *inp_pathresolve_at(const char *name, const char *dir);
char *search_plain_identifier(char *str, const char *identifier);
@ -1756,7 +1755,7 @@ FILE *inp_pathopen(const char *name, const char *mode)
if the file isn't in . and it isn't an abs path name.
*-------------------------------------------------------------------------*/
static char *inp_pathresolve(const char *name)
char *inp_pathresolve(const char *name)
{
struct variable *v;
struct stat st;

2
src/frontend/inpcom.h

@ -8,5 +8,5 @@
struct card *insert_new_line(struct card *card, char *line,
int linenum, int linenum_orig);
char *inp_pathresolve(const char *name);
#endif

113
src/xspice/evt/evtcheck_nodes.c

@ -32,7 +32,7 @@
When using XSPICE to simulate digital devices in a mixed-mode simulation,
bridging devices must be included in the circuit to pass signals between the
analogue simulator and XSPICE. Such devices may be included in the netlist,
or they may can be inserted automatically. Different types of automatic
or they can be inserted automatically. Different types of automatic
bridge may exist in the same circuit, depending on signal direction and
characteristics of the connected device, for example digital devices
powered by differing voltages. Non-digital XSPICE nodes are supported.
@ -95,21 +95,26 @@ for device libraries whose devices are defined by subcircuits.
the enclosing subcircuits for a definition of the parameter.
If found, set vcc from the parameter.
3: If a command interpreter variable "no_auto_bridge_family": exists, go to
step 5. Search the connected device instances for a parameter,
"family" with a string value. The first one found will be used.
If the first character of the value is not '*', the setup card will
be ".include bridge_FFFFF_DDD.cir" where FFFFF is the family and
DDD is the signal direction for the XSPICE device: "in", "out" or
"inout". The device card will be "Xauto_bridge%d %s %s
bridge_FFFFF_DDD vcc=%g", so a suitably parameterised subcircuit
must be defined in the included file.
4: If the first character of "family" was '*', look for a variable
"auto_bridge_FFFFF_TTTT_DDD" where FFFFF is the family without '*',
TTTT is the node type string and DDD is the direction. So this might be
"auto_bridge_74HCT_d_inout" for a digital node. Use the variable's value
as in step 6, proceeding to step 5 if checks fail.
3: If a command interpreter variable "no_auto_bridge_family": exists,
go to step 5. Search the connected XSPICE device instances for a
parameter, "family" with a string value. The first one found will
be used. If no such instance exists, search for a string-valued
parameter, "family", in enclosing subcircuits, as in step 2. If
the first character of the value is not '*', the setup card may be
".include bridge_FFFFF_TTTT_DDD.subcir" where FFFFF is the family,
TTTT is as before and DDD is the signal direction for the XSPICE
device: "in", "out" or "inout". This form will be used only when
the required file can be found. In that case, the device card will
be "Xauto_bridge%d %s %s bridge_FFFFF_TTTT_DDD vcc=%g", so a
suitably parameterised subcircuit must be defined in the included
file.
4: If the first character of "family" was '*', or no file was found,
look for a variable "auto_bridge_FFFFF_TTTT_DDD" where FFFFF is the
family without '*', TTTT is the node type string and DDD is the
direction. So this might be "auto_bridge_74HCT_d_inout" for a
digital node. Use the variable's value as in step 6, proceeding to
step 5 if checks fail.
5: Look for a variable "auto_bridge_TTTT_DDD" where TTTT and DDD are as before.
@ -160,7 +165,7 @@ for device libraries whose devices are defined by subcircuits.
and invoked by:
set auto_bridge_d_out_30 = ( ".include test_sub.cir"
set auto_bridge_d_out = ( ".include test_sub.subcir"
+ "xauto_buf%d %s %s auto_buf vcc=%g"
+ 1 )
*/
@ -195,10 +200,15 @@ static struct card *expand_deck(struct card *head)
struct card *card, *next;
char **pointers;
int i, dico;
bool save_debug;
/* Save the current parameter symbol table. */
/* Save the current parameter symbol table and debug global.
* Prevent overwriting of debug output in inp_readall().
*/
dico = nupa_add_dicoslist();
save_debug = ft_ngdebug;
ft_ngdebug = FALSE;
/* Count the cards, allocate and fill a pointer array. */
@ -221,6 +231,7 @@ static struct card *expand_deck(struct card *head)
circarray = pointers;
card = inp_readall(NULL, Infile_Path, FALSE, TRUE, NULL);
card = inp_subcktexpand(card);
ft_ngdebug = save_debug;
/* Destroy the parameter table that was created in subcircuit/parameter
* expansion and restore the previous version.
@ -479,8 +490,8 @@ static struct bridge *find_bridge(Evt_Node_Info_t *event_node,
family = NULL;
deep = scan_devices(event_node, ckt, &family);
/* Look for a real parameter (.param type) in the device's subcircuit
* and those enclosing it.
/* Look for a real parameter (.param type) and perhaps a string-valued
* "family" parameter in the device's subcircuit and those enclosing it.
*/
snprintf(buff, sizeof buff, "%s", deep);
@ -490,7 +501,11 @@ static struct bridge *find_bridge(Evt_Node_Info_t *event_node,
snprintf(dot + 1, sizeof buff - (size_t)(dot - buff), "%s", vcc_parm);
vcc = nupa_get_param(buff, &ok);
}
if (ok)
if (!family) {
snprintf(dot + 1, sizeof buff - (size_t)(dot - buff), "family");
family = nupa_get_string_param(buff);
}
if (ok && family)
break;
*dot = '\0';
dot = strrchr(buff, '.');
@ -506,12 +521,29 @@ static struct bridge *find_bridge(Evt_Node_Info_t *event_node,
}
}
if (!family)
family = nupa_get_string_param("family");
if (family && cp_getvar("no_auto_bridge_family", CP_BOOL, NULL, 0))
family = NULL;
if (family && *family == '*') {
s_family = family + 1;
family = NULL; // Not used for matching.
if (family) {
if (*family == '*') {
s_family = family + 1; // Use variable look-up.
} else {
char *fam_inc_path;
/* Check if an include file exists for the family. */
snprintf(buff, sizeof buff, "bridge_%s_%s_%s.subcir",
family, type_name, dirs[direction]);
fam_inc_path = inp_pathresolve(buff);
if (fam_inc_path) {
tfree(fam_inc_path);
s_family = NULL;
} else {
s_family = family; // Use variable look-up.
}
}
} else {
s_family = NULL;
}
@ -523,10 +555,19 @@ static struct bridge *find_bridge(Evt_Node_Info_t *event_node,
bridge->direction == direction) {
if (family) {
if (!strcmp(family, bridge->family)) {
/* Return vcc for formatting: requires bridge->max == 1. */
if (!s_family && bridge->max == 1) {
/* Set bridge vcc for formatting. */
bridge->vcc = vcc;
break;
} else {
/* Using cards from variable, or shared sub-circuit:
* vcc must also match.
*/
if (bridge->vcc == vcc)
break;
}
}
} else if (bridge->vcc == vcc) { // Match vcc.
break;
@ -538,23 +579,23 @@ static struct bridge *find_bridge(Evt_Node_Info_t *event_node,
/* Determine if a bridging element exists, starting with the node type. */
if (family) {
if (s_family) {
/* Family variable lookup. */
snprintf(buff, sizeof buff, "auto_bridge_%s_%s_%s",
s_family, type_name, dirs[direction]);
cp_getvar(buff, CP_LIST, &cvar, sizeof cvar);
} else if (family) {
/* Use standard pattern for known parts family. */
snprintf(buff, sizeof buff, ".include bridge_%s_%s.cir",
family, dirs[direction]);
snprintf(buff, sizeof buff, ".include bridge_%s_%s_%s.subcir",
family, type_name, dirs[direction]);
setup = copy(buff);
snprintf(buff, sizeof buff,
"Xauto_bridge%%d %%s %%s bridge_%s_%s vcc=%%g",
family, dirs[direction]);
"Xauto_bridge%%d %%s %%s bridge_%s_%s_%s vcc=%%g",
family, type_name, dirs[direction]);
format = copy(buff);
max = 1;
} else if (s_family) {
/* Family variable lookup. */
snprintf(buff, sizeof buff, "auto_bridge_%s_%s_%s",
s_family, type_name, dirs[direction]);
cp_getvar(buff, CP_LIST, &cvar, sizeof cvar);
}
if (!format && !cvar) {

Loading…
Cancel
Save