A CPU may have its control function implemented entirely in hardware. Alternatively, the machine instructions may be interpreted by a simpler machine which directly controls the timing and flow of data within the CPU. The program which runs on this simpler machine is called a microprogram or the control store of the CPU. Insertion of a different control store results in a machine with different machine (assembly language) instructions. The execution of the microprogram consists of loading instructions from the control store into the microinstruction register (MIR). This register directly controls the flow of information in the machine.
Tanenbaum describes a simple horizontal microcode machine called the Mic-1 shown in Figure 1. The machine executes a microprogram which is stored in the control store. The subprograms in the control store correspond to individual instructions at the conventional machine level (the assembly language of the machine). Tanenbaum implements a complete assembly language called Mac-1 in the Mic-1 control store. More detailed descriptions of the Mic-1 and Mac-1 with examples are given in the appendix.
Figure 1: The Mic-1 machine as it appears in the Tanenbaum text.
(Permission from Prentice Hall for publication is pending.)
The material on microprogramming is quite complicated and requires an understanding of the conventional instruction cycle of a Von Neumann machine. Students find this difficult, in part because there are two instruction cycles to keep track of, one at the microcode level and one at the assembly language level. We have taught this material for several years, never feeling satisfied with the students' grasp of this material. Although they seem to understand the lecture presentations and could do the assigned problems, fundamental understanding is often lacking. We had considered implementing a Mic-1 simulator for the students to use, but there just was not enough real estate on the screen of an ASCII terminal to make this feasible.
Several years went by in which we were involved in other teaching projects, and so we did not teach this course for a while. In fall 1994 one of us (Steve Robbins) was assigned to teach the course again. In the meantime the course had moved from using ASCII terminals connected to a VAX to Sun workstations. The availability of megapixel displays solved the real estate problem. Two options were available --- write a simulator for student experimentation or have the students write the simulator as a class assignment. The problem with the latter approach is that most of the code for such a simulator involves boring routines to display the state of the simulated machine. While this might be good for teaching programming techniques, it is not directly related to the course. Also, it would be nice to let the students take advantage of the graphics capabilities of the workstations, but the programming required normally far exceeds the capabilities of the students at this level. These difficulties were overcome by using the XTANGO [7] computer animation system as the display vehicle for the simulations.
The idea of a Mic-1 simulator is quite simple since the machine itself is simple. The basic simulator is a program which takes two command line arguments, a control store and a memory file. The first file is a representation of the 79-word control store used in the Mic-1 machine. The second file represents the memory of the Mac-1 machine and contains the assembled Mac-1 assembly language program to execute along with its data. The simulator initializes certain data structures and then goes into a loop:
while(1) {
subcycle_1();
subcycle_2();
subcycle_3();
subcycle_4();
}
Each of the subcycle routines performs the operations corresponding to that subcycle. For example, the routine subcycle_1() might just consist of:
MIR = decode_MIR(control_store[MPC]);where control_store is an array of 32-bit quantities and MIR is a structure of the type:
typedef struct {
int addr;
int Areg;
int Breg;
int Creg;
int ENC;
int WR;
int RD;
int MAR;
int MBR;
int SH;
int ALU;
int COND;
int AMUX;
} MIR_decoded;
The decode_MIR routine just shifts and masks its argument to produce the required fields.
Of course to make this simulator useful, there must be some interaction with the user. The user should be able to single step through the execution of the Mic-1 at the three levels of Mic-1 subcycle, Mic-1 cycle, and Mac-1 instruction cycle. Most of the code for the simulator involves displaying what is going on in a useful way.