Table of Contents

Node procedure

On read-in

A NODE_MAP belongs to a CARD_LIST, which stores a circuit. Read-in is implemented in a lang_* plugin. At this time, the NODE_MAP is populated as needed whenever a connection is made.

loop(devices) {
    parse_ports:
	set_port_by_name | set_port_by_index
	    calls node_t::new_node, NODE_MAP::new_node
	    which enters to node_map (per scope)
	    (n_()) (_nnn)	points to a USER_NODE in scope()->nodes()
	    (t_()) (_idx)	flat, global id number (==_nnn->user_number)
	    (m_()) (_m)		INVALID_NODE (==-1)
            (link())            node_t*. union find structure.
}

special cases: The first node in the toplevel scope (position 0) is reserved for ground, named “0”. Floating ports in subcircuit instances have e_()==INVALID_NODE.

NODE_MAP stores (by pointer) instances of USER_NODE. A USER_NODE has a node_t at n_(0), it stores the index aka user number. This way, a USER_NODE acts as a one-port device with a connection to the node at its index.

A Port in a device that is not connected during read-in will later be assigned to a floating node. In modelgen-verilog, The $port_connected function indicates this situation following Verilog-AMS LRM Section 6.5.6.

modules

defining modules {

all_new, makes_own_scope
"name" is the  name of the port for outside, not used by spice and spectre.
"value" is for inside

“all_new” disallows ground and dups, because the internal name may be used externally. Dups are allowed internally. Not sure if it works. }

Done with read-in.

expansion

two cases

A CARD_LIST is expanded to prepare the circuit for simulation. This may either happen immediately after read-in, or after taking a copy, as when instantiating a clone of a subcircuit. A subcircuit clone lacks the USER_NODEs in its NODE_MAP.

SIM_DATA

in SIM_DATA::init(scope) {

  if (is_first_expand) (no nodes allocated yet) {
      0. map_toplevel_nodes
          a node_t vector has been allocated (in scope->nodes())
          connect all nodes in subdevices and USER_NODES to the respective node_t in that vector.
          i.e. call map_subckt_node(&top_nodes[0], *ci) on all their net_nodes
1. scope->expand() ..  includes precalc_first, expand_first, expand, expand_last
    For devices that have a subckt, expand() makes a copy.
    Code to do this is per devicetype, with too much duplicated code.
    Using DEV_SUBCKT::expand().
    Which usually does:
	renew_subckt() .. which is really new_subckt(), makes an empty one.
	subckt()->expand() .. recursive .. does real copy here
	node links: 	node_t::link() reference to parent in union forest.
2 -- node allocation
          node_t::allocate()  allocate a node if needed.
          
          

node_t::map()

connect a node_t to the effective NODE instance that contains the simulation data. set _nnn to point to a LOGIC_NODE. set _m=_nnn→matrix_number();