CS0447 Project 4
Due April 20 (at mid-night)
Write a C++ program that simulates a multicycle CPU which executes a limited
set of MIPS instructions, namely lw, sw, add, ori, beq and an exit system
call. The input to your simulation will be a machine language program stored
in a file "prog.dat". Specifically, your machine should recognize the following
opcodes in the high order six bits of an instruction, and simulate the execution
of that instruction:
-
0000 00 === add
-
0011 01 === ori
-
0001 00 === beq
-
1011 00 === sw
-
1001 00 === lw
-
1111 11 === system call to exit.
The exit system call should display the content of the 32 machine registers
as well as the allocated memory locations (all displayed in hex) before
terminating the simulation.
The simulated architecture is a modification of the one shown in Figure 5.33
of your textbook. The components of that architecture and the connections
among these components are given in
the attached handout.
The finite state
machine of Figure 5.42 should be slightly modified in accordance with the
modifications in the architecture. The modified finite state machines
describing the control for the architecture is also given in the attached
handout. The control signals corresponding to each state in the finite
state machine are as follows (most of the signals have the same meaning as in
the textbook):
-
State 0:
MemRead, IorD = 0 , IRWrite ,
ALUSrcA = 0 , ALUSrcB = 01, ALUOp = add, PCSource = 0, PCWrite
-
State 1:
ALUSrcA = 0 , ALUSrcB = 11, ALUOp = add, RegRead, Save
-
State 2:
ALUSrcA = 1 , ALUSRCB = 10, ALUOp = add, Save
-
State 3:
IorD = 1 , MemRead
-
State 4:
RegDst = 0 , MemtoReg = 1, RegWrite
-
State 5:
IorD = 1 , MemWrite
-
State 6:
ALUSrcA = 1 , ALUSrcB = 00 , ALUOp = add , Save
-
State 7:
RegDst = 1 , MemtoReg = 0 , RegWrite
-
State 8:
ALUSrcA = 1 , ALUSrcB = 10 , ALUOp = or , Save
-
State 9:
RegDst = 0 , MemtoReg = 0 , RegWrite
-
State 10:
ALUSrcA = 1 , ALUSrcB = 00 , ALUOp = subtract
-
State 11:
PCSource = 1 , PCWrite
Your simulation should define an object (class) for each of the major components
of the architecture. The public members of each object should be:
-
storage element(s) storing the output data of the component
-
function(s) that correspond(s) to the control signals for the component.
While simulating each component, the input to this component should be
fetched from the output storage element of the component(s) connected to it
in the architecture (in the same way you did in Project 3). To simplify the
design, multiplexers are not considered as separate components, but rather as
parts of other components.
A class "machine" should be defined to include the five major components of
the architecture. Namely, mem_unit, alu, registers, PC_unit and IR_unit.
This class has only two public members;
-
a "load_prog" function to read a machine language program from the file
"prog.dat" and load it to sequential locations of a simulated memory
in the class "mem_unit" starting at location zero. "load_prog" should also
initialize the program counter to zero.
-
a "clock_cycle" function which simulates what happens during one clock cycle.
This function should emulate the finite state machine control, which will
require that the class "machine" keeps track of the current machine state
in a private variable "state". The function "clock_cycle" can be implemented
as a large switch statement, which depending on the "state", the op-code of
the instruction stored in the PC_unit and the zero flag in the alu, calls
the appropriate functions of the components classes, thus simulating the
effect of the corresponding control signals. Note that the order in which the
functions are called may be crucial in some states.
Your main program, will thus look as follows:
void main{
machine mips ;
mips.load_prog() ;
while(1) mips.clock_cycle;
}
INPUT:
The file
"prog.dat"
should include a sequence of machine language instructions,
each instruction being a 32-bit word encoded in hexadecimal. For example
34 03 00 01 # | ori $3,$0, 1 | memory location 00
|
90 04 00 28 # | lw $4, x | memory location 04
|
34 05 00 00 # | ori $5,$0, 0 | memory location 08
|
34 06 00 01 # | ori $6,$0, 1 | memory location 0C
|
10 86 00 03 # | top: beq $4,$6, done | memory location 10
|
00 A6 28 00 # | add $5,$5,$6 | memory location 14
|
00 C3 30 00 # | add $6,$6,$3 | memory location 18
|
10 00 FF FC # | beq $0,$0, top | memory location 1C
|
B0 05 00 2C # | done: sw $5,sum | memory location 20
|
FC 00 00 00 # | exit | memory location 24
|
00 00 00 40 # | x: .word 64 | memory location 28
|
00 00 00 00 # | sum: .word | memory location 2C
|
Any character beyond the # sign in a line is a comment and is not loaded
into the memory of the machine. Actually, you may assume that prog.dat
does not include comments -- only 8 hex symbols per line.
OUTPUT:
The only output is a well formatted display of the registers and memory when
an exit system call is encountered.