Merge branch 'pre-master-45' into bt_dev
This commit is contained in:
commit
91f20af48f
|
|
@ -1283,6 +1283,13 @@ struct card *inp_readall(FILE *fp, const char *dir_name, const char* file_name,
|
|||
return cc;
|
||||
}
|
||||
|
||||
static char *skip_token(char *s)
|
||||
{
|
||||
s = skip_ws(s); /* Advance past space chars. */
|
||||
s = skip_non_ws(s); /* Skip over token. */
|
||||
return skip_ws(s);
|
||||
}
|
||||
|
||||
|
||||
static struct inp_read_t inp_read(FILE* fp, int call_depth, const char* dir_name,
|
||||
const char* file_name, bool comfile, bool intfile)
|
||||
|
|
@ -1420,8 +1427,8 @@ static struct inp_read_t inp_read(FILE* fp, int call_depth, const char* dir_name
|
|||
/* now handle .title statement */
|
||||
if (ciprefix(".title", buffer)) {
|
||||
char* s;
|
||||
s = skip_non_ws(buffer); /* skip over .title */
|
||||
s = skip_ws(s); /* advance past space chars */
|
||||
|
||||
s = skip_token(buffer);
|
||||
|
||||
/* only the last title line remains valid */
|
||||
tfree(new_title);
|
||||
|
|
@ -2800,13 +2807,11 @@ static void inp_fix_macro_param_func_paren_io(struct card *card)
|
|||
|
||||
if (ciprefix(".subckt", card->line) || ciprefix("x", card->line)) {
|
||||
/* remove () */
|
||||
str_ptr = skip_non_ws(card->line);
|
||||
// skip over .subckt, instance name
|
||||
str_ptr = skip_ws(str_ptr);
|
||||
if (ciprefix(".subckt", card->line)) {
|
||||
str_ptr = skip_non_ws(str_ptr); // skip over subckt name
|
||||
str_ptr = skip_ws(str_ptr);
|
||||
}
|
||||
|
||||
str_ptr = skip_token(card->line); // Skip over .subckt.
|
||||
if (ciprefix(".subckt", card->line))
|
||||
str_ptr = skip_token(str_ptr); // Skip over subckt name.
|
||||
|
||||
if (*str_ptr == '(') {
|
||||
*str_ptr = ' ';
|
||||
while (*str_ptr != '\0') {
|
||||
|
|
@ -2824,8 +2829,8 @@ static void inp_fix_macro_param_func_paren_io(struct card *card)
|
|||
|
||||
if (ciprefix(".para", card->line)) {
|
||||
bool is_func = FALSE;
|
||||
str_ptr = skip_non_ws(card->line); // skip over .param
|
||||
str_ptr = skip_ws(str_ptr);
|
||||
|
||||
str_ptr = skip_token(card->line); // skip over .param
|
||||
while (!isspace_c(*str_ptr) && *str_ptr != '=') {
|
||||
if (*str_ptr == '(')
|
||||
is_func = TRUE;
|
||||
|
|
@ -2874,13 +2879,8 @@ static char *get_subckt_model_name(char *line)
|
|||
{
|
||||
char *name, *end_ptr;
|
||||
|
||||
name = skip_non_ws(line); // eat .subckt|.model
|
||||
name = skip_ws(name);
|
||||
|
||||
|
||||
|
||||
name = skip_token(line); // Eat .subckt or .model
|
||||
end_ptr = skip_non_ws(name);
|
||||
|
||||
return copy_substring(name, end_ptr);
|
||||
}
|
||||
|
||||
|
|
@ -2890,23 +2890,16 @@ static char *get_model_name(char *line, int num_terminals)
|
|||
char *beg_ptr, *end_ptr;
|
||||
int i = 0;
|
||||
|
||||
beg_ptr = skip_non_ws(line); /* eat device name */
|
||||
beg_ptr = skip_ws(beg_ptr);
|
||||
|
||||
for (i = 0; i < num_terminals; i++) { /* skip the terminals */
|
||||
beg_ptr = skip_non_ws(beg_ptr);
|
||||
beg_ptr = skip_ws(beg_ptr);
|
||||
}
|
||||
beg_ptr = skip_token(line); // Eat device name.
|
||||
for (i = 0; i < num_terminals; i++)
|
||||
beg_ptr = skip_token(beg_ptr); // Eat terminal.
|
||||
|
||||
if (*line == 'r') /* special dealing for r models */
|
||||
if ((*beg_ptr == '+') || (*beg_ptr == '-') ||
|
||||
isdigit_c(*beg_ptr)) { /* looking for a value before model */
|
||||
beg_ptr = skip_non_ws(beg_ptr); /* skip the value */
|
||||
beg_ptr = skip_ws(beg_ptr);
|
||||
beg_ptr = skip_token(beg_ptr); /* Skip the value, */
|
||||
}
|
||||
|
||||
end_ptr = skip_non_ws(beg_ptr);
|
||||
|
||||
return copy_substring(beg_ptr, end_ptr);
|
||||
}
|
||||
|
||||
|
|
@ -2918,12 +2911,8 @@ static char *get_model_type(char *line)
|
|||
if (!ciprefix(".model", line))
|
||||
return NULL;
|
||||
|
||||
beg_ptr = skip_non_ws(line); /* eat .model */
|
||||
beg_ptr = skip_ws(beg_ptr);
|
||||
|
||||
beg_ptr = skip_non_ws(beg_ptr); /* eat model name */
|
||||
beg_ptr = skip_ws(beg_ptr);
|
||||
|
||||
beg_ptr = skip_token(line); /* Eat .model */
|
||||
beg_ptr = skip_token(beg_ptr); /* Eat model name. */
|
||||
return gettok_noparens(&beg_ptr);
|
||||
}
|
||||
|
||||
|
|
@ -3655,8 +3644,8 @@ static char *inp_fix_subckt(struct names *subckt_w_params, char *s)
|
|||
if (equal &&
|
||||
(!strstr(s, "params:") || !isspace_c(s[-1]))) {
|
||||
/* get subckt name (ptr1 will point to name) */
|
||||
ptr1 = skip_non_ws(s);
|
||||
ptr1 = skip_ws(ptr1);
|
||||
|
||||
ptr1 = skip_token(s);
|
||||
for (ptr2 = ptr1; *ptr2 && !isspace_c(*ptr2) && !isquote(*ptr2);
|
||||
ptr2++)
|
||||
;
|
||||
|
|
@ -4275,8 +4264,8 @@ static void inp_fix_inst_calls_for_numparam(
|
|||
continue;
|
||||
if (d) {
|
||||
char *subckt_line = d->line;
|
||||
subckt_line = skip_non_ws(subckt_line);
|
||||
subckt_line = skip_ws(subckt_line);
|
||||
|
||||
subckt_line = skip_token(subckt_line);
|
||||
|
||||
int num_subckt_params = inp_get_params(subckt_line,
|
||||
subckt_param_names, subckt_param_values);
|
||||
|
|
@ -4385,8 +4374,7 @@ static void inp_get_func_from_line(struct function_env *env, char *line)
|
|||
struct function *function;
|
||||
|
||||
/* skip `.func' */
|
||||
line = skip_non_ws(line);
|
||||
line = skip_ws(line);
|
||||
line = skip_token(line);
|
||||
|
||||
/* get function name */
|
||||
end = line;
|
||||
|
|
@ -5501,8 +5489,7 @@ static void inp_add_params_to_subckt(
|
|||
if (!strstr(subckt_line, "params:")) {
|
||||
new_line = tprintf("%s params: %s", subckt_line, param_ptr);
|
||||
|
||||
subckt_name = skip_non_ws(subckt_line);
|
||||
subckt_name = skip_ws(subckt_name);
|
||||
subckt_name = skip_token(subckt_line);
|
||||
end_ptr = skip_non_ws(subckt_name);
|
||||
add_name(subckt_w_params, copy_substring(subckt_name, end_ptr));
|
||||
}
|
||||
|
|
@ -7867,9 +7854,7 @@ static void inp_fix_temper_in_param(struct card *deck)
|
|||
controlled_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
lhs_b = skip_non_ws(curr_line); // eat .param
|
||||
lhs_b = skip_ws(lhs_b);
|
||||
|
||||
lhs_b = skip_token(curr_line); // Eat .param.
|
||||
lhs_e = skip_back_ws(equal_ptr, curr_line);
|
||||
|
||||
/* skip if this is a function already */
|
||||
|
|
@ -8094,9 +8079,7 @@ static void inp_fix_agauss_in_param(struct card *deck, char *fcn)
|
|||
controlled_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
lhs_b = skip_non_ws(curr_line); // eat .param
|
||||
lhs_b = skip_ws(lhs_b);
|
||||
|
||||
lhs_b = skip_token(curr_line); // Eat .param.
|
||||
lhs_e = skip_back_ws(equal_ptr, curr_line);
|
||||
|
||||
/* skip if this is a function already */
|
||||
|
|
@ -8332,10 +8315,8 @@ static void inp_quote_params(struct card *c, struct card *end_c,
|
|||
|
||||
char *s = curr_line;
|
||||
|
||||
for (j = 0; j < num_terminals + 1; j++) {
|
||||
s = skip_non_ws(s);
|
||||
s = skip_ws(s);
|
||||
}
|
||||
for (j = 0; j < num_terminals + 1; j++)
|
||||
s = skip_token(s);
|
||||
|
||||
while ((s = ya_search_identifier(
|
||||
s, deps[i].param_name, curr_line)) != NULL) {
|
||||
|
|
@ -8403,7 +8384,6 @@ static void inp_quote_params(struct card *c, struct card *end_c,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/* VDMOS special:
|
||||
Check for 'vdmos' in .model line.
|
||||
check if 'pchan', then add p to vdmos and ignore 'pchan'.
|
||||
|
|
@ -8429,16 +8409,17 @@ static int inp_vdmos_model(struct card *deck)
|
|||
curr_line = card->line;
|
||||
|
||||
if (ciprefix(".model", curr_line)) {
|
||||
cut_line = search_plain_identifier(curr_line, "vdmos");
|
||||
if (cut_line) {
|
||||
cut_line = skip_token(curr_line);
|
||||
cut_line = skip_token(cut_line);
|
||||
if (!strncmp(cut_line, "vdmos", 5)) {
|
||||
/* A VDMOS model line, may be vdmosn or vdmosp if re-input. */
|
||||
|
||||
wl_append_word(&wl, &wl, copy_substring(curr_line, cut_line));
|
||||
wlb = wl;
|
||||
if (search_plain_identifier(cut_line, "pchan")) {
|
||||
if (search_plain_identifier(cut_line, "pchan") ||
|
||||
cut_line[5] == 'p') {
|
||||
wl_append_word(NULL, &wl, copy("vdmosp ("));
|
||||
}
|
||||
else if (search_plain_identifier(cut_line, "nchan")) {
|
||||
wl_append_word(NULL, &wl, copy("vdmosn ("));
|
||||
}
|
||||
else {
|
||||
wl_append_word(NULL, &wl, copy("vdmosn ("));
|
||||
}
|
||||
|
|
@ -9199,9 +9180,10 @@ static struct modellist *inp_find_model_1(
|
|||
struct nscope *scope, const char *name)
|
||||
{
|
||||
struct modellist *p = scope->models;
|
||||
for (; p; p = p->next)
|
||||
for (; p; p = p->next) {
|
||||
if (model_name_match(name, p->modelname))
|
||||
break;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -583,11 +583,18 @@ doit(struct card *deck, wordlist *modnames) {
|
|||
scale = 1;
|
||||
|
||||
error = 0;
|
||||
/* Second pass: do the replacements. */
|
||||
/* Second pass: do the replacements.
|
||||
Check if binning is used for .model inside of the subcircuit.
|
||||
Reduce .model lines to the one with appropriate w and l.
|
||||
(Inspired by Skywater PDK with excessive use of binning (161 bins)
|
||||
in the subcircuit referencing a MOS device) */
|
||||
do { /* while (!error && numpasses-- && gotone) */
|
||||
struct card *c = deck;
|
||||
struct card *prev_of_c = NULL;
|
||||
bool foundmodel = FALSE;
|
||||
|
||||
gotone = FALSE;
|
||||
|
||||
for (; c; prev_of_c = c, c = c->nextcard) {
|
||||
if (ciprefix(invoke, c->line)) { /* found reference to .subckt (i.e. component with refdes X) */
|
||||
|
||||
|
|
@ -597,16 +604,13 @@ doit(struct card *deck, wordlist *modnames) {
|
|||
gotone = TRUE;
|
||||
t = tofree = s = copy(c->line); /* s & t hold copy of component line */
|
||||
|
||||
/* make scname point to first non-whitepace chars after refdes invocation
|
||||
* e.g. if invocation is Xreference, *scname = reference
|
||||
*/
|
||||
/* scname contains the refdes Xname */
|
||||
tofree2 = scname = gettok(&s);
|
||||
/*scname += strlen(invoke); */
|
||||
while ((*scname == ' ') || (*scname == '\t') || (*scname == ':'))
|
||||
scname++;
|
||||
|
||||
/* Now set s to point to last non-space chars in line (i.e.
|
||||
* the name of the model invoked
|
||||
/* Now set s to point to last non-space chars in the x line (i.e.
|
||||
* the name of the model invoked)
|
||||
*/
|
||||
while (*s)
|
||||
s++;
|
||||
|
|
@ -617,38 +621,47 @@ doit(struct card *deck, wordlist *modnames) {
|
|||
s--;
|
||||
s++;
|
||||
|
||||
/* iterate through .subckt list and look for .subckt name invoked */
|
||||
/* Iterate through .subckt list and look for .subckt name
|
||||
corresponding to the subckt name extracted from the x line */
|
||||
for (sss = subs; sss; sss = sss->su_next)
|
||||
if (eq(sss->su_name, s))
|
||||
break;
|
||||
|
||||
|
||||
/* At this point, sss points to the .subckt invoked,
|
||||
* and scname points to the netnames
|
||||
* involved.
|
||||
/* At this point,
|
||||
* c is the card with the x line.
|
||||
* scname points to the netname of the x line involved.
|
||||
* s is the subckt name extracted from the x line.
|
||||
* sss points to the subcircuit referenced by the x line
|
||||
* sss->su_def is the contents of the subcircuit.
|
||||
*/
|
||||
|
||||
|
||||
/* If no .subckt is found, don't complain -- this might be an
|
||||
* instance of a subckt that is defined above at higher level.
|
||||
*/
|
||||
if (sss) {
|
||||
// tprint(sss->su_def);
|
||||
|
||||
/* copy of the contents between .subckt and .ends */
|
||||
struct card *su_deck = inp_deckcopy(sss->su_def);
|
||||
/* If we have modern PDKs, we have to reduce the amount of memory required.
|
||||
We try to reduce the models to the one really used.
|
||||
Otherwise su_deck is full of unused binning models.*/
|
||||
Otherwise su_deck is full of unused binning models.
|
||||
c->w > 0 and c->l > 0 point to an x line with given w and l
|
||||
(typically a call to a MOS device). */
|
||||
if ((newcompat.hs || newcompat.spe) && c->w > 0 && c->l > 0) {
|
||||
/* extract wmin, wmax, lmin, lmax */
|
||||
struct card* new_deck = su_deck;
|
||||
struct card* enter_su_deck = su_deck;
|
||||
struct card* prev = NULL;
|
||||
while (su_deck) {
|
||||
/* find a .model line */
|
||||
if (!ciprefix(".model", su_deck->line)) {
|
||||
prev = su_deck;
|
||||
su_deck = su_deck->nextcard;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* check if line contains wmin, wmax, lmin, lmax
|
||||
if available, extract its values,
|
||||
if not, go to next line */
|
||||
char* curr_line = su_deck->line;
|
||||
float fwmin, fwmax, flmin, flmax;
|
||||
char *wmin = strstr(curr_line, " wmin=");
|
||||
|
|
@ -716,32 +729,39 @@ doit(struct card *deck, wordlist *modnames) {
|
|||
su_deck = su_deck->nextcard;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* check if x line's w and l are withing the limites of wmin, wmax, lmin, lmax */
|
||||
float csl = (float)scale * c->l;
|
||||
/* scale by nf */
|
||||
float csw = (float)scale * c->w / c->nf;
|
||||
/*fprintf(stdout, "Debug: nf = %f\n", c->nf);*/
|
||||
if (csl >= flmin && csl < flmax && csw >= fwmin && csw < fwmax) {
|
||||
/* use the current .model card */
|
||||
/* if within the limits, use the current .model card */
|
||||
prev = su_deck;
|
||||
su_deck = su_deck->nextcard;
|
||||
foundmodel = TRUE;
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
/* if not within the limits,
|
||||
delete the .model line not fitting the device */
|
||||
struct card* tmpcard = su_deck->nextcard;
|
||||
line_free_x(prev->nextcard, FALSE);
|
||||
su_deck = prev->nextcard = tmpcard;
|
||||
}
|
||||
}
|
||||
su_deck = new_deck;
|
||||
/* go back to the first card of su_deck */
|
||||
su_deck = enter_su_deck;
|
||||
}
|
||||
|
||||
if (!su_deck) {
|
||||
fprintf(stderr, "\nError: Could not find a model for device %s in subcircuit %s\n",
|
||||
scname, sss->su_name);
|
||||
if (!foundmodel && (newcompat.hs || newcompat.spe) && c->w > 0 && c->l > 0) {
|
||||
fprintf(stderr, "\nError: Could not find a model\n"
|
||||
" for device %s in transistor subcircuit %s\n", scname, sss->su_name);
|
||||
fprintf(stderr, " with w = %.3g and l = %.3g\n\n", c->w, c->l);
|
||||
controlled_exit(1);
|
||||
}
|
||||
|
||||
foundmodel = FALSE;
|
||||
|
||||
struct card *rest_of_c = c->nextcard;
|
||||
|
||||
/* Now we have to replace this line with the
|
||||
|
|
@ -782,8 +802,8 @@ doit(struct card *deck, wordlist *modnames) {
|
|||
|
||||
tfree(tofree);
|
||||
tfree(tofree2);
|
||||
}
|
||||
}
|
||||
} /* if (ciprefix(invoke, c->line)) */
|
||||
} /* for (; c; prev_of_c = c, c = c->nextcard) */
|
||||
} while (!error && numpasses-- && gotone);
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -12,15 +12,15 @@ Copyright 1992 Regents of the University of California. All rights reserved.
|
|||
|
||||
/* ARGSUSED */
|
||||
int
|
||||
CKTdltNod(CKTcircuit *ckt, CKTnode *node)
|
||||
CKTdltNod(CKTcircuit* ckt, CKTnode* node)
|
||||
{
|
||||
return CKTdltNNum(ckt, node->number);
|
||||
}
|
||||
|
||||
int
|
||||
CKTdltNNum(CKTcircuit *ckt, int num)
|
||||
CKTdltNNum(CKTcircuit* ckt, int num)
|
||||
{
|
||||
CKTnode *n, *prev, *node, *sprev;
|
||||
CKTnode* n, * prev, * node, * sprev;
|
||||
int error;
|
||||
|
||||
if (!ckt->prev_CKTlastNode->number || num <= ckt->prev_CKTlastNode->number) {
|
||||
|
|
@ -28,32 +28,33 @@ CKTdltNNum(CKTcircuit *ckt, int num)
|
|||
controlled_exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
prev = NULL;
|
||||
node = NULL;
|
||||
prev = NULL;
|
||||
node = NULL;
|
||||
sprev = NULL;
|
||||
|
||||
for (n = ckt->CKTnodes; n; n = n->next) {
|
||||
if (n->number == num) {
|
||||
node = n;
|
||||
sprev = prev;
|
||||
}
|
||||
prev = n;
|
||||
if (n->number == num) {
|
||||
node = n;
|
||||
sprev = prev;
|
||||
}
|
||||
prev = n;
|
||||
}
|
||||
|
||||
if (!node)
|
||||
return OK;
|
||||
return OK;
|
||||
|
||||
ckt->CKTmaxEqNum -= 1;
|
||||
|
||||
if (!sprev) {
|
||||
ckt->CKTnodes = node->next;
|
||||
} else {
|
||||
sprev->next = node->next;
|
||||
ckt->CKTnodes = node->next;
|
||||
}
|
||||
else {
|
||||
sprev->next = node->next;
|
||||
}
|
||||
if (node == ckt->CKTlastNode)
|
||||
ckt->CKTlastNode = sprev;
|
||||
ckt->CKTlastNode = sprev;
|
||||
|
||||
error = SPfrontEnd->IFdelUid (ckt, node->name, UID_SIGNAL);
|
||||
error = SPfrontEnd->IFdelUid(ckt, node->name, UID_SIGNAL);
|
||||
tfree(node);
|
||||
|
||||
return error;
|
||||
|
|
|
|||
|
|
@ -145,9 +145,9 @@ MOS1noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt,
|
|||
N_GAIN, inst->MOS1dNodePrime, inst->MOS1sNodePrime,
|
||||
(double) 0.0);
|
||||
if (newcompat.s3) {
|
||||
noizDens[MOS1FLNOIZ] *= model->MOS1fNcoef *
|
||||
noizDens[MOS1FLNOIZ] *= inst->MOS1m * model->MOS1fNcoef *
|
||||
exp(model->MOS1fNexp *
|
||||
log(MAX(fabs(inst->MOS1cd), N_MINLOG))) /
|
||||
log(MAX(fabs(inst->MOS1cd / inst->MOS1m), N_MINLOG))) /
|
||||
(data->freq *
|
||||
inst->MOS1w *
|
||||
(inst->MOS1l - 2 * model->MOS1latDiff) *
|
||||
|
|
@ -155,18 +155,18 @@ MOS1noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt,
|
|||
} else {
|
||||
switch (model->MOS1nlev) {
|
||||
case 0:
|
||||
noizDens[MOS1FLNOIZ] *= model->MOS1fNcoef *
|
||||
noizDens[MOS1FLNOIZ] *= inst->MOS1m * model->MOS1fNcoef *
|
||||
exp(model->MOS1fNexp *
|
||||
log(MAX(fabs(inst->MOS1cd), N_MINLOG))) /
|
||||
log(MAX(fabs(inst->MOS1cd / inst->MOS1m), N_MINLOG))) /
|
||||
(data->freq *
|
||||
(inst->MOS1l - 2 * model->MOS1latDiff) *
|
||||
(inst->MOS1l - 2 * model->MOS1latDiff) *
|
||||
sqrt(coxSquared));
|
||||
break;
|
||||
case 1:
|
||||
noizDens[MOS1FLNOIZ] *= model->MOS1fNcoef *
|
||||
noizDens[MOS1FLNOIZ] *= inst->MOS1m * model->MOS1fNcoef *
|
||||
exp(model->MOS1fNexp *
|
||||
log(MAX(fabs(inst->MOS1cd), N_MINLOG))) /
|
||||
log(MAX(fabs(inst->MOS1cd / inst->MOS1m), N_MINLOG))) /
|
||||
(data->freq *
|
||||
inst->MOS1w *
|
||||
(inst->MOS1l - 2 * model->MOS1latDiff) *
|
||||
|
|
@ -174,7 +174,7 @@ MOS1noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt,
|
|||
break;
|
||||
case 2: case 3:
|
||||
noizDens[MOS1FLNOIZ] *= model->MOS1fNcoef *
|
||||
inst->MOS1gm * inst->MOS1gm /
|
||||
inst->MOS1gm * inst->MOS1gm / inst->MOS1m /
|
||||
(pow(data->freq, model->MOS1fNexp) *
|
||||
inst->MOS1w *
|
||||
(inst->MOS1l - 2 * model->MOS1latDiff) *
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ MOS2load(GENmodel *inModel, CKTcircuit *ckt)
|
|||
double GateBulkOverlapCap;
|
||||
double GateDrainOverlapCap;
|
||||
double GateSourceOverlapCap;
|
||||
double OxideCap;
|
||||
double OxideCap, unscaledOxideCap;
|
||||
double SourceSatCur;
|
||||
double arg;
|
||||
double cbhat;
|
||||
|
|
@ -144,8 +144,8 @@ MOS2load(GENmodel *inModel, CKTcircuit *ckt)
|
|||
here->MOS2m * EffectiveLength;
|
||||
Beta = here->MOS2tTransconductance * here->MOS2w *
|
||||
here->MOS2m/EffectiveLength;
|
||||
OxideCap = model->MOS2oxideCapFactor * EffectiveLength *
|
||||
here->MOS2m * here->MOS2w;
|
||||
unscaledOxideCap = model->MOS2oxideCapFactor * EffectiveLength * here->MOS2w;
|
||||
OxideCap = unscaledOxideCap*here->MOS2m;
|
||||
|
||||
|
||||
if(SenCond){
|
||||
|
|
@ -599,7 +599,7 @@ next1: if(vbs <= -3*vt) {
|
|||
|
||||
/*XXX constant per device */
|
||||
factor = 0.125*model->MOS2narrowFactor*2.0*M_PI*EPSSIL/
|
||||
OxideCap*EffectiveLength;
|
||||
unscaledOxideCap*EffectiveLength;
|
||||
/*XXX constant per device */
|
||||
eta = 1.0+factor;
|
||||
vbin = here->MOS2tVbi*model->MOS2type+factor*phiMinVbs;
|
||||
|
|
@ -664,7 +664,7 @@ next1: if(vbs <= -3*vt) {
|
|||
1e4 /*(cm**2/m**2)*/;
|
||||
cdonco = -(gamasd*dsrgdb+dgddvb*sarg1)+factor;
|
||||
|
||||
xn = 1.0+cfs/OxideCap*here->MOS2m*
|
||||
xn = 1.0+cfs/unscaledOxideCap*
|
||||
here->MOS2w*EffectiveLength+cdonco;
|
||||
|
||||
tmp = vt*xn;
|
||||
|
|
|
|||
|
|
@ -134,9 +134,9 @@ MOS2noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt,
|
|||
N_GAIN, inst->MOS2dNodePrime, inst->MOS2sNodePrime,
|
||||
(double) 0.0);
|
||||
if (newcompat.s3) {
|
||||
noizDens[MOS2FLNOIZ] *= model->MOS2fNcoef *
|
||||
noizDens[MOS2FLNOIZ] *= inst->MOS2m * model->MOS2fNcoef *
|
||||
exp(model->MOS2fNexp *
|
||||
log(MAX(fabs(inst->MOS2cd), N_MINLOG))) /
|
||||
log(MAX(fabs(inst->MOS2cd / inst->MOS2m), N_MINLOG))) /
|
||||
(data->freq *
|
||||
inst->MOS2w *
|
||||
(inst->MOS2l - 2 * model->MOS2latDiff) *
|
||||
|
|
@ -144,18 +144,18 @@ MOS2noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt,
|
|||
} else {
|
||||
switch (model->MOS2nlev) {
|
||||
case 0:
|
||||
noizDens[MOS2FLNOIZ] *= model->MOS2fNcoef *
|
||||
noizDens[MOS2FLNOIZ] *= inst->MOS2m * model->MOS2fNcoef *
|
||||
exp(model->MOS2fNexp *
|
||||
log(MAX(fabs(inst->MOS2cd), N_MINLOG))) /
|
||||
log(MAX(fabs(inst->MOS2cd / inst->MOS2m), N_MINLOG))) /
|
||||
(data->freq *
|
||||
(inst->MOS2l - 2 * model->MOS2latDiff) *
|
||||
(inst->MOS2l - 2 * model->MOS2latDiff) *
|
||||
model->MOS2oxideCapFactor);
|
||||
break;
|
||||
case 1:
|
||||
noizDens[MOS2FLNOIZ] *= model->MOS2fNcoef *
|
||||
noizDens[MOS2FLNOIZ] *= inst->MOS2m * model->MOS2fNcoef *
|
||||
exp(model->MOS2fNexp *
|
||||
log(MAX(fabs(inst->MOS2cd), N_MINLOG))) /
|
||||
log(MAX(fabs(inst->MOS2cd / inst->MOS2m), N_MINLOG))) /
|
||||
(data->freq *
|
||||
inst->MOS2w *
|
||||
(inst->MOS2l - 2 * model->MOS2latDiff) *
|
||||
|
|
@ -163,7 +163,7 @@ MOS2noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt,
|
|||
break;
|
||||
case 2: case 3:
|
||||
noizDens[MOS2FLNOIZ] *= model->MOS2fNcoef *
|
||||
inst->MOS2gm * inst->MOS2gm /
|
||||
inst->MOS2gm * inst->MOS2gm / inst->MOS2m /
|
||||
(pow(data->freq, model->MOS2fNexp) *
|
||||
inst->MOS2w *
|
||||
(inst->MOS2l - 2 * model->MOS2latDiff) *
|
||||
|
|
|
|||
|
|
@ -134,9 +134,9 @@ MOS3noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt,
|
|||
N_GAIN, inst->MOS3dNodePrime, inst->MOS3sNodePrime,
|
||||
(double) 0.0);
|
||||
if (newcompat.s3) {
|
||||
noizDens[MOS3FLNOIZ] *= model->MOS3fNcoef *
|
||||
noizDens[MOS3FLNOIZ] *= inst->MOS3m * model->MOS3fNcoef *
|
||||
exp(model->MOS3fNexp *
|
||||
log(MAX(fabs(inst->MOS3cd), N_MINLOG))) /
|
||||
log(MAX(fabs(inst->MOS3cd / inst->MOS3m), N_MINLOG))) /
|
||||
(data->freq *
|
||||
(inst->MOS3w - 2 * model->MOS3widthNarrow) *
|
||||
(inst->MOS3l - 2 * model->MOS3latDiff) *
|
||||
|
|
@ -144,18 +144,18 @@ MOS3noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt,
|
|||
} else {
|
||||
switch (model->MOS3nlev) {
|
||||
case 0:
|
||||
noizDens[MOS3FLNOIZ] *= model->MOS3fNcoef *
|
||||
noizDens[MOS3FLNOIZ] *= inst->MOS3m * model->MOS3fNcoef *
|
||||
exp(model->MOS3fNexp *
|
||||
log(MAX(fabs(inst->MOS3cd), N_MINLOG))) /
|
||||
log(MAX(fabs(inst->MOS3cd / inst->MOS3m), N_MINLOG))) /
|
||||
(data->freq *
|
||||
(inst->MOS3l - 2 * model->MOS3latDiff) *
|
||||
(inst->MOS3l - 2 * model->MOS3latDiff) *
|
||||
model->MOS3oxideCapFactor);
|
||||
break;
|
||||
case 1:
|
||||
noizDens[MOS3FLNOIZ] *= model->MOS3fNcoef *
|
||||
noizDens[MOS3FLNOIZ] *= inst->MOS3m * model->MOS3fNcoef *
|
||||
exp(model->MOS3fNexp *
|
||||
log(MAX(fabs(inst->MOS3cd), N_MINLOG))) /
|
||||
log(MAX(fabs(inst->MOS3cd / inst->MOS3m), N_MINLOG))) /
|
||||
(data->freq *
|
||||
(inst->MOS3w - 2 * model->MOS3widthNarrow) *
|
||||
(inst->MOS3l - 2 * model->MOS3latDiff) *
|
||||
|
|
@ -163,7 +163,7 @@ MOS3noise(int mode, int operation, GENmodel * genmodel, CKTcircuit * ckt,
|
|||
break;
|
||||
case 2: case 3:
|
||||
noizDens[MOS3FLNOIZ] *= model->MOS3fNcoef *
|
||||
inst->MOS3gm * inst->MOS3gm /
|
||||
inst->MOS3gm * inst->MOS3gm / inst->MOS3m /
|
||||
(pow(data->freq, model->MOS3fNexp) *
|
||||
(inst->MOS3w - 2 * model->MOS3widthNarrow) *
|
||||
(inst->MOS3l - 2 * model->MOS3latDiff) *
|
||||
|
|
|
|||
|
|
@ -94,12 +94,11 @@ MOS9noise (int mode, int operation, GENmodel *genmodel, CKTcircuit *ckt,
|
|||
NevalSrc(&noizDens[MOS9FLNOIZ], NULL, ckt,
|
||||
N_GAIN,inst->MOS9dNodePrime, inst->MOS9sNodePrime,
|
||||
(double)0.0);
|
||||
noizDens[MOS9FLNOIZ] *= model->MOS9fNcoef *
|
||||
noizDens[MOS9FLNOIZ] *= inst->MOS9m * model->MOS9fNcoef *
|
||||
exp(model->MOS9fNexp *
|
||||
log(MAX(fabs(inst->MOS9cd),N_MINLOG))) /
|
||||
log(MAX(fabs(inst->MOS9cd / inst->MOS9m),N_MINLOG))) /
|
||||
(data->freq *
|
||||
(inst->MOS9w - 2*model->MOS9widthNarrow) *
|
||||
inst->MOS9m *
|
||||
(inst->MOS9l - 2*model->MOS9latDiff) *
|
||||
model->MOS9oxideCapFactor * model->MOS9oxideCapFactor);
|
||||
lnNdens[MOS9FLNOIZ] =
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ VSRCaccept(CKTcircuit *ckt, GENmodel *inModel)
|
|||
&& here->VSRCcoeffs[4] != 0.0
|
||||
? here->VSRCcoeffs[4] : ckt->CKTstep;
|
||||
PW = here->VSRCfunctionOrder > 5
|
||||
&& here->VSRCcoeffs[5] != 0.0
|
||||
&& here->VSRCcoeffs[5] >= 0.0
|
||||
? here->VSRCcoeffs[5] : ckt->CKTfinalTime;
|
||||
PER = here->VSRCfunctionOrder > 6
|
||||
&& here->VSRCcoeffs[6] != 0.0
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ VSRCload(GENmodel *inModel, CKTcircuit *ckt)
|
|||
&& here->VSRCcoeffs[4] != 0.0
|
||||
? here->VSRCcoeffs[4] : ckt->CKTstep;
|
||||
PW = here->VSRCfunctionOrder > 5
|
||||
&& here->VSRCcoeffs[5] != 0.0
|
||||
&& here->VSRCcoeffs[5] >= 0.0
|
||||
? here->VSRCcoeffs[5] : ckt->CKTfinalTime;
|
||||
PER = here->VSRCfunctionOrder > 6
|
||||
&& here->VSRCcoeffs[6] != 0.0
|
||||
|
|
|
|||
|
|
@ -149,12 +149,18 @@ create_model(CKTcircuit *ckt, INPmodel *modtmp, INPtables *tab)
|
|||
|
||||
if (p) {
|
||||
char *value;
|
||||
INPgetTok(&line, &value, 1);
|
||||
|
||||
modtmp->INPmodfast->defaults =
|
||||
wl_cons(copy(parm),
|
||||
wl_cons(value,
|
||||
modtmp->INPmodfast->defaults));
|
||||
INPgetTok(&line, &value, 1);
|
||||
if (p->dataType & IF_SET) {
|
||||
modtmp->INPmodfast->defaults =
|
||||
wl_cons(copy(parm),
|
||||
wl_cons(value, modtmp->INPmodfast->defaults));
|
||||
} else {
|
||||
fprintf(stderr,
|
||||
"Ignoring attempt to set a default "
|
||||
"for read-only instance parameter %s in:\n %s\n",
|
||||
p->keyword, modtmp->INPmodLine->line);
|
||||
}
|
||||
} else {
|
||||
|
||||
double dval;
|
||||
|
|
@ -286,6 +292,7 @@ INPgetModBin(CKTcircuit *ckt, char *name, INPmodel **model, INPtables *tab, char
|
|||
|
||||
for (modtmp = modtab; modtmp; modtmp = modtmp->INPnextModel) {
|
||||
|
||||
/* exact: 1, with binning extension .[0-9]: 2*/
|
||||
if (model_name_match(name, modtmp->INPmodName) < 2)
|
||||
continue;
|
||||
|
||||
|
|
@ -328,8 +335,8 @@ INPgetModBin(CKTcircuit *ckt, char *name, INPmodel **model, INPtables *tab, char
|
|||
*model = modtmp;
|
||||
return NULL;
|
||||
}
|
||||
fprintf(stderr, "Warning: no model found for w=%.3e and l=%.3e\n", w, l);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
* an Icarus Verilog simulation (libvvp.so).
|
||||
* Licensed on the same terms as Ngspice.
|
||||
*
|
||||
* Copyright (c) 2024 Giles Atkinson
|
||||
* Copyright (c) 2024-2025 Giles Atkinson
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
|
@ -18,6 +18,12 @@
|
|||
|
||||
#include "coroutine_shim.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include "../../../visualc/src/include/ngspice/config.h"
|
||||
#else
|
||||
#include "ngspice/config.h" // For NGSPICELIBDIR
|
||||
#endif
|
||||
|
||||
#include "ngspice/cmtypes.h" // For Digital_t
|
||||
#include "ngspice/cosim.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -342,7 +342,7 @@ else
|
|||
if $fh > 0
|
||||
fclose $fh
|
||||
else
|
||||
echo Can not find bulid file $msvcfile
|
||||
echo Can not find build file $msvcfile
|
||||
quit
|
||||
end
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue