Flash
From Ece

Contents |
Team Name Members
Team Name: Flash
Team Leader: Jarvis Adams
Team Members: Joe Buza, Jarvis Adams, and Trey Gaines
Design Overview
The project is based on the design and simulation of a 16-bit MIPS RISC processor. The simulation of this processor will be built out of C++ source code with the ability to execute fifteen instructions. We will use the falling edge triggered as our clocking methodology. For our registers file, there will be 16 registers included; each register in the file being 16-bits wide.
Instruction Formats
S-Format
| 4 bit opcode | 2 bit P | 1 bit A | 1 bit A | 8 bit Immediate |
subi(0011), lp(0101), addi(0010), jmp(1001), spc(1101)
O-Format
| 4 bit opcode | 2 bits V | 2 bits V | 2 bits V | 2 bits P | 1 bits T | 2 bits P | 1 bit free |
xor(1011), or(1000), sub(1111), slr(0111), sll(1010)
L-Format
| 4 bit opcode | 5 bit Immediate Label | 1 bit A | 1 bit T | 2 bit regType | 2 bit Corresponding regAddress |
beq(0000), bin(0001), jmpi(1100)
F-Format
| 4 bit opcode | 2 bit regType l | 2 bit Corresponding regAddress | 2 bit regType | 2 bit Corresponding regAddress | 4 bit free |
lw(0100), quit(1110), cas(0110)
* To allow for register addressing: v = 00 t = 01 a = 10 p = 11
Instruction List
1-0000-Name: Branch if Equal Syntax: beq(labelToJumpTo, Reg_A_AddressToIntegerToCompare1, Reg_T_AddressToIntegerToCompare2) Purpose: pCodeLn9 Instruction Type: L 2-0001-Name: Branch if Negative Syntax: bin(labelToJumpTo_T_or_P, RegType, CorrespondingRegAddressOfValueToCheckTheSignBitOf) Purpose: pCodeLn’s 9 and 12. pCode line 9 condition to break from the loop if the parameter is less than 0 instead of greater than 0. Instruction Type: L 3-0010-Name: Add Immediate Syntax: addi(ImmediateToAddToRegA) Purpose: pCodeLn22 Instruction Type: S 4-0011-Name: Subtract Immediate Syntax: subi(registerToPlaceResult, registerOf1stParam, immediateValue) Purpose: pCodeLn10 Instruction Type: S 5-0100-Name: Load Word Syntax: lw(destinationRegister, destinationRegAddress, sourceRegister, sourceRegAddress) Purpose: pCodeLn11 Instruction Type: F 6-0101-Name: Load Partial Syntax: lp(AddressOfWhich_P_RegisterToUpdate,8BitHexValue) Purpose: pCodeLn’s 15 and 20 Instruction Type: S Note: The physical ability would lie with the ALU as it would be able to combinationally match the upper and lower data of two different registers to another register;it would internally just use a mux. When we implement this in C++, we can’t represent lines, so we would just use our integer2binary_Converter method of our simulator object, to convert both to binary before concatenating them together. We could then possibly convert that number back to decimal with convert16B2Decimal method of simulator.I’m guessing we are allowed to code with decimal values, since I think he just wants us to use appropriate types when defining our variables. Actually, I know he is letting us use decimal values,because the sample_code.pdf uses int’s which are decimal by definition. 7-0110-Name: Combine and Store Syntax: cas(RegType, AddressOfWhichPRegisterToStoreResultOfCombination) Purpose: pCodeLn’s 12, 15, and 20 Instruction Type: F 8-0111-Name: Shift Logical Right Syntax: Current: slr(regAddressOfTypeV_forShifingAndStoringResult) Possibility1: slr(RegTypeForShiftingAndStoringResult, CorrespondingRegAddress) Purpose: pCodeLn13 Instruction Type: O 9-1000-Name: Bitwise OR Syntax: or(registerToPlaceResult, registerOf1stParam, registerOf2ndParam) Purpose: pCodeLn14 Instruction Type: O 10-1001-Name: Jump Syntax: Current: jmp(P_regAddressContainingLabelToJumpTo) Possible: jmp(RegType, CorrespondingRegTypesAddress) Purpose: pCodeLn end-of-Ln9 Instruction Type: S 11-1010-Name: Shift Logical Left Syntax: Current: sll(RegAdressOfTypeV_ForShiftingAndStoringResult) Possibility1: slr(RegTypeForShiftingAndStoringResult, CorrespondingRegAddress) Purpose: pCodeLn18 Instruction Type: O 12-1011-Name: Bitwise Exclusive OR Syntax: xor(registerToPlaceResult, registerOf1stParam, registerOf2ndParam) Purpose: pCodeLn19 Instruction Type: O 13-1100-Name: Jump Immediate Syntax: jmpi(immediate) Purpose: pCodeLn16 Instruction Type: L 14-1101-Name: Store PC Syntax: spc(PRegisterAddressToStorePCInto) Purpose: pCodeLn9 Instruction Type: S 15-1110-Name: Quit Syntax: quit(null) Purpose: pCodeLn24 Instruction Type: F 16-1111-Name: Subtract Syntax: sub(registerToPlaceResult, registerOf1stParam, immediateValue) Purpose: pCodeLn12 Instruction Type: O
Assembly
//Comments and Blank Lines
// We can add comments here if we make the InstructionMemory object's method:
// take out the comment lines. We can do this by only using // and doing
// a check at the beginning of each line for //. If we find it then, we will
// move the read marker to the next line of this file.
// We can add a check for a black line too by asking if we are on a new line
// and the current character is a new line character.
// Trey brought to my attention we can directly convert this file into machine
// code. So, we don't need to create a parser for blank lines or comments.
//Program Description
// This program is a direct representation of the pseudocode given on slide 2 of
// Dr. Sherif's "Project_instructions.pdf". It is our assembly code.
//I've looked through all the code and there are no more registers that are
// needed by the pCode (pseudocode). I don't see a reason to add any more
// registers either at the moment. Hence, at the moment, we only need to
// address 7 registers. To address 7 registers, we only need 3 bits.
// Weak area: We could probably just convert all the register types into 1
// register type. We could also separate the registers as we are used to.
// The thing is we would have to develop separete parameters for each register
// type in our instruction format, and that might waist instruction space
// unless we choose the instruction type wisely when we associate the
// instructions to a type. Also pCode even has a comment saying we are
// allowed to renumber the registers as we choose.
//Register definition 2: the pCode has 3 type v registers, 1 type t register,
// and 2 type a registers. With this type t would be wasting a data bit, since
// 1 bit can address 2 registers, but there is only 1 of this type. Type v
// would be wasting a register too, because the 2 bits needed to represent the
// last register "3" could also access a 4th register, but a 4th register of
// type v is not needed/specified by the pCode.
//Register definition 1: Def: just have 1 register type.
// The only problem with this system is we could accidentally address the same
// register within the same instruction accidentally when we are programming,
// but I don't forsee that as a problem. Our program is not writing to
// instruction memory either, so there is no possible way that the program
// could accidentally create an instruction that addresses the same register
// within the same instruction.
// I will make the conversion of the pCode's specific types right now into
// address equivalents.
/*
$v0 = 0040hex; // you can redefine $v0-3, $t0, and $a0-1 with
$v1 = 000;
$v2 = 001;
$v3 = 010;
$t0 = 011;
$a0 = 100;
$a1 = 101;
*/
//Register Definition 1 problem2:
// Ah, there is another problem I can forsee. Some instructions require us
// to address two or more registers. If we just had 1 register, then we
// would have to use full 3 bits for each access = 6 bits instead of like he
// defined it... for example: 2bits for reg v + 1 bit for reg t = only 3 bits
// used in that instruction type.
//Now that I've considered problem2, I will continue to design as
// insinuated by the pCode.
/*
* To reiterate: the pCode has 3 type v registers, 1 type t register,
* and 2 type a registers.
* That means we need instruction types that have address fields:
* 2bits for reg v's 3 registers
* 1bit for reg t's 1 register
* 1bit for reg a's 2 registers
*
*/
//Register Definition 1 benifit2:
// if we just have one register, and we choose to decrease the number of bits
// needed in addressing registers, thus decreasing number of bits need for
// total register access by an instruction, then we don't have to worry about
// creating different instruction types depending on parameters that need to
// access specific registers. For example: we wouldn't need both an
// add1($a,$a,$a), add2($a,$a,$b), add3($a,$b,$a),...addx($c,$b,$a).
//##########################Instruction Types###################################
//refer to "../Reference/InstructionTypes.rtf" file.
//####################################ISA#######################################
//refer to "../Reference/ISA.rtf" file.
//##########################Registers we need###################################
/*
* Those directly referenced by the pCode
$v0
$v1
$v2
$v3
$t0
$a0
$a1
* For zero value
$t1
* To allow for register addressing:
v = 00
t = 01
a = 10
p = 11 //P stands for "Program" register, it is used for Partials and PC
* Note on instruction memory: If we have 60 instructions in the assembly, then
we need, 2^6=64, 6 bits to address those instructions, so we would need a PC
of only 6 bits instead of 16.
*Note: we need another register type, 'p', for holding partial immediate values
from pCodeLn's 12, 15, and 20.
* p can have 2 16-bit registers, because we can remove the values from
its 2 registers, because of pCodeLn12's will be finished with the values and
will restore the values on the next iteration of the while loop.
* despite p only needing 2 registers by pCodeLn12, we will use p to store
PC values as well.
*/
//############################The Program#######################################
//lines 1-7:
/*
We can automatically place the following values in the registers during
simulator constructor run.
$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;
*/
//line 9: while ($a1 > 0) do {
/*
To test a > condition here we need a sub instruction to get a value from
*
* Notes from writting another meeting date:
* parameter1 - parameter2
* If 0 thgen our code's comparison yeilds that parameter1 is equal to
* parameter 2 otherwise parameter1 is either < or > paramete2.
* If running this statement, then we determined the result is !=0.
* If subtraction was done, parameter1 = parameter2, then if there is a negative value, then
* We can't subtract a negative from a positive, because that would be equivalent to adding two negatives.
* Current Notes:
* In this case we don't have two different parameters. We know that 1
* parameter is 0. All we have to do here is test if it is 0 and if it is
* not, then check the sign bit. If the sign bit says the number is negative,
* then the number is obviously less than 0, otherwise it is > 0. Hence, if
* the sign bit is positive, then jump to the end of the while loop. Otherwise
* the loop will continue.
* If it the beq returns true, that means the comparison the register value
* held 0. Since 0 is not less than 0, we would normally break from the loop.
* To break from the loop in assembly, we will use a label as a parameter.
* The beq will jump to this label when this case occurs.
*/
//Name: Store the PC
//Warning: this might take some extra thought in making this happen in C++,
// given that we are dealing with a pipelined system. Since it is just used
// on the third stage of the first instruction, it shouldn't be a problem,
// because next two instruction
//Theory:
// There is an instruction that later needs a machine code version address of
// a label, and it needs to access it from a register, hence a new instruction
// is in order.
// The follwing new one will take the instruction address indicated by the Program
// counter, and store it for later reference by a jump or branch instruction.
// The -2 is due to the timing in which the instruction can be performed...
// the timing in which the PC can be accessed.
//Definition of instruction:
// Store the pc-2 instruction address in register p2.
spc($p2)
StartOfWhile:
//Theory:
// We can define one of our registers to be the zero register or...
// We can use a beqi insruction type that lets us compare anything here, but
// the pCode only requires a comparison of zero.
// We currently have the capability to access 2 registers that are not addressed
// by the pCode. Let's use one of these 2 registers to represent the zero
// value. I've chosen $t1 to represent the zero register (1 is closest to 0 :-))
// We will do the subtraction here and storing the result instead of
// combinationally reacting (branching) on a result of 0, because we will
// need to do another branch test on the result, so we store it for use in
// the bin (branch if negative) instruction.
//Description of instruction:
// Subtract rightmost parameter(parameter 3) from parameter 2 and store the
// value in register t0.
// If the value stored in $a1 is 0, then end the loop by branching to the
// "EndOfWhile" label.
beq(EndOfWhile, $a1, $t1);
//Theory:
// If it is not 0, we still need to check if $a1 is negative, i.e. < 0 as stated
// by the pCode condition. The sign bit of a number will tell us the number
// is negative if == 1 and positive if == 0.
// By the time this instruction runs, it should have the subtracte result of
// two numbers placed in a register for access by this instruction.
//Description of instruction:
// bin stands for branch if negative. It will branch to the label if the sign
// bit of the second parameter is 1, since a sign bit of 1 means the parameter is
// negative and - > 0 is false. Otherwise the sign bit of the parameter is 0,
// meaning the parameter is positive, so we have the condition + > 0 is true,
// so we do nothing, and flow of control goes to the next instruction.
bin(EndOfWhile, $t, $0);
//line 10: $a1 = $a1 - 1;
//Theory:
// We need an instruction to take an immediate negative value. I've looked
// through the code and the larget immediate value I see is on pCodeLn13. The
// value is 8. To represent that value in sign-notation, we need 4 bits...
// 1 bit for the negative and 3 bits for the value 8.
// We also know that the data referenced by the parameter $a1 is positive,
// because it would not have made it in the while loop otherwise, so we don't
// need to check the sign and determine if an addition operation is needed.
//Definition of instruction:
// Subtractract -1 from what is in address $a1, and store the result in $a1.
subi($a1, $a1, 1);
//line 11: $t0 = Mem[$a0];
//Theory:
// We know what load word does. We need to store in the t register so
// that requires 1 bit to address it. We need to load a word from Data Memory.
// We must decide how large we want to make Data Memory. We may decide to
// resruction the design in order to allow for instructions stored in data
// memory, otherwise we only need it as large as the number of things that
// will be stored there at any one time.
// Weak area: Not sure if we really need to use a register to access Data Memory
// if we need to access all registers to get the address of Data Memory. After
// this assembly program is complete, ask if we can just use reg a for Data
// Memory access or if we even need the 16 bits of a register to access Data
// Memory.
// This instruction format allows us to access any of the 12 registers with
// only 4 bits vs the 5 bits it would take via addressing a register directly.
//Description of instruction:
// N/A 4:10pm:Take what is in data memory at the address indicated by the 4th parameter,
// and store it in the t register at the address indicated by the first
// parameter.
// --end N/A--
// Actually, since we are restricted from overighting the zero register which
// is stored in t1, we could make this instruction just automatially know that
// it will be storing into the t register location $t0.
// We could also tell it which register to access as well.
lw($t,$0,$a,$0) //(01b,00b,10b,00b)
//line12: if ($t0 > 0100hex) then {
lp($p0,01hex)
lp($p1,00hex)
//Theory:
// We need to store an immediate 16 bit value in a register so we can operate
// on it.
// Need an instruction to move a 16 bit chunk of data into register
// memory. It could just take one register address (either V0, V2) and let
// the ALU determine if it is register V and address 00 or 10 then it is the
// first 8 bits of the 16 word and store it in that address in v reg mem, and if
// 01 or 11, then it would store the 2nd 8 bits of the word in that address of
// v mem.
// The reason registers A or T are not used is A normally used to store
//Definition of instruction:
// Take the lower portion of the 16 bit number (stored in $p0), combine it
// with the upper half of that 16 bit number (stored in $p1), and store it in
// back in $p0.
cas($p,$0)
//Theory:
// We need to compare two values by subtracting them both.
// Since we are doing a > comparison, we expect a result of - to mean false,
// and + to mean true.
// If $t0 is -, then (-) - (+) = -, and if $t0 is +, then (+)-(+) depends on
// which parameter is bigger. If param1 > param2 (false in other words), we
// expect result of sub to = +. If param1 < param2 (true in other words), we
// expect result of sub to = -.
//Definition of instruction:
// Subtract $p0 from $t0 and store the results back in $p0.
sub($p0,$t0,$p0)
//Theory:
// If our if condition is not met (meaning we got a - in the result of the
// subtraction of the previous step), then we need to branch to the "else"
// lable. Else, continue.
bin(Else,$p,$0)
//line 13: $v0 = $v0 ÷ 8;
//Name: slr = shift logical right
//Theory:
// Need to shift the bits right 3 times in order to do the equivalent of
// multiplying by 2, 3 times. 2*2*2=8, which is what the immediate value is.
// We only need this instruction here, so there is no need for further
// parameters.
//Definition of instruction:
// Shift the bits of the word addressed by $v0 right 1 bit, and store the result
// back in the same register.
slr($v0)
slr($v0)
slr($v0)
//line 14: $v1 = $v1 | $v0; //or
//Theory:
// Seems self explainatory. It does an or operation on the bits and stores
// them in a destination register.
//Definition of instruction:
// Or v1 and v0 with each other and store the result back in v1.
or($v1,$v1,$v0)
//line 15: Mem[$a0] = FF00hex;
//Name: lp = load partial
//Theory:
// Since ip is only used in pCodeLn's 15 and 20, and both of those lines only
// access register a, we can make this lp instruction take only the register
// type 'p' address that it needs to store which half in.
lp($p0,00hex)
lp($p1,FFhex)
//Name: cas = combine and store
//Theory:
// We need an instruction to move a 16 bit chunk of memory into register
// memory.
// Since we only need cas on pCodeLn 15 and 20, and they both are sending data
// to register $a0, we don't have to accept that as a parameter. However,
// pCodeLn12 needs a 16 bit immediate loaded into the t register, so we will
// make this instruction reusable by adding the register parameter.
// We also know that both the halves of the 16 bit word are stored in register p, lower
// half is in register p0 and upper half is in p1, so we don't have to accept
// that as a parameter either. So, we don't need any parameters on this
// instruction.
//Definition of instruction:
// Combine bits 0-7 from p0 and 8-15 from p1 into a 16-bit word and store that
// word in data memory located at the address stored in the parameter.
cas($a,$0)
//line 16: }
//Theory:
// We have use done the "if" body code, and we need to skip over the "else"
// body code, because the if statement from pCodeLn12 semantically says so.
//Definition of Instruction:
// Move to the point past the "else" body code addressed by the label in the
// parameter.
jmpi(EndOfElse)
//line 17: begining of the else statement
Else:
//line 18: $v2 = $v2 × 4;
//Name: sll = shift logical left
//Theory:
// We need to multiply by 4.
// Shifting bits left 1 bit equals a multiply by 2, so if we shift the bits
// left twice, then 2*2=4.
//Definition of instruction:
// Shift the bits of register $v2 left twice and store the results back in $v2
sll($v2)
sll($v2)
//line 19: $v3 = $v3 ⊕ $v2; //xor
//Name: xor = exclusive or
//Definition of Instruction:
// Do an xor operation of the values addressed by $v3 and $v2, and store the
// result back in $v3.
xor($v3,$v3,$v2)
//line 20: Mem[$a0] = 00FFhex;
lp($p0,FFhex)
lp($p1,00hex)
//Name: cas = combine and store
//Theory:
// We need an instruction to move a 16 bit chunk of memory into register
// memory.
// Since we only need cas on pCodeLn 15 and 20, and they both are sending data
// to register $a0, we don't have to accept that as a parameter. However,
// pCodeLn12 needs a 16 bit immediate loaded into the t register, so we will
// make this instruction reusable by adding the register parameter.
// We also know that both the halves of the 16 bit word are stored in register p, lower
// half is in register p0 and upper half is in p1, so we don't have to accept
// that as a parameter either. So, we don't need any parameters on this
// instruction.
//Definition of instruction:
// Combine bits 0-7 from p0 and 8-15 from p1 into a 16-bit word and store that
// word in data memory located at the register type 'a' address stored in the
// parameter.
cas($a,$0)
//line 21: } //end of else statement
EndOfElse:
//line 22: $a0 = $a0 + 2;
//Theory:
// Simply need to add an immediate value to a register and store the results
// back in that same register. This is the only use of this instruction, so
// we can make it as efficient as we need it to be or fit it to another
// instruction type to cut down on instruction types.
// We also know that the data referenced by the parameter is positive, because
// it the first value stored in it is 0010hex from pCodeLn6 and it only
// gets incremented by 2 each time. However there is a risk of overflow.
// We can't have overflow here, because the while will break.
//Definition of instruction:
addi(2)
//end of line 9: while($a1 > 0) do {}
EndOfWhile: // required by line pCodeLn9 assembly
//Theory:
// Need something to reset the PC back to the Beginning of the while loop.
// We don't have a need for the entire 16 bits for addressing an instruction
// in our program, because we won't even have 64 instructions in the program.
// With 64 instruction could be addressed with only 7 bits. This means we
// can use an 16 bit instruction that uses 16-7bits to do whatever and still
// have room for an immediate jump address. The only thing required by the
// this instruction is what is required by all instructions, the opcode, and
// the opcode is only 4 bits, so we will have plenty of room.
//Definition of instruction:
// Set the PC equal to an immediate instruction address equal to that at label
// StartOfWhile.
jmp($p2) //instruction address of StartOfWhile
//line 24: end the program
//Theory:
// We just need an instruction to say when to stop the processor and program
// from running any more.
quit(null)
Machine Code
1101 10 0 0 00000000 //spc($p2)
0000 11001 1 1 00 00 //beq(EndOfWhile(ALn26,MLn25,19x), $a1, $t1) Label:StartOfWhile
0001 11001 0 0 01 00 //bin(EndOfWhile(ALn26,MLn25,19x), $t, $0)
0011 00 1 1 00000001 //subi($a1, $a1, 1)
0100 01 00 10 00 0000 //lw($t,$0,$a,$0)
0101 00 0 0 00000001 //lp($p0,01hex)
0101 01 0 0 00000000 //lp($p1,00hex)
0110 11 00 00 00 0000 //cas($p,$0)
1111 00 00 00 00 0 00 0 //sub($p0,$t0,$p0)
0001 10010 0 0 11 00 //bin(Else(ALn19,MLn18,12x),$p,$0)
0111 00 00 00 00 0 00 0 //slr($v0)
0111 00 00 00 00 0 00 0 //slr($v0)
0111 00 00 00 00 0 00 0 //slr($v0)
1000 01 01 00 00 0 00 0 //or($v1,$v1,$v0)
0101 00 0 0 00000000 //lp($p0,00hex)
0101 01 0 0 11111111 //lp($p1,FFhex)
0110 10 00 00 00 0000 //cas($a,$0)
1100 11000 0 0 00 00 //jmpi(EndOfElse(ALn25,MLn24,18x))
1010 10 00 00 00 0 00 0 //sll($v2) Label: Else:
1010 10 00 00 00 0 00 0 //sll($v2)
1011 11 11 10 00 0 00 0 //xor($v3,$v3,$v2)
0101 00 0 0 11111111 //lp($p0,FFhex)
0101 01 0 0 00000000 //lp($p1,00hex)
0110 10 00 00 00 0000 //cas($a,$0)
0010 00 0 0 00000010 //addi(2) Label: EndOfElse:
1001 10 0 0 00000000 //jmp($p2) Label: EndOfWhile:
1110 00 00 00 00 0000 //quit(null)
Datapath

Meeting Progress April 5
We got the Register class and the outline of the RISC processor created. Next meeting will be thursday April 7. There we will draw our processor out and outline exactly what instructions we will need and how they will need to be implemented.
Planned Meetings
- Thursday March 31st
- Monday April 4th
- Thursday April 7th
- Monday April 11th
- Thursday April 14th




