As the first two parts of this series discussed, building a physical implementation of the entire HRRG computer (or, "The Beast") from the ground up is a huge undertaking that would be both time-consuming and expensive. The HRRG team's cunning solution to this conundrum is to create an HRRG emulator program that provides virtual representations of all of the cabinets (functional units) forming The Beast. (See the "Who is to blame?" Web page linked in Resources for a list of people involved in the various aspects of this project.) The HRRG emulator will be available for free download with Part 4 of this series. At that time, I'll describe how to use it and how to create your own virtual cabinets.
The idea is that you will be able to create programs in our simple assembly language, assemble them (using an assembler we will provide), and immediately run these programs on the HRRG emulator. Then, when you are ready, you can create a physical cabinet to implement a part of the system. You can then run this physical cabinet -- which could be as simple as a single 8-bit word of memory -- in conjunction with the rest of the system that remains in the virtual world. As you build more and more physical cabinets, you can use these to replace their virtual counterparts until -- eventually -- you have an entire system in the physical domain. (You will also be able to run your physical cabinet(s) in conjunction with remote cabinets located around the world through the Internet, but this will be the topic of a future article.)
To understand how things work in the emulation world, you must appreciate that -- as far as possible and insofar as it makes sense to do so -- the emulation is trying to mimic any actions that take place in the physical domain. So, here's a reminder of what a purely physical system would look like:
Figure 1. A purely physical implementation of The Beast
In addition to its core logic (implemented in the technology of your choice), each physical cabinet contains a General-Purpose Input/Output (GPIO) card. The GPIO cards communicate by transmitting and receiving packets of information back and forth between themselves using a RS485 multidrop serial interface (we chose this type of interface because it's "cheap-and-cheerful," easy to implement, robust, and tolerates a "noisy" environment).
Each GPIO card is configured (programmed) with a unique 6-byte MAC address; each card is also configured to understand the type of cabinet in which it currently resides (I'll return to discuss this configuration in a moment). When a GPIO card sees an incoming packet, it checks that packet to determine (a) in what type of cabinet the packet originated and (b) what type of information the packet contains. For example, if a packet containing status information originated in the ALU Logic cabinet, then the GPIO card residing in the Status Logic cabinet will present these new values to the signals driving its physical implementation. By comparison, the GPIO card in the Control Logic cabinet will ignore any status information originating in the ALU (it will only accept status information originating in the Status Logic cabinet itself).
The beauty of this scheme is that most of the complexity is handled by the GPIO cards. The physical logic in the heart of the cabinet (implemented in the technology of your choice) is required only to process data and control signals that are relevant to that logic.
Of course, this scheme relies on each of the GPIO cards being configured (programmed) with an "Identity" -- that is, the type of cabinet in which it resides and its unique 6-byte MAC address. Furthermore, the GPIO cards in any ROM, RAM, Input Port, and Output Port cabinets are also configured with an address range (that is, a 16-bit start address and a 16-bit end address).
Performing this configuration is one of the duties of the HRRG emulator, which resides on your host PC. The PC communicates this configuration information through a PC Bridge (PCBR) card, which communicates with the PC through a USB 2.0 port and with the HRRG through the RS485 multidrop interface, as Figure 2 illustrates.
Figure 2. Configuring a purely physical implementation of The Beast
Even in the case of a purely physical implementation of The Beast, you will still need to run the HRRG emulator at least one time to program all of the GPIO cards in the system with their identities. The GPIO cards store this configuration in on-board Flash memory, so they need only be configured a single time (unless you decide to change something).
Having said this, even if you do have a purely physical implementation of The Beast, it is advantageous to leave the HRRG emulator running on the PC connected into the system as Figure 2 illustrates. This is because the emulator can "snoop" and record any data packets as they race around the system, which is useful for a variety of reasons, including debugging a new cabinet that you are just bringing online.
The reason the discussions on the GPIO cards above are of interest in the context of the HRRG emulator will become apparent as we proceed. First consider a high-level view of a purely virtual implementation of the HRRG, as Figure 3 illustrates.
Figure 3. A purely virtual implementation of The Beast
Each of the virtual cabinets are independent entities (except for the Clock Generator and Control Logic cabinet, which are treated as one). These virtual cabinets communicate using the same packets as do the physical units. Furthermore, each virtual cabinet contains a Virtual GPIO (VGPIO) card. These VGPIO cards are configured in a similar manner to their physical counterparts; that is, each is configured to understand its cabinet type, to be assigned a unique 6-byte MAC address, and -- in the case of ROM, RAM, Input Port, and Output Port cabinets -- to be assigned an address range.
As I previously noted, in the fullness of time, as we start to create physical cabinets, we will use these cabinets to replace their virtual counterparts. In this case, the remaining virtual cabinets and the new physical cabinets will communicate by passing their packets of information around through the PC Bridge card, as Figure 4 illustrates.
Figure 4. A mixed virtual-physical implementation of The Beast
Observe that Figure 4 shows only a single RAM cabinet and a single Output Ports cabinet to emphasize the point. In reality there can be multiple virtual and/or physical ROM, RAM, Input Ports, and Output Ports cabinets, each occupying their own range of addresses.
Before proceeding, I'll show you a sneak preview of the emulator. Initially we will provide only a single example of each type of cabinet. The way the emulator is architected, however, means that anyone can create his or her own virtual cabinets as DLL (Dynamic Link Library) objects. When you do create such a cabinet, you simply drop its DLL into the appropriate emulator folder on your PC. When you subsequently come to create an HRRG "Project," you select which cabinets you wish to combine to form your system.
As you select the virtual cabinets you wish to use, they appear in a "virtual rack." Figure 5 presents a cut-down portion of the rack showing the control, status, and ALU cabinets. (Click to see the full-size image.)
Figure 5. The virtual control, status, and ALU cabinets
When the emulator is running, the various LEDs and displays light up to reflect what's happening in each of the cabinets. Each of the cabinets can be displayed full-size as Figure 5 shows, or they can be "collapsed" so as to consume less real estate on your screen. For example, Figure 6 shows the Control, Status, ALU, and Address cabinets in their collapsed state (double-clicking on a collapsed cabinet returns it to its full size). (Click to see the full-size image of Figure 6.)
Figure 6. Each virtual cabinet can be "collapsed"
Figure 6 also shows a virtual ROM cabinet and a virtual RAM cabinet. You can have multiple instantiations of these memory cabinets, so long as each is assigned its own unique range of addresses. You can also associate a default "contents" file with each memory cabinet, and these contents will be automatically loaded into the cabinets when power is applied to the system. When the system is running, these memory cabinets automatically scroll to whichever location is being read from or written to (it's incredibly cool; you really ought to see it . . . he said with a wicked grin).
The HRRG emulator serves a number of different functions. As I've already discussed, for example, it allows you to immediately start writing and testing programs. This is because each type of cabinet has default versions, and these default versions are delivered with the emulator.
Using the HRRG emulator also allows you to "start off small" by creating a single physical cabinet and running that cabinet in conjunction with the remaining cabinets being represented in the virtual domain. In fact, this leads to another key feature of the HRRG emulator, which is using it to create, test, and debug virtual prototypes of your cabinets before you commit time and resources on a physical implementation.
Now, when you come to create your own virtual cabinets (I'll explain how to do this in Part 4, which is when the HRRG emulator will be available for you to play with), it would be easy to use "programming tricks" to generate small and efficient representations. You have to restrain yourself from doing this, however, because what you're really trying to do is to create virtual representations that -- as closely as possible -- mimic the operation of their physical counterparts.
As examples, we've assumed that the default versions of the cabinets supplied with the HRRG emulator are to be created out of simple "Jelly-Bean" integrated circuits of the TTL (Transistor-Transistor Logic) variety. Accompanying Part 4, I will provide the pseudo-code representations we used to create our virtual cabinets and also the source code for the cabinets.
Also of interest is the fact that one of the features provided by the HRRG emulator is a simple and intuitive interface that allows you to define a series of data packets to be presented to a target cabinet and the response packets you expect to see coming back from that cabinet.
Figure 7. The device tester
As Figure 7 shows, you can define the contents of packets you wish to transmit (shown as 'T' in the leftmost column) and the responses you expect to receive (shown as 'R' in the leftmost column). You can also include comment ('C') lines, which aren't shown here. When you run the tester, it transmits its packets, waits for any responses, and displays the results by inserting '=' lines and highlighting any differences between actual ('=') and expected ('R') responses.
Test sequences can be saved by name and reloaded and rerun as required. The device tester is obviously extremely useful with regard to debugging a newly created virtual cabinet. Furthermore, the same test sequence can subsequently be reused on a physical cabinet.
Just to give you a "taste" as to the sort of issues we're considering, take the case of the ~BUSY signal. The following discussions focus on this signal in the context of physical cabinet implementations, but the virtual representations also have to support this capability.
The point is that, in the real world, some physical implementations will be faster or slower than others. A memory cabinet (implemented using vacuum tubes, for example) might respond relatively quickly to a request from the control cabinet. By comparison, an ALU cabinet (implemented using trained hamsters racing round mazes, for example) might respond relatively slowly to a request from the control cabinet.
One possibility would be to slow the system clock down to accommodate the slowest cabinet. But this has a major disadvantage in that one type of cabinet (say an Output Port cabinet) that is used relatively infrequently may be much slower than all of the other cabinets. In this case, the system would be running slower than it could be operating for most of the time.
Ideally the system should run as fast as possible. The solution decided upon is that when the control cabinet issues a packet to which it expects a response, it sets the ~BUSY signal to its active (logic 0) state. Once the ~BUSY signal is in its active state, the control cabinet will ignore any subsequent clock signals until it receives a return packet from the target cabinet; amongst other things, this packet will have the ~BUSY signal returned to its inactive (logic 1) state.
The GPIO card in the physical cabinet will always see ~BUSY signals in incoming packets and -- by one means or another -- set appropriate ~BUSY values in outgoing packets. There are two main techniques the GPIO card may use to achieve this. The first technique is for the GPIO card to handle everything itself. For example, consider a high-level view of one of the cabinets -- say the ALU cabinet -- using this technique, as Figure 8 shows:
Figure 8. The GPIO card can handle timing by itself
Assume the Control Logic cabinet issues a packet requesting that the ALU cabinet perform some action and return some result -- this packet will have the ~BUSY signal set to its active state. Using this first technique, the GPIO card will present the appropriate signals to the inputs of the ALU Logic and then wait a pre-programmed amount of time (this can be set to any value between 0 and 65,535 microseconds).
At the end of this delay, the GPIO card will sample the signals coming out of its cabinet, gather them together, and transmit its response packet to the outside world (this response will include the ~BUSY signal being returned to its inactive state). This is the simplest arrangement, but it fails to address situations where a cabinet may respond with variable speed. For example, consider a memory cabinet in which data is stored in a carousel-type arrangement (like a "wheel"). If the required data is in the "basket" that is currently at the "reader," then the response will be relatively fast. By comparison, if the required data is in a basket that is at the far side of the "wheel" from the "reader," the response will be much slower.
To address such a variable-delay scenario, the GPIO card can be programmed to present a copy of the incoming ~BUSY signal to logic in the cabinet. The GPIO will then poll (keep on sampling) a corresponding ~BUSY signal coming out of the logic in the cabinet until this signal indicated that the cabinet has completed its operation, at which point the GPIO card will sample the other signals coming out of the logic, gather them together, and transmit its response packet to the outside world.
To understand this, first consider a totally unrealistic (but simple to comprehend) example as shown in Figure 9:
Figure 9. The ~BUSY signal
Here's the way this works. When the cabinet is originally powered up, the GPIO card sets its ~BUSY_in signal to its inactive state (logic 1, saying "not busy"). In the artificial example shown above, this ~BUSY_in signal first passes through a delay element and then through an inversion. Thus, after some delay, the ~BUSY_out signal ends up carrying a logic 0 value, which says "I'm busy."
At some stage, the Control Logic cabinet sends a packet instructing the ALU cabinet to do something. This control packet has its ~BUSY signal set to its active state (logic 0). The GPIO first checks the ~BUSY_out signal to ensure that it is in its logic 0 ("I'm busy") state (I'll return to this point shortly). Assuming that the ~BUSY_out signal is in its logic 0 ("I'm busy") state, the card will present the appropriate signals to the inputs of the ALU Logic. At the same time, it will present the new ~BUSY signal from the packet to the physical cabinet in the form of the ~BUSY_in signal.
The GPIO card now starts polling the ~BUSY_out signal. Initially this has a value of 0, which indicates that it's busy. Eventually, after the incoming signal has passed through the delay element and the inversion, the ~BUSY_out signal will transition to a logic 1, thereby indicating a "not busy" condition. At this point, the GPIO card gathers the appropriate output signals from the ALU Logic and bundles them together in a packet that it sends back to the Control Logic cabinet. This packet effectively has its ~BUSY signal set to the value on the ~BUSY_out signal, which is 1, meaning "not busy."
Now, here's the clever part (or, at least, one of them). At the same time as the GPIO card transmits this packet back to the Control Logic cabinet, it also sets the ~BUSY_in signal to its inactive (logic 1) state, and this signal now starts to propagate its way through the delay element and the inversion. We now have one of two possible scenarios:
- The Control Logic cabinet has its own delays, or it's busy instructing other cabinets to do something, or whatever. The point is that, under this scenario, the new logic 1 value on the ~BUSY_in signal has time to propagate through to its inverted state on the ~BUSY_out signal before the Control Logic cabinet sends a new packet to the ALU cabinet. In this case, this new packet is handled in exactly the same manner as discussed above.
- The Control Logic cabinet immediately sends a new packet to the ALU cabinet before the new logic 1 value on the ~BUSY_in signal has time to propagate through to its inverted state on the ~BUSY_out signal. In this case, when the new packet comes in and the GPIO card checks the state of the ~BUSY_out signal, it sees a logic 1 value saying "not busy."
Effectively the ~BUSY_in and ~BUSY_out signals are both currently in the same logic 1 ("not busy") states. The GPIO card understands what has happened, so it simply starts polling the ~BUSY_out signal waiting for it to transition into its logic 0 ("I'm busy") state. When this occurs, the GPIO card presents the appropriate signals to the inputs of the ALU Logic. At the same time, it presents the new ~BUSY signal from the packet to the physical cabinet in the form of the ~BUSY_in signal, and everything carries on in the same manner as discussed above.
Now, as I said, the previous scenario is actually totally unrealistic. Rather than implementing things this way, you would simply use the GPIO card's internal timing mode. However, take a look at a somewhat more realistic scenario as presented in Figure 10:
Figure 10. Using the ~BUSY signal as a trigger
The new "Special Logic" uses the ~BUSY_in signal as a trigger, monitors certain signals coming out of the ALU Logic, and -- ultimately -- controls the value on the ~BUSY_out signal. In this case, the "delay" elements would manifest themselves in the ALU logic and the "Special Logic." Actually, the "Inversion" would also be part of the "Special Logic," but we've shown it as being separate and distinct for the purposes of clarity. Although this might look a little complicated, any complexity is in the way the "Special Logic" is implemented; from the perspective of the GPIO card, the ~BUSY_in and ~BUSY_out signals work as described for Technique 2 - Scenario 1.
As one final scenario, consider the configuration shown in Figure 11:
Figure 11. Only using the ~BUSY_out signal
In this case, the only inputs to the "Special Logic" come from the ALU Logic itself (the "Special Logic" monitors certain signals looking for specific values/transitions and reacting accordingly). The point is that the GPIO card doesn't need to know anything about this; it can carry on placing values on the ~BUSY_in signal to its heart's content. The fact that these values aren't actually used doesn't affect anything, and the GPIO card can do everything in the same way as it did for Technique 2 - Scenarios 1 and 2.
Well, that's all for now. In Part 4 we will make the HRRG emulator available and walk you through a demonstration in which you load virtual cabinets into the rack to form a virtual system, create a simple program, assemble it into machine code, load it into the emulator, and run it. You'll also learn how to create your own virtual cabinets for use with the emulator.
- Get an RSS feed for this series or subscribe to the zone newsletter IBM microNews and be notified each time a new installment is published. (Find out more about RSS feeds of developerWorks content; find out more about IBM microNews.)
Part 1 of this
series describes how the plan for the
Heath Robinson Rube Goldberg multifarious technology computer project came
- Find numerous suggestions for "The Beast" on the HRRG
Project Web page.
The various folks involved in the HRRG project in one way or another are
introduced in this Who is to blame? Web page.
- Download a compressed (*.zip) file containing an Adobe. Acrobat. (*.pdf) version
"The Official DIY Calculator CPU Data Book" from the Area-51 folder
on the DIY Calculator's Web site.
The various input and output signals for the functional blocks forming
HRRG's CPU are detailed on this Partitioning the CPU Web page.
the book How Computers Do Math, which features the same CPU that
will be used to form the basis for the HRRG, from www.Amazon.com.
- Download a virtual version of the same CPU that will be used to form the basis for
the HRRG for free from the "Downloads" page on the DIY Calculator
The "More Cool Stuff" page on the DIY Calculator Web site contains a
treasure trove of topics, including A
History of Calculators and Computers, A
Timeline of Calculators, Computers, and Other Stuff, The
Computing Universe, Rounding Algorithms 101, and a rather interesting paper
on Color Vision.
IBM Semiconductor Solutions Technical Library
hosts a wealth of information -- from
specifications and user manuals to product briefs and errata and much more.
Get products and technologies
downloads on one page.
- Participate in the discussion forum.
Take part in the IBM developerWorks Power Architecture technology forums.
Send a letter to the editor.
Clive (Max) Maxfield is the author/co-author of a number of books,
including Bebop to the Boolean Boogie (An Unconventional Guide to
Electronics) and How Computers Do Math, featuring the pedagogical and
phantasmagorical virtual DIY Calculator.
In addition to being a hero, trendsetter, and leader of fashion, Max is widely regarded as being an expert in all aspects of computing and electronics (at least by his mother). Max was once referred to as "an industry notable" and a "semiconductor design expert" by someone famous who wasn't prompted, coerced, or remunerated in any way.