Differences

This shows you the differences between two versions of the page.

Link to this comparison view

gnucap:manual:tech:nodes [2025/05/16 10:29] (current)
felixs created (outline)
Line 1: Line 1:
 +===== 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.
 +
 +<code>
 +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.
 +}
 +</code>
 +
 +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();
 +
 +
  
gnucap/manual/tech/nodes.txt · Last modified: 2025/05/16 10:29 by felixs
 
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Run by Debian Driven by DokuWiki