6. cschem implementation - hierarchy

{imp6:0} Hierarchical design is implemented in a way that keeps non-hierarchical design simple while does not complicate hierarchical design too much either. Carefully designed non-hierarchical sheets can be easily reused in hierarchical designs - the most important thing to note is how global networks are used.

6.1. Topologies

{imp6:1} The following table demonstrates all 3 topologies mentioned in the specification:
flat single-tree multi-tree

{imp6:2} Notable special cases:

{imp6:3} The multi-tree setup could have a new top sheet that just references all the roots and it's then a single-tree setup. So how does the multi-tree setup differs from the single-tree setup? Only that it does not have such a single top-level sheet that references all others. The reason to keep this possibility open is the project file. A project file can list all the top level sheets (roots), having to have a redundant or extra top level file just for this list would be annoying. On the other hand, the project file can describe non-cschem-aspects of the project, which a schematics sheet can't, so it's not possible to omit the project file as an optional feature.

6.2. Hierarchical example for all network parameter types

{imp6:4} Assume there is a project with two sections: a sensitive analog circuitry (called "an") and a high frequency logical control circuitry (called "dig"). The analog circuit contains 4 copies of the same subcircuit ("amp") and some glue. The whole design is a module that could be used in a bigger circuit.

{imp6:5} This section gives one of the many possible ways to implement this with cschem, described in a top-down way.

{imp6:6} Because of its simplicity, the single-tree topology is chosen. A top sheet (root sheet) is created with two symbols: one for "an" and one for "dig", with symbol attribute cschem/child/name set to "an" and "dig" respectively.

{imp6:7} There will be a few control signals that need to travel between the two; these are added as terminals to both symbols and they are connected with wires-nets on the top sheet. an and dig also need to take power, "Vcc" and "GND" terminals are added on both. The top sheet is a good place to connect the Vcc of the two worlds with ferrite beads and capacitors added to avoid digital noise ending up in "an", separating the networks to avcc/dvcc and agnd/dgnd.

{imp6:8} We will have a subtree-local "enable" signal that should be used by both "an" and "dig" to enable the circuitry. Instead of passing this through terminals, we will define it as a subtree-local circuit, "netname=v/enable" on the top sheet.

{imp6:9} Since the whole project would be a reusable part within a bigger project, the top page should have terminals to get networks from a parent later. These terminals shall be named, placed on the sheet and connected to the a network. Our network "v/enable" will be connected to a sheet terminal called "enable".

{imp6:10} For "dig" we create a single sheet. It should have sheet-level terminals matching the ones we used on the top sheet for the "dig" symbol. We do not have a terminal for the enable signal, tho: whenever we need to connect a symbol terminal to it, we can just add a "connect=^enable", which means "connect to our parent's enable signal". The rest of the signals and connections can be realized normally, as if this was the only sheet; named networks should have the "./" prefix in their netname to avoid binding to global nets.

{imp6:11} For "an", we follow the same procedure, except it won't have much of its own circuitry will be 4 copies of the same symbol referencing to "amp". Most probably "an" will never need to use the "enable" signal.

{imp6:12} We create the "amp" sheet, the same way as we did create the digital sheet. We again can use the "connect=^enable" trick to connect terminals to the enable signal defined on our top sheet.

{imp6:13} Finally, there should be a global chassis ground. Every module that has any electronics in it shall be connected to the chassis ground. This is realized by a global network chgnd, assumed to "just exist". It would be normally created by the user of our subtree. Connection to the chassis ground is done by "connect=chgnd" (which does not enforce "chgnd" to be global, but allows that).

{imp6:14} The final "flow of nets" is as shown on the figure below. Blue objects are sheet-local; red arrows represent a connection through terminals on both ends; green lines are subtree-local network bindings, without the use of terminals. Purple lines are global network bindings.

6.2. Considerations for the example

{imp6:15} We did not enforce "chgnd" to be global, but referenced it without a prefix: lookup scope is "auto". This means a search is started from bottom up, and the first subtree-local "chgnd" can be used, or as a fallback, the global one will be used (or even created if nobody else did yet). It's a good practice to do this: we can not be sure what hierarchy we'd have above us, and it may be that the user will want to quarantine us chgnd-wise, by creating a "v/chgnd" a few levels up. This way the "chgnd" network can be split up by subtree.

{imp6:16} Referencing the enable network from amp as "^/enable" is safe: even if the hierarchy above us have "v/enable" defined, the search will always stop at the innermost hit, so "amp" will always bind to the "v/enable" of "an".

{imp6:17} This is a typical use of subtree-local networks: instead of complicating the API of both "an" and "amp" by more ports for networks that will be shared by all instances anyway. It's sort of a global network, without "infecting" other parts of the hierarchy. The actual way it's bound to ext_enable can be a simple "connect=v/enable" on the sheet level (input) terminal for the "enable" network on the top sheet. This would both create "v/enable" and connect it to the input.

{imp6:18} Reusing "amp" in another project without "an" is easy. The API of "an" is defined as:

{imp6:19} In a hierarchical setup global nets like chgnd is dangerous and probably better to avoid. For example if no other sheet creates a chgnd, multiple instances of "an" will still create one and get connected through it in a way that this network is then never really grounded. The obvious reason chgnd is included in the above example is to demonstrate how global nets work. The reason the concept of global nets exists in cschem is to support the flat topology.

6.3. How the netlist would be generated

{imp6:20} In case of flat netlist syntax: the hierarchy exists only in the concrete model - once the project is compiled into an abstract model, that model is flat. Generating the flat netlist from the flat abstract model should be trivial, especially that names are already unique and flat in the abstract model.

{imp6:21} In case of hierarchic netlist: there are strong cross-referencing between the flat abstract model and the hierarchic concrete model. The exporter plugin would start working from the abstract model and by looking at the cross references it would be able to understand the original hierarchy.