0

Let's say I create a block with resistors R1 and R2. I want to use this block as a subcircuit in other designs. The typical way to pass in the values for R1 and R2 is to right-click on the block and type in the values as shown in the image below.

How do I pass the parameters to the block X1 as a spice command instead of right-clicking and typing the parameters manually? I would like to put all my parameters in a file and use the .include statement to import the values.

Leonhard Euler
  • 374
  • 3
  • 10
  • 1
    Just look over [this LTspice](https://i.stack.imgur.com/kkKtZ.png) example from my collection of LTspice ideas I've worked on in the past. It's a PNG, but it is big and you can zoom up on it where you need to. You can see pretty much everything LTspice offers in terms of parameterizing SUBCKT blocks. If you can't find it in that mess, then it's probably not available. I used everything there that I know about. So it exhausts my abilities. – jonk Jun 24 '21 at 06:54
  • You can set up default params within a SUBCKT and over-ride them with a call to it. A SUBCKT can have more parameters inside it, only some of which are over-ridden, or it can have fewer parameters in it and the caller can provide more than it knows how to use, too. You can set up a default arrangement and then override just the parts of that default you want to over-ride. You can refer to global parameters in the computations as well as local parameters in any combination. I'm not sure what you actually need. If you look at that picture I provided yesterday, I think it's enough for all needs. – jonk Jun 24 '21 at 19:15
  • However, I probably don't understand why you think there is any difficulty. For example, you can create a SUBCKT block that has default parameter values for your two resistors. You can use that block in another SUBCKT and there you only may want to modify one of the resistor values, not both. You don't have to specify both. You can just specify one. You can have very complex circuit with lots of parameters and stamp it around all over the place, and only have to modify the few things you care about when using it, picking up defaults for the rest. You can have the defaults be global or local. – jonk Jun 24 '21 at 19:22
  • So, if you post up a very specific schematic that works, but where there is also a very specific complaint that you can express clearly and ask if there "is a better way to achieve X" then I might take a hack at answering. But right now, what you show is... not enough. I can't really tell what the complaint really is about. I can just see a simplistic example that you imagine is sufficient to communicate. To me, it's not. But that may just be me. That said, I need more than I see. Questions I don't feel I fully understand merit only a few comments from me. No reflection on you. That's just me. – jonk Jun 24 '21 at 19:26

1 Answers1

1

In the way you constructed your block with the two resitors, in that same way you can pass parameters to subcircuits using your block:

* a subcircuit/block with two resistors whose
* values need to be defined externally

.subckt r2d2 a b
r1 a 1 {r1}
r2 1 b {r2}
.ends r2d2

* another subcircuit that makes use of r2d2, and
* who needs, in turn, the value for its own,
* internal resistor, defined externally:

.subckt 3po x y
xu1 x 1 r2d2 r1={p} r2=1k
r1 1 y {q}
.ends 3po

* using 3po in some schematic/netlist with
* externally defined values :

xu1 m n 3po p=2k q={a}
.param a=3k

As you can see, not all subcircuit parameters need to be defined in .param statements, the same way not all need to be defined inside the instance of the subcircuit; they can be mixed. Using an .inc can be done the usual way from this point forward.


Just to be sure it's clear: subcircuits are like a scope and anything that happens inside a subcircuit stays within that subcircuit, unless it's made available to the outside from within the subcircuit. That means either passing parameters to the subcircuit (what you're showing in your picture) or external pins that make available internal quantities (voltage, current) to the outside world.

Also see this answer.

If your purpose is to have the .param statemens residing in an external file to be included with .inc then the only way to change them is through assignment with {}, which implies editing by hand -- one or another. The only other shortcut to defining each parameter, separately, is to have all the parameters related through a function, in which case, instead of a long .param line you can have a .func. The values will then be f(1), f(2), etc, and the function .func f(x) {2*x+1} (for example).

a concerned citizen
  • 21,167
  • 1
  • 20
  • 40
  • Let's say I use 10 such r2d2 blocks. Then I would have to assign a parameter to each one of them, such as `r1={r1}` and `r2={r2}`. This is exactly the issue I am trying to avoid. I don't want to right-click any block and start assigning random names to them. I was hoping there would be some sort of command such as `.subckt instance_name params: r1=1k r2=1k`. This way I don't right-click anything and I know the block whose parameter I am changing. – Leonhard Euler Jun 23 '21 at 20:52
  • 1
    @ChadWinters It looks like you need the same parameters for all the blocks, i.e. `r1=1k` for all. In that case, what I said very much applies: place one block, assign parameters in curly braces (`r1={r1}`), copy-paste to your heart's desire, then add `.param r1=1k`. With that you've changed the values for all. If you want to avoid either the naming part (`r1={r1}`) or the copy-paste (or both), you're out of luck because what happens inside a subcircuit stays within the subcircuit. Those `{}` assignments are the only way to pass parameters. Or add an external pin and read some voltage, but... – a concerned citizen Jun 23 '21 at 21:33
  • 1
    ...that won't work for values, since they will be `time`-related. In general, comodity comes at a price. In order to have an `.inc` for `.param`s you need to define the values with `{}`. The advantage of assigning values like this is that you can change them all from one `.param` statement. The disadvantage is that you need to type. – a concerned citizen Jun 23 '21 at 21:36
  • I think you misunderstood me. The resistor values are not 1k for all blocks. That would make this whole question pointless since I could just set the values in the subcircuit and be done with it. I would like to know if there's a way to instantiate 10+ blocks and assign different values to the resistors of each block without having to right-click and set a random parameter name for each resistor value which I can later change. I hope my question is a bit clearer now. – Leonhard Euler Jun 23 '21 at 22:41
  • 1
    @ChadWinters I think this answer covers the most you'll be able to manage using LTspice, since you'll have to set up the right-clicking at least once to put placeholder global parameters. That's what 3P0 was trying to tell us, but he's easily tuned out until you realize you're stuck in an asteroid field with no hyperdrive. I think the disconnect might be that you believe it's possible to modify parameters of an instance outside of the actual instantiation command, which you cannot do. If you still think we're missing the point, I suggest editing your question to add more details. – Ste Kulov Jun 24 '21 at 04:45
  • @ChadWinters Can you expand on "*random parameter*"? Do you mean a Monte Carlo analysis with `mc()`? Anyway, I also said that "*If you want to avoid [...], you're out of luck because [...]*" (beside other things). Can you tell me how do you intend to modify the values for each block without editing the values? Because I don't see any other way. If the values are related then a `.func` will do, but you still need to edit each value: `{f(1)}`, `{f(2)}`, etc, and only one function such as e.g. `.func f(x) {2*x+1}`. If you want the parameters to reside in an external file, `{}` is the only way. – a concerned citizen Jun 24 '21 at 07:22
  • I've also added this to my answer. – a concerned citizen Jun 24 '21 at 07:30
  • @aconcernedcitizen I hope you didn't think I was being combatant in my previous answer. Let me try to be extremely clear. Let's say I have a subcircuit with with 2 resistors `r1` and `r2`. I want to use this subcircuit in a design 10 times. If I understood you correctly, I would have to: 1. right-click on a block 1 and type in the params field `r1 = {RR1} r2 = {RR2}` 2. right-click on a block 2 and type in the params field `r1 = {RR3} r2 = {RR4}` 3. do the same for the rest. With the above, I can now use a `.params RR1=10K RR2=1K ...`. Is this what you meant in your post? – Leonhard Euler Jun 24 '21 at 16:55
  • @ChadWinters Yes, or explicit assignment: `r1=10k, r2=1k, ...` for each resistor. No matter what, editing is needed, because what you want, to simply place the subcircuit without any modifications and use `.param r1=1k` (external file, or not) will not affect in the least anything inside a subcircuit because, as mentioned, anything that happens inside the subcircuit stays within the subcircuit. However, `{}` instead of explicit will allow external `.param` statements to change them. No combative counter measures have been deployed, and I hope I was also clear enough. – a concerned citizen Jun 24 '21 at 17:07
  • @aconcernedcitizen Thanks for your understanding. Well, this problem is what the whole question is about. I thought there was some syntax such as `.subckt block1 params: r1=1.22k r2=1.2k`. – Leonhard Euler Jun 24 '21 at 20:50
  • @ChadWinters Right, but can you see the problem with that thinking? You have only *one definition* for the `.subckt`, and in there you have `r1={r1} r2={r2}`, that's it. Placing N instances in a schematic will be done with the same `r1={r1} r2={r2}`, N times over. So how would you be able to differentiate between the `r1` from the first instance, and the `r1` from the second? That's the problem. In order to be able to, you'll have to either make *separate* `.subckt` definitions for each instance, e.g. `.subckt r2d2_1 ...`, `.subckt r2d2_2 ...`, all with separate settings, or what I suggested. – a concerned citizen Jun 25 '21 at 06:44
  • Both solutions require the same thing: editing each value by hand N times -- and that's what you were trying to avoid. Well, to be fair, it's only N times if you define the values explicitely, i.e. `r1=1k r2=2k ...`, because parametric will take 2N times: `r1={r1} r2={r2} ...` + `.param r1=1k r2=2k ...`. The `.param` block can be either in the schematic or outside of it, it doesn't matter, but parametric assignment of values will allow changing them from the same location/file, as opposed to revisiting all the instances one by one. That was the whole message that I tried to convey. – a concerned citizen Jun 25 '21 at 06:47