Chipmunk is an analog/digital-circuit simulator written by David Gillespie of Cal Tech and John Lazzaro of UC Berkeley. They actually refer to it simply as log. The term "Chipmunk" stems from the fact that the package is distributed via from a directory of that name at the Chipmunk homepage at Cal Tech.
The package is freely copyable, i.e. public-domain. It should run on virtually any Unix X11 system. The document here is intended as a fairly thorough introduction to the major features of Chipmunk. I have set up some simplified installation instructions.
Make sure the bin subdirectory of the Chipmunk directory is in your search path, and then type
diglogTwo windows will be created, one labeled mylib and the other newcrt. You will be drawing circuits in the first of these, while the second will be used for things such as text input.
A nice convenience is that in most cases, when input is asked for the second window, you can type it even if the mouse is still in the first window.
Note that the windows can be resized, just as ordinary X windows can, so that you get a larger drawing area.
Chipmunk is designed for color monitors, but is quite usable with monochrome monitors too. In the latter case, before starting, add a variable for your X-server, using the X11 xrdb command:
xrdb -merge mylib.color: black_and_white ctrl-d
The Chipmunk documentation (and ours here) frequently refers to the terms tap and press and drag. These are what you would expect them to be, but for completeness they are defined here: tap means to click the left mouse button; press and drag means to click the left mouse button, without releasing it, and drag the cursor to whatever location is desired.
The documentation also loosely (and wrongly) refers to any object as a ``gate.'' MSI components, e.g. multiplexers, are considered gates.
Do the following to get a quick introduction to Chipmunk:
Chipmunk features a three-tiered component database:
To choose a component, simply press and drag it to the desired position.
To choose a component, press and drag the symbol. The mylib window will revert to its original state, i.e. to the space where you are drawing a circuit, and you can release the symbol wherever you want there. (In fact, you can even release it in the Tier 1 menu at the bottom of the screen, replacing one of the symbols there. This is useful if you think you will be using this component frequently.)
To leave Tier 2 if you have not chosen a component there, simply tap a point in the blank area of the screen.
To choose a component, tap its name. Then exit Tier 3, by hitting the space bar. The component will now appear in Tier 2.
A `>' on a component's pin means that this is a clock input.
A bubble on a component's pin means that this input is active-low, i.e. "0 means yes, 1 means no."
A pin is said to be "floated" if it is not connected to the rest of the circuit. For an output pin, this means the value on the pin will have no effect on the rest of the circuit, even if a physical connection exists.
The Digital Switch is a source of either 0 or 1, and is initialized to 0. Each time you tap it, it toggles, first to a 1, then a 0, then a 1 again, and so on. A 1 appears as a red-filled circle on color monitors, and as a white-filled circle in monochrome; a 0 appears as an unfilled circle.
Like a Digital Switch, but sends 1's only, and only when you tap it (try to tap it in or near the circle). This is good as a substitute for a clock, when you are testing a circuit. To verify that the pulse is reaching a given point, attach an EDGE component at that point; it will light up when a pulse comes, and not go out again until you tap it.
This is a convenient way to replace four Digital Switches. Just tap the value you want, and from that point onward, the four output pins will contain the 4-bit representation of the hex digit you tapped (least significant bit next to the F).
The LED acts as a sensor of 0 or 1. It displays the 0 or 1 in the same manner as for the Digital Switch above.
This is the output analog of the Digital Hexadecimal Keypad, conveniently replacing four LED's.
Tri-state devices are used for connecting a given entity to, or electrically isolating the entity from, other entities.
The typical usage is to connect registers to buses. Say we have several registers which can output to the same bus. At any given time, we want the value in only one (actually, at most one) of the registers to be copied to the bus, which in turn means that we need a way to electrically isolate the other registers from the bus. We can accomplish the latter by placing tri-state devices between the registers and the bus, and connecting the control pins of those devices to the register-selection digital logic.
For example, the Chipmunk component catalog includes the 74374 device, an 8-bit register which includes its own tri-state devices incorporated into the chip. The left-side pins are the data inputs to the register, the bottom pin is the clock, and the right-side pins are the outputs, i.e. they contain the value stored in the register.
What makes the 74374 differ from an ordinary register, though, is the pin at the top. If a value of 1 is input to that pin, the output pins will be floated.
Suppose that we are building a CPU which includes a register file of 16 8-bit registers, with output to a bus. We could use 16 74374's, with their tri-state pins connected as follows. Elsewhere in the CPU there would be four lines indicating which register is to be copied onto the bus (typically this would be a 4-bit field within the instruction). We would feed these four lines into a 4-to-16 decoder, whose 16 outputs (negated) would then be attached to the tri-state control pins of the 16 74374's.
For more flexibility, though, we may need to use ordinary registers, without internal tri-state devices, in conjunction with separate, external tri-state devices. Component 74126 provides this capability for individual lines, whereas the 74244 does this for two 4-bit quantities (which could be identical). For the 74126, the left pin is the input and the top pin is control (1 to connect the input to the output, 0 to "float").
The 74245 component provides bidirectional tri-state connections, very useful for buses. If the bottom pin is held high, then all pins on the two sides are floated. If the bottom pin is held low, then the top pin controls the direction of current---left to right if low, right to left if high.
Your wire will consist of one or more line segments. As an example, suppose you wish to draw a wire like this:
a b ........... . . . . ........ c dTo draw this line, simply tap at the places a, b, c and d, and finally click the right button.
If the line you are drawing crosses an existing line, they will be considered to not touch each other. If on the other hand they form a T shape, then they will be considered to touch, and a dark circle will appear there to indicate this.
If a line becomes dashed, even temporarily, you have accidentally made one line coincident to another, and should remove one of the lines. Similarly, if you suddenly see the screening flashing red, you have probably created a short circuit; delete the last line you drew.
As you will see as you start using Chipmunk, it is fairly good about aligning endpoints of lines. Consider, for example, this situation:
a b ........... . e f . .................. . . ........ c dSuppose you wish to draw a line to connect d and e, i.e
a b ........... . e f . ................................ . . . . ........ c dIf you start, say, at d, then move upward, you do not have to be that careful in assessing where to make your ``right turn'' toward e. As long as you are close to the height level of e, Chipmunk will adjust your position to match that level exactly.
All digital Chipmunk components, no matter how complex, are modeled as having total gate delay equal to 1 time unit.
The brief documentation give by Chipmunk on-line is often not very clear. For some components, more information is available by tapping the component while in CNFG mode, but this is still very brief. Some major components will be clarified here. Note, however, that in many cases you will need to experiment with a component in order to determine what each of the pins do.
The SHIFT component implements a four-bit shift register. Starting with the D pin and then going counterclockwise, here are the roles of the various pins: D is for serial data input, the main type of input used in shift registers; next are four pins which are used for parallel input; next is the clock input; the next four pins are the contents of the register; finally, the M pin controls whether the loading of the register at the clock pulse is done from D (M = 0) or from the parallel inputs (M = 1).
The adder components (2-bit and 4-bit) are numbers 7482 and 7483 in LIBR. The least-significant bit is at the top left, carry-out at the bottom right. Make sure to specify the carry-in at the top (0 if you are not using it); do not leave it floating.
MUXs in Chipmunk are called ``data selectors.''
For example, the 74157 will choose one of two 4-bit inputs (pins on the left edge), outputting the one chosen to the four pins on the right edge. Make the right-hand pin at the bottom edge low, and use the left-hand pin for the MUX control (0 selects the upper input, 1 the lower).
The 74153 selects one of 4 1-bit inputs on the left and copies it to the output on the right (as long as the top input is kept low or unconnected). The four inputs are numbered 0-3, starting at the top. The control inputs are the 2 pins on the bottom, the left of which is the more significant bit.
This compares the two four-bit numbers input to the bottom pins (MSBs are the leftmost pins). The three pins coming out of the left edge indicate whether the first number is greater than, equal to or less than the second, respectively.
The input is on the left, output on the right, with the least significant bits uppermost in both cases. The bottom input is the clock, and the top is an asynchronous clear, active-low.
This is a static RAM chip which stores 8K 8-bit words.
The address pins are on the left, with the least-significant bit on the top.
The data pins are on the bottom, with the least-significant bit on the right.
The three pins on the top---CE (Chip Enable, labeled with a clock symbol, not CE), R (Read) and OE (Output Enable)---are for control. R is active-high, while CE and OE are active low. To perform a read of the chip, input 0 to CE (to choose this chip), 1 to R (for a read) and 0 to OE (to enable the internal tri-state connections for output). For a write, input 0 to CE and 0 to R (the OE value will not matter). If you are building a clocked system, and if you intend to do writes to this chip (otherwise, you can use it as a ROM), your input to CE will usually be AND-ed with a clock.
Be sure not to leave any of the address pins floating, as they will be taken to have the value 1 in that case. If they are 0s, connect them to real 0s.
SRAM8K is an example of a Chipmunk component which can be ``configured''; Chipmunk allows you to tailor parameters of such components for your application. In the case of SRAM8K, this means for instance that you can conveniently load a set of initial values into a SRAM8K instance from a disk file.
To configure an SRAM8K, enter CNFG mode. Tap the SRAM8K, and go to the newcrt window, where you will see a menu of SRAM8K parameters.
You can move from one menu item to another via the up- and down-arrow keys, and you can set items to your liking by either using the right- and left-arrow keys (to cycle through choices) or by typing in your choice (e.g. in the case of numeric items). Once you have the choice you want in a given item, you can tell Chipmunk to use it by using an up- or down-arrow key to leave it. (Note: Do not hit the Enter key, as that will simply change the item back to the default value.)
The first menu item is Mode, with choices Read-only, Deposit and Deposit Next. The first of these allows you to examine any location within the SRAM8K; the second allows you to enter a value into any location; and the third is an extension of the second, allowing you to sequentially step through consecutive memory locations, depositing values in each location in turn. Two Address and two Data items in the menu allow you to given addresses and data in either hex or decimal.
For example, suppose we wish to put the value 15 (decimal) into location 3 of the chip. We would first get into CNFG mode and then tap the interior of the SRAM8K chip, as mentioned above. A menu would then appear in the newcrt window, with the first menu item, Mode, highlighted. If Mode is not already Deposit, we would change to it using the right- and left-arrow keys, and then use the down-arrow key to get to the Address menu item, say the hex version. We would then type 3, and then hit down-arrow again (which will make the decimal version of the item now display 3 too). We would hit the down-arrow key again until we get to Data (decimal), and type 15. To make the latter official, we now hit the down-arrow key again. That brings us to a question about saving the contents of the SRAM8K to a file. Suppose we don't want to do so. If the item says Yes, we use the right- and left-arrow keys to make it say No. Then we leave the menu, by tapping anywhere in the menu window.
To test that this worked, i.e. that location 3 really does contain 15, we could put the value 1 on the top two address pins of the chip, put 0s on the bottom 11 address pins, put 0 on CE, 1 on R, 0 on OE, and LEDs on the rightmost four data pins.
Of particular interest are the menu items dealing with disk files, which allow you to save the current contents of the SRAM8K into a file, or load previously-saved contents. To save to a file, set the ``Save in circuit file'' item to Yes, and type the file name in the indicated item; a suffix of .ram for the file name is recommended (and is used if you supply a suffixless name). Once you have typed in the name, tap it. The name will then disappear from the screen, but the file will indeed be written at that time.
By the way, the file format is straightforward ASCII. For example, I placed the values 3i in locations i, i = 0,1,2,3,4,5,6 and the value 4 in location 0x100, and then saved the memory contents to a file 3.ram. Here are the first few lines which were then created in that file:
0000:000306090C0F12000000000000000000 0010:00000000000000000000000000000000 0020:00000000000000000000000000000000 0030:00000000000000000000000000000000 0040:00000000000000000000000000000000 0050:00000000000000000000000000000000 0060:00000000000000000000000000000000 0070:00000000000000000000000000000000 0080:00000000000000000000000000000000 0090:00000000000000000000000000000000 00A0:00000000000000000000000000000000 00B0:00000000000000000000000000000000 00C0:00000000000000000000000000000000 00D0:00000000000000000000000000000000 00E0:00000000000000000000000000000000 00F0:00000000000000000000000000000000 0100:04000000000000000000000000000000 0110:00000000000000000000000000000000
There is a more advanced example of using SRAM8K later in this mini-manual.
TNEG is a T ("toggle") flip-flop. If the T input is 1, then each pulse of the clock changes Q from 0 to 1 and vice versa. In essence, it is a mod 2 counter. (The word "negative" here means that the input is accepted during the falling edge of the clock pulse.)
You can use TNEG without connecting anything to the top and bottom pins. These have asynchronous Set and Clear functions, meaning that you can use them to set (to 1) or clear (to 0) the value of Q at any time, not just when the clock input is pulsed (i.e. asynchronously). If you wish to use these functions, keep in mind that they are active-low. So, for example, if you connect a Digital Pulse Generative Switch to a NOT gate, and connect the latter to the top input of the TNEG, then if you pulse, Q will change 1 (or stay at 1, if it was already 1), no matter what the other inputs are. Similarly, if you connect a Digital Pulse Generative Switch and a NOT to the bottom input, then a pulse will change Q to 0.
DPOS is an ordinary D flip-flop. The input will be copied to Q during the rising part of the clock pulse. The top and bottom inputs work like those of TNEG.
This is a tri-state buffer. The output is the box; connect this to whatever you need. The input is on the other side of the triangle from the box. The control is on the side of the triangle; if this is 1, then the input is connected to the output.
A very handy tool for reducing clutter on your screens is to use the TO and FROM components, which set up "invisible" wire connections. Here is how to use them:
Say you would like to have an "invisible" wire between two components (for example, wires) A and B, with the invisible connection being named XYZ. Then draw a line connecting A to the "arrowhead" portion (further-right point) of a FROM component. Then tap the arrowhead, resulting in a beep and a red blotch appearing; type XYZ and return, causing an XYZ label to appear there. Now go to B. Draw a line connecting B to the stem of a TO component, and label the latter XYZ in the same manner. Then A and B are connected, just the same as if you had drawn a wire from one to the other.
This is a 1-out-of-16 multiplexor (MUX). The inputs are numbered 0 to 15, from top to bottom on the left edge, and are selected via the four pins on the bottom edge, whose least significant bit is on the right. The pin at the top should be connected to 0 or left floating. The output is on the right edge, and is active-low.
For the 74138, connect 1 to the top pin on the left edge, and leave the two "bubble" pins beneath it floating. The input is in the bottom three pins on the left edge, least significant bit on top. Output is on the right edge, least significant bit on top, active-low.
The 74139 is similar. Again, float the top-left pin. Input and output pins have LSB on top; output is active-low.
In ROT mode, you can rotate any component (typically within the menu at the bottom of the mylib screen), simply by repeatedly tapping it. This makes connections easier.
To move an item, just press and drag it.
You can move a whole region in one operation. To do this, first press and drag the mouse, which will create a box in the screen. Then release the mouse button, which will change the box borders to dashed-line form. Then move the mouse and when you reach the point where you wish to move your region, click the right mouse button.
Press and drag the mouse on Editing, releasing on Copy. Then tap the item to be copied. Move the mouse pointer to the desired place, and then hit the left mouse button. Keep moving the mouse pointer and hitting the left mouse button until you've made the desired number of copies. Then hit the right mouse button to end copy mode.
If you wish to copy an entire region, first enter Copy mode as described above. Then drag the mouse to produce a box around the region to be copied (see instructions for moving, above). Then copy as described above, by repeatedly moving the mouse and hitting the left button.
You can enter delete mode by choosing the Delete item in the Editing portion of the mylib window, or by hitting the `d' key. (Many of the mouse actions have keystroke equivalents.) The cursor will change to a picture of a pair of scissors. You can then repeatedly move the cursor to different items, tapping each one you wish to delete. (You may have to move the cursor a little before you find a place at which the cut works.)
You can delete a whole region by pressing and dragging the mouse, which will create a box in the screen; everything in the box will be deleted.
When you finish, leave delete mode by clicking the right mouse button.
Quick trick: A fast way to delete a simple object like a wire is to simply drag it down off the bottom of the screen.
You should make liberal use of labels in your drawing, as they serve as analogs of program comments.
To make a label, hit the `l' key, and then start typing your label. It will appear near the lower-left edge of the mylib window. When you are finishing typing, hit the return key, and you can then use Move capability (see below) to move the label to wherever you want it in the picture.
The mylib window holds one "page" at a time. You can draw different circuits on different pages, and copy from one to another. To switch to page n, just type n.
Each page is essentially infinite in scope; you can scroll using the arrow keys. You can also resize the mylib window just like you would any X11 window.
You will find the Probe mode especially handy. Just hit the `.' key to enter this mode, and hit the key again when you wish to exit.
The purpose of Probe mode is to quickly and conveniently do what an LED would do-check the value on a line. While in this mode, whenever you move the cursor near a wire, the 1-or-0 value on that line will be displayed, in the form of a bar or absence of the bar (on color monitors, the bar will be red). The position of the bar will be above the Frills and Editing portion at the lower left of the mylib screen (and also lower right).
You should stay in Probe mode only temporarily, because some functions cannot be executed while in that mode. To leave Probe mode, simply select Probe again.
Look below the field labeled "Misc" at the bottom right of the main screen. It will say ROT or MIR- or MIR| or CNFG. You can choose among these by repeatedly tapping on that field. For instance, if it says ROT and you tap ROT, it becomes MIR-.
This field determines what happens when you tap a "gate" (i.e. a Chipmunk component). We are mainly interested in the cases ROT and CNFG: If you tap a component in ROT mode, the component rotates orientation; if you tap it in CNFG mode, you either get to specify some configuration data for the component or receive some brief information on how to use it.
As with programming, modular design is essential to building complex digital systems. Chipmunk facilitates such design.
IMPORTANT NOTE: Chipmunk is very unforgiving of errors in the module creation and usage processes. Be absolutely sure to follow the directions here to the letter.
To create a module (recall that Chipmunk refers to this as a "gate," which is an abuse of the term), do the following:
You will get a message that the module is being compiled. This message seems to stay forever, but actually the compilation should only take a second or two unless the circuit is really large. You can make the message disappear by hitting the space bar a couple of times. (Similarly, each time you change the module, you will get a message ``recompiling'' which will stay for a long time; hit the space bar to get rid of it if it bothers you.)
Note: You are not allowed to directly connect a wire directly from one point of a module box to another, without having the wire go through any intermediate gates. If you do, Chipmunk will complain that you have shorted together two template pins. This is a problem, because in some cases you may wish to do this; for instance, you may need one of the outputs of a module to be identical to one of the inputs. If so, put in some "filler" gates, e.g. two NOT gates in series.
Each time you connect a wire to the box, a message should appear concerning the number of connections and ports this module has, ports meaning places where you should connect, and connections being the number of places where you have connected so far. (If such a message doesn't appear, then you do not have an official module, and it will not work.) When you have connected all the wires ("ports") needed by a module, its outline will become brighter.
It is possible to have more than one module on the same display page, and to save all the modules on a page into a single .lgf file. When building circuits with a large number of modules, this means you have to keep track of fewer files, load fewer files upon startup, and use fewer pages. It thus becomes a great convenience factor, so you are strongly encouraged to make use of this feature.
Suppose I wish to store modules A and B, currently in a.lgf and b.lgf, into a single .lgf file. Here are steps I could take:
Most of the Chipmunk components are written in Chipmunk's LOGED language, and any of these can be used in creating a module. However, a small number of components, such as the SRAM8K, are written in Pascal, and these cannot be used in modules.
Note that each instance gate has a limit on the number of pins it can use. The limit is displayed when you position the mouse pointer over the gate in LIBR.
To refresh the screen, several methods are available, such as tapping it, hitting the space bar, and so on.
Chipmunk assumes TTL electronics, which normally should not concern you, except that one implication is that if you do not connect anything to an input pin of a component, this has the same effect as if you had connected a 1 to it.
One drawback of Chipmunk is that it assumes that each component, no matter how complex, takes one clock cycle to operate. This is OK for our purposes, and it avoids the subtle timing problems which plague many digital simulation programs.
I have found that on some machine types, sometimes Chipmunk encounters errors due to insufficient window memory. To avoid this, make sure that your mylib and newcrt windows do not overlap any other window. You may wish to iconify or temporarily delete some windows. Above all, avoid the DEC machines as your X11 server (i.e. the machine at which your windows are displayed), which seem to have some problem with their X11 software. In any case, frequent saving of your Chipmunk pages to their files would be wise.
This is an example of how a multiplexor can be used to implement the analog of "if-then-else" from the programming world. (Click your mouse here to obtain the actual Chipmunk circuit file.)
This circuit converts a 4-bit integer stored in signed-magnitude form to 2s complement form. ( Click here if you need to review these forms.) The 4-bit input is via the hex keypad at the middle left. If the sign bit is a 0, then the output is equal to the input. On the other hand, if the sign bit is a 1, it is changed to a 0, then the resulting 4-bit string is inverted (note the Chipmunk INV4 component), then we add 1 (stored in the upper-left hex keypad). The two cases are both fed into the '157 MUX, which is controlled by a line which we have connected to the sign bit. (In other examples in which a MUX is used for "if-then-else," then we would have a more complex set of gates whose output feeds into the MUX's control bit.
Here is an example of the use of various Chipmunk features. We wish to design a circuit which will constantly tell us the values of n mod 5 and n div 5, where n is the number of clock pulses received so far. Instead of actually doing computation, though, we can take the following simpler route. (Click your mouse here to obtain the actual Chipmunk circuit file.)
We maintain two counters, one for n mod 5 and the other for n div 5. The first counter should be incremented on every clock cycle, but should be cleared each time it reaches 5. The second counter should be incremented only at those cycles in which the first counter is cleared.
The circuit is in the file ModDiv5.lgf in the NMDoc subdirectory of the Chipmunk directory. Run Chipmunk and then load this file before reading further, so that you can refer to the circuit diagram while reading the next few paragraphs.
I have placed labels ``mod 5'' and ``div 5'' at the two Binary Counters. Note that I have attached Hexadecimal Displays (obtained from Tier 2) at the outputs of the two Binary Counters; I could have just placed individual LED's, but the Hexadecimal Displays are more convenient and are clearer.
At the left I have placed a Digital Pulse-Generative Switch, which will serve as ``clock'' input for testing the circuit. Try tapping it a few times (at least until the mod count cycles back to 0), watching the mod and div counts change.
At the top, I have placed a Digital Switch, and a label ``init.'' As the label implies, the Digital Switch is used to initialize the two Binary Counters to 0 when we first start the circuit (the C input in a Binary Counter clears the counter).
I have placed a label ``74138'' next to a Decoder, which I obtained from Tier 3. The numbers 74xxx are those used in standard component catalogs. Note that the 74138 description says that the outputs are active low, i.e. 0 means yes and 1 means no. For example, if the inputs are 101, i.e. 5, then pin 5 of the output will be 0, meaning, ``Yes, the input was 5.'' This is why I have the NOT gates at the two output pins I am using.
Looking again a pin 5, you will see that it leads ultimately to the C input of the mod counter. This is because I want the count to revert to 0 after reaching 5. At the same time I want the div counter to be incremented. This is why the clock pulse is ANDed with the (negated) output of pin 4. (Why not 5? The reason is that this would present a timing problem; experiment with this a little and you will see.)
Here is an example of use of the SRAM8K component. The .lgf file is available here. Load it into Chipmunk before reading further.
In this very simple example we are using an SRAM8K chip to store four 2-bit words. We have 2-bit address and data buses, a clock line, and a read/write line (1 for read, 0 for write), to which we have attached Digital Switches, LEDs and a Digital Pulse Generative Switch.
To write a value to our little memory here, first set the Digital Switches on A0, A1, D0 and D1 according to what value you want to write to which word of our memory. Set the Digital Switch on the Read/Write line to 0. Then tap the "clock" (the Digital Pulse Generative Switch).
Write a few values to memory. Then try reading them: Simply set A0 and A1 to the desired address, and set the Read/Write line to 1. Check via the LEDs on D0 and D1.
Note the tri-state devices on the Digital Switches on D0 and D1, which are crucial since these lines serve for both reading and writing.
Adding something to a variable and then storing the sum back in the variable is one of the most common operations in computing, as in the C code
Y += X;
Here we need to first read Y, then add X to it, then store the sum back in Y, i.e. write to Y. Some multiprocessor computer systems add extra hardware near the memory to expedite this operation; instead of a CPU doing the addition, it is done by this extra hardware. We call this operation "fetch and add."
(The reason for having special fetch-and-add hardware is that in multiprocessor systems, the memory is usually very "far"---in a timing sense---from the CPUs, so that each trip to memory takes a long time. The special hardware then allows us to make only one trip to memory instead of two.)
Before going any further, load the .lgf file.
Now, how does the circuit work? The key point is that we will need two clock cycles for the fetch-and-add, because we cannot both read and write the SRAM8K (labled "memory") in one cycle. So, we need something to keep track of "what time it is," in terms of the count of clock cycles. Since our operation only takes two clock cycles, our "time" can be measured mod 2, i.e. in just a single bit. For that purpose I have placed a TNEG ("toggle") flip flop near the upper-left section of the circuit.
The "time" is stored in the Q output of that TNEG. If you follow the line to the R input of the SRAM8K, you see that at time 0 we read from memory. If you follow the line to the tri-state buffers, you see that at time 1 we write to memory.
For simplicity, we are using 2 bits as both our word and address size.
In this example we are constructing fetch-and-add-1 hardware. So, we have an '83 adder, one addend of which comes from reading the SRAM8K and the other addend being the constant 1. The sum is then stored in the '175 register for safekeeping until the write-cycle.
Click here to get the files for this example. They involve building up more and more complex MUXs from simple ones. See the README files for details.