Reading and Tools
- Patterson & Hennessy: 2.10, 4.1–4.4
In our class meetings last week and currently (and next week, too), we have studied intensely the construction of a simple, one instruction per clock cycle data path for a subset of the MIPS 32-bit ISA. The instruction set we are considering consists of operations for arithmetic and logic (add,sub,and,or, and slt), for loading from and storing to a main memory (lw and sw), and support for conditional and unconditional jumps (beq and j).
We have focused our efforts on dividing the data path into individual modules whose abstractions will allow us to compose them together in a finished project. In this assignment, you'll implement simulations for all of our work to date.
Instruction Selection. We settled on the following abstraction for a module that stores a program's instructions and generates on each clock cycle the appropriate instruction to execute next.
For this problem, implement this component, according to the work we completed in class.
In Logisim, the component you want for the instruction memory is a RAM (look under the Memory tool menu). Set the "address bit width" to 24 and the "data bit width" to 32.
Note that 24 bits is the largest possible address size, but that we're working with 32-bit addresses. This is a fundamental limitation of Logisim, which has selfishly refused to provided an unlimited supply of objects each equal in size to the the total resources of some personal computers. There's no way around this. Just drop the 8 high-order bits, and we'll pretend that all addressing happens to the low-order 224 bytes. (Actually, this is not unrealistic, since in a real machine, programs and data all reside in the memory addressing space.)
You can (and should) test your work by loading instructions for a program into the instruction memory and watching the instructions output in sequence with each clock edge. See the entries for the RAM component and for "poking memory", in the online User's Guide.
In our structuring of this component, we left open the problem of actually computing jump address (jaddr) values. We'll need to tackle that, of course, but for this module, assume the values of seq/j and the address input on jaddr have been properly computed elsewhere from some appropriate branch or unconditional jump.
Arithmetic/Logic Instructions. As of the end of class on Wednesday, November 13th, we have the following abstraction for this component:
Implement this component, sufficient to support the instructions add, sub, and, or, and slt. In addition to the obvious correctness requirements regarding the selection of registers for reading and writing, your component must support the correct ALUOp values, as documented in Section 4.4 and in Appendix B of P&H.
In Assignment #6, you built your own 32-bit register file and 32-bit ALU, both of which are, in principle, adequate to the job here. However, the 32-bit register file that you built from the gate level has too many components (roughly 10,000) for Logisim to handle its simulation properly, regardless of whether your version is fully correct. I have sent to each of you my version of the register file, which uses the built-in Register component. You should use my version for your work here.
You're also welcome to use my ALU, though you don't need it, if yours is working correctly. I encourage you to refer to mine as a study reference only. Besides it's much more satisfying to use your own.
Unlike the instruction selection component, our work for this part is still in progress. In particular, we have not addressed the problem of using this component to compute jump target addresses from the offsets given in beq instructions, nor have we discussed the role of arithmetic and logic operations in implement the load and store operations. If you find that the abstraction given here is incomplete or can be improved (adding additional control signals as inputs, consolidating or modifying input output lines, etc.), feel free to do so. Just make sure that the abstraction you design is clear (i.e. save this component as a sub-circuit, separate from other components in the datapath).
I'll impose only a few requirements. First, the determination of ALUOp and other control signals in the data path, all of which are computed from the highest 6 bits of an instruction (and some times the lowest 6, as well), should be done outside of this module. As a point of reference, the "Control" and "ALU Control" ovals in Figure 4.24 of P&H should not be implemented here. Second, this component does not include a RAM. Whether that means you should ignore the lw and sw instructions completely is for you to figure out. Finally, the actual computation of jump addresses is a separate concern from ordinary arithmetic/logical instructions, and it should be kept separate from this component here.
To hand in your files:
You should save the two parts of this work either as individual circuit files or as individual sub-circuits in a file named "mini_mips.circ". Either way, put everything in a folder called hw8 and submit that to your hand-in directory.