# 10. cschem implementation - forge

{imp10:0} The most common example of for forge is the generic power (rail) symbol. The power symbol has a single terminal, usually named 1. This terminal should be connected to the rail network named, within the symbol, e.g. to VDDQ. This can be done using the connect attribute with value 1:VDDQ.

{imp10:1} But VDDQ also needs to be printed as a dyntext. Dyntext can not address the first element of an array and especially can not remove the "1:" section. If the text object contains simply "VDDQ" without dyntext, it means this information is stored twice, once in the connect attribute, once in the text object. Such setup is prone to errors in case of a generic power symbol where the user needs to change the rail text. (It is okay to hardwire things like that in a Vcc-like symbol where the user can not change rail value.)

{imp10:2} An easy solution with the forge plugin is to store "VDDQ" in an custom attribute, which is printed using dyntext and not specify the connect attribute at all. Instead specify forge that creates connect from the custom attribute.

{imp10:3} Example forge script for the above, assuming the custom attribute is called rail and terminal name is 1:

    delete,forge/tmp
    scalar,forge/tmp
    sub,^,1:,forge/tmp
    suba,$,rail,forge/tmp
    array,connect
    append,connect,forge/tmp

{imp10:4} The first two operations ensures an empty scalar attribute called forge/tmp. The next two use regex to build 1:rail in forge/tmp (rail is substituted with the value of attribute rail, because of suba). The last two operations ensure connect exists as an array type attribute and appends the new connection to it.

## 10.1. cschem implementation - stances and build options

{imp10:5} Suppose the current project of 3 sheets is of an MCU controlled board with various sensors. The MCU, the interface circuity and some of the sensors are mandatory, but some of the more expensive sensors are optional. A design decision is made so that there are models standard, advanced and professinal. There is only one PCB is made for all options, but different components are DNP'd for the different options.

{imp10:6} The implementation in cschem is:

- set up the possible values for the model stance to a list of: standard, advanced and professinal
- set the value of the model stance to one of them, e.g. advanced
- for each abstract component that is not present on all three models, visit the symbol(s) contributing to that component and add a conditional forge attribute that creates a pcb/dnp attribute if the component should not be populated on the pcb for a given stance

{imp10:7} For example take a sensor that should be on advanced and professinal but not on standard. Create the array type attribute forge-if/model-dnp (the model-dnp part is arbitrary) with this content (each line is an array element):

    (stance.model != "advanced") && (stance.model != "professinal")
    scalar,pcb/dnp
    sub,^.*$,DNP,pcb/dnp

{imp10:8} The condition specifies when the component is DNP. Alternatively it could be written as (stance.model == "standard").

{imp10:9} The rest of the forge is setting the pcb/dnp attribute to DNP. The value could be anything, as long as the attribute exists and is non-empty, the export mechanism should take it as true. Using DNP is practical for dyntext printing the attribute value on the sheet.

{imp10:10} Note: stances and lists of possible stance values shall be stored in the project file (e.g. project role configuration) and not on sheet level because it affects the abstract model, which uses all sheets of the project.

{imp10:11} Now suppose there's an orthogonal property, whether the device is going to ha a battery option, which affects whether the board has a battery charger circuit. All three models can be shipped with or without the battery option. One way to handle this is to double the stance.model values, from 3 to 6, so each has a battery and a no-battery variant. But a more elegant solution is to keep the original 3 models and use the sub_major stance with two values, with-battery or no-battery. The process of creating the stance values and creating the DNP forge for the battery charger is the same as above, using stance.sub_major instead of stance.model.