## Back annotation

### Theory of operation

Forward annotation is when the schematics editor exports a full "current state" of the project in a netlist and pcb-rnd loads that. On pcb-rnd side this is called import schematics or import netlist (the latter loads connectivity information only, the former connectivity and a lot of metadata like footprints and component values).

After a forward annotation, pcb-rnd will be in sync about the "current state" of the project. The user will go on editing; most changes that are in-line with the imported netlist/schematics (the rats nest will guarantee that). There may be mistakes, for example accidentally shorting two nets; these are changes contradicting the imported netlist. This is also detected by the rats nest code in pcb-rnd and a short circuit warning is generated. (Note: the user needs to invoke the check manually, e.g. using the hotkey {c r}).

For pcb-rnd to be able to perform the check any time, the imported netlist, called input netlist needs to be saved in the board file.

Back annotation is when the user makes a deliberate edit in pcb-rnd that contradicts with the input netlist (or at least not mentioned in the input netlist), then pcb-rnd keeps track on this deviation from the input netlist and later on the deviation is sent back to the schematics editor where the schematics is upgraded to incorporate the chnages made in pcb-rnd.

Just by looking at a conflicting edit, pcb-rnd can not decide if it was accidental or delibrate. Therefore by default pcb-rnd assumes a conflicting edit is a mistake. When the user wants make a deliberate deviation from the input netlist, they need to indicate this by using a dedicated commandfor making the change so pcb-rnd understands it's a change that needs to be tracked and back annotated.

Tracking such changes intended for back annotation is done using the netlist patch, which is also saved in the board file (when using the right file format). The netlist patch is an ordered list of simple, atomic operations the user made to deliberately change the "current state" of the project in pcb-rnd. This netlist patch is then can be exported in pcb-rnd and imported in the schematics editor where the schematics can be upgraded. Then upon the next forward annotation, pcb-rnd automatically detects if changes on the board's netlist patch are applied to the schematics and removes those changes from the board's netlist patch.

Implementation detail: once a deliberate change is made for back annotation, pcb-rnd assumes this is the new state of the project and all checks are done accordingly. For example if the user uses back annotation tools to remove the connection of U4-3 to gnd, what the next rats nest generatio (hotkey: {c r}) does is making sure that all connections from the input netlist are done properly, except for the "U4-3 to gnd" connection, which is still part of the input netlist but not part of the "current state" of the project. This is done by maintaining a second netlist in memory, called the edited netlist; this one is never saved in a file. The edited netlist is the input netlist plus netlist patches applied.

Schematics editor side support: in the simplest case the schematics editor should load the back annotation patch file and present it as a list of changes the user needs to perform. A more advanced approach is also auto-detect whether the changes have been done and present the state of each item of the list on the UI. An even more advanced feature is when the schematics editor can make edits, upon explicit request from the user, to implement items from the list (sch-rnd can do this for most instructions).

### Schematics editors and file formats and versions

At the time of writing (September 2023), the following back annotation support is available.

Back annotation file formats that can be saved from pcb-rnd:

format | comments
--- | ---
bap | The old Back Annotation Patch format originally developed for pcb-rnd to gschem back annotation; limited to a few types of instructions: can do pin swaps, break conn and add conn; this file format is very simple but lacks header and version information so can not be extended/upgraded.
tEDAx backann v1 | Similar functionality as bap, but has a proper file format with header, well documented syntax (handling corner cases like escaping whitespace) and versioning so that it could be upgraded. Supports the same features as bap, plus subcircuit and network attribute changes.
tEDAx backann v2 | Newer version of backann; also supports adding and removing subcircuits.
pcb | This is an internal format that should be used only by the code when saving the old .pcb format from the times when pcb-rnd still used gEDA/PCB's file format but already extended it (for example with netlist patches). Supported functionality matches bap, but nothing reads this format from a stand-alone file.

Schematic editors that can use pcb-rnd exported back annotations:

software | limitations
--- | ---
sch-rnd | none - supports everything pcb-rnd does; supports auto-fix for most instructions
xschem | works using the old bap format; later on may upgrade to tEDAx backann v2; no auto-fix
gschem | from about 2019 (1.10.x), it supports bap; no auto-fix; no hope for an upgrade

Schematic editors vs. file format version vs. functionality:

software | bap | tEDAx backann v1 | tEDAx backann v2 | present list of changes | auto-detect if item is implemented | auto-fix item when requested
--- | --- | --- | --- | --- | --- | ---
sch-rnd | yes | yes | yes | yes | yes | yes
gschem | yes | no | no | yes | yes | no
xschem | yes | no | no | yes | ? | ?

Board formats/versions: back annotation patches are saved only in the gEDA/PCB format and lihata board format. A gEDA/PCB file saved with netlist patch may be unreadable in gEDA/PCB (but is readable by early versions of pcb-rnd). Some features are accessible only in lihata board format, and some even have minimum file format version requirements, see the li:netlist_patch subtree in the file format doc.

### Operations that can be back annotated

This section lists all operations that are available for back annotation. A few of them are demonstrated in the sch-rnd back annotation tutorial video. The rest work very similar; this section concentrates on what each operations does on instruction level and where to find the given operation. The network window can be invoked from the window menu or with the hotkey {w n}.

#### Inspecting the netlist patch

GUI: netlist patch (a.k.a. back annotation) window; can be be invoked from the window menu. Lists all instructions in order. The Remove button can be used (at your own risk) to remove any instruction (potentially breaking further instructions depending on this one).

CLI: save the file in the lihata v9 format and look for the li:netlist_patch subtree.

#### Add connection

Creates a new connection between a terminal and a network. The terminal can not be conncted to any network at the moment.

GUI: select the line tool and the rat layer and draw a line from the given terminal to any other terminal that's on the target network.

GUI: select terminals, then network window; select a network on the left side, click on the "add conn" button. This will add all selected terminals to the selected network. Selected objects that are non-terminal are ignored.

CLI: BaConn(selected|object, add, [netname])

#### Break connection

Breaks an existing connection between a terminal and a network.

GUI: network window; select a network on the left side, select the a terminal on the right side list, click on the "break conn" button.

CLI: BaConn(selected|object, remove)

#### Swap terminals

Remove the connection of both terminals selected and add new connection for each, swapping the two connections. GUI: network window; select a network on the left side, select the a terminal on the right side list, click on the "break conn" button.

GUI: select two terminals then menu: Connects/Design changes.../Swap nets

CLI: select two terminals then action: NetList(swap)

#### Remove net

Break all connectsions to the given net.

GUI: network window; select a network on the left side, click on the "del" button.

CLI: action: NetList(remove, netname)

#### Rename net

Break all connectsions to the given net and make the same connections to a new net with a new name.

GUI: network window; select a network on the left side, click on the "rename" button.

CLI: action: NetList(rename, old_netname, new_netname)

#### Merge nets

Break all connectsions to the source net and make the same connections to the also existing destination net. This effectively moves over all connections from src to dst, merging the two nets keeping dst and removing src.

GUI: network window; select a network on the left side, click on the "merge" button.

CLI: action: NetList(merge, src_netname, dst_netname)

#### Claim net

Create a new net, with connections to existing subcircuit terminals, by looking at copper objects on the board.

GUI: menu: Connects/Design changes.../Claim net*.

GUI: netlist window, Claim button group.

CLI: action ClaimNet()

#### Add new subcircuit

Add the creation of an existing subcircuit to the back annotation list by refdes.

GUI: place a subcircuit, make sure it has an unique refres; right click over an empty area of the subcircuit; this brings up the subc contextmenu; select back annotation then Add.

CLI: action: BaSubc(object|selected, add)

#### Remove subcircuit

Add the removal of an existing subcircuit to the back annotation list by refdes. Also remove all connections to the subcircuit.

GUI: find a subcircuit with unique refres; right click over an empty area of the subcircuit; this brings up the subc contextmenu; select back annotation then Del.

CLI: action: BaSubc(object|selected, del)

#### Subcircuit: footprint replace

Replace selected subcircuits on board from the library and remember the footprint attribute change on the netlist patch.

GUI: select subcircuits; Connects/Design changes.../Replace selected footprints

CLI: action: ReplaceFootprint()

#### Change or create subcircuit attribute

Remember a new attribute value for an existing attribute, or create a new key/val attribute for back annotation for a subcricuit.

GUI: open the property editor for the subcircuit (e.g. right click subcircuit context menu), select an attribute or the 'a' subtree on the left side; the backann checkbox appears on the bottom, make sure it's checked in; make the necessary attribute modification

CLI: propset() while conf node editor/backann_subc_attr_edit is set to true

#### Change or create network attribute

Remember a new attribute value for an existing attribute, or create a new key/val attribute for back annotation for a network.

GUI: network window, select net on the left side, click the attr button. There is no backann checkbox in this propedit window, all changes are back annotated by default.

CLI: propset() while conf node editor/backann_subc_attr_edit is set to true

### Historical aspects

An overview on how the feature got designed and how previous versions worked and evolved can be found in the backann pool node.