(This page is currently being substantially reworked!)

Contents

Introduction

Digital simulation of the AGC electrical design can provide detailed insight into how the computer functions.  Aside from satisfying simple personal interest, this is very valuable if you wish to create a simulation of the AGC, in the manner of Virtual AGC Project's Block II AGC software simulator or Block I AGC software simulator, or John Pultorak's Block I AGC hardware simulator, and want to have some way of verifying that your creation works properly.

Realize, though, that the purpose of such simulations can only be accurate examination or verification of AGC behavior, and they are not practical substitutes for software (such as our yaAGC program) designed and dedicated solely to running AGC software.  While you can use digital electrical simulations to run AGC software, these simulations are very much slower than real time.  One day, as computer speeds continue to advance, I expect that digital electrical simulations will be much faster than now!  But "faster than now" not now.  Recognize too that while simulation of the AGC or DSKY's analog circuitry is also possible, that's not what I'm talking about here.  It is simulation of the digital circuitry — i.e., the collection of logic gates in the AGC — that will be of interest.

Here's an executive summary of the workflow of the digital-simulation process as I envisage it, and which will be used throughout the remainder of this page: 

#
Workflow Step
Comment
1
The electrical schematics — in our case, the original schematics of the AGC — are transcribed for use with modern schematic-capture software. The schematic-capture software in question is called KiCad EDA.  The transcribed schematic files are here.
2
Netlists — i.e., files that list every electrical connection in a given electrical schematic — are created.
KiCad itself creates the netlist files.  There are many different formats of netlist files, all containing roughly the same information.  For our workflow, the specific format known in KiCad as ORCAD PCB 2 is required.
3
The netlists+schematics+initial conditions are translated into Verilog source code. Verilog is a high-level hardware description language.  The translation into Verilog source code is performed by a Python 3 script called dumbVerilog.py that we provide, assisted by another such script that's called dumbInitialization.py

Note:  These scripts are specialized for AGC digital circuits ~1970, and will not produce anything useful when applied to non-AGC circuitry or to analog circuitry.
4
A "test bench" — i.e., a description in Verilog source code of the external inputs into the emulated circuitry vs time — is written. There's a helpful Python 3 script, dumbTestbench.py, which can automate a little of this for you, but the script can't read your mind (yet!), so you still have to make some choices for yourself.
5
A model of the Erasable/Fixed Memory — i.e., the executable form of the AGC software that the emulated AGC circuitry is going to run — is converted into Verilog source code. This has already been done, at least for an incomplete selection of the AGC software versions available to us.
6
The Verilog source code for the AGC circuitry, the test bench, and the erasable/fixed memory are compiled together into an executable form. Our workflow specifically uses the Icarus Verilog (iVerilog) compiler for this.
7
The executable Verilog program is then run in an emulator.
Our workflow uses the iVerilog emulator for this.  Typically, this creates a "dump file" of whichever of the AGC's signals were considered to be interesting when the test bench was written.
8
The output data dumped by the emulation is viewed as waveforms, similar to an oscilloscope, or else is post-processed in some other manner. Our workflow uses a program called GTKWave for this visualization of the results.

Aside:  Regarding the choice of software used in the workflow — i.e., the holy trinity KiCad, iVerilog, and GTKWave —, disagreement as to whether these are the optimal choices is always possible, and indeed likely if you happen to be a person with expertise in this particular area.  The programs were chosen because they are free of charge (and indeed are open source, like the Virtual AGC Project itself) and available for Linux, Windows, and Mac OS.  If you can make it work with the fancier tools a professional may have at their disposal, then by all means do so and let me know.  I won't change an open-source workflow into a non-open-source workflow no matter how terrific an alternate tool may be, but at least I'll be interested to hear the news and can parrot it back to the general public!

Although multiple types of simulation are possible, we'll concentrate just on these particular configurations:

One slight point of confusion is that in the AGC design, the various plug-in circuits are called "modules", while Verilog also uses the term "modules" for its constructs that are similar to "functions" or "subroutines" in other programming languages.  Now as it happens, we've implemented the simulation in such a way that each AGC module actually is modeled as a single Verilog module.  That's more-or-less a coincidence, though, and if you attempt to work with any simulations that differ from those we've pre-prepared for you, you may have to watch out for the dual meaning of this term.

References

The Virtual AGC Project's Electro-Mechanical page.

Apollo-era AGC/DSKY electrical-schematic diagrams:

AGC/DSKY electrical schematics transcribed into KiCad electrical-design software, plus Verilog translations:

Open-source software:

Mike Stewart's similar transcription + simulation effort:

Aside:  It should be noted that the AGC simulations described on this page were not based on Mike Stewart's pre-existing project, other than in spirit.  Mike's simulation was a very important resource in the sense that cross comparisons of the results output by Mike's implementation with those output by mine provided a way to detect errors in both implementations that would not have been easily discoverable otherwise.  And I can honestly tell you that it would never even have occurred to me to try this if Mike hadn't already done what he did!  It's very much a case of "me too!" on my part.   With that said, there are some pros and cons that work in both directions.  My schematics closely match the original AGC schematics, so closely that you can overlay them, while Mike's schematics are intended to be — and I believe, are! — functionally identical to the original schematics, but impossible to verify vs the original schematics without considerable intellectual effort.  Mike's version is more efficient in the sense that his simulation runs significantly faster than mine ... but you can't compare his side-by-side with the original schematics to verify correctness as you can with mine.  Which approach you prefer is a matter of taste.  What I'll be discussing here is my own approach rather than Mike's.

Workstation Setup

If you are using Virtual AGC via the Virtual AGC 64-bit Virtual Machine, then everything is already set up for you.

If not, you'll want to install the following software on your computer:

On Ubuntu Linux or Debian Linux, or derivatives of either of them like Linux Mint, installation of the three programs mentioned above is as simple as using the command "sudo apt install kicad iverilog gtkwave"; with Red Hat or Fedora, I believe but don't guarantee that you could use "sudo yum install kicad iverilog gtkwave"; on other Linux platforms, Solaris, or FreeBSD there's likely to be some easy way, but you'll have to research it yourself.

On Windows, install KiCad from the installer found at the hyperlink given above; watch for an option to add the KiCad command-line program (kicad-cli.exe) to your PATH, and if there is such an option then be sure to take advantage of it.  There's also an installer providing both Icarus Verilog and GTKWave, and I'd suggest using it rather than the individual hyperlinks given above.  But note that you'll find some additional setup instructions at the end of this section.

On Mac OS, the least-painful approach would seem to be installing homebrew, if you don't already have it, and then using brew to install the three programs rather than doing anything recommended at the links above.

Aside:  While the foregoing advice about Mac OS results in an easy installation, there are things about the process that are unpleasant and perhaps warrant a few words of warning so that you won't be blind-sided when you encounter them. 

On all operating systems, download the "schematics" branch of the Virtual AGC repository from GitHub.  There are many different ways you might do this, depending on your computer platform and personal tastes, and I wouldn't presume to dictate to you.  For the sake of discussion, however, I'll assume that you've done this by creating a folder called "virtualagc-schematics" in your home directory.  For example, if you have the git program installed on your computer, you could do it with a command like:

git clone --depth=1 -b schematics https://github.com/virtualagc/virtualagc.git virtualagc-schematics

Install Python 3 if not already installed, and then install the Python module TatSu:

pip install tatsu

or perhaps

pip3 install tatsu

or perhaps

pip[3] install --break-system-packages tatsu

Aside:  This "--break-system-packages" option doesn't imply that there's anything wrong with the TatSu package.  Rather, it relates to a wonderful new trend of using Python environments which are "externally managed", in which no new Python modules whatever can be installed in the default environment without this "--break-system-packages" command-line option.   Isn't that a lovely development in user-friendliness?  Easily-extensible systems that can't be extended?   Ubuntu has it; Mac OS has it; soon, everybody may have it.  Oh brave new world that has such stuff in it!

Within the virtualagc-schematics folder (or whatever you chose to call it) you've just created, you'll find a folder called "Scripts".  Add the path to this Scripts folder into your PATH environment variable.  Depending on your particular computer platform, the way of doing that varies.  But the following should usually work:

Extra Environment Variables for Windows and Mac OS: 

Even More Environment Variables for Windows:

It's likely that the changes to the PATH or PYTYONPATH won't affect any existing command line terminals which are already open, so you'll probably have to open a new command-line terminal to get the benefit of the change(s).

First Example: Simulating a Small Digital Circuit

The Virtual AGC software repository already contains some fully-worked out examples of digital simulations. The simplest example is something called "testVerilog", which is actually a small circuit block extracted from the AGC's circuit module A1, the "scaler" module.  Per the installation instructions in the preceding section, all of the workflow steps will be carried out in the folder virtualagc-schematics/Schematics/testVerilog/.  The results given below were generated using KiCad v6, but any later version should work as well, I hope.  If you have KiCad v5 or earlier, the transcribed schematics are no longer present in the current repository, and the module schematics (testVerilog/*.sch) would have to be retrieved from the older repository version tagged as "KiCad-5"; but I have not tested, and other files might need retrieval as well.

Aside:  My intent is to walk you through the steps of the simulation workflow.  If you haven't the fortitude for that — I understand and forgive you! —, there's a script (simulateModuleII or simulateModuleII.bat) which can do all of the work for you and just present you with the visualization of the simulation data created by the workflow.  If you feel strong enough, then take the high road and skip past simulateBlockII to the main narrative instead of running the script.

But if you must, here's how to take the low road and use the script.  For KiCad 7 or later, you can do the following (with \ in place of / in Windows):

cd virtualagc-schematics/Schematics/testVerilog
simulateModuleII A1

It's slightly more involved for KiCad 6:

cd virtualagc-schematics/Schematics/testVerilog
# Edit module.kicad_sch in eeschema and generate netlist file module.net,
# via eeschema's File/Export/Netlist/OrcadPCB2/Export Netlist.
# Then exit eeschema.
eeschema module.kicad_sch
simulateModuleII A1 module.net

After the simulation completes, you can just jump down to workflow step #8 to see the simulation data displayed in a visualization program.

Workflow Step #1:  We've actually transcribed this circuit for you already as a file called module.kicad_sch, so you needn't do anything.  Still, just to give you an idea how it works, here's very high-level summary.

Start with the original Apollo Program schematic-diagram drawing for module A1, which is drawing 2005259A, two sheets (click to enlarge):

 

Don't be confused by the fact that the inputs of NOR gates in the circuit are decorated with little triangles that make the gates look like rocket ships.  (Was it intentional, I wonder?)  They're just regular NOR gates in spite of that.  The numbered oval pads are the inputs from or outputs to the AGC backplane into which the various AGC circuitry modules plug.  Perhaps I should also point out that the NOR gates used in the AGC were open-drain gates, in which you can directly tie together outputs from different gates (effectively AND'ing them without any literal AND gate).  

Aside:  I won't cover here how to actually transcribe paper drawings of electrical schematics into KiCad schematic files.  It's a complicated affair.  Just any old transcription won't do.  And honestly, you may not have to understand how to make transcriptions anyway, since I've already transcribed all of the pre-existing AGC schematics for you.  Nevertheless, in the Appendix there's a list of some of the rules you'd have to follow to get schematic files that are usable for our simulation workflow.  There are also common-sense rules that aren't covered in the Appendix, such as "you have to use wires for electrical interconnections rather than just lines".  One rule not in the Appendix that I've personally followed in order to make verification of correctness of the transcriptions much simpler is that the transcribed schematics should appear to be so visually identical to the originals that you can overlay them with nothing perceptibly out of place.  There's no technical necessity for that particular rule.  Mike Stewart's transcriptions, for example, are designed entirely for functional correctness and have no visual resemblance whatever to the originals.  On the other hand, Mike's transcriptions don't follow the rules laid out in the Appendix either, so certain steps in our simulation workflow (which post-date Mike's transcriptions) will fail.  In case you're wondering how to transcribe a circuit so as to make it visually identical to the original, KiCad's schematic capture program, eeschema, allows you to use a JPG image as the backdrop of your schematic.  Thus if you use the scanned images (as seen above) for your backdrops in eeschema, you can almost-trivially insure that all of your components and wires are in exactly the right places, which also helps to insure that the nets in the transcription are as they should be.

Transcriptions which follow the rules in the Appendix (and my additional criteria) look like this:

 

Now as I mentioned, AGC module A1 is the "scaler" circuit.  If you want to read about it in some detail, you can look at section 4-5.3.4 of document ND-1021042, which covers the theory of operation of this module.  The module's purpose is to take a clock signal called FS01/ (a 51.2 KHz square wave), which you can see coming into the module from the AGC's backplane near the upper left on the first sheet of the schematic, and to run it through a sequence of identical circuit blocks that successively cut the frequency of that signal in half, as follows, outputting those slower clocks back to the AGC's backplane:

ND-1021042 has a handy table listing all of the values for FS01 through FS17, but for whatever reason doesn't deign to list FS18 through FS33 for us.

To simplify things, the testVerilog example cuts this all down so that just the first of the many divide-by-two circuit blocks.  The abridged circuit produces the output signal FS02 from input signal FS01/ and implements what's known to electrical engineers as a "flip-flop".   Here is an image of that circuit:


Workflow Step 2:  One way to create the netlist is to load the schematic file into eeschema, then from the main menu select File/Export/Netlist/OrcadPCB2/ExportNetlist and create a file called module.net.  For this discussion, I did this from using KiCad v6, and got the resulting file

( { EESchema Netlist Version 1.1 created  Tue 14 Jan 2025 05:51:55 AM CST }
( /00000000-0000-0000-0000-00005d281baf $noname J2 ConnectorA1-200
( 202 Net-(J2-Pad202) )
( 204 Net-(J2-Pad204) )
( 205 Net-(J2-Pad205) )
( 206 Net-(J2-Pad206) )
( 208 Net-(J2-Pad208) )
( 209 Net-(J2-Pad209) )
( 212 0VDCA )
( 222 +4VDC )
( 236 0VDCA )
( 250 +4VDC )
( 260 0VDCA )
)
( /00000000-0000-0000-0000-00005d281ba1 $noname U129 D3NOR-+4VDC-0VDCA-ABC-E_F
( 1 Net-(U127-Pad8) )
( 2 Net-(J2-Pad202) )
( 3 Net-(J2-Pad205) )
( 4 Net-(U127-Pad2) )
( 5 0VDCA )
( 6 0VDCA )
( 7 Net-(U127-Pad8) )
( 8 Net-(J2-Pad204) )
( 9 Net-(J2-Pad202) )
( 10 +4VDC )
)
( /00000000-0000-0000-0000-00005d281b3e $noname U126 D3NOR-+4VDC-0VDCA-A_B-E_F
( 6 0VDCA )
( 7 Net-(U126-Pad7) )
( 8 Net-(J2-Pad206) )
( 9 Net-(J2-Pad208) )
)
( /00000000-0000-0000-0000-00005d281b94 $noname U127 D3NOR-+4VDC-0VDCA-B_C-E_F
( 1 Net-(U126-Pad7) )
( 2 Net-(U127-Pad2) )
( 3 Net-(J2-Pad204) )
( 4 0VDCA )
( 5 0VDCA )
( 6 0VDCA )
( 7 Net-(U126-Pad7) )
( 8 Net-(U127-Pad8) )
( 9 Net-(J2-Pad204) )
( 10 +4VDC )
)
( /00000000-0000-0000-0000-00005d281b45 $noname U128 D3NOR-+4VDC-0VDCA-ABC-E_F
( 1 Net-(U127-Pad2) )
( 2 Net-(U127-Pad8) )
( 3 Net-(J2-Pad205) )
( 4 Net-(J2-Pad209) )
( 5 0VDCA )
( 6 0VDCA )
( 7 Net-(U126-Pad7) )
( 8 Net-(U127-Pad2) )
( 9 Net-(J2-Pad209) )
( 10 +4VDC )
)
)
*

Workflow Step #3: Conversion to Verilog source code. 

The Verilog source code is created by the following steps in Linux:
dumbVerilog.py A1 module.net pins.txt 20 ../empty.init module.kicad_sch >module.v
dumbInitialization.py <module.v
dumbVerilog.py A1 module.net pins.txt 20 A1.init module.kicad_sch >module.v
In Windows, it would instead be
python -m dumbVerilog A1 module.net pins.txt 20 ..\empty.init module.kicad_sch >module.v
python -m dumbInitialization <module.v
python -m dumbVerilog A1 module.net pins.txt 20 A1.init module.kicad_sch >module.v
While in Mac OS, it would be
python3 -m dumbVerilog A1 module.net pins.txt 20 ..\empty.init module.kicad_sch >module.v
python3 -m dumbInitialization <module.v
python3 -m dumbVerilog A1 module.net pins.txt 20 A1.init module.kicad_sch >module.v
The details of this procedure are covered in the technical Appendix.  In brief, pins.txt is a file describing backplane connections that's appropriate for AGC models 2003200 or 2003993, though it doesn't really serve any purpose here since the backplane is used only to interconnect multiple logic modules, and uses only a portion of a single logic module.  20 is the propagation delay of the NOR gates in nanoseconds.  As I mentioned before, in this example circuit the various NOR gates form a flip-flop.  The file A1.init is used to specify whether the flip-flop is initially "on" or "off" at the start of the digital simulation.  It is a file that you can create manually — though generally with considerable inconvenience —, and the purpose of the first two steps of the process above is to heuristically create a version of A1.init that will probably be "good enough".  In point of fact, the repository supplies a module.init for you that could have been used in place of A1.init in the third step above, so that the first two steps above could have been skipped.  The A1.init generated above might look like
# Auto-generated for module A1 by dumbInitialization.py.
U127 1 0
U129 1 0

and is telling us that initially, we can choose output signal U127-J to be HIGH (1), U127-K to be LOW (0), U129-J to be HIGH, and U129-K to be LOW.  I say it "might" look like that, because there are other consisten initial conditions that could be generated instead, such as:
# Auto-generated for module A1 by dumbInitialization.py.
U126 0 1
U127 0 1
U128 1 0
The Verilog source code (module.v) that you get after the final step is below, depending on which initial conditions were generated.  Even if you don't know Verilog, I think you can get some sense of what's what.  The bulk of the file, namely the assign statements, define how the internal signals and output signals change at each timestep of the simulation.  The rst signal is not present in the schematic, and is simply always added by dumbVerilog.py.  It's what allows the initial conditions of memory — in this case, the flip-flop — to be set up, but is normally active only at the very beginning of the simulation.  Verilog doesn't allow signal names like "FS01/", because the character "/" isn't legal for signal names, so the translator has automatically changed "FS01/" to "FS01_".
// Verilog module auto-generated for AGC module A1 by dumbVerilog.py

module A1 (
rst, FS01_, F02A, F02B, FS02, FS02A
);

input wire rst, FS01_;

output wire F02A, F02B, FS02, FS02A;

parameter GATE_DELAY = 20; // This default may be overridden at compile time.
initial $display("Gate delay (A1) will be %f ns.", GATE_DELAY);

// Gate A1-U129A
pullup(g38205);
assign #GATE_DELAY g38205 = rst ? 1'bz : ((0|g38203|FS01_|F02B) ? 1'b0 : 1'bz);
// Gate A1-U129B
pullup(F02B);
assign #GATE_DELAY F02B = rst ? 0 : ((0|g38205|FS02) ? 1'b0 : 1'bz);
// Gate A1-U126B
pullup(FS02A);
assign #GATE_DELAY FS02A = rst ? 0 : ((0|g38204) ? 1'b0 : 1'bz);
// Gate A1-U127A
pullup(g38204);
assign #GATE_DELAY g38204 = rst ? 1'bz : ((0|FS02|g38203) ? 1'b0 : 1'bz);
// Gate A1-U127B
pullup(FS02);
assign #GATE_DELAY FS02 = rst ? 0 : ((0|g38204|g38205) ? 1'b0 : 1'bz);
// Gate A1-U128A
pullup(g38203);
assign #GATE_DELAY g38203 = rst ? 0 : ((0|F02A|FS01_|g38205) ? 1'b0 : 1'bz);
// Gate A1-U128B
pullup(F02A);
assign #GATE_DELAY F02A = rst ? 0 : ((0|g38204|g38203) ? 1'b0 : 1'bz);
// End of NOR gates


endmodule
Workflow Step #4: Creation of a test bench.  This is the point in a simulation workflow where you would have to decide how you want the input signals supplied to the circuit to vary over time, as well as which output signals from the circuit you want to log for later viewing or analysis.  Those decisions together comprise what's called the "test bench".  The test bench could be yet another Verilog source-code file, though it turns out to be more-convenient for it to be a pair of files, one to hold your personal choices, and another to include anything that can be figured out via automation.

The automated portion is performed like so:
# In Linux:
dumbTestbench.py <module.v >module_tb.v
# Or in Windows:
python -m dumbTestbench <module.v >module_tb.v
# Or in Mac OS:
python3 -m dumbTestbench <module.v >module_tb.v
which gives you the following:
// Verilog testbench created by dumbTestbench.py
`timescale 1ns / 1ps

module agc;

parameter GATE_DELAY = 20;
`include "tb.v"

wire F02A, F02B, FS02, FS02A;

A1 iA1 (
rst, FS01_, F02A, F02B, FS02, FS02A
);
defparam iA1.GATE_DELAY = GATE_DELAY;

endmodule

You needn't worry (I hope!) about what any of that means.  I'll just point out that it tells the emulator that the basic time scale of the simulation is 1 nanosecond (with a precision of 1 picosecond), the propagation delay through the NOR gates is by default 20 nanoseconds, and that the file tb.v, which is where the "personal choices" mentioned above are stored, is automatically imported.

In our case, the "personal choices" are mine rather than yours, unless you invent new ones, and the tb.v file I give you is this:
// Include-file used by module_tb.py for automating testbench generation.

reg rst = 1;
initial begin
// Assumes compilation with the -fst option.
$dumpfile("module.fst");
$dumpvars(0, agc);

# 2000 rst = 0;
# 500000 $finish;
end

reg FS01_ = 0;
always #9765.625 FS01_ = !FS01_;

initial
$timeformat(-6, 0, " us", 10);
initial
$monitor("At time %t, rst=%d, FS01_=%d, F02B=%d, FS02=%d, FS02A=%d, FS02A=%d", $time, rst, FS01_, F02B, FS02, F02A, FS02A);

The "reg rst =1" means that the rst signal is going to be an input signal into the circuit we're testing, but here within the test bench it's going to be a "register" that remembers it's own settings, as opposed to a "wire" (which cannot remember anything).  Thus, we set rst to 1 and it will stay that way until we say otherwise.  A few lines later we will see "# 2000 rst = 0", which means that 2000 nanoseconds (2 μs) after startup, the test bench is going to reset the rst signal to 0, and leave it there.  The "# 500000 $finish" that you will also see there says that the simulation itself will actually end after 500 μs.  The intervening "$dumpfile" and "$dumpvars" statements say that an output log-file called testVerilog.lxt is going to be opened, and that the values of all of the input and output variables are going to be dumped into it on a cycle-by-cycle basis, for later analysis. 

The "reg FS01_ = 0" means that FS01_ (FS01/) is also an input to the circuit being tested, and that it starts out at 0.  But "always #9765.625 FS01_ = !FS01_" means that FS01_ is going to be toggled every 9.765625 μs during the simulation.  Recall that FS01/ is a 51.2 KHz square wave in the AGC, and therefore it toggles from low-to-high or high-to-low at a rate of 102.4 KHz, or (surprise!) every 9.765625 μs.

Finally, the "initial" statements at the very end describe the status messages which the simulation is going to print out whilst running.  These messages are just informative, and have nothing to do with the data being dumped out on the module.fst.  You don't even need to print out any status messages if you don't want to.

Workflow Step #5:  Modeling memory.  Since we're just simulating a single logic module of the AGC, rather than the AGC as a whole, we don't need any memory other than the flip-flop that the circuit implements, so  we don't need this step.

Workflow Step #6:  In this example, we have created two Verilog source code files, the one describing the logic module (module.v) and the one describing the test-bench (module_tb.v, which automatically imports tb.v as well).  We need to compile these together to get the "executable" form of the digital simulation we want to perform:
iverilog -o module.vvp module_tb.v module.v
I can't show you the contents of module.vvp — I bet you're relieved! —, since it's a binary file rather than a human-readable one.

Workflow Step #7:  Here's how to run the simulation:
vvp module.vvp -fst
I get messages something like this when I do that:
Gate delay (A1) will be 20.000000 ns.
FST info: dumpfile module.fst opened for output.
Gate delay (A1) will be 20.000000 ns.
FST info: dumpfile module.fst opened for output.
At time       0 us, rst=1, FS01_=0, F02B=x, FS02=x, FS02A=x, FS02A=x
At time       0 us, rst=1, FS01_=0, F02B=0, FS02=0, FS02A=0, FS02A=0
At time       2 us, rst=0, FS01_=0, F02B=0, FS02=0, FS02A=0, FS02A=0
At time       9 us, rst=0, FS01_=1, F02B=0, FS02=0, FS02A=0, FS02A=0
At time       9 us, rst=0, FS01_=1, F02B=1, FS02=0, FS02A=0, FS02A=0
At time      19 us, rst=0, FS01_=0, F02B=1, FS02=0, FS02A=0, FS02A=0
At time      19 us, rst=0, FS01_=0, F02B=1, FS02=1, FS02A=0, FS02A=1
At time      19 us, rst=0, FS01_=0, F02B=0, FS02=1, FS02A=0, FS02A=1
At time      29 us, rst=0, FS01_=1, F02B=0, FS02=1, FS02A=0, FS02A=1
At time      29 us, rst=0, FS01_=1, F02B=0, FS02=1, FS02A=1, FS02A=1
At time      39 us, rst=0, FS01_=0, F02B=0, FS02=1, FS02A=1, FS02A=1
At time      39 us, rst=0, FS01_=0, F02B=0, FS02=0, FS02A=1, FS02A=1
At time      39 us, rst=0, FS01_=0, F02B=0, FS02=0, FS02A=0, FS02A=0
At time      48 us, rst=0, FS01_=1, F02B=0, FS02=0, FS02A=0, FS02A=0
At time      48 us, rst=0, FS01_=1, F02B=1, FS02=0, FS02A=0, FS02A=0
...
At time     468 us, rst=0, FS01_=0, F02B=0, FS02=0, FS02A=0, FS02A=0
At time     478 us, rst=0, FS01_=1, F02B=0, FS02=0, FS02A=0, FS02A=0
At time     478 us, rst=0, FS01_=1, F02B=1, FS02=0, FS02A=0, FS02A=0
At time     488 us, rst=0, FS01_=0, F02B=1, FS02=0, FS02A=0, FS02A=0
At time     488 us, rst=0, FS01_=0, F02B=1, FS02=1, FS02A=0, FS02A=1
At time     488 us, rst=0, FS01_=0, F02B=0, FS02=1, FS02A=0, FS02A=1
At time     498 us, rst=0, FS01_=1, F02B=0, FS02=1, FS02A=0, FS02A=1
At time     498 us, rst=0, FS01_=1, F02B=0, FS02=1, FS02A=1, FS02A=1

Thus as promised, FS01_ (FS01/) toggles about every 10 microseconds, while FS02 toggles about every 20 microseconds, though it's a bit of a pain to extract that conclusion from the messages.
Workflow Step #8: Visualization.  Pull the dump-file created by running the simulation, namely module.fst, into the GTKWave visualization program,
# In Linux or Windows:
gtkwave module.fst
In Mac OS, I think it would just be easier to open GTKWave from the desktop (rather than figuring out how to do it from a command line), and use its File menu to navigate to virtualagc-schematics/Schematics/testVerilog/module.fst.

You'll see something like the following.  (Actually, there are a few interactive steps to set the viewing timescale, select the specific signals to view, and the order in which the signals should appear, but if you've been motivated enough to get this far, I think you can figure those bits out for yourself!  But you can look at GTKwave's online documentation to see how to use the visualizer, if you cannot monkey through it yourself.) 



In comparison, here's a clipping out of the corresponding waveform Figure 4-121 from the contemporary theory of operation document ND-1021042:



Note:  While the waveforms shown in the two graphs are the same, there is  nevertheless a significant difference:   Figure 4-121 purports to display the signal FS01, whereas our data visualization displays signal FS01/, which is inverted from FS01.  Then too, the position of the final pulse of F02B doesn't match.  One of us must be wrong!  Which one could it be?  Could it be ... me?  Could it be ... them?  The suspense is terrible!  I hope it'll last.  Check it out yourself.

Cheat sheet:  I've made most of this line white-on-white, to make it harder to read accidentally.  If you highlight this entire line, I expect it will be enlightening.   To figure out who's wrong, it's relatively easy to work backward from the condition F02A HIGH to see what conditions it requires for the inputs of the various NOR gates, then to work backward to the NOR gates feeding those inputs, and so on.  You'll quickly find that F02A HIGH implies that FS01/ is HIGH as well, which means that Figure 4-121 is wrong in asserting that F02A is HIGH at the same time as FS01 is HIGH.  Identical reasoning applies to determining the conditions for F02B being HIGH, demonstrating that Figure 4-121 is incorrect about the positioning of the final pulse.

Big Example: Simulating an Entire AGC

Choices To Make

There are several important choices to be made at the very beginning of any attempt at simulating a whole AGC.  I suppose that making those choices could form a Step #0 in the simulation workflow:
  1. Which model of AGC is to be simulated?
  2. Which of the available AGC programs is going to be run on the simulated AGC?
  3. What is the test bench going to be like?
Regarding choice of AGC model:  Aside from dash numbers suffixed to part numbers, the list of AGC models really boils down to those in the following table:

Generic AGC Model
Block
Mission
Spacecraft
Specific Dash Number
1003565
I
AS-202
CM
1003565-011
1003700
I
Apollo 4
CM
1003700-051
Apollo 6
CM
1003700-071
2003100
II
2TV-1
CM
2003100-061
II
LTA-8
LM
2003100-071
2003200
II
(None)
CM
2003200-031
(None)
LM
2003200-041
2003993
II
Apollo 5
LM
2003993-011
Apollo 7 CM 2003993-031
etc.

Aside:  Model 2003993, in differing specific dash numbers, was used for almost all missions, so I hope you'll forgive me for running out of steam at the end of the table and just covering all of the remaining missions with a bland "etc." rather than giving you 20+ more rows of model 2003993!  The way to get the information for the missing entries is by drilling down into the GN&C mission hierarchy table.  That is also the place to go in order to match a particular AGC model to a specific set of electrical schematics.

But there are really less choices than it appears at first glance.  There's a table in the Technical Appendix that lists all of the logic modules appearing in the different AGC models, in terms of the assocated schematic-diagram drawing numbers, and we can summarize what we learn from that table as follows:

Or in other words, the only essentially-different cases are that we can simulate either AGC model 1003700 (Block I) or model 2003993 (Block II). 

Aside:  And of those two choices, only the simulation workflow for Block II has been debugged so far and can be considered mature enough to be "working", so the choice reduces to AGC model 2003993 ... which coincidentally, is the one that is likely most desired by people.

The executive summary of all that is that as of right now, any simulating we'll be doing will be for AGC model 2003993.

Regarding the choice of AGC software:  In principle, any of the available Block I AGC software versions can be used in a simulated AGC model 1003700, while any of the available Block II AGC software versions can be used in a simulated AGC model 2003993.  Any Block II core-rope — in the form of a "bin" file produced by the AGC assembler, yaYUL — can be converted to a Verilog source code by a Python program provided by Mike Stewart that's called bin_to_verilog_rom.py.  In practice, 15 or so AGC software versions have been converted by Mike and are already found with the transcribed schematics, in a folder called "roms".  I would recommend the program called "Validation-hardware-simulation".

Regarding the test bench:  Well, this is really no different than what was discussed in the preceding section, except that we need a test bench for the entire AGC, rather than test benches for individual logic modules.  I have created some test-bench files that can be used as starting points.  The are named tb-2003993.v, tb-2003200.v, etc.

The Workflow

So as just explained, we'll be simulating the model 2003993 AGC. 
Aside:  As in the case of simulating a single module, I've provided a script which can perform the entire sequence of steps needed to carry out the simulation, assuming that the choices described in the preceding section have been made.  At the moment, the script only works for Linux or Mac OS, or something similar enough,  but I haven't yet created the equivalent batch file for Windows.  The script is run from the Schematics directory, and its calling sequence from the command line is
simulateAGC AGCMODEL SOFTWARE VERILOGPARMS
where AGCMODEL defaults to "2003993", SOFTWARE defaults to "Validation-hardware-simulation", and VERILOGPARMS (a quoted list of command-line parameters for the Verilog compiler that alter values in the test bench) is empty ("").  By default, every signal is logged by the simulation. To run the simulation while accepting all of the defaults, you could use the simple command.
simulateAGC
This will perform the entire workflow and jump you right to the visualization of the data output by the simulation, thus avoiding the possibility of having to learn anything in the meantime.
What makes whole-AGC simulations trickier than single module simulations is that while the same basic workflow holds, some of the steps of the workflow are carried for each logic module comprising the circuit, while other steps combine the logic-module-specific large into single large files pertaining to the whole AGC, and yet other steps operate on those whole-AGC files.

Thus given a particular AGC model that's a candidate for simulation, we must first have a proper idea of what schematic diagrams are specific to the logic modules in that AGC model.  The table in the Technical Appendix informs us on this topic.  In the case of our present example, it tells us a model 2003993 AGC has the following logic modules:
Of course, these schematic transcriptions already exist, so once again, workflow Step #1 (creation of schematic transcriptions) leaves us with nothing to do.

Workflow Step #2 is creation of netlist files.  This is done precisely as for the single logic modules we talked about in the preceding section, and must be done for each of the unique schematics listed above.  I mention "unique" schematics, because it's certainly possible for the same schematic to apply to more than logic module.  That's not the case for the 2003993, but is the case for AGC model 1003700.

At Workflow Step #3 (creation of Verilog source-code files for the logic modules we begin to experience some differences from the single-module case.  In the case of single-module simulation, this step was roughly:
  1. Run dumbVerilog.py for the logic module to generate a kind of "rough draft" of the Verilog source code.
  2. Run dumbInitialization.py on the rough drafts to create an initialization file for the implicit flip-flops in the design.
  3. Run dumbVerilog.py again, using the new initialization file to get the final form of the module's Verilog source code.
For whole-AGC simulation, this step instead becomes the following procedure:
  1. Run dumbVerilog.py for each of the logic modules comprising the AGC to generate a kind of "rough draft" of the Verilog source code for each of them.
  2. Combine all of the rough-draft Verilog source-code files for the modules by appending them end-to-end into one big file.
  3. Run dumbInitialization.py on the big Verilog file to generate an initialization file.
  4. Run dumbVerilog.py for each of the logic modules comprising the AGC, this time using the just-created initialization file, to generate a final form of the Verilog source code for each of them.
  5. Combine all of the final Verilog source-code files for the modules by appending them end-to-end into one big file that contains their collective final Verilog source code.
For the sake of simplifying the discussion, let's abbreviate "big final Verilog file" as BFVF.

Workflow Step #4 (testbench generation).  The BFVF is used as input for dumbTestbench.py.  And the appropriate file tb-AGCMODEL.v must be copied to tb.v or else you must devise your own testbench file for tb.v instead.

Workflow Step #5 (Verilog source-code creation for erasable and fixed memory) is completely new, since we didn't have to do it at all for the single-module case.  Three separate things go into simulation of erasable and fixed memory:

Combining those ideas, what Step #5 of the workflow does is to copy the appropriate file Schematics/roms/SOFTWAREVERSION.v to Schematics/roms/rom.v, and then appends the holy trinity of RAM.v, ROM.v, and BUFFER.v to the end of the BFVF.

Workflow Step #6 (compilation of the Verilog). The BFVF and the testbench file generated by dumbTestbench.py in Step #4 above are the input files to the compiler. 

Workflow Steps #7 and #8 differ from the single-module case in no respect.

But the full AGC has a lot of signal nets in it — about 8500 of them —, so there's a lot more flexibility in choosing which of those you want to look at in the data visualization than there is in any single logic module.  In case it hasn't been clear already, any or all of the signals logged when the simulation was performed can be displayed, in any order, with or without various kinds of decorations.  Which ones of them to display, and how, is typically a matter on which you'd consult the schematic diagrams and/or the theory-of-operation documents a lot in order to figure out which signals were helpful and which were merely clutter.  What I've done for pedagogical purposes in the screenshot below is to select the signals corresponding to the upper portion of Figure 4-121 of the theory-of-operations document  ND-1021042, of which you may recall that in the preceding section I used only the lower portion of that figure.  One comforting feature of this simulation is that when we saw this same data in the preceding section, the test bench had supplied the input signal FS01/ at the proper clock rate, whereas in our full-AGC simulation here, signal FS01/ is instead generated by the upstream portions of the circuitry.  And yet the simulation still generates an FS01/ signal at the same correct frequency as before.



And here's the aforementioned upper portion of Figure 4-121:

Perfect match!

Because you're sharp-eyed and clever — if not, how could you possibly be reading this right now? —, I can detect some skepticism.  I can hear you saying, "But wait!  Didn't you conclusively demonstrate in the preceding section that Figure 4-121 was bonkers, and was mistakenly displaying the signal FS01/ where it wrongly says it's displaying signal FS01?  And if that's true, how could this now be a perfect match?!!!"  You know what?  You're right.  Well, right and wrong, I think.  I can't give you a 100% certain explanation of what happened when Figure 4-121 was drawn, but I visualize it something like this:

There!  That neatly explains, I think, why I'm right, and everyone else is to blame for any apparent errors, and how my simulation is beautiful and perfect.  And they said it could not be done!  My next trick will to be to run for public office of some kind.  On the other hand, alternate explanations concluding that I and my simulations are idiotic are welcome too.  Anything that advances the dialog!  Let me know if you come up with one.

Technical Appendix

AGC Software for Simulation Purposes

Unmodified AGC software may not be 100% suitable for the purposes of digitally simulating the AGC electronics, and may require some modifications in order to be suitable.  At this writing, the only example of this is in the Validation program, which is a small suite of test routines for the AGC CPU that I wrote, based on the original documentation.  However, Validation is an interactive program, and dependence on a DSKY may not be very desirable in the context of simulating the digital electronics of the AGC.  One approach to this problem would be simply to clone the AGC program one wishes to run, and then make whatever changes were desired directly to the cloned source code.

Another approach is to embed directives in the original AGC program that act like conditional compilation, so that sections of the source code can be modified at assembly time without maintaining two copies of the source code.  The assembler (yaYUL) supports this approach via a command-line switch, --simulation, and embedded directives -SIMULATION or +SIMULATION within end-of-line comments in the AGC source code.  Lines of AGC source code without either of these embedded directives, or with those directives embedded in full-line comments, are processed normally by yaYUL whether or not the --simulation command-line switch is present.  However, if --simulation is in effect, yaYUL comments out any lines with an embedded -SIMULATION directive.  Conversely, if --simulation is not in effect, yaYUL comments out any lines with an embedded +SIMULATION directive.

The AGC Validation program has such directives embedded in it, and when assembled with --simulation produces a version of the program more-suitable for simulating the AGC electronics.  This alternate version of Validation is known as Validation-hardware-simulation, and thus is the program run by default when simulating the AGC electronics.

More-sophisticated AGC test programs (such as Borealis) and the original test programs (like Aurora and Sundial) are available as well, but they have not received the treatment mentioned above.

Transcribing/Editing a Schematic Diagram with eeschema

This is too detailed a topic for me to give much helpful advice about in a limited space.  Plus, I consider it unlikely that you'll find yourself needing to transcribe an AGC-related schematic diagram.  I will simply point out the following:

Creating a Netlist with eeschema

There are two methods. 

Method 1:  While viewing the top-level page of a schematic diagram in eeschema, select File/Export/Netlist from the main menu.  In the "Export Netlist" window which pops up, select the tab labeled "OrcadPCB2" and click the button labeled "Export Netlist".  In the "Save Netlist File" dialog which appears, which should have pre-chosen the folder containing the top-level schematic file itself, save the netlist as "module.net".

Method 2:  For KiCad v.7 or later, the netlist can be created from a command line without even running eeschema.  The command would be

kicad-cli sch export netlist --output module.net --format orcadpcb2 module.kicad_sch

Converting Netlists to Verilog Source Code with dumbVerilog.py

The supplied tools for converting a netlist (or more accurately, a netlist plus the associated schematic) to Verilog source code are specific to AGC logic modules as originally designed in the Apollo era, and to our specific manner of transcribing those those drawings for use with eeschema.  Departing from any of those conditions could render the supplied tools useless, thus forcing you to manually create whatever Verilog source code you think represents your digital circuit.  The conditions are:
Aside:  To be completely honest, I'm no longer entirely sure how many of these rules the supplied tools actually depend upon, as opposed to these rules just being the ones obeyed by the original developers.  Most of them are relied upon.
To convert a single schematic to Verilog source code, the Python 3 script dumbVerilog.py is used:
dumbVerilog.py MODULE module.net pins.txt DELAY module.init module.kicad_sch [WIRETYPE] >module.v
The files called pins.txt and module.init are covered in the succeeding sections.  The file pins.txt will be searched for if not found; it may be either in the current directory, the directory containing dumbVerilog.py itself (the usual case), or else specified with an explicit path.  The parameters "module.net", "module.kicad_sch" (or just "module.sch" for KiCad v.5), and "module.v" are generally literal.  As for the remaining command-line parameters:

The pins.txt File

Abstractly, the AGC circuitry consists of a number of "modules" (each represented by an electrical schematic), plugged into a "backplane".  The backplane, again abstractly, consists of a set of connectors whose pins are interconnected by wires.  However, there is no schematic diagram as such for the backplane, so to incorporate the backplane into our simulation the interconnections in the backplane must be specified in some other form.  That alternate form of description is the pins.txt file, which is just a text file having a separate line in it for each pin of each connector on the backplane. 

Each line of the file has four fields, delimited by space characters.  Those fields are:

  1. A module number (Ann or Bnn).
  2. A pin number on the backplane connector for the module.
  3. A signal type:  IN, OUT, INOUT, BP, FIX, FOX, NC, SPARE
  4. A signal name (blank if signal type is NC or SPARE)
Aside:  Technically, there are actually two separate backplanes, designated "A" and "B", into which the AGC modules Ann and Bnn respectively plug, with some interconnections between the two backplanes.  The pins.txt file describes both, so we may as well think of it simply as one big backplane.

Regarding the module-to-backplane connectors, for the logic modules that interest us for simulation purposes, each module had a physical 284-pin connector consisting of 4 rows of 71 pins each.  (The 21st pin from either end of a row was missing, so you could equally-well consider it physically to be a 276-pin connector consisting of 4 rows of 69 pins each.  But the pin numbering pretends that the missing pins were present.)  On the other hand, on the electrical schematics for the logic modules, each of the 71-pin rows was considered a separate connector, and thus the schematics show 4 separate connectors each, designated as J1, J2, J3, and J4.

Just to emphasize this point, in case the message was lost in the details:  In pins.txt each backplane connector for a logic module has 284 pins, while on the logic module's electrical schematics there are instead 4 connectors of 71 pins each.

In principle, a separate pins.txt file should be used for each different AGC model.  In practice, there's little difference between AGC models 2003200 and 2003993, and so there is presently a single pins.txt file used for those two models.  As far as other AGC models is concerned, there is presently no available pins.txt for them.

Aside:  Strictly speaking, this isn't quite true.  The existing pins.txt was derived from Mike Stewart's digital simulation of the AGC.  Mike's backplane pin data was derived in turn by a script that analyzed his Verilog files.  Thus if we indeed wanted to generate a separate pins.txt file for each Block II AGC model we'd have an awkward chicken-and-egg problem, since dumbVerilog.py needs pins.txt before generating our Verilog files, whereas the only automated way of generating pins.txt does so after creating the Verilog files.  On the other hand, for Block I AGC's I've created a similar file, pinsBlockI.txt, by processing Block I schematics (rather than Verilog files) using an AWK script, so perhaps the same technique could be used for Block II as well.  However, the pinsBlockI.txt file is in a somewhat different format than pins.txt, and dumbVerilog.py isn't presently able to support that particular format.  Although I don't recall for certain, I suppose this means that I had only done preliminary work on Block I AGC simulation, without having taken it to the point of the simulation actually functioning. 

The module.init file and dumbInitialization.py

The only digital components present in AGC logic-module schematics are dual triple-input open-drain NOR gates (as in the figure to the left), which in themselves are stateless; i.e., the output signal of a NOR gate is directly determined by the current state of its input signals.  Or at least, the output is determined by the state of the input signals after however long it takes the signals to propagate through the gate, which is nominally 20 nanoseconds.  Nevertheless, it is possible to interconnect NOR gates in such a way that a block of NOR gates has an output signal that does not necessarily depend on the current state of the inputs.  In other words, the block of NOR gates has "memory".  The most-common such circuit block in the AGC uses several NOR gates to form what's known as a "flip-flop"; i.e., a memory element capable of indefinitely storing a single bit indefinitely.  Or rather, of storing a bit until the power is cycled, at which point the value of the bit is lost.  The testVerilog circuit used in examples above is such a flip-flop. 

This has an implication on the initial conditions for a digital simulation, since we need to specify not only the levels of the input signals to the circuit being simulated, but the initial states of these implicit flip-flops as well.  After power-up is no issue, since if we know the states of the flip-flops at power up, the simulation itself takes care of computing their states at later times.  But we first have to have some way of knowing what the states were at power-up in order to do that.

In the design of the physical AGC, almost no effort was given to putting these implicit flip-flops into any given state.  (And in those cases where an effort had been made, the mechanisms used would put the simulated flip-flops into a known state too.)  Rather, the developers just seemed to feel that the flip-flops would generally settle down into some stable state, and that happy thought proved to be adequate for their purposes.  For our purposes, namely digital simulation, it's not enough!  In simulation, it's perfectly possible for a such a flip-flop to oscillate indefinitely without ever settling down into some stable state, which means that the Verilog emulator could get stuck in an infinite loop or timeout while trying to compute the initial state of the circuit.  No good!

To specify the initial states of flip-flops, module.init allows you to state the initial output signal of any or all of the NOR gates.  As we say in the figure above, a dual NOR-gate component used in the AGC has two outputs, which are designated as pin J for one of the NOR gates and K for the other of the NOR gates.  The way these are specified in module.init is that there is a line in the file for each dual NOR component that you want to specify, and that line has the format

Unnn OutputJ [ OutputK [ DelayJ [ DelayK ] ] ]
where Unnn is the reference designator of the dual-NOR component and OutputJ and OutputK are the output signal levels (0 or 1, default 0) at pins J and K of the dual-NOR component.  DelayJ and DelayK are the respective propagation delays for the two NOR gates, in units as described for the DELAY parameter of dumbVerilog.py as discussed earlier, which is also the default for any omitted DelayJ or DelayK.

You can also annotate the module.init file with comments (preceded by "#") or blank lines, if it helps you document what's being done.

In general, there won't be any single "correct" module-init file, since the only constraint on possible module.init files is that the specified signal levels are logically consistent with respect to the properties of NOR gates.  For a single flip-flop in its simplest form, there are two guaranteed consistent states, namely "on" and "off".  Indeed, if there were a single logically-consistent configuration, then the circuit would be useless since its state could never change.  So there are multiple consistent forms of module.int.  For testVerilog, for example, one such form for module.init (and indeed, the one we've provided within the repository) looks like:
U127 1 0
U129 1 0

In other words, U127's J output is 1 ("on") and K output is 0 ("off"); and the same for U129.  I've illustrated that in the image to the right by coloring NOR-gate outputs specified initially as 1 in green, and those specified initially as 0 in red.  You don't need to specify the output for every NOR gate, and thus the outputs of U126 and U128 are left unspecified.  But if you manually create the module.init file, it's entirely up to you to determine which ones you want to specify; and since not all possible combinations of signals are logically consistent, you must insure the consistency, which can be quite tiresome if done manually.  Because of the way NOR gates work, specifying that U129's OutputJ is 1 forces U127 OutputK, U128 OutputJ, and U129 OutputK all to be 0.  So if you specified any of those latter outputs to be 1, you'd be creating an inconsistent set of inital conditions.

Fortunately, a consistent set of flip-flop initializations can conveniently be generated using the Python 3 script dumbInitialization.py.  The syntax is simply

dumbInitialization.py <TheVerilogSourceCode.v

where TheVerilogSourceCode.v is (surprise!) the Verilog source-code for which you wish to generate some initialization information.  There are actually two basically-different scenarios in terms of acquiring the TheVerilogSourceCode.v file:

  1. If you're interested in simulating a single module, you can just use module.v.
  2. If you're interested in simulating an entire AGC, you should concatenate the module.v files for each of the AGC's logic modules, end to end, into one big file.  The order in which the individual files appear does not matter.

Actually, these are just the two extreme cases of the unified scenario "concatenate all of the module.v files comprising the circuit in which you're interested".  But there's a practical difference between cases #1 and #2, in that if you decide you want to simulate (say) AGC model 2003993, you probably don't actually know without considerable research which particular logic modules comprise it, thus increasing the difficulty level.  Another tricky aspect is that some logic-module drawing numbers are repeated in an AGC.  For example for the Block I AGC, schematic 1006540A is used not only for module A1, but also for A2 through A16 as well, and thus there is no single "module.v" associated with schematic 1006540A, but rather a module.v generated for module A1, one generated for module A2, and so on.    The table below is a handy cheat sheet of the logic modules vs schematic numbers relevant to various AGC models.  I suppose I should warn you that the revision levels shown for the schematic drawings are simply the revisions we have, rather than necessarily the ones originally used.  AGC model 2003100, alas!, is highlighted mostly in red to indicate schematics that haven't survived or to which we have no access.

Logic
Module
Drawing Number
Module Description
AGC 1003565
AGC 1003700
AGC 2003100
AGC 2003200
AGC 2003993
Block I
Block II
A1
1006540A 1006540A
2005059E
2005259A
2005259A
Logic Flow, Bit Scaler Module
A2
1006540A 1006540A
2005060D
2005260A
2005260A
Logic Flow, Bit Scaler Module
A3
1006540A 1006540A
2005051D
2005251A
2005251A
Logic Flow, Bit S Q Register and Decoding
A4
1006540A 1006540A
2005062C
2005262A
2005262A
Logic Flow, Bit Stage Branch Decoding Module
A5
1006540A 1006540A
2005061D
2005261A
2005261A
Logic Flow, Bit Cross Point Generator No. I
A6
1006540A 1006540A
2005063F
2005263A
2005263A
Logic Flow, Bit Cross Point Generator II
A7
1006540A 1006540A
2005052D
2005252A
2005252A
Logic Flow, Bit Service Gates
A8
1006540A 1006540A
2005055D
2005255-
2005255-
Logic Flow, Bit 4 Bit Module
A9
1006540A 1006540A
2005056C
2005256A
2005256A
Logic Flow, Bit 4 Bit Module
A10
1006540A 1006540A
2005057E
2005257A
2005257A
Logic Flow, Bit 4 Bit Module
A11
1006540A 1006540A
2005058D
2005258A
2005258A
Logic Flow, Bit 4 Bit Module
A12
1006540A 1006540A
2005053F
2005253A
2005253A
Logic Flow, Bit Parity and S Register
A13
1006540A 1006540A
2005069E
2005269-
2005269-
Logic Flow, Bit Alarms
A14
1006540A 1006540A
2005064F
2005264A
2005264B
Logic Flow, Bit Memory Timing & Addressing
A15
1006540A 1006540A
2005065D
2005265A
2005265A
Logic Flow, Bit
RUPT Service
A16
1006540A 1006540A
2005066D
2005266-
2005266-
Logic Flow, Bit
INOUT I
A17
1006543D
1006543D
2005067B
2005267A
2005267A
Logic Flow "C"
INOUT II
A18
1006542-
1006542-
2005068C
2005268A
2005268A
Logic Flow "B"
INOUT III
A19


2005070E
2005270-
2005270-

INOUT IV
A20


2005054C
2005254-
2005254-

Counter Cell I
A21
1006556A
1006556A
2005050J
2005250-
2005250-
Logic Flow "S"
Counter Cell II
A22
1006553E
1006553E
2005071B
2005271-
2005271-
Logic Flow "P"
INOUT V
A23
1006545-
1006545-
2005072C
2005272A
2005272A
Logic Flow "E"
INOUT VI
A24
1006555A
1006555A
2005073A
2005273A
2005273A
Logic Flow "R"
INOUT VII
A25
1006554-
1006554-



Logic Flow Q

A26
1006549B
1006549B



Logic Flow "J"

A27
1006544B
1006544B



Logic Flow D

A28
1006552A
1006552A



Logic Flow "N"

A29
1006559D
1006559D



Logic Flow "V"

A30
1006548-
1006548-



Logic Flow "H"

A31
1006548- 1006548-



Logic Flow "H"

A32
1006546A 1006546A



Logic Flow "F"

A33
1006547G
1006547G



Logic Flow "G"

A34
1006547G
1006547G



Logic Flow "G"

A35
1006541B
1006541B



Logic Flow "A"

A36
1006557D
1006557D



Logic Flow "T"

A37
1006550F
1006550F



Logic Flow "L"

A38
1006551- 1006551-



Logic Flow "M"

Fixed and Erasable Memory


fixed_erasable_memory
fixed_erasable_memory
fixed_erasable_memory


Because dumbInitialization.py expects to be dealing with a collection of modules rather than necessarily an individual module, it does not output any file specifically called "module.init".  Rather, it expects to be operating on an entire AGC circuit, so it outputs separate initialization files for each of the AGC's logic modules:  A1.init, A2.init, and so on.  As you may recall, the testVerilog circuit is a snippet from the circuit for logic module A1, so we'd have to rename A1.init as module.init after running dumbInitializion.py.  Still, the operation seems pretty simple.

This supposed simplicity hides a nasty chicken-and-egg truth, namely that we need to have module.init for dumbVerilog.py to produce module.v, and we need module.v for dumbInitialization.py to produce module.init.  Catch 22!

Fortunately, this circle is not as vicious as it appears, since all you really have to do is follow this 3-step procedure:

  1. Use dumbVerilog.py with an empty module.init, or else one of your own devising, to create module.v.  We actually provide such an empty module.init (Schematics/empty.init) for this very purpose.
  2. Use dumbInitialization.py to generate A1.init, and rename A1.init as module.init.
  3. Use dumbVerilog.py again, to regenerate module.v.

And indeed, this process works for us, giving us

# Auto-generated for module A1 by dumbInitialization.py.
U127 1 0
U129 1 0

Converting Verilog Module to Verilog Test Bench

The preceding sections have described how to create a Verilog description of each individual AGC module, and the initialization for that Verilog, but only in such a way that the modules stand alone and don't fit together in any meaningful way.  It's as if the individual AGC modules weren't plugged into the AGC's backplane.  A "test bench", which itself is Verilog source code is like the backplane in that it provides a way to wire all of the AGC modules' Verilog files together.

You have some choices to make and some manual work to do in creating the test bench.  But first, there's an automation procedure that can be performed to get you partway there.  Recall that in the preceding section we talked about how to create what we called TheVerilogSourceCode.v for the circuitry you want to simulate.  We reuse that file right now:
dumbTestbench.py <TheVerilogSourceCode.v >TestBench.v
The Verilog source-code created by dumbTestbench.py is not quite the complete test bench, because dumbTestbench.py isn't aware of any personalized choices which needs to be made by you rather than by a computer.  The file it creates, TestBench.v, itself imports another Verilog source-code file called "tb.v" to contain these personalized changes, and it's this file tb.v that you must create.  The kinds of customizations covered by tb.v include such things as:
Unfortunately, it's outside of my scope here to give you a full introduction to Icarus Verilog testbenches, so I'd advise you to search for online tutorials and documentation that supply a better grounding on the subject.  For reference in your perusing those materials, here's the test-bench file created by dumbTestbench.py for the testVerilog example used so often above,
// Verilog testbench created by dumbTestbench.py
`timescale 1ns / 1ps

module agc;

parameter GATE_DELAY = 20;
`include "tb.v"

wire F02A, F02B, FS02, FS02A;

A1 iA1 (
rst, FS01_, F02A, F02B, FS02, FS02A
);
defparam iA1.GATE_DELAY = GATE_DELAY;

endmodule
and here's the tb.v file it includes, as created by me:
// Include-file used by dumbTestbench.py for automating testbench generation.

reg rst = 1;
initial begin
// Assume compilation with -fst switch.
$dumpfile("testVerilog.fst");
$dumpvars(0, agc);

# 2000 rst = 0;
# 500000 $finish;
end

reg FS01_ = 0;
always #4882.8125 FS01_ = !FS01_;

initial
$timeformat(-6, 0, " us", 10);
initial
$monitor("At time %t, rst=%d, FS01_=%d, F02B=%d, FS02=%d, FS02A=%d, FS02A=%d", $time, rst, FS01_, F02B, FS02, F02A, FS02A);
Some of the features of this file were already explained earlier, at least somewhat, though the testbench discussed there was a somewhat earlier version than the one shown above.

Compilation of the Verilog Source Code

The Icarus Verilog compiler, iverilog, has a lot of options that you can research online if you need them.  I'm not aware of any options we need, though, and think that compilation is just
iverilog -o OUTPUT.vvp ListOfVerilogSourceCodeModulesIncludingTheTestBench

For a single logic module or other standalone schematic, that's typically just

iverilog -o module.vvp module_tb.v module.v

For a collection of modules, such as an entire AGC, the basic command is still the same, but it's a bit more complicated since the list of Verilog source-code files is much larger and includes:

Running the Simulation

This is the easiest thing of all, since the command is simply

vvp module.vvp -fst

The -fst option perhaps requires some explanation.  It selects the file format to be used for logging simulation data.  Because our intention is to use gtkwave to visualize the logged data (see the next section), it's necessary to choose a file format supported both by vvp and by gtkwave, or at least can be inter-converted.  At the present writing (vvp v11 and gtkwave v3.3.x), that would appear to be a wide and confusing range of formats:

The bad news or good news (depending on your point of view) is that gtkwave documentation makes it clear that all of the formats I've italicized are scheduled to be deleted in gtkwave v4, in addition to which GHW is a format used only for VHDL and therefore is unlikely ever to be supported by Verilog systems.  That leaves only VCD and FST likely to be common to iverilog and gtkwave in the future.  Of these two remaining formats, VCD (from gtkwave documentation) "is the industry standard file format generated by most Verilog simulators and is specified in IEEE-1364. This is the slowest of the formats for the viewer to process and requires the most memory. However, this format is ubiquitous, and almost all tools support it".  Whereas FST "is designed for very fast sequential and random access".  Which to choose is, of course, a matter of personal preference.

Visualization of the Simulation Data

It's probably best to review the gtkwave documentation if you have questions, rather than relying on anything I have to say about it.  The command to do it is simply

gtkwave NameOfTheSimulationLogFile

Tying It All Together

For a Single Block II Logic Module, a Portion Thereof, or Similar

As mentioned earlier, if you're running Linux or Windows, I've written a shell script (for Linux) and a corresponding batch file (for Windows) that combines all of the steps, mostly.  So far, I have no Mac OS equivalent.

All you have to do is this:
  1. Create a schematic (module.sch for KiCad v5- or module.kicad_sch for KiCad v6+), if it doesn't already exist.
  2. Create a tb.v file, as described above.
  3. From within the folder containing your schematic and the tb.v file, run the following command:
simulateBlockII A1 [NETLIST.net]

Of course, the parameter A1 is specific to the testVerilog example, and probably would be something else for you.  The module.net parameter is optional, in the sense that simulateBlockII will try to generate a file called module.net itself if the parameter is missing, but NETLIST.net must already exist if the parameter is present.  KiCad v7 or later is required if you're going to omit the NETLIST.net parameter.

For an Entire AGC

The equivalent for an entire AGC is the shell script simulateAGC.  I do not yet have a Windows batch that duplicates this shell script, so for now it's only for platforms like Linux or Mac OS that support bash-type shell scripts.  The script is run from the Schematics/ folder containing the folders for the individual schematics.  The usage is:
simulateAGC AGC_MODEL AGC_SOFTWARE "LIST_OF_OPTIONS"
Any of the command-line parameters can be omitted (from the end of the line) or replaced by "" (if in the middle of the line) to use default values for them.

These parameters are:
Prior to the creation of the shell script simulateAGC, the simulation-workflow steps could instead be performed via the make utility, using the makefile Schematics/Makefile.  This Makefile has since been deemphasized due to the fact that it is Linux-only and I felt that maintaining it by extending it to Mac OS and/or Windows would be too troublesome and fragile.  Nevertheless, it still works and provides essentially the same functionality as simulateAGC, with these provisos:
For example, the makefile could be used as:
cd Schematics
make
vvp 2003200.vvp -fst
gtkwave agc.fst




This page is available under the Creative Commons No Rights Reserved License
Last modified by Ronald Burkey on 2025-01-17

Virtual AGC is hosted
              by ibiblio.org