Team Thunderdome (Two Bytes Enter, One Bit Leaves):
From Ece
Welcome to Team Thunderdome's homepage. Two Bytes Enter, One Bit Leaves.
Contents |
Proposal
Team Name and Members
Team name: Thunderdome
Team Leader: Jonathan Leigh
Team Member: Kendra Carr
Team Member: Thomas McDaniel
Design Overview
We have 8 registers, the zero register starting at $zero, then $v0-3 will be our values for function results and expression evaluation registers, $t0 is our temp register, then $a0-1 are our argument registers.
Our design will be a rising edge read trigger, and a falling edge write triggered design.
Register Numbers:
| RegName | RegNumber(Binary) | RegNumber(Decimal) |
| $zero | 000 | 0 |
| $v0 | 001 | 1 |
| $v1 | 010 | 2 |
| $v2 | 011 | 3 |
| $v3 | 100 | 4 |
| $t0 | 101 | 5 |
| $a0 | 110 | 6 |
| $a1 | 111 | 7 |
Instruction Format
R-type:
| Opcode | Rs | Rt | Rd | Func |
| 4 bit | 3 bit | 3 bit | 3 bit | 3 bit |
I-type:
| Opcode | Rt | Rs | Immediate |
| 4 bit | 3 bit | 3 bit | 6 bit |
J-Format
| Opcode | |
| 4 bit | |
Instructions
| Name | Mnemonic | Operation | Opcode | Func | Format |
| NOP | nop | Nothing | 0000 | ||
| Add | add | add rd, rs, rt | 0001 | 000 | R |
| Sub | sub | sub rd, rs, rt | 0010 | 001 | R |
| Add Immediate | addi | addi rt, rs, constant | 0011 | I | |
| Or | or | or rd, rs, rt | 0100 | 010 | R |
| And | and | and rd, rs, rt | 0101 | 011 | R |
| Or Immediate | ori | ori rt, rs, constant | 0110 | I | |
| And Immediate | andi | andi rt, rs, constant | 0111 | I | |
| Exclusive Or | xor | xor rd, rs, rt | 1000 | 100 | R |
| Set less than | slt | slti rd, rs, rt | 1001 | 101 | R |
| Load Word | lw | lw rt, rs, offset | 1010 | I | |
| Store Word | sw | sw rt, rs, offset | 1011 | I | |
| Branch equals | beq | beq rs, rt, address | 1100 | I | |
| Jump | j | j address | 1101 | J | |
| Shift left logical immediate | slli | slli rt, rs, constant | 1110 | I | |
| Shift right logical immediate | srli | srli rt, rs, constant | 1111 | I |
Assembly language and machine code for the test program (Pseudocode)
$v0 = 0040hex; // you can redefine $v0-3, $t0, and $a0-1 with
$v1 = 1010hex; // your register numbers such as $1, $2, etc.
$v2 = 000Fhex;
$v3 = 00F0hex;
$t0 = 0000hex;
$a0 = 0010hex;
$a1 = 0005hex;
while ($a1 > 0) do {
$a1 = $a1 –1;
$t0 = Mem[$a0];
if ($t0 > 0100hex) then {
$v0 = $v0 ÷ 8;
$v1 = $v1 | $v0; //or
Mem[$a0] = FF00hex;
}
else {
$v2 = $v2 × 4;
$v3 = $v3 ⊕ $v2; //xor
Mem[$a0] = 00FFhex;
}
$a0 = $a0 + 2;
}
return;
| Label | Instruction # | Assembly Language | Hex | Machine Code |
| While: | | addi $t0, $zero, $zero | 3000 | 0011 000 101 000000 |
| | slt $t0, $t0, $a1 | 99C0 | 1001 101 111 101 101 | |
| | beq $t0, $zero, L1 | C802 | 1100 000 101 000010 | |
| | j End | D017 | 1101 000000010111 | |
| L1: | | addi $a1, $a1, -1 | 3FE1 | 0011 111 111 100001 |
| | lw $t0, 0($a0) | A980 | 1010 110 100 000000 | |
| | addi $a0, $zer0, 16 | 3C10 | 0011 110 000 010000 | |
| | slli $a0, $a0, 4 | ED84 | 1110 110 110 000100 | |
| | slt $t0, $t0, $a1 | 9B7D | 1001 101 111 101 101 | |
| | beq $t0, $zero, L2 | CA08 | 1100 000 101 001000 | |
| | slli $v2, $v2, 4 | E6C4 | 1110 011 011 000100 | |
| | xor $v3, $v3, $v2 | 891C | 1000 100 011 100 100 | |
| | addi $t0, $t0, 16 | 3B50 | 0011 101 101 010000 | |
| | slli $t0, $t0, 4 | EB44 | 1110 101 101 000100 | |
| | addi $t0, $t0, -1 | 3B61 | 0011 101 101 100001 | |
| | sw $t0, 0($a0) | BB80 | 1011 110 101 000000 | |
| | j Add | D008 | 1101 000000001000 | |
| L2: | | srli $v0, $v0, 8 | F248 | 1111 001 001 001000 |
| | or $v1, $v1, $v0 | 448A | 0100 010 001 010 010 | |
| | addi $t0, $t0, 16 | 3B50 | 0011 101 101 010000 | |
| | slli $t0, $t0, 4 | EB44 | 1110 101 101 000100 | |
| | addi $t0, $t0, -1 | 3B61 | 0011 101 101 100001 | |
| | slli $t0, $t0, 8 | EB48 | 1110 101 101 001000 | |
| | sw $t0, 0($a0) | BB80 | 1011 110 101 000000 | |
| Add: | | addi $a0, $a0, 2 | 3D82 | 0011 110 110 000010 |
| | j while | D819 | 1101 100000011001 | |
| End: | | Nop | 0000 | 0000000000000000 |
Tasks and Schedule
| Name | Tasks | Week 1 | Week 2 | Week 3 | Week 4 | Week 5 |
| Jon, Kendra, Tom | Proposal | X | ||||
| Jon, Kendra, Tom | Datapath | X | ||||
| Jon, Kendra, Tom | Control Unit | X | ||||
| Jon,
Kendra, Tom | Forwarding | X | ||||
| Jon,
Kendra, Tom | Hazard Detection Unit | X | ||||
| Jon | Detailed Design Document | X | ||||
| Kendra,
Tom | Coding | X | X | |||
| Jon | Website | X | X | X | X | |
| Jon | Report | X | X |
Planned Meetings
Tuesday 10:45-3
Sunday 2-4
Team Name
Thunderdome
Language
We plan to do a software implementation of a 16-bit pipelined RISC processor using Java and netbeans as our integrated development environment.
Datapath
Data Hazard/Forwarding Unit
Meetings
Sunday Oct 25 2-4pm (Proposal) Tuesday Oct 27 10:45-11 (Quick Discusson) Sunday Nov 1 2-5pm (Datapath) Tuesday Nov 3 10:45-11 (Quick Discussion about coding methods) Thursday Nov 5 10:45-11:15 (Assignment of coding modules) Sunday Nov 15 5-7 pm (Assigned Coding) Tuesday Nov 17 10:45-11:15 (Talked about coding) Thursday Nov 19 10:45-11:15 (Talked about coding) Sunday Nov 22 6-9 (Coded) Tuesday Nov 24 5-12 (Finished final report)
Software Architecture Design
Legend:
This box represents a class. The class name goes in the top of the box, the variables go in the middle of the box, and the methods of the class go in the bottom.
| | |
| | |
| MUX | This class represents all the MUX's in our system. This includes the program counter MUX, the MUX's for the write back value, and all the other MUXs. There is only 1 MUX class that can be recycled for all these objects. This MUX class takes in three inputs (Input1, Input2, Input3), which represent the lines that feed in from the data paths. The ControlSignal variable is a public variable that will be set by the ControlUnit class. When getValue() is called, it will look at the value of the ControlSignal variable to select which Input variable to return. |
| Adder | Adder is a class that has two sixteen bit Input variables. The computeResult method will be used to return the result of adding the Input1 and Input2 variables together. |
| InstructionMemory | This class represents the Instruction Memory register. The instructionCounter variable is a private variable that represents the actual blocks of memory that will store binary values. It should be implemented as an ArrayList<Byte> (an arraylist object that holds bytes), but the tool I was using does not allow me to specify their variable type as this, thus it is just shown as List. The pointer variable is also a private variable, which points to a block in memory that is going to be manipulated. The loadInstruction method is for loading in the values when the simulation initially starts. The programmer will have to use the setInstructionPointer method to set the pointer to the correct address then write the value to it with loadInstruction. Remember though, when you call loadInstruction you are sending it a 16 bit instruction, but by the instructions of our project we must keep our Instruction Memory in 8 bit slots. Therefore you will have to store half of the instruction in the first block, and the other half of the instruction in the second block.
The getInstruction method is for getting an instruction out of the InstructionMemory from the current place the pointer is at. It will have to read two blocks (8 bit blocks) and combine them to get the full 16-bit instruction. The isLastInstruction method is for telling our driver class (RISC_CPU) when to stop executing and end our simulation. |
| ProgramCounter | This class simulates the ProgramCounter. The nextInstruction variable holds the address of the next instruction to be executed. The value of the next instruction can be set using the setNextInstruction method. The getNextInstruction method can be used to get the address of the next instruction to be executed, which will be fed into the InstructionMemory, using it's setInstructionPointer method. |
| ShiftLeft1 | This is a simple class that takes a number and shifts it left by 1. The shiftLeft method is what will perform the shift and return the result. |
| IF_ID_Buffer | This class holds the values of the Instruction between the fetch and decode cycles. The Instruction and Flush variables are both public. The Flush variable is supposed to tell whether the buffer needs to be flushed or not. I am not sure what it's function is, but it was in our data path diagram. |
| SignExtend | This class takes in a value with it's signExtend method and extends it to be a 16-bit value. |
| Registers | This class represents the Registers ($zer0-$a1) that will hold values during computation. The register variable is a private variable that will be implemented as an ArrayList<Short>, which holds all the values of the registers ($zer0-$a1). These registers in the ArrayList have statically assigned numbers (see Appendix A). I guess that the RegisterWrite will be the value that tells whether the register is to write a value or not, but this variable will probably be controlled by the RISC_CPU class (which talks to the ControlUnit). The writeRegister method will write a value to the 8-bit register address given (we really only need 3 bits, but there is no 3-bit type in java, only a Byte which is 8 bits). The readRegister will also take an 8-bit register address and retrieve the 16-bit value out of that register. |
| EXE_MEM_Buffer | This class holds the values inbetween the execute and memory stages. The variables are pretty straight forward. |
| DataMemory | This represents extra memory storage of the DataMemory register. At the startup of our simulation we will need to load values into it by using the loadMemory. |
| MEM_WB_Buffer | This class holds variables for the stage between the memory and the writeback. |
| ID_EX_Buffer | This holds values between the decode and execute stages. |
| ALU | This class computes all values fed into it from Input1 and Input2. By using the setOpcode method it will set the opcode (a private variable of the class), and then when the computeResult method is called it will know which method to call based on the opcodes. Add, sub, beq, etc are all private methods of this class that are only to be accessed by this class. |
| | |
| | |
| Clock | Keeps track of the current cycle of the chip. The cycle variable is a private variable which represents the current cycle the chip is on. The tick method will increment the clock to the next cycle. The getCurrentCycle method will return which cycle the chip is currently set to. The reset method will reset the cycle variable back to zero. |
| RISC_CPU | This is where our "main" method will go. This class drives the entire program. I intestinally left it's methods blank because we haven't figured out the logic for the forwarding and hazard detection unit yet, which will probably significantly affect how the program is executed through this class. |
| ControlUnit | This class holds all the control signals for the program. The ControlUnit's variables will be read and manipulated by the RISC_CPU class. |
| HazardDetectionUnit | This class will have methods for detecting hazards. We do not know what they are at this current time. |
| ForwardingUnit | This class will have methods for detecting when values need to be forwarded, we do not know what they are at the current time. |
| MemoryTable | This is a class that will hold the Address, Hex Value, and Binary Value of both the Registers and the DataMemory at each cycle. These values will be stored in the table variable, which is an ArrayList<MemoryTableValue> (MemoryTableValue is our own class). To add an entry to this table use it's addEntry method. |
| MemoryTableValue | This will hold the actual values of the Address, Hex Value, and Binary Value of the contents in the Registers and the DataMemory at each cycle. These values will then be put into the MemoryTable class by using it's addEntry method. |
| Fetch | This class represents the Fetch stage of the CPU. It will use its internal components to do computation and then pass the value onto the IF_ID_Buffer class. RISC_CPU will drive these actions. |
| Decode | This class represents the Decode stage of the CPU. It acts the same as the Fetch class, except it passes its values to the ID_EXE_Buffer. |
| Execute | This class represents the Execute stage of the CPU. It acts the same as the Fetch class, except it passes its values to the EXE_MEM_Buffer. |
| Memory | This class represents the Memory Stage of the CPU. It acts the same as the Fetch class, except it passes its values to the EXE_MEM_Buffer. |
| WriteBack | This class represents the Write Back stage of the CPU. It acts the same as the Fetch class, except it passes its values to the MEM_WB_Buffer. |
Appendex A
Statically Assigned Register Numbers:
| RegName | RegNumber(Binary) | RegNumber(Decimal) |
| $zero | 000 | 0 |
| $v0 | 001 | 1 |
| $v1 | 010 | 2 |
| $v2 | 011 | 3 |
| $v3 | 100 | 4 |
| $t0 | 101 | 5 |
| $a0 | 110 | 6 |
| $a1 | 111 | 7 |






