JoeyDelp / JoSIM

Superconductor Circuit Simulator
MIT License
73 stars 33 forks source link

Subcircuit questions #81

Open grahamrow opened 1 year ago

grahamrow commented 1 year ago

Hi all, hope you're doing well. Was testing Josim (like the cmake build system!) and found some issues with subcircuits regarding input nodes labels and parameters.

  1. Subcircuit input Node labels cannot be referenced in .print statements, e.g.:
    
    X1 TEST 1 0
    I1      0 1 1.0

.subckt TEST IN GND R1 IN GND 10.0 .ends

.tran 0.25p 5n 0 1.0p .print v(IN.X1) .end

yields

W: Controls Unknown device/node IN|X1 Cannot store results for this device/node. Ignoring this store request.

Expected behavior would be to look up the proper node label based on the input mapping. To be fair this is easy to work around, but is expected behavior for those coming from WRspice (IIRC).
2. Subcircuit parameters appear to be broken (unless I'm the broken one!), e.g.:

X1 TEST 1 0 RES=10.0 I1 0 1 1.0

.subckt TEST IN GND R1 IN GND RES .ends

.tran 0.25p 5n 0 1.0p .print v(1) .end

yields 

E: Parsing The following variables were not found/defined. Please ensure that these variables exist within the netlist. Variables: RES

Another attempt, trying to interpret the manual's instructions for declarations:

X1 TEST 1 0 RES=5.0 I1 0 1 1.0

.subckt TEST IN GND RES=10 R1 IN GND RES .ends

.tran 0.25p 5n 0 1.0p .print v(1) .end

which yields

E: Input The IO of line "X1" does not match the subcircuit IO. Please check the line and ensure correct IO and that parameters do not contain spaces.


Expected behavior is to substitute the indicated LABEL=VALUE pairs into the subcircuit instantiation, as indicated in the manual and by custom. I'll try to dig through the source a bit, but wanted to bring this up. Thanks for pushing this project forwards!
grahamrow commented 1 year ago

Okay, in void Netlist::expand_io of Netlist.cpp the code only checks the first token in the line for a match to the parameters:

    if (params.count(tokens.front()) != 0) {
       insert_parameter(tokens, params);
    }

where really it should iterate over each token, i.e.:

    int64_t match_count = 0;
    for (auto & element : tokens) {
      if (params.count(element) != 0) {
          match_count++;
      }
    }
    if (match_count != 0) {
      insert_parameter(tokens, params);
    }

Though this creates an E: Out of range error. This is a bug so clearly some more tweaks are needed...

grahamrow commented 1 year ago

Okay, I think I have this solved, will open a pull request since continuing to comment will surely be annoying for everyone đŸ˜„

JoeyDelp commented 1 year ago

Hi Graham, thanks for raising this issue.

The first issue is one that I can easily add to the functionality as you mentioned, since it's just a matter of keeping track of which subcircuit node maps to which internal node when expanding the netlist.

The second I will try to address more clearly in the manual. The first example you tried was almost correct,

X1 TEST 1 0 R1=10.0
I1      0 1 1.0

.subckt TEST IN GND
    R1 IN GND RES
.ends

.tran 0.25p 5n 0 1.0p
.print v(1)
.end

The only change is that you need to specify the actual component, and not the parameter that you are changing.

Edit: Haven't looked at the code in a while and spoke nonsense, edited to remove nonsense

grahamrow commented 1 year ago

Thanks Joey,

Ahh, okay interesting that works well for RLCs, etc.. I'd been planning to use parameters for amplitudes and frequencies on sources with expression-based source terms. How would that work if there's no explicit association with the parameter name? e.g.:

X1 TEST 1 0 AMP=1.0 FREQ=1e9 (can't use I1 here since there are multiple parameters)
I1      0 1 1.0

.subckt TEST IN GND
    R1 IN GND 10.0
    I1 GND IN sin(0 AMP FREQ)
.ends

.tran 0.25p 5n 0 1.0p
.print v(1)
.end

I'd messed around with just searching all tokens in all subcircuit lines and replacing any token with a match based on the parameter/value map, but the tokens get parsed with characters like ")" and "(" and presumably some other arithmetical operators so I wanted to pause and check with you.

brainkz commented 1 year ago

Hi @grahamrow and @JoeyDelp ,

I use JoSIM a lot in my research and wrote a utility to flatten the hierarchical netlist while considering named parameters. The flattened netlist is then passed to josim-cli.

It's been working well for me and I added some extra tweaks to make it work with the tests in JoSIM. Perhaps, this script could be polished and integrated into JoSIM, if that is of any interest?

JoeyDelp commented 1 year ago

Hi @brainkz, this functionality is already present in JoSIM. When you run with verbose level 3 (`-V 3') a flattened netlist with named parameters substituted is produced on screen.

brainkz commented 1 year ago

Thanks for the heads up, and sorry that I did not write my message clearly. The purpose of the utility is to extend JoSIM's support to named parameters, thus enabling definitions with keyword parameters

...
.subckt COMPARATOR in out clk area_top=2.0 area_bot=2.5 lout=1e-12
    Btop clk in  jjmit area=area_top
    Bbot in  0   jjmit area=area_bot
    Lout in  out lout
.ends
X1 COMPARATOR a b t area_top=4 area_bot=5 lout=1e-11
X2 COMPARATOR c d t area_top=3
...

to yield a netlist where parameters area_top=4 area_bot=5 lout=1e-11 and area_top=3 in, respectively, X1 and X2 are propagated into subcircuit (akin to HSPICE)

...
BTOP|1 T A JJMIT AREA=4
BBOT|1 A 0 JJMIT AREA=5
LOUT|1 A B  1e-11
BTOP|2 T C JJMIT AREA=3
BBOT|2 C 0 JJMIT AREA=2.5
LOUT|2 C D  1e-12
...

(Node renaming was inspired by Netlist.cpp)