Micah Tseng
11/06/2023, 12:47 AMTim Edwards
11/06/2023, 2:18 AM.option SEED=random
.Micah Tseng
11/06/2023, 2:20 AMTim Edwards
11/06/2023, 2:23 AMMicah Tseng
11/06/2023, 2:27 AMmc_mm_switch
parameter after loading the libraries to make sure nothing in there set it a different value using `csparam`and it is still 1.Micah Tseng
11/06/2023, 2:27 AMTim Edwards
11/06/2023, 2:29 AMMicah Tseng
11/06/2023, 2:30 AMTim Edwards
11/06/2023, 2:30 AMMicah Tseng
11/06/2023, 3:01 AMreset
command (https://sourceforge.net/p/ngspice/ngspice/ci/master/tree/examples/Monte_Carlo/MC_ring.sp#l49 and ). I think that’s the key, but now I’m running into an issue where reset (and mc_source
) are loosing net names in the circuit.
You’ve helped a lot. Thank you. I may just write a python script.Micah Tseng
11/06/2023, 3:02 AMMicah Tseng
11/06/2023, 3:08 AMreset
command do you? I feel like I’m close.Micah Tseng
11/06/2023, 3:30 AMreset
and mc_source
reloads the circuit so it also reloads which nets it saves. You have to call save
after reset or mc_source
2. both reset
and mc_source
calls reloads the circuit which also reloads set SEED=random
to the original sample of the unix clock. So you can’t use set SEED=random
. I’m not entirely sure what’s happening under the hood (the manual isn’t clear), but not calling set SEED=random
works.Stefan Schippers
11/06/2023, 3:59 PMreset
instruction after run = run + 1Stefan Schippers
11/06/2023, 4:06 PM.control
setseed 9
reset
let run=0
dowhile run <= 100
save all
tran 1n 4000n uic
print run
print @m.x1.xml.msky130_fd_pr__pfet_01v8_lvt[vth]
print @m.x1.xmr.msky130_fd_pr__pfet_01v8_lvt[vth]
remzerovec
write tb_bandgap_opamp.raw
set appendwrite
reset
let run = run + 1
end
.endc
When I start a new circuit I copy paste from this working circuit. It is impossible to remember where to put all the reset instructions and the precise order of statements to have a working simulation.Micah Tseng
11/06/2023, 4:13 PMTim Edwards
11/17/2023, 3:10 PMsrc/frontend/inp.c
lines 434 to 442 from
/* option seed=random [seed='random'] */
if (eq(token, "random") || eq(token, "{random}")) {
time_t acttime = time(NULL);
/* get random value from time in seconds since 1.1.1970 */
int rseed = (int)(acttime - 1600000000);
cp_vset("rndseed", CP_NUM, &rseed);
com_sseed(NULL);
has_seed = TRUE;
}
to
/* option seed=random [seed='random'] */
if (eq(token, "random") || eq(token, "{random}")) {
struct timeval tv;
gettimeofday(&tv, NULL);
/* get random value from current timestamp microseconds */
int rseed = (int)(tv.tv_usec);
cp_vset("rndseed", CP_NUM, &rseed);
com_sseed(NULL);
has_seed = TRUE;
}
?
Using .option SEED=random
has the unfortunate property of asserting a new random value based on time()
every time reset
is called or every time the program is run (even overriding the use of setseed
within a control block), and using time()
to generate the seed has the very unfortunate property of returning a value in seconds which is a long, long time on a computer. If I am trying to do a mismatch analysis on a simple circuit using a DC
analysis, then it can end up running 30 or 40 analyses with the exact same random seed. There are really multiple issues here: (1) .option SEED
should not be able to override `setseed`; and (2) random seeds should be based on microseconds or even CPU clock tick counts. If you want to be pedantic and avoid the case where an analysis takes exactly one second, then I would suppose that int rseed = (int)(<http://tv.tv|tv.tv>_usec) + (int)random();
would be a reasonable solution.Holger Vogt
11/17/2023, 3:57 PMHolger Vogt
11/17/2023, 5:39 PMTim Edwards
11/17/2023, 5:46 PMclock_gettime()
? That would be even better because it uses struct timespec
with field tv_nsec
for a timestamp in nanoseconds.