Project 2 - Fully Pipelined Mips

CS3410 Library Components Guide


Using MIPS RAM as byte addressed and little endian RAM

Here is a screenshot as I am writing the byte value 0x44 into byte address 32. Since the RAM is word addressed, this byte gets written to one of the four bytes at word address 32/4 = 8; you can see the A input to the RAM is 8. Since I want little-endian behavior, address 32 corresponds to the little end of the word (address 35 would be the big end of the same word, where 0x11 is stored); you can see the selector input is set to activate only the little end of the word. I am also reading at the same time, so you can see the 0x44 being read out on the litle end of the D output. If I were to activate all of the selectors, the RAM would output 0x11223344, which is the word stored at word address 8, i.e. byte address 4 * 8 = 32, which contains bytes 32 through 35.

ram2

Here is another screenshot as I am writing the byte value 0x2b into byte address 43. Since the ram is word addressed, this byte gets written to one of the bytes at word address 43/4 = 10; you can see the A input to the RAM is 0xa = 10. Since I want little-endian behavior, address 43 corresponds to the big end of the word (address 40 would be the little end of the same word, where 0x52 is stored); you can see the selector input is set to activate only the big end of the word. I am also reading at the same time, so you can see the 0x2b being read out on the big end of the D output. If I were to activate all of the selectors, the RAM would output 0x2b000d52, which is the word stored at word address 0xa = 10, i.e. byte address 4 * 10 = 40, which contains bytes 40 through 43.

ram1

For writing byte 0xbb, depending on the address, I might want to put it at the big end, little end, or somewhere in the middle. Similarly for reading a byte, depending on the address, I might want to grab the bytes from the big end, little end, or somewhere in the middle. Hint: For writing, just direct the desired byte to all four positions then activate writing for just the one you want. For reading, you will need to select between the four possible positions where the byte might appear on the RAM's D output.

On the other hand, reading and writing whole words is trivial. The RAM is 32 bits wide, so just send the whole 32-bits to the memory, and read the whole 32-bits back to the CPU. You could try to be clever by swapping the order of each word's four bytes when writing to RAM, and un-swapping them when reading from RAM. This, however, would be entirely pointless. Can you tell why? Try it to see if it makes it any easier to read and write bytes.


cs3410 Component Library Guide

The "CS3410 Components" library will only appear if you are using the most recent version of Logisim, downloaded from the course website. Please ensure that you are using the correct version. If so, you should have a folder in your sidebar containing the following components:

MIPS RAM. This component is identical to Logisim's regular 32-bit wide, word-addressed RAM component, except the single-bit sel input is replaced by a 4-bit input to selectively enable or disable access to individual bytes within a 32-bit word. For instance, if the memory contains the word 0xAABBCCDD at the current address, then sel=0011 will access only the least significant halfword (0xCCDD), and sel=1000 will access only the most significant byte (0xAA). This component does not have a defined endianness since it is word addressed. Byte addressed memory (either little-endian or big-endian) can be emulated: to access byte-address 4 (the fifth byte in memory) in little-endian mode, one would set a=1 (second word) and sel=0001 (least significant byte); to access byte-address 4 (the fifth byte in memory) in big-endian mode, one would set a=1 (second word) and sel=1000 (most significant byte).


Register File. A 32-bit wide by 32-registers deep register file. Register $0 is hard-wired to zero at all times, and writes to $0 are ignored. Inputs rA and rB are used to select register values to output on the A and B outputs. When the clock is triggered, if WE is high, the data value at input W is stored in register rW. The register file can be configured to use rising clock edges as trigger (the default), falling edge, or to be level sensitive.


MIPS Program ROM. A 32-bit wide byte-addressed ROM, with built-in MIPS assembler. Use the attributes panel to load a MIPS assembly file into the ROM. The PC input specifies the address of the current instruction, and must be a multiple of 4. The output is the 32-bit machine code instruction at the PC address, or an error if the PC is invalid. Reading addresses outside the range of code supplied by the assembly file will cause the ROM to output zero, which happens to encode a no-op in MIPS. The assembly language is in the format described below.


MIPS ALU. Computes a result as follows:

Op name C
000xshift left C = B << Sa;
001xadd C = A + B
0100shift right logical C = B >>> Sa
0101shift right arithmetic C = B >> Sa
011xsubtract C = A - B
1000and C = A & B
1010or C = A | B
1100xor C = A ^ B
1110nor C = ~(A | B)
1001eq C = (A == B) ? 1 : 0
1011ne C = (A != B) ? 1 : 0
1101gtz C = (A > 0) ? 1 : 0
1111lez C = (A ≤ 0) ? 1 : 0

Incrementer. An adjustable-width incrementer. Takes its input A on the left and outputs A+1 on the right.

LCD Video. If WE is high on the rising edge of CLK, writes a pixel on the LCD screen at the location given by the 7-bit unsigned X and Y coordinates. The pixel color is specified by 16-bit RGB input (in 5-5-5 format). The RST input resets the LCD screen. With some cleverness, you can redirect memory writes to this device to let your program draw on the LCD screen. Logisim also comes with some interesting input and output devices which can be used similarly.