Download as pdf or txt
Download as pdf or txt
You are on page 1of 45

EGRE 426 - Lab 4 - Page 1

Lab 4 Final Report

1. Team Members
Dakota Bernacki
Noah Routhier

Date: 11/19/20

“On my honor, I have neither given nor received unauthorized aid on this assignment”

Dakota Bernacki

“On his honor, I have neither given nor received unauthorized aid on this assignment”

Noah Routhier
EGRE 426 - Lab 4 - Page 2

2. Implementation Diagram
EGRE 426 - Lab 4 - Page 3

3. Datapath
Datapath Components
Program Counter:
Inputs:
PC_ADDR --Updated Program Counter
PC_rst --When asserted hi resets PC to 0
clk --System clock
Outputs:
PC --The current value of the Program Counter

A simple, 11bit-wide D type register, PC holds the current value of the program
counter. On every rising edge of the clock, it is updated with the new program
counter value.

Instruction Memory:
Inputs:
PC --The current value of the Program Counter
prog_flash --The instruction to be stored in the Instruction Memory
ins_wr --When asserted hi allows the memory to be programmed
ins_rst --When asserted hi resets all instruction location values to 0
clk --System clock

Outputs:
Instruction --The current instruction as pointed to by the Program Counter

An assembly of 256 16bit-wide D type registers, the instruction memory holds the
16bit instructions to be executed. It is indexed by the current value of the program
counter and updates its output on every rising edge of the clock.

Control:
Inputs:
Instruction [15-11] --The Opcode of the instruction

Outputs:
ALU_func --The control Opcode for the ALU
I-type --The bit that indicates if an I-type instruction is being executed
reg_WR --The enable line for writing to the register
jump_ins --The indicator line for a jump instruction
data_WR --The enable line for writing to the data memory
mem_to_reg --The select bit for choosing the output of the ALU or data memory

Control interprets the upper 5 bits of the current instruction and generates the
control bits and ALU operation opcode for said instruction. It is composed of
EGRE 426 - Lab 4 - Page 4

combinational logic elements and is capable of handling 32 different instructions.


[only 22 are currently utilized] A large switch statement is used to interpret the
opcode; then the outputs are set by each distinct case.

Register Memory:
Inputs:
Instruction[4-2] --The address of the RD register
Instruction[7-5] --The address of the RT register
Instruction[10-8] --The address of the RS register
result --The result of the instruction [if applicable]
reg_rst --When asserted hi resets all register location values to 0
reg_WR --When asserted hi allows value on result to be stored
clk --System clock

Outputs:
A --The contents of RS
operand2 --The contents of RT

An assembly of 8 16bit-wide D type registers, the register memory holds the current
values being operated on. It is indexed by the current values of the RD, RS, and RT
segments of the instruction. And it updates its output on every rising edge of the
clock.

ALU:
Inputs:
A --The value of RS
B --The value of RD or the extended immediate value
ALU_func --The operation the ALU is to carry out

Outputs:
ALU_result --The result of the ALU operation
branch_true --The indicator bit for a branch instruction

The ALU is capable of 14 mathematical operations which are indexed by a switch


statement. Each operation is determined by the combinational logic in each switch
statement.
The supported operations, 0-13, are:
1. Addition
2. Subtraction
3. And
4. Or
5. Exclusive Or
6. Shift Left Logical
7. Shift Right Logical
8. Shift Right Arithmetic
EGRE 426 - Lab 4 - Page 5

9. Set Less Than


10. Branch Equal
11. Branch Less Than
12. Branch Less Than or Equal
13. Branch Greater Than
14. Branch Greater Than or Equal

Data Memory:
Inputs:
dat_addr --The address at which to store mem_data at or output data_read
mem_data --The data to be stored
data_WR --When asserted hi allows the memory to be programmed
data_rst --When asserted hi resets all memory location values to 0
clk --System clock

Outputs:
data_read --The data to be output

An assembly of 256 16bit-wide D type registers, the data memory holds the values
calculated or needed by the program. It is indexed by the output of the ALU and
receives the value of operand2 [RT]. It updates its output on every rising edge of the
clock.
EGRE 426 - Lab 4 - Page 6

4. ALU Control
ALU Control Bits:
The ALU is controlled by a bitstring, of length four, which indexes its switch
statement. Of the 16 possible instructions, only 14 are used. For each instruction,
the bitstring is generated by the control unit and sent to the ALU.

ALU Functions:
1. Addition
Adds input A to input B. No carry is accounted for.
2. Subtraction
Subtracts input B from input A. No overflow accounted for.
3. And
Performs bitwise AND on input A and B.
4. Or
Performs bitwise OR on input A and B.
5. Exclusive Or
Performs bitwise XOR on input A and B.
6. Shift Left Logical
Shifts input A left by the shift amount specified by input B.
7. Shift Right Logical
Shifts input A right by the shift amount specified by input B.
8. Shift Right Arithmetic
Shifts input A right by the shift amount specified by input B; preserves the sign bit of
A during the shift.
9. Set Less Than
If input A is less than input B, the output equals 1. Else the output equals 0.
10. Branch Equal
If input A equals input B set branch_true equal to 1.
11. Branch Less Than
If input A is less than input B set branch_true equal to 1.
12. Branch Less Than or Equal
If input A is less than or equal to input B set branch_true equal to 1.
13. Branch Greater Than
If input A is greater than input B set branch_true equal to 1.
14. Branch Greater Than or Equal
If input A is greater than or equal to input B set branch_true equal to 1.
EGRE 426 - Lab 4 - Page 7

5. Control Unit
Describe the control unit and its inputs and outputs in details.
Control Unit:
The control unit is comprised of a switch statement, indexed by the upper five bits of
the current instruction. Of the 32 possible instructions, only 22 are used. Every time
a new instruction is received, the control unit interprets it and updates the ALU
control signal and the other control bits.

Control Unit Input and Outputs:


Inputs:
Instruction [15-11]
These five bits index the correct position of the switch statement so the
control unit outputs the proper control signals.

Outputs:
ALU_func
A bitstring of length four that determines the operation that the ALU
performs.

I-type
Set hi for all I-type instructions ​except branches​. This signal controls which
values of the register are used for storing the result and in determining if the
2nd register output or the immediate value is used in the ALU’s calculation.

reg_WR
Set hi when the result of an instruction needs to be stored in the register.

jump_ins
Set hi when the result of an instruction needs to be stored in the register.
This happens only for jump instructions.

data_WR
Set hi when the result of an instruction needs to be stored in the data
memory. This happens only for store word instructions.

mem_to_reg
Set hi when the output of the data memory needs to be stored in the register.
This happens only for load word instructions.
EGRE 426 - Lab 4 - Page 8

6. Simulation Results Memory and Register File


Memory and register file contents at clock cycle: 0
Instruction Memory:
Address Hex Value Binary Value
0x000 0x0000 0000 0000 0000 0000
Others 0x0000 0000 0000 0000 0000

Data Memory:
Address Hex Value Binary Value
0x010 0x0000 0000 0000 0000 0000
0x011 0x0000 0000 0000 0000 0000
0x012 0x0000 0000 0000 0000 0000
0x013 0x0000 0000 0000 0000 0000
0x014 0x0000 0000 0000 0000 0000
Others 0x0000 0000 0000 0000 0000

Register file:
Register Name Register # Hex Value Binary Value
n0 1 0x0000 0000 0000 0000 0000
s0 2 0x0000 0000 0000 0000 0000
s1 3 0x0000 0000 0000 0000 0000
s2 4 0x0000 0000 0000 0000 0000
t0 5 0x0000 0000 0000 0000 0000
t1 6 0x0000 0000 0000 0000 0000
t2 7 0x0000 0000 0000 0000 0000
t3 8 0x0000 0000 0000 0000 0000
EGRE 426 - Lab 4 - Page 9

Memory and register file contents at clock cycle: 33 (initialized)


Instruction Memory:
Address Hex Value Binary Value
0x000 0x9010 1001 0000 0001 0000
0x001 0x3881 0011 1000 1000 0001
0x002 0x9486 1001 0100 1000 0110
0x003 0x38A1 0011 1000 1010 0001
0x004 0x95AC 1001 0101 1010 1100
0x005 0x3DB0 0011 1101 1011 0000
0x006 0x38CF 0011 1000 1100 1111
0x007 0x38EF 0011 1000 1110 1111
0x008 0x97E4 1001 0111 1110 0100
0x009 0x3820 0011 1000 0010 0000
0x00A 0x3850 0011 1000 0101 0000
0x00B 0x3865 0011 1000 0110 0101
0x00C 0x6B0B 0110 1011 0000 1011
0x00D 0xAB61 1010 1011 0110 0001
0x00E 0x7220 0111 0010 0010 0000
0x00F 0x3801 0011 1000 0000 0001
0x010 0x9008 1001 0000 0000 1000
0x011 0x6907 0110 1001 0000 0111
0x012 0xA483 1010 0100 1000 0011
0x013 0x1D94 0001 1101 1001 0100
0x014 0xA801 1010 1000 0000 0001
0x015 0x9008 1001 0000 0000 1000
0x016 0x8200 1000 0010 0000 0000
0x017 0xF81D 1111 1000 0001 1101
0x018 0x4807 0100 1000 0000 0111
0x019 0x96C2 1001 0110 1100 0010
0x01A 0x36FC 0011 0110 1111 1100
0x01B 0xA801 1010 1000 0000 0001
0x01C 0x8200 1000 0010 0000 0000
0x01D 0x3A41 0011 1010 0100 0001
0x01E 0x9010 1001 0000 0001 0000
0x01F 0xF80C 1111 1000 0000 1100
Others 0x0000 0000 0000 0000 0000

Data Memory:
Address Hex Value Binary Value
0x010 0x0101 0000 0001 0000 0001
0x011 0x0110 0000 0001 00010000
0x012 0x0011 0000 0000 0001 0001
0x013 0x00F0 0000 0000 1111 0000
0x014 0x00FF 0000 0000 1111 1111
Others 0x0000 0000 0000 0000 0000
Register file:
Register Name Register # Hex Value Binary Value
n0 1 0x0000 0000 0000 0000 0000
s0 2 0x0000 0000 0000 0000 0000
s1 3 0x0000 0000 0000 0000 0000
s2 4 0x0000 0000 0000 0000 0000
t0 5 0x0000 0000 0000 0000 0000
t1 6 0x0000 0000 0000 0000 0000
t2 7 0x0000 0000 0000 0000 0000
t3 8 0x0000 0000 0000 0000 0000
EGRE 426 - Lab 4 - Page 10

Memory and register file contents for each loop:


After the first loop, clock cycle: 60
Data Memory:
Address Hex Value Binary Value
0x010 0xFF00 1111 1111 0000 0000
0x011 0x0110 0000 0001 0001 0000
0x012 0x0011 0000 0000 0001 0001
0x013 0x00F0 0000 0000 1111 0000
0x014 0x00FF 0000 0000 1111 1111
Others 0xFF00 0000 0000 0000 0000

Register file:
Register Name Register # Hex Value Binary Value
n0 1 0x0000 0000 0000 0000 0000
s0 2 0x0101 0000 0001 0000 0001
s1 3 0x0011 0000 0000 0001 0001
s2 4 0x0004 0000 0000 0000 0100
t0 5 0x0008 0000 0000 0000 1000
t1 6 0x1018 0001 0000 0001 1000
t2 7 0x000F 0000 0000 0000 1111
t3 8 0x00F0 0000 0000 1111 0000

After the second loop, clock cycle: 75


Data Memory:
Address Hex Value Binary Value
0x010 0xFF00 1111 1111 0000 0000
0x011 0xFF00 1111 1111 0000 0000
0x012 0x0011 0000 0000 0001 0001
0x013 0x00F0 0000 0000 1111 0000
0x014 0x00FF 0000 0000 1111 1111
Others 0x0000 0000 0000 0000 0000

Register file:
Register Name Register # Hex Value Binary Value
n0 1 0x0000 0000 0000 0000 0000
s0 2 0x0110 0000 0001 0001 0000
s1 3 0x0012 0000 0000 0001 0010
s2 4 0x0003 0000 0000 0000 0011
t0 5 0x0001 0000 0000 0000 0001
t1 6 0x1019 0001 0000 0001 1001
t2 7 0x000F 0000 0000 0000 1111
t3 8 0x00F0 0000 0000 1111 0000
EGRE 426 - Lab 4 - Page 11

After the third loop, clock cycle: 88


Data Memory:
Address Hex Value Binary Value
0x010 0xFF00 1111 1111 0000 0000
0x011 0xFF00 1111 1111 0000 0000
0x012 0x00FF 0000 0000 1111 1111
0x013 0x00F0 0000 0000 1111 0000
0x014 0x00FF 0000 0000 1111 1111
Others 0x0000 0000 0000 0000 0000

Register file:
Register Name Register # Hex Value Binary Value
n0 1 0x0000 0000 0000 0000 0000
s0 2 0x0011 0000 0000 0001 0001
s1 3 0x0013 0000 0000 0001 0011
s2 4 0x0002 0000 0000 0000 0010
t0 5 0x0001 0000 0000 0000 0001
t1 6 0x1019 0001 0000 0001 1001
t2 7 0x003C 0000 0000 0011 1100
t3 8 0x00CC 0000 0000 1100 1100

After the fourth loop, clock cycle: 101


Data Memory:
Address Hex Value Binary Value
0x010 0xFF00 1111 1111 0000 0000
0x011 0xFF00 1111 1111 0000 0000
0x012 0x00FF 0000 0000 1111 1111
0x013 0x00FF 0000 0000 1111 1111
0x014 0x00FF 0000 0000 1111 1111
Others 0x0000 0000 0000 0000 0000
Register file:
Register Name Register # Hex Value Binary Value
n0 1 0x0000 0000 0000 0000 0000
s0 2 0x00F0 0000 0000 1111 0000
s1 3 0x0014 0000 0000 0001 0100
s2 4 0x0001 0000 0000 0000 0001
t0 5 0x0001 0000 0000 0000 0001
t1 6 0x1019 0001 0000 0001 1001
t2 7 0x00F0 0000 0000 1111 0000
t3 8 0x003C 0000 0000 0011 1100
EGRE 426 - Lab 4 - Page 12

After the fifth, clock cycle: 114


Data Memory:
Address Hex Value Binary Value
0x010 0xFF00 1111 1111 0000 0000
0x011 0xFF00 1111 1111 0000 0000
0x012 0x00FF 0000 0000 1111 1111
0x013 0x00FF 0000 0000 1111 1111
0x014 0x00FF 0000 0000 1111 1111
Others 0x0000 0000 0000 0000 0000

Register file:
Register Name Register # Hex Value Binary Value
n0 1 0x0000 0000 0000 0000 0000
s0 2 0x00FF 0000 0000 1111 1111
s1 3 0x0015 0000 0000 0001 0101
s2 4 0x0000 0000 0000 0000 0000
t0 5 0x0001 0000 0000 0000 0001
t1 6 0x1019 0001 0000 0001 1001
t2 7 0x03C0 0000 0011 1100 0000
t3 8 0x03FC 0000 0011 1111 1100
EGRE 426 - Lab 4 - Page 13

7. Integrated output data from the simulation results


Memory (data):
Hex value after each loop
Address Initial 1st 2nd 3rd 4th 5th
0x0010 0x0101 0xFF00 0xFF00 0xFF00 0xFF00 0xFF00
0x0011 0x0110 0x0110 0xFF00 0xFF00 0xFF00 0xFF00
0x0012 0x0011 0x0011 0x0011 0x00FF 0x00FF 0x00FF
0x0013 0x00F0 0x00F0 0x00F0 0x00F0 0x00FF 0x00FF
0x0014 0x00FF 0x00FF 0x00FF 0x00FF 0x00FF 0x00FF
Register file (data):
Hex value after each loop
Register Initial 1st 2nd 3rd 4th 5th
t0 [4] 0x0040 0x0008 0x0001 0x0001 0x0001 0x0001
t1 [5] 0x1010 0x1018 0x1019 0x1019 0x1019 0x1019
t2 [6] 0x000F 0x000F 0x000F 0x003C 0x00F0 0x03C0
t3 [7] 0x00F0 0x00F0 0x00F0 0x00CC 0x003C 0x03FC

This data is taken directly from the output file [​cpu_out.txt​] that is generated by our testbench. Said
file has been included in the appendix of this document and the zip file of the code.

8. Bonus Materials
Thus far, the only modifications made to the design for this purpose was to increase the
opcode size from 4 to 5 bits [to support the additional instructions] and to have the ALU not
set the I-type signal for the branch instructions though they are I-type. [to support more
than the single required branch type].

We added four new branch instructions which are not in the standard instruction set for
MIPS:
1. Branch greater than or equal to
2. Branch greater than
3. Branch less than or equal to
4. branch less than

We programmed an excel sheet to translate our mips assembly code into machine code,
which we used to compile our instructions
EGRE 426 - Lab 4 - Page 14

9. Discussion
Simulation Program Optimization:
Originally our simulator required a number of NOPs inserted, after the instruction to be
programmed, equal in length to the total number of instructions executed by the program.
This was quickly changed to only require two additional commands. The first to reset the
registers and PC and the second to set all testbench outputs to 0.

Non-Functioning Components:
NONE
The design is fully functional and performs as expected.

Additional Discussion:
Our testbench outputs the data from the register file and data memory to a text file
cpu_out.txt. (see appendix G)
The CPU was programmed via a .txt file. (see appendix H)
Appendix A consists of the test waveforms of the CPU running the example program.

Appendices B-F consist of our VHDL code as follows:


● top_lvl_tst.vhd
● top_lvl.vhd
● ALU.vhd
● control.vhd
● D_register_scalable.vhd

Appendix I is the assembly for the example code.

Appendix J is the layout of our instructions and registers.

Appendix K is our instruction set.

10. Final Version of Simulator Code


See appendix B for our top level testbench.
EGRE 426 - Lab 4 - Page 15

Appendix A
Example program output testwaves
Whole program: [from programming to completion]

Start of program:
EGRE 426 - Lab 4 - Page 16

End of loop 1:

End of loop 2:
EGRE 426 - Lab 4 - Page 17

End of loop 3:

End of loop 4:
EGRE 426 - Lab 4 - Page 18

End of loop 5/result:


EGRE 426 - Lab 4 - Page 19

Appendix B
top_lvl_tst.vhd:
library​ ​ieee​;
use​ ​ieee​.​std_logic_1164​.​all​;
use​ ​ieee​.​numeric_std​.​all​;
use​ ​STD​.​textio​.​all​;
use​ ​ieee​.​std_logic_textio​.​all​;

entity​ top_lvl_tst ​is


end​ top_lvl_tst​;

architecture​ Behavioral ​of​ top_lvl_tst ​is

​-- Maximum delay for the DUT it's bit_vector size and the number of test cases
​constant​ MAX_DELAY ​:​ ​time​ ​:=​ ​20​ ms​;
​constant​ Memory_size ​:​ ​integer​ ​:=​ ​16​;
​constant​ PC_size ​:​ ​integer​ ​:=​ ​11​;
​constant​ ALU_SIZE ​:​ ​integer​ ​:=​ ​4​;

​--DUT signals
​--Input
​signal​ prog_flash ​:​ ​STD_LOGIC_VECTOR​(​Memory_size​-​1​ ​downto​ ​0​);
​signal​ ins_WR ​:​ ​STD_LOGIC​;
​signal​ data_flash ​:​ ​STD_LOGIC_VECTOR​(​Memory_size​-​1​ ​downto​ ​0​);
​signal​ data_fash_addr ​:​ ​STD_LOGIC_VECTOR​(​Memory_size​-​1​ ​downto​ ​0​);
​signal​ prog_data_WR ​:​ ​STD_LOGIC​;
​signal​ CLK_sig ​:​ ​STD_LOGIC​ ​:=​ ​'0'​;
​signal​ ins_rst ​:​ ​STD_LOGIC​;
​signal​ reg_rst ​:​ ​STD_LOGIC​;
​signal​ data_rst ​:​ ​STD_LOGIC​;
​signal​ PC_rst ​:​ ​STD_LOGIC​;

--Output
​signal​ t0_reg_out ​:​ ​STD_LOGIC_VECTOR​(​Memory_size​-​1​ ​downto​ ​0​);
​signal​ t1_reg_out ​:​ ​STD_LOGIC_VECTOR​(​Memory_size​-​1​ ​downto​ ​0​);
​signal​ t2_reg_out ​:​ ​STD_LOGIC_VECTOR​(​Memory_size​-​1​ ​downto​ ​0​);
​signal​ t3_reg_out ​:​ ​STD_LOGIC_VECTOR​(​Memory_size​-​1​ ​downto​ ​0​);
​signal​ dat_addr16 ​:​ ​STD_LOGIC_VECTOR​(​Memory_size​-​1​ ​downto​ ​0​);
​signal​ dat_addr17 ​:​ ​STD_LOGIC_VECTOR​(​Memory_size​-​1​ ​downto​ ​0​);
​signal​ dat_addr18 ​:​ ​STD_LOGIC_VECTOR​(​Memory_size​-​1​ ​downto​ ​0​);
​signal​ dat_addr19 ​:​ ​STD_LOGIC_VECTOR​(​Memory_size​-​1​ ​downto​ ​0​);
​signal​ dat_addr20 ​:​ ​STD_LOGIC_VECTOR​(​Memory_size​-​1​ ​downto​ ​0​);
​signal​ ins_out_tb :​ ​ ​STD_LOGIC_VECTOR​(​Memory_size​-​1​ ​downto​ ​0​);
​signal​ PC_out_tb :​ ​ ​STD_LOGIC_VECTOR​(​11​-​1​ ​downto​ ​0​);
EGRE 426 - Lab 4 - Page 20

​--File open
​file​ file_ins_mem ​:​ ​text​;
​file​ file_cpu_out ​:​ ​text​;

​begin

​--Clock process for register


CLK_process ​:​ ​process​(​CLK_sig​)
​begin
CLK_sig ​<=​ ​not​ CLK_sig ​after​ ​10​ ms​;​ ​--Clocked at 1/10 sec
​end​ ​process​ CLK_process​;

​--Input generator
stimulus ​:​ ​process
​variable​ instruction ​:​ ​line​;
​variable​ SPACE ​:​ ​character​;
​variable​ pf_tmp ​:​ ​STD_LOGIC_VECTOR​(​Memory_size​-​1​ ​downto​ ​0​);
​variable​ ins_WR_tmp ​:​ ​STD_LOGIC​;
​variable​ df_tmp ​:​ ​STD_LOGIC_VECTOR​(​Memory_size​-​1​ ​downto​ ​0​);
​variable​ dfa_tmp ​:​ ​STD_LOGIC_VECTOR​(​Memory_size​-​1​ ​downto​ ​0​);
​variable​ data_WR_tmp ​:​ ​STD_LOGIC​;
​variable​ ins_rst_tmp ​:​ ​STD_LOGIC​;
​variable​ reg_rst_tmp ​:​ ​STD_LOGIC​;
​variable​ data_rst_tmp​:​ ​STD_LOGIC​;
​variable​ PC_rst_tmp ​:​ ​STD_LOGIC​;

​begin
file_open​(​file_ins_mem​,​ ​"instruction_memory.txt"​,​ read_mode​);

​while​ ​not​ ​endfile​(​file_ins_mem​)​ ​loop​ ​--Read in all program instructions


​readline​(​file_ins_mem​,​ instruction​);
​read​(​instruction​,​ pf_tmp​);
​read​(​instruction​,​ SPACE​);
​read​(​instruction​,​ ins_WR_tmp​);
​read​(​instruction​,​ SPACE​);
​read​(​instruction​,​ dfa_tmp​);
​read​(​instruction​,​ SPACE​);
​read​(​instruction​,​ df_tmp​);
​read​(​instruction​,​ SPACE​);
​read​(​instruction​,​ data_WR_tmp​);
​read​(​instruction​,​ SPACE​);
​read​(​instruction​,​ ins_rst_tmp​);
​read​(​instruction​,​ SPACE​);
​read​(​instruction​,​ reg_rst_tmp​);
​read​(​instruction​,​ SPACE​);
​read​(​instruction​,​ data_rst_tmp​);
​read​(​instruction​,​ SPACE​);
​read​(​instruction​,​ PC_rst_tmp​);

prog_flash ​<=​ pf_tmp​;​ ​--Pass program instructions to DUT


ins_WR ​<=​ ins_WR_tmp​;
EGRE 426 - Lab 4 - Page 21

data_fash_addr ​<=​ dfa_tmp​;


data_flash ​<=​ df_tmp​;
prog_data_WR ​<=​ data_WR_tmp​;
ins_rst ​<=​ ins_rst_tmp​;
reg_rst ​<=​ reg_rst_tmp​;
data_rst ​<=​ data_rst_tmp​;
PC_rst ​<=​ PC_rst_tmp​;

​wait​ ​for​ MAX_DELAY​;


​end​ ​loop​;

​wait​;
file_close​(​file_cpu_out​);​ ​--Stop the process to avoid an infinite loop
​end​ ​process​ stimulus​;

--Example file line layout:


-- 16bitInstruction instructionWRbit 16bitDataADDR 16bitData dataWRbit instructionRSTbit registerRSTbit dataRSTbit
PCrstBIT
-- 0011101001011111 1 1000001000100000 1111100000000001 1 0 0 0 0 This is a std progrqamming line with data
for ins and data mem

--Required 1st line


-- 0000000000000000 0 0000000000000000 0000000000000000 0 1 1 1 1
--INSERT VALUES TO BE PROGRAMMED HERE
--Required closing lines:
-- 0000000000000000 0 0000000000000000 0000000000000000 0 0 1 0 1
-- 0000000000000000 0 0000000000000000 0000000000000000 0 0 0 0 0

-​ -DUT component instantiation


DUT ​:​ ​entity​ ​work​.​top_level​(​Structural​)
​GENERIC​ ​MAP​(​N ​=>​ Memory_size​,​ PC_size ​=>​ PC_size​,​ ALU_size ​=>​ ALU_size​)
​port​ ​map​(​prog_flash ​=>​ prog_flash​,​ ins_WR ​=>​ ins_WR​,​ data_flash ​=>​ data_flash​,
data_flash_addr ​=>​ data_fash_addr​,​ prog_data_WR ​=>​ prog_data_WR​,​ ins_rst ​=>​ ins_rst​,
reg_rst ​=>​ reg_rst​,​ data_rst ​=>​ data_rst​,​ PC_rst ​=>​ PC_rst​,​ clk ​=>​ CLK_sig​,
t0_reg_out ​=>​ t0_reg_out​,​ t1_reg_out ​=>​ t1_reg_out​,​ t2_reg_out ​=>​ t2_reg_out​,
t3_reg_out ​=>​ t3_reg_out​,​ dat_addr16 ​=>​ dat_addr16​,​ dat_addr17 ​=>​ dat_addr17​,
dat_addr18 ​=>​ dat_addr18​,​ dat_addr19 ​=>​ dat_addr19​,​ dat_addr20 ​=>​ dat_addr20​,
ins_out_tb ​=>​ ins_out_tb​,​ PC_out_tb ​=>​ PC_out_tb​);

-- Process monitor
monitor ​:​ ​process
​variable​ count ​:​ ​integer​ ​:=​ ​0​;
​variable​ data ​:​ ​line​;
​variable​ newline ​:​ ​string​(​1​ ​to​ ​1​)​ ​:=​ ​" "​;
​variable​ t0 ​:​ ​string​(​1​ ​to​ ​4​)​ ​:=​ ​"t0: "​;
​variable​ t1 ​:​ ​string​(​1​ ​to​ ​4​)​ ​:=​ ​"t1: "​;
​variable​ t2 ​:​ ​string​(​1​ ​to​ ​4​)​ ​:=​ ​"t2: "​;
​variable​ t3 ​:​ ​string​(​1​ ​to​ ​4​)​ ​:=​ ​"t3: "​;
​variable​ mem16 ​:​ ​string​(​1​ ​to​ ​4​)​ ​:=​ ​"16: "​;
​variable​ mem17 ​:​ ​string​(​1​ ​to​ ​4​)​ ​:=​ ​"17: "​;
​variable​ mem18 ​:​ ​string​(​1​ ​to​ ​4​)​ ​:=​ ​"18: "​;
​variable​ mem19 ​:​ ​string​(​1​ ​to​ ​4​)​ ​:=​ ​"19: "​;
EGRE 426 - Lab 4 - Page 22

​variable​ mem20 ​:​ ​string​(​1​ ​to​ ​4​)​ ​:=​ ​"20: "​;


​variable​ clk_cyc ​:​ ​string​(​1​ ​to​ ​14​)​ ​:=​ ​"Clock Cycles: "​;

​begin
file_open​(​file_cpu_out​,​ ​"cpu_out.txt"​,​ write_mode​);

​while​ true ​loop


​wait​ ​on​ PC_out_tb​;​ ​--Waits for event on input [Program Counter]

​--Writes to file at power up, after programming, and after each loop
​IF​ ins_out_tb ​=​ ​"1111100000001100"​ ​OR​ PC_out_tb ​=​ ​"00000000000"​ ​THEN
​write​(​data​,​ clk_cyc​);
​write​(​data​,​ count​);
​writeline​(​file_cpu_out​,​ data​);

​write​(​data​,​ t0​);
​write​(​data​,​ t0_reg_out​);
​writeline​(​file_cpu_out​,​ data​);

​write​(​data​,​ t1​);
​write​(​data​,​ t1_reg_out​);
​writeline​(​file_cpu_out​,​ data​);

​write​(​data​,​ t2​);
​write​(​data​,​ t2_reg_out​);
​writeline​(​file_cpu_out​,​ data​);

​write​(​data​,​ t3​);
​write​(​data​,​ t3_reg_out​);
​writeline​(​file_cpu_out​,​ data​);

​write​(​data​,​ newline​);
​writeline​(​file_cpu_out​,​ data​);

​write​(​data​,​ mem16​);
​write​(​data​,​ dat_addr16​);
​writeline​(​file_cpu_out​,​ data​);

​write​(​data​,​ mem17​);
​write​(​data​,​ dat_addr17​);
​writeline​(​file_cpu_out​,​ data​);

​write​(​data​,​ mem18​);
​write​(​data​,​ dat_addr18​);
​writeline​(​file_cpu_out​,​ data​);

​write​(​data​,​ mem19​);
​write​(​data​,​ dat_addr19​);
​writeline​(​file_cpu_out​,​ data​);
EGRE 426 - Lab 4 - Page 23

​write​(​data​,​ mem20​);
​write​(​data​,​ dat_addr20​);
​writeline​(​file_cpu_out​,​ data​);

​write​(​data​,​ newline​);
​writeline​(​file_cpu_out​,​ data​);
​write​(​data​,​ newline​);
​writeline​(​file_cpu_out​,​ data​);
​ELSE
​--NOTHING
​END​ ​IF​;
count ​:=​ count ​+​ ​1​;​ ​--Increments # of clk ticks
​end​ ​loop​;
file_close​(​file_cpu_out​);
​ nd​ ​process​ monitor​;
e

end​ Behavioral​;
EGRE 426 - Lab 4 - Page 24

Appendix C
top_lvl.vhd:
library​ ​ieee​;
use​ ​ieee​.​std_logic_1164​.​ALL​;
use​ ​ieee​.​numeric_std​.​ALL​;

entity​ top_level ​IS


​GENERIC​ ​(​N ​:​ ​INTEGER​ ​:=​ ​16​;
PC_size ​:​ ​INTEGER​ ​:=​ ​11​;
ALU_size ​:​ ​INTEGER​ ​:=​ ​4​);
​PORT​(​ prog_flash ​:​ ​in​ ​std_logic_vector​(​N​-​1​ ​downto​ ​0​);
ins_WR ​:​ ​in​ ​std_logic​;
data_flash ​:​ ​in​ ​std_logic_vector​(​N​-​1​ ​downto​ ​0​);
data_flash_addr ​:​ ​in​ ​std_logic_vector​(​N​-​1​ ​downto​ ​0​);
prog_data_WR ​:​ ​in​ ​std_logic​;
ins_rst ​:​ ​in​ ​std_logic​;
reg_rst ​:​ ​in​ ​std_logic​;
data_rst ​:​ ​in​ ​std_logic​;
PC_rst ​:​ ​in​ ​std_logic​;
clk ​:​ ​in​ ​std_logic​;
t0_reg_out ​:​ ​out​ ​std_logic_vector​(​N​-​1​ ​downto​ ​0​);
t1_reg_out ​:​ ​out​ ​std_logic_vector​(​N​-​1​ ​downto​ ​0​);
t2_reg_out ​:​ ​out​ ​std_logic_vector​(​N​-​1​ ​downto​ ​0​);
t3_reg_out ​:​ ​out​ ​std_logic_vector​(​N​-​1​ ​downto​ ​0​);
dat_addr16 ​:​ ​out​ ​std_logic_vector​(​N​-​1​ ​downto​ ​0​);
dat_addr17 ​:​ ​out​ ​std_logic_vector​(​N​-​1​ ​downto​ ​0​);
dat_addr18 ​:​ ​out​ ​std_logic_vector​(​N​-​1​ ​downto​ ​0​);
dat_addr19 ​:​ ​out​ ​std_logic_vector​(​N​-​1​ ​downto​ ​0​);
dat_addr20 ​:​ ​out​ ​std_logic_vector​(​N​-​1​ ​downto​ ​0​);
ins_out_tb ​:​ ​out​ ​std_logic_vector​(​N​-​1​ ​downto​ ​0​);
PC_out_tb ​:​ ​out​ ​std_logic_vector​(​11​-​1​ ​downto​ ​0​));

END​ top_level​;

--ins_mem_size reg_mem_size data_mem_size

architecture​ structural ​of​ top_level ​is


--SIGNALS
--Data Locations
type​ ins_mem_file ​is​ ​array​ ​(​256​-​1​ ​downto​ ​0​)​ ​of​ ​STD_LOGIC_VECTOR​(​N​-​1​ ​downto​ ​0​);
type​ reg_mem_file ​is​ ​array​ ​(​8​-​1​ ​downto​ ​0​)​ ​of​ ​STD_LOGIC_VECTOR​(​N​-​1​ ​downto​ ​0​);
type​ data_mem_file ​is​ ​array​ ​(​256​-​1​ ​downto​ ​0​)​ ​of​ ​STD_LOGIC_VECTOR​(​N​-​1​ ​downto​ ​0​);
type​ ins_index_addr ​is​ ​array​ ​(​256​-​1​ ​downto​ ​0​)​ ​of​ ​STD_LOGIC​;
type​ reg_index_addr ​is​ ​array​ ​(​8​-​1​ ​downto​ ​0​)​ ​of​ ​STD_LOGIC​;
type​ data_index_addr ​is​ ​array​ ​(​256​-​1​ ​downto​ ​0​)​ ​of​ ​STD_LOGIC​;

signal​ ins_mem_out ​:​ ins_mem_file ​:=​ ​(​others​=>(​others​=>​'0'​));​ ​--Temp for instruction output
EGRE 426 - Lab 4 - Page 25

signal​ ins_WR_Index ​:​ ins_index_addr ​:=​ ​(​others​=>​'0'​);​ ​--Temp for instruction enable

signal​ reg_mem_out ​:​ reg_mem_file ​:=​ ​(​others​=>(​others​=>​'0'​));​ ​--Temp for reg outputs
signal​ reg_WR_Index ​:​ reg_index_addr ​:=​ ​(​others​=>​'0'​);​ ​--Temp for reg enable

signal​ data_mem_out ​:​ data_mem_file ​:=​ ​(​others​=>(​others​=>​'0'​));​ ​--Temp for data memory output
signal​ data_WR_Index​:​ data_index_addr ​:=​ ​(​others​=>​'0'​);​ ​--Temp for data memory enable

--Top Level Wiring


signal​ PC ​:​ ​std_logic_vector​(​PC_size​-​1​ ​downto​ ​0​);​ ​--Program counter
signal​ PC_2 ​:​ ​std_logic_vector​(​PC_size​-​1​ ​downto​ ​0​);​ ​--Incrimented PC
signal​ PC_ADDR ​:​ ​std_logic_vector​(​PC_size​-​1​ ​downto​ ​0​);​ ​--Altered PC
signal​ calc_addr ​:​ ​std_logic_vector​(​PC_size​-​1​ ​downto​ ​0​);​ ​--Added to PC_2 when branch or jump
signal​ BJ_ADDR ​:​ ​std_logic_vector​(​PC_size​-​1​ ​downto​ ​0​);​ ​--Branch OR Jump addr
signal​ Instruction ​:​ ​std_logic_vector​(​N​-​1​ ​downto​ ​0​);​ ​--From ins mem
signal​ ext_imm ​:​ ​std_logic_vector​(​N​-​1​ ​downto​ ​0​);​ ​--Bits [4-0] of Instruction extened to 16bit
signal​ A ​:​ ​std_logic_vector​(​N​-​1​ ​downto​ ​0​);​ ​--A input of ALU/RS output of register
signal​ B ​:​ ​std_logic_vector​(​N​-​1​ ​downto​ ​0​);​ ​--B input of ALU/imm OR RT output of register
signal​ operand2 ​:​ ​std_logic_vector​(​N​-​1​ ​downto​ ​0​);​ ​--RT output of register
signal​ ALU_result ​:​ ​std_logic_vector​(​N​-​1​ ​downto​ ​0​);​ ​--ALU output
signal​ dat_addr ​:​ ​std_logic_vector​(​N​-​1​ ​downto​ ​0​);​ ​--The address to store data at
signal​ mem_data ​:​ ​std_logic_vector​(​N​-​1​ ​downto​ ​0​);​ ​--The data to be stored
signal​ data_read ​:​ ​std_logic_vector​(​N​-​1​ ​downto​ ​0​);​ ​--Output of Data mem
signal​ result ​:​ ​std_logic_vector​(​N​-​1​ ​downto​ ​0​);​ ​--Output of ALU OR Data mem
signal​ Dest ​:​ ​std_logic_vector​(​2​ ​downto​ ​0​);

signal​ ALU_func ​:​ ​std_logic_vector​(​ALU_size​-​1​ ​downto​ ​0​);​--Control code for ALU


signal​ I_type ​:​ ​std_logic​;​ ​--1 if I-type instruction
signal​ reg_WR ​:​ ​std_logic​;​ ​--1 if instruction writes ot register
signal​ jump_ins ​:​ ​std_logic​;​ ​--1 if J-type instruction
signal​ branch_true ​:​ ​std_logic​;​ ​--1 if breanch ins calc returns TRUE
signal​ bran_jump ​:​ ​std_logic​;​ ​--1 if branch calc TRUE OR jump_ins TRUE
signal​ data_WR ​:​ ​std_logic​;​ ​--Data WR signal from Control
signal​ data_WR2 ​:​ ​std_logic​;​ ​--1 if instruction write to data memeory
signal​ mem_to_reg ​:​ ​std_logic​;​ ​--1 if instruction reads from data memory

begin
--COMPONENET INSTANTIATIONS
​--ALU
ALU ​:​ ​ENTITY​ ​work​.​ALU​(​behavior​)
​GENERIC​ ​MAP​(​N ​=>​ N​)
​PORT​ ​MAP​(​a ​=>​ A​,​ b ​=>​ B​,​ func ​=>​ ALU_func​,​ result ​=>​ ALU_result​,​ branch ​=>​ branch_true​);

-​ -Control Logic
Control ​:​ ​ENTITY​ ​work​.​control​(​behavior​)
​GENERIC​ ​MAP​(​N ​=>​ N​,​ ALU_size ​=>​ ALU_size​)
​PORT​ ​MAP​(​Instruction ​=>​ Instruction​,​ ALU_func ​=>​ ALU_func​,​ I_type ​=>​ I_type​,​ reg_WR ​=>​ reg_WR​,
jump_ins ​=>​ jump_ins​,​ data_WR ​=>​ data_WR​,​ mem_to_reg ​=>​ mem_to_reg​);

​--Memory Locations
Program_Counter ​:​ ​ENTITY​ ​work​.​D_Register​(​behavior​)​ ​--Write ALWAYS enabled
EGRE 426 - Lab 4 - Page 26

​GENERIC​ ​MAP​(​N ​=>​ PC_size​)


​PORT​ ​MAP​(​d ​=>​ PC_ADDR​,​ clk ​=>​ clk​,​ rst ​=>​ PC_rst​,​ en ​=>​ ​'1'​,
q ​=>​ PC​);

generator1​:​ ​for​ I ​in​ ​256​-​1​ ​downto​ ​0​ ​generate​ ​--Instruction memory


ins_mem ​:​ ​ENTITY​ ​work​.​D_Register​(​behavior​)
​GENERIC​ ​MAP​(​N ​=>​ N​)
​PORT​ ​MAP​(​d ​=>​prog_flash​,​ clk ​=>​ clk​,​ rst ​=>​ ins_rst​,​ en ​=>​ ins_WR_Index​(​I​),
q ​=>​ ins_mem_out​(​I​));
​end​ ​generate​ generator1​;

generator2​:​ ​for​ I ​in​ ​8​-​1​ ​downto​ ​0​ ​generate​ ​--Register memory


reg_mem ​:​ ​ENTITY​ ​work​.​D_Register​(​behavior​)
​GENERIC​ ​MAP​(​N ​=>​ N​)
​PORT​ ​MAP​(​d ​=>​ result​,​ clk ​=>​ clk​,​ rst ​=>​ reg_rst​,​ en ​=>​ reg_WR_Index​(​I​),
q ​=>​ reg_mem_out​(​I​));
​end​ ​generate​ generator2​;

generator3​:​ ​for​ I ​in​ ​256​-​1​ ​downto​ ​0​ ​generate​ ​--Data memory


data_mem ​:​ ​ENTITY​ ​work​.​D_Register​(​behavior​)
​GENERIC​ ​MAP​(​N ​=>​ N​)
​PORT​ ​MAP​(​d ​=>​ mem_data​,​ clk ​=>​ clk​,​ rst ​=>​ data_rst​,​ en ​=>​ data_WR_Index​(​I​),
q ​=>​ data_mem_out​(​I​));
​end​ ​generate​ generator3​;

--PROCESSES
​--Instruction write and read
instructionwrite ​:​ ​PROCESS​(​prog_flash​,​ ins_WR​,​ ins_rst​,​ clk​)​ ​IS
​BEGIN
ins_WR_Index​(​255​ ​downto​ ​to_integer​(​unsigned​(​PC​))+​1​)​ ​<=​ ​(​others​=>​'0'​);​ ​--set signals above desired index
ins_WR_Index​(​to_integer​(​unsigned​(​PC​)))​ ​<=​ ins_WR​;​ ​--set desired index
ins_WR_Index​(​to_integer​(​unsigned​(​PC​))-​1​ ​downto​ ​0​)​ ​<=​ ​(​others​=>​'0'​);​ ​--set signals above desired index
​END​ ​PROCESS​;

​--Instruction read
Instruction ​<=​ ins_mem_out​(​to_integer​(​unsigned​(​PC​)));

​--Register write and read


registerwrite ​:​ ​PROCESS​(​result​,​ reg_WR​,​ reg_rst​,​ clk​)​ ​IS
​BEGIN
reg_WR_Index​(​7​ ​downto​ ​to_integer​(​unsigned​(​Dest​))+​1​)​ ​<=​ ​(​others​=>​'0'​);​ -​ -set signals above desired index
reg_WR_Index​(​to_integer​(​unsigned​(​Dest​)))​ ​<=​ reg_WR​;​ -​ -set desired index
reg_WR_Index​(​to_integer​(​unsigned​(​Dest​))-​1​ ​downto​ ​0​)​ ​<=​ ​(​others​=>​'0'​);​ -​ -set signals above desired
index
​END​ ​PROCESS​;

​--Register read
A ​<=​ reg_mem_out​(​to_integer​(​unsigned​(​Instruction​(​10​ ​downto​ ​8​))));​ ​--RS
operand2 ​<=​ reg_mem_out​(​to_integer​(​unsigned​(​Instruction​(​7​ ​downto​ ​5​))));​ ​--RT
EGRE 426 - Lab 4 - Page 27

​--Data write and read


datawrite ​:​ ​PROCESS​(​operand2​,​ data_WR2​,​ data_rst​,​ prog_data_WR​,​ clk​)​ ​IS
​BEGIN
​IF​ prog_data_WR ​=​ ​'1'​ ​THEN
data_WR_Index​(​255​ ​downto​ ​to_integer​(​unsigned​(​dat_addr​(​7​ ​downto​ ​0​)))+​1​)​ ​<=​ ​(​others​=>​'0'​);​ ​--set
signals above desired index
data_WR_Index​(​to_integer​(​unsigned​(​dat_addr​(​7​ ​downto​ ​0​))))​ ​<=​ data_WR2​;​ ​--set
desired index
data_WR_Index​(​to_integer​(​unsigned​(​dat_addr​(​7​ ​downto​ ​0​)))-​1​ ​downto​ ​0​)​ ​<=​ ​(​others​=>​'0'​);​ ​--set
signals above desired index
​ELSE
data_WR_Index​(​255​ ​downto​ ​to_integer​(​unsigned​(​dat_addr​(​7​ ​downto​ ​0​)))+​1​)​ ​<=​ ​(​others​=>​'0'​);​ ​--set
signals above desired index
data_WR_Index​(​to_integer​(​unsigned​(​dat_addr​(​7​ ​downto​ ​0​))))​ ​<=​ data_WR2​;​ ​--set
desired index
data_WR_Index​(​to_integer​(​unsigned​(​dat_addr​(​7​ ​downto​ ​0​)))-​1​ ​downto​ ​0​)​ ​<=​ ​(​others​=>​'0'​);​ ​--set
signals above desired index
​END​ ​IF​;
​END​ ​PROCESS​;

​--Data read
data_read ​<=​ data_mem_out​(​to_integer​(​unsigned​(​ALU_result​(​7​ ​downto​ ​0​))));​ ​--Change if you alter data
mem size

--Data memory programming logic


dataprog ​:​ ​PROCESS​(​clk​)​ ​IS
​BEGIN
​IF​ prog_data_WR ​=​ ​'1'​ ​THEN
dat_addr ​<=​ data_flash_addr​;
mem_data ​<=​ data_flash​;
data_WR2 ​<=​ prog_data_WR​;
​ELSE
dat_addr ​<=​ ALU_result​;
mem_data ​<=​ operand2​;
data_WR2 ​<=​ data_WR​;
​END​ ​IF​;
​END​ ​PROCESS​;

--Top Level Logic


CPU ​:​ ​PROCESS​(​clk​,​ Instruction​,​ ext_imm​,​ branch_true​,​ I_type​,​ PC_2​,​ calc_addr​,
operand2​,​ jump_ins​,​ BJ_ADDR​,​ bran_jump​,​ mem_to_reg​,​ data_read​,​ ALU_result​)
​BEGIN
PC_2 ​<=​ ​std_logic_vector​((​unsigned​(​PC​))​ ​+​ ​1​);​ ​--PC Adder

ext_imm​(​15​ ​downto​ ​0​)​ ​<=​ ​"00000000000"​ ​&​ Instruction​(​4​ ​downto​ ​0​);​ ​--Concatenate to extend
​--ext_imm(4 downto 0) <= Instruction(4 downto 0);
​--ext_imm(15 downto 5) <= "00000000000";

​if​ branch_true ​=​ ​'1'​ ​then


calc_addr ​<=​ BJ_ADDR​(​10​ ​downto​ ​0​);
EGRE 426 - Lab 4 - Page 28

​else
calc_addr ​<=​ Instruction​(​10​ ​downto​ ​0​);
​end​ ​if​;

BJ_ADDR ​<=​ ​std_logic_vector​(​signed​(​PC_2​)+​signed​(​ext_imm​(​10​ ​downto​ ​0​)));​ ​--Signed Adder

​if​ I_type ​=​ ​'1'​ ​then


Dest ​<=​ Instruction​(​7​ ​downto​ ​5​);​ -​ -RT
​else
Dest ​<=​ Instruction​(​4​ ​downto​ ​2​);​ -​ -RD
​end​ ​if​;

​if​ I_type ​=​ ​'1'​ ​then


B ​<=​ ext_imm​;​ ​--RD
​else
B ​<=​ operand2​;​ ​--RT
​end​ ​if​;

bran_jump ​<=​ branch_true ​OR​ jump_ins​;

​if​ bran_jump ​=​ ​'1'​ ​then


PC_ADDR ​<=​ calc_addr​;
​else
PC_ADDR ​<=​ PC_2​;
​end​ ​if​;

​if​ mem_to_reg ​=​ ​'1'​ ​then


result ​<=​ data_read​;
​else
result ​<=​ ALU_result​;
​end​ ​if​;

​END​ ​PROCESS​;

--Values out for testbench


t0_reg_out ​<=​ reg_mem_out​(​4​);
t1_reg_out ​<=​ reg_mem_out​(​5​);
t2_reg_out ​<=​ reg_mem_out​(​6​);
t3_reg_out ​<=​ reg_mem_out​(​7​);
dat_addr16 ​<=​ data_mem_out​(​16​);
dat_addr17 ​<=​ data_mem_out​(​17​);
dat_addr18 ​<=​ data_mem_out​(​18​);
dat_addr19 ​<=​ data_mem_out​(​19​);
dat_addr20 ​<=​ data_mem_out​(​20​);
ins_out_tb ​<=​ Instruction​;
PC_out_tb ​<=​ PC​;

end​ structural​;
EGRE 426 - Lab 4 - Page 29

Appendix D
ALU.vhd:
library​ ​ieee​;
use​ ​ieee​.​std_logic_1164​.​ALL​;
use​ ​ieee​.​numeric_std​.​ALL​;

entity​ ALU ​IS


​GENERIC​(​N ​:​ ​INTEGER​ ​:=​ ​16​);
​PORT​(​ a ​:​ ​in​ ​std_logic_vector​(​N​-​1​ ​downto​ ​0​);​ ​--Var input
b ​:​ ​in​ ​std_logic_vector​(​N​-​1​ ​downto​ ​0​);
func ​:​ ​in​ ​std_logic_vector​(​3​ ​downto​ ​0​);​ ​-- ALU operator select
result ​:​ ​out​ ​std_logic_vector​(​N​-​1​ ​downto​ ​0​);​ ​--Result output
branch ​:​ ​out​ ​std_logic​);​ ​--Zero flag
END​ ALU​;

architecture​ behavior ​of​ ALU ​is


signal​ tmp ​:​ ​signed​(​N​-​1​ ​downto​ ​0​);
signal​ logic_tmp ​:​ ​std_logic_vector​(​N​-​1​ ​downto​ ​0​);

BEGIN
​process​(​a​,​ b​,​ func​,​ logic_tmp​,​ tmp​)​ ​-- Sensitivity List includes internal signals
​BEGIN
​case​ func ​is
​WHEN​ ​"0000"​ ​=>​ ​--Add
tmp ​<=​ ​signed​(​a​)​ ​+​ ​signed​(​b​);

branch ​<=​ ​'0'​;

result ​<=​ ​std_logic_vector​(​tmp​);

​WHEN​ ​"0001"​ ​=>​ ​--Subtract


tmp ​<=​ ​signed​(​a​)​ ​-​ ​signed​(​b​);

branch ​<=​ ​'0'​;

result ​<=​ ​std_logic_vector​(​tmp​);

​WHEN​ ​"0010"​ ​=>​ ​--AND


logic_tmp ​<=​ a ​AND​ b​;

branch ​<=​ ​'0'​;

result ​<=​ logic_tmp​;

​WHEN​ ​"0011"​ ​=>​ ​--OR


logic_tmp ​<=​ a ​OR​ b​;

branch ​<=​ ​'0'​;


EGRE 426 - Lab 4 - Page 30

result ​<=​ logic_tmp​;

​WHEN​ ​"0100"​ ​=>​ ​--XOR


logic_tmp ​<=​ a ​XOR​ b​;

branch ​<=​ ​'0'​;

result ​<=​ logic_tmp​;

​WHEN​ ​"0101"​ ​=>​ ​--SLL


logic_tmp ​<=​ ​std_logic_vector​(​shift_left​(​unsigned​(​a​),​ ​to_integer​(​unsigned​(​b​))));

branch ​<=​ ​'0'​;

result ​<=​ logic_tmp​;

​WHEN​ ​"0110"​ ​=>​ ​--SRL


logic_tmp ​<=​ ​std_logic_vector​(​shift_right​(​unsigned​(​a​),​ ​to_integer​(​unsigned​(​b​))));

branch ​<=​ ​'0'​;

result ​<=​ logic_tmp​;

​WHEN​ ​"0111"​ ​=>​ ​--SRA


logic_tmp ​<=​ ​std_logic_vector​(​shift_right​(​signed​(​a​),​ ​to_integer​(​unsigned​(​b​))));

branch ​<=​ ​'0'​;

result ​<=​ logic_tmp​;

​WHEN​ ​"1000"​ ​=>​ ​--Set less than


​if​ a ​<​ b ​then
result​(​N​-​1​ ​downto​ ​1​)​ ​<=​ ​(​N​-​1​ ​downto​ ​1​ ​=>​'0'​);
result​(​0​ ​downto​ ​0​)​ ​<=​ ​"1"​;
​else
result ​<=​ ​(​N​-​1​ ​downto​ ​0​ ​=>​'0'​);
​end​ ​if​;

branch ​<=​ ​'0'​;

​WHEN​ ​"1001"​ ​=>​ ​--Branch equal


​if​ a ​=​ b ​then
result ​<=​ ​(​N​-​1​ ​downto​ ​0​ ​=>​'0'​);
branch ​<=​ ​'1'​;
​else
result ​<=​ ​(​N​-​1​ ​downto​ ​0​ ​=>​'0'​);
branch ​<=​ ​'0'​;
​end​ ​if​;

​WHEN​ ​"1010"​ ​=>​ ​--Branch less than


​if​ ​signed​(​a​)​ ​<​ ​signed​(​b​)​ ​then
EGRE 426 - Lab 4 - Page 31

result ​<=​ ​(​N​-​1​ ​downto​ ​0​ ​=>​'0'​);


branch ​<=​ ​'1'​;
​else
result ​<=​ ​(​N​-​1​ ​downto​ ​0​ ​=>​'0'​);
branch ​<=​ ​'0'​;
​end​ ​if​;

​WHEN​ ​"1011"​ ​=>​ ​--Branch less than or equal


​if​ ​signed​(​a​)​ ​<=​ ​signed​(​b​)​ ​then
result ​<=​ ​(​N​-​1​ ​downto​ ​0​ ​=>​'0'​);
branch ​<=​ ​'1'​;
​else
result ​<=​ ​(​N​-​1​ ​downto​ ​0​ ​=>​'0'​);
branch ​<=​ ​'0'​;
​end​ ​if​;

​WHEN​ ​"1100"​ ​=>​ ​--Branch greater than


​if​ ​signed​(​a​)​ ​>​ ​signed​(​b​)​ ​then
result ​<=​ ​(​N​-​1​ ​downto​ ​0​ ​=>​'0'​);
branch ​<=​ ​'1'​;
​else
result ​<=​ ​(​N​-​1​ ​downto​ ​0​ ​=>​'0'​);
branch ​<=​ ​'0'​;
​end​ ​if​;

​WHEN​ ​"1101"​ ​=>​ ​--Branch greater than or equal


​if​ ​signed​(​a​)​ ​>=​ ​signed​(​b​)​ ​then
result ​<=​ ​(​N​-​1​ ​downto​ ​0​ ​=>​'0'​);
branch ​<=​ ​'1'​;
​else
result ​<=​ ​(​N​-​1​ ​downto​ ​0​ ​=>​'0'​);
branch ​<=​ ​'0'​;
​end​ ​if​;

​WHEN​ ​others​ ​=>​ ​--Catchall


result ​<=​ ​(​N​-​1​ ​downto​ ​0​ ​=>​'0'​);
branch ​<=​ ​'0'​;

​end​ ​case​;
​ ND​ ​process​;
E
END​ behavior​;
EGRE 426 - Lab 4 - Page 32

Appendix E
control.vhd:
library​ ​ieee​;
use​ ​ieee​.​std_logic_1164​.​ALL​;
use​ ​ieee​.​numeric_std​.​ALL​;

entity​ control ​IS


​GENERIC​(​N ​:​ ​INTEGER​ ​:=​ ​16​;
ALU_size ​:​ ​INTEGER​ ​:=​ ​4​);
​PORT​(​ Instruction ​:​ ​in​ ​std_logic_vector​(​N​-​1​ ​downto​ ​0​);​ ​--Input instruction
ALU_func ​:​ ​out​ ​std_logic_vector​(​ALU_size​-​1​ ​downto​ ​0​);​ ​--ALU function select
I_type ​:​ ​out​ ​std_logic​;​ ​--I-type instruction flag
reg_WR ​:​ ​out​ ​std_logic​;​ ​--Enable register write flag
jump_ins ​:​ ​out​ ​std_logic​;​ ​--Xqt jump instruction flag
data_WR ​:​ ​out​ ​std_logic​;​ ​--Enable data write flag
mem_to_reg ​:​ ​out​ ​std_logic​);​ ​--Select output of data memory flag
END​ control​;

architecture​ behavior ​of​ control ​is


signal​ parse_ins ​:​ ​std_logic_vector​(​5​-​1​ ​downto​ ​0​);

BEGIN
parse ​:​ ​PROCESS​(​Instruction​,​ parse_ins​)​ ​IS
​BEGIN
parse_ins ​<=​ Instruction​(​N​-​1​ ​downto​ N​-​5​);​ ​--Collect 5 upper bits of instruction

​case​ parse_ins ​is


​WHEN​ ​"00000"​ ​=>​ ​--NO OPERATION [NOP]
ALU_func ​<=​ ​"0000"​;
I_type ​<=​ ​'0'​;
reg_WR ​<=​ ​'0'​;
jump_ins ​<=​ ​'0'​;
data_WR ​<=​ ​'0'​;
mem_to_reg ​<=​ ​'0'​;

​WHEN​ ​"00001"​ ​=>​ ​--ADDITION [ADD]


ALU_func ​<=​ ​"0000"​;
I_type ​<=​ ​'0'​;
reg_WR ​<=​ ​'1'​;
jump_ins ​<=​ ​'0'​;
data_WR ​<=​ ​'0'​;
mem_to_reg ​<=​ ​'0'​;

​WHEN​ ​"00010"​ ​=>​ ​--BITWISE AND [AND]


ALU_func ​<=​ ​"0010"​;
I_type ​<=​ ​'0'​;
reg_WR ​<=​ ​'1'​;
jump_ins ​<=​ ​'0'​;
data_WR ​<=​ ​'0'​;
mem_to_reg ​<=​ ​'0'​;
EGRE 426 - Lab 4 - Page 33

​WHEN​ ​"00011"​ ​=>​ ​--BITWISE OR [OR]


ALU_func ​<=​ ​"0011"​;
I_type ​<=​ ​'0'​;
reg_WR ​<=​ ​'1'​;
jump_ins ​<=​ ​'0'​;
data_WR ​<=​ ​'0'​;
mem_to_reg ​<=​ ​'0'​;

​WHEN​ ​"00100"​ ​=>​ ​--SET LESS THAN [SLT]


ALU_func ​<=​ ​"1000"​;
I_type ​<=​ ​'0'​;
reg_WR ​<=​ ​'1'​;
jump_ins ​<=​ ​'0'​;
data_WR ​<=​ ​'0'​;
mem_to_reg ​<=​ ​'0'​;

​WHEN​ ​"00101"​ ​=>​ ​--SUBTRACTION [SUB]


ALU_func ​<=​ ​"0001"​;
I_type ​<=​ ​'0'​;
reg_WR ​<=​ ​'1'​;
jump_ins ​<=​ ​'0'​;
data_WR ​<=​ ​'0'​;
mem_to_reg ​<=​ ​'0'​;

​WHEN​ ​"00110"​ ​=>​ ​--BITWISE EXCLUSIVE OR [XOR]


ALU_func ​<=​ ​"0100"​;
I_type ​<=​ ​'0'​;
reg_WR ​<=​ ​'1'​;
jump_ins ​<=​ ​'0'​;
data_WR ​<=​ ​'0'​;
mem_to_reg ​<=​ ​'0'​;

​WHEN​ ​"00111"​ ​=>​ ​--ADD IM [ADDI]


ALU_func ​<=​ ​"0000"​;
I_type ​<=​ ​'1'​;
reg_WR ​<=​ ​'1'​;
jump_ins ​<=​ ​'0'​;
data_WR ​<=​ ​'0'​;
mem_to_reg ​<=​ ​'0'​;

​WHEN​ ​"01000"​ ​=>​ ​--BITWISE AND IMM [ANDI]


ALU_func ​<=​ ​"0010"​;
I_type ​<=​ ​'1'​;
reg_WR ​<=​ ​'1'​;
jump_ins ​<=​ ​'0'​;
data_WR ​<=​ ​'0'​;
mem_to_reg ​<=​ ​'0'​;

​WHEN​ ​"01001"​ ​=>​ ​--BRANCH EQUAL [BEQ]


ALU_func ​<=​ ​"1001"​;
EGRE 426 - Lab 4 - Page 34

I_type ​<=​ ​'0'​;


reg_WR ​<=​ ​'0'​;
jump_ins ​<=​ ​'0'​;
data_WR ​<=​ ​'0'​;
mem_to_reg ​<=​ ​'0'​;

​WHEN​ ​"01010"​ ​=>​ ​--BRANCH GREATER THAN [BGT]


ALU_func ​<=​ ​"1100"​;
I_type ​<=​ ​'0'​;
reg_WR ​<=​ ​'0'​;
jump_ins ​<=​ ​'0'​;
data_WR ​<=​ ​'0'​;
mem_to_reg ​<=​ ​'0'​;

​WHEN​ ​"01011"​ ​=>​ ​--BRANCH GREATER THAN OR EQUAL [BGE]


ALU_func ​<=​ ​"1101"​;
I_type ​<=​ ​'0'​;
reg_WR ​<=​ ​'0'​;
jump_ins ​<=​ ​'0'​;
data_WR ​<=​ ​'0'​;
mem_to_reg ​<=​ ​'0'​;

​WHEN​ ​"01100"​ ​=>​ ​--BRANCH LESS THAN [BLT]


ALU_func ​<=​ ​"1010"​;
I_type ​<=​ ​'0'​;
reg_WR ​<=​ ​'0'​;
jump_ins ​<=​ ​'0'​;
data_WR ​<=​ ​'0'​;
mem_to_reg ​<=​ ​'0'​;

​WHEN​ ​"01101"​ ​=>​ ​--BRANCH LESS THAN OR EQUAL [BLE]


ALU_func ​<=​ ​"1011"​;
I_type ​<=​ ​'0'​;
reg_WR ​<=​ ​'0'​;
jump_ins ​<=​ ​'0'​;
data_WR ​<=​ ​'0'​;
mem_to_reg ​<=​ ​'0'​;

​WHEN​ ​"01110"​ ​=>​ ​--LOAD WORD [LW]


ALU_func ​<=​ ​"0000"​;
I_type ​<=​ ​'1'​;
reg_WR ​<=​ ​'1'​;
jump_ins ​<=​ ​'0'​;
data_WR ​<=​ ​'0'​;
mem_to_reg ​<=​ ​'1'​;

​WHEN​ ​"01111"​ ​=>​ ​--BITWISE OR IMM [ORI]


ALU_func ​<=​ ​"0011"​;
I_type ​<=​ ​'1'​;
reg_WR ​<=​ ​'1'​;
jump_ins ​<=​ ​'0'​;
EGRE 426 - Lab 4 - Page 35

data_WR ​ =​ ​'0'​;
<
mem_to_reg ​<=​ ​'0'​;

​WHEN​ ​"10000"​ ​=>​ ​--STORE WORD [SW]


ALU_func ​<=​ ​"0000"​;
I_type ​<=​ ​'1'​;
reg_WR ​<=​ ​'0'​;
jump_ins ​<=​ ​'0'​;
data_WR ​<=​ ​'1'​;
mem_to_reg ​<=​ ​'0'​;

​WHEN​ ​"10001"​ ​=>​ ​--SET LESS THAN IMM [SLTI]


ALU_func ​<=​ ​"1000"​;
I_type ​<=​ ​'1'​;
reg_WR ​<=​ ​'1'​;
jump_ins ​<=​ ​'0'​;
data_WR ​<=​ ​'0'​;
mem_to_reg ​<=​ ​'0'​;

​WHEN​ ​"10010"​ ​=>​ ​--SHIFT LEFT LOGICAL [SLL]


ALU_func ​<=​ ​"0101"​;
I_type ​<=​ ​'1'​;
reg_WR ​<=​ ​'1'​;
jump_ins ​<=​ ​'0'​;
data_WR ​<=​ ​'0'​;
mem_to_reg ​<=​ ​'0'​;

​WHEN​ ​"10011"​ ​=>​ ​--SHIFT RIGHT ARITHMETIC [SRA]


ALU_func ​<=​ ​"0111"​;
I_type ​<=​ ​'1'​;
reg_WR ​<=​ ​'1'​;
jump_ins ​<=​ ​'0'​;
data_WR ​<=​ ​'0'​;
mem_to_reg ​<=​ ​'0'​;

​WHEN​ ​"10100"​ ​=>​ ​--SHIFT RIGHT LOGICAL [SRL]


ALU_func ​<=​ ​"0110"​;
I_type ​<=​ ​'1'​;
reg_WR ​<=​ ​'1'​;
jump_ins ​<=​ ​'0'​;
data_WR ​<=​ ​'0'​;
mem_to_reg ​<=​ ​'0'​;

​WHEN​ ​"10101"​ ​=>​ ​--SUB IMM [SUBI]


ALU_func ​<=​ ​"0001"​;
I_type ​<=​ ​'1'​;
reg_WR ​<=​ ​'1'​;
jump_ins ​<=​ ​'0'​;
data_WR ​<=​ ​'0'​;
mem_to_reg ​<=​ ​'0'​;
EGRE 426 - Lab 4 - Page 36

​WHEN​ ​"11111"​ ​=>​ ​--JUMP [J]


ALU_func ​<=​ ​"0000"​;
I_type ​<=​ ​'0'​;
reg_WR ​<=​ ​'0'​;
jump_ins ​<=​ ​'1'​;
data_WR ​<=​ ​'0'​;
mem_to_reg ​<=​ ​'0'​;

​WHEN​ ​others​ ​=>​ ​--Catchall; same as NOP


ALU_func ​<=​ ​"0000"​;
I_type ​<=​ ​'0'​;
reg_WR ​<=​ ​'0'​;
jump_ins ​<=​ ​'0'​;
data_WR ​<=​ ​'0'​;
mem_to_reg ​<=​ ​'0'​;

​end​ ​case​;
​ ND​ ​process​;
E
END​ behavior​;
EGRE 426 - Lab 4 - Page 37

Appendix F
D_register_scalable.vhd:
Library​ ​IEEE​;
use​ ​IEEE​.​std_logic_1164​.​all​;

entity​ D_Register ​is


​GENERIC​ ​(​N ​:​ ​INTEGER​ ​:=​ ​32​);​ ​-- Allows for scalability
​PORT​ ​(​d ​:​ ​in​ ​STD_LOGIC_VECTOR​ ​(​N​-​1​ ​downto​ ​0​);​ ​--Input
clk ​:​ ​in​ ​STD_LOGIC​;​ ​--Clock
rst ​:​ ​in​ ​STD_LOGIC​;​ ​--Reset
en ​:​ ​in​ ​STD_LOGIC​;​ ​--Enable
q ​:​ ​out​ ​STD_LOGIC_VECTOR​ ​(​N​-​1​ ​downto​ ​0​));​ ​--Output
end​ D_Register​;

architecture​ behavior ​of​ D_Register ​is

begin
up_counter ​:​ ​process​(​clk​,​ rst​)
​begin
​if​(​rst ​=​ ​'1'​)​ ​then
q ​<=​ ​(​others​ ​=>​ ​'0'​);
​elsif​(​rising_edge​(​clk​)​ ​AND​ ​(​en ​=​ ​'1'​))​ ​then
q ​<=​ d​;
​end​ ​if​;
​end​ ​process​ up_counter​;
end​ behavior​;
EGRE 426 - Lab 4 - Page 38

Appendix G
cpu_out.txt
Clock Cycles: 0
t0: 0000000000000000
t1: 0000000000000000
t2: 0000000000000000
t3: 0000000000000000

16: 0000000000000000
17: 0000000000000000
18: 0000000000000000
19: 0000000000000000
20: 0000000000000000

Clock Cycles: 33
t0: 0000000000000000
t1: 0000000000000000
t2: 0000000000000000
t3: 0000000000000000

16: 0000000100000001
17: 0000000100010000
18: 0000000000010001
19: 0000000011110000
20: 0000000011111111

Clock Cycles: 60
t0: 0000000000001000
t1: 0001000000011000
t2: 0000000000001111
t3: 0000000011110000

16: 1111111100000000
17: 0000000100010000
18: 0000000000010001
19: 0000000011110000
20: 0000000011111111

Clock Cycles: 75
t0: 0000000000000001
t1: 0001000000011001
t2: 0000000000001111
t3: 0000000011110000

16: 1111111100000000
EGRE 426 - Lab 4 - Page 39

17: 1111111100000000
18: 0000000000010001
19: 0000000011110000
20: 0000000011111111

Clock Cycles: 88
t0: 0000000000000001
t1: 0001000000011001
t2: 0000000000111100
t3: 0000000011001100

16: 1111111100000000
17: 1111111100000000
18: 0000000011111111
19: 0000000011110000
20: 0000000011111111

Clock Cycles: 101


t0: 0000000000000001
t1: 0001000000011001
t2: 0000000011110000
t3: 0000000000111100

16: 1111111100000000
17: 1111111100000000
18: 0000000011111111
19: 0000000011111111
20: 0000000011111111

Clock Cycles: 114


t0: 0000000000000001
t1: 0001000000011001
t2: 0000001111000000
t3: 0000001111111100

16: 1111111100000000
17: 1111111100000000
18: 0000000011111111
19: 0000000011111111
20: 0000000011111111
EGRE 426 - Lab 4 - Page 40

Appendix H

instruction_memory.txt

0000000000000000 0 0000000000000000 0000000000000000 0 1 1 1 1


1001000000010000 1 0000000000010000 0000000100000001 1 0 0 0 0
0011100010000001 1 0000000000010001 0000000100010000 1 0 0 0 0
1001010010000110 1 0000000000010010 0000000000010001 1 0 0 0 0
0011100010100001 1 0000000000010011 0000000011110000 1 0 0 0 0
1001010110101100 1 0000000000010100 0000000011111111 1 0 0 0 0
0011110110110000 1 0000000000000000 0000000000000000 0 0 0 0 0
0011100011001111 1 0000000000000000 0000000000000000 0 0 0 0 0
0011100011101111 1 0000000000000000 0000000000000000 0 0 0 0 0
1001011111100100 1 0000000000000000 0000000000000000 0 0 0 0 0
0011100000100000 1 0000000000000000 0000000000000000 0 0 0 0 0
0011100001010000 1 0000000000000000 0000000000000000 0 0 0 0 0
0011100001100101 1 0000000000000000 0000000000000000 0 0 0 0 0
0110101100001011 1 0000000000000000 0000000000000000 0 0 0 0 0
1010101101100001 1 0000000000000000 0000000000000000 0 0 0 0 0
0111001000100000 1 0000000000000000 0000000000000000 0 0 0 0 0
0011100000000001 1 0000000000000000 0000000000000000 0 0 0 0 0
1001000000001000 1 0000000000000000 0000000000000000 0 0 0 0 0
0110100100000111 1 0000000000000000 0000000000000000 0 0 0 0 0
1010010010000011 1 0000000000000000 0000000000000000 0 0 0 0 0
0001110110010100 1 0000000000000000 0000000000000000 0 0 0 0 0
1010100000000001 1 0000000000000000 0000000000000000 0 0 0 0 0
1001000000001000 1 0000000000000000 0000000000000000 0 0 0 0 0
1000001000000000 1 0000000000000000 0000000000000000 0 0 0 0 0
1111100000011101 1 0000000000000000 0000000000000000 0 0 0 0 0
0100100000000111 1 0000000000000000 0000000000000000 0 0 0 0 0
1001011011000010 1 0000000000000000 0000000000000000 0 0 0 0 0
0011011011111100 1 0000000000000000 0000000000000000 0 0 0 0 0
1010100000000001 1 0000000000000000 0000000000000000 0 0 0 0 0
1000001000000000 1 0000000000000000 0000000000000000 0 0 0 0 0
0011101001000001 1 0000000000000000 0000000000000000 0 0 0 0 0
1001000000010000 1 0000000000000000 0000000000000000 0 0 0 0 0
1111100000001100 1 0000000000000000 0000000000000000 0 0 0 0 0
0000000000000000 0 0000000000000000 0000000000000000 0 0 1 0 1
0000000000000000 0 0000000000000000 0000000000000000 0 0 0 0 0
EGRE 426 - Lab 4 - Page 41

Appendix I
Example code assembly:

Assembly Machine Code

Testing rd/rt/ad rt/im


Program Psuedo Code PC PC Hex label inst dr rs m Hex Binary

100100000001
//ensure n0 is 0 0 0000 sl n0 n0 16 9010 0000

001110001000
$v0 = 0040hex; //64 1000000 1 0001 addi t0 n0 1 3881 0001

100101001000
2 0002 sl t0 t0 6 9486 0110

001110001010
$v1 = 1010hex; //4112 1000000010000 3 0003 addi t1 n0 1 38A1 0001

100101011010
4 0004 sl t1 t1 12 95AC 1100

001111011011
5 0005 addi t1 t1 16 3DB0 0000

001110001100
$v2 = 000Fhex; //15 1111 6 0006 addi t2 n0 15 38CF 1111

001110001110
$v3 = 00F0hex; //240 11110000 7 0007 addi t3 n0 15 38EF 1111

100101111110
8 0008 sl t3 t3 4 97E4 0100

001110000010
$t0 = 0000hex; //0 0 9 0009 addi s0 n0 0 3820 0000

001110000101
$a0 = 0010hex; //16 10000 10 000A addi s1 n0 16 3850 0000

001110000110
$a1 = 0005hex; //5 101 11 000B addi s2 n0 5 3865 0101

while ($a1 > 0) 011010110000


do { //Loop 5 times 12 000C Loop ble n0 s2 Sneak 6B0B 1011

101010110110
$a1 = $a1 –1; //Decriment loop count 13 000D subi s2 s2 1 AB61 0001

011100100010
$t0 = Mem[$a0]; //Load a0 14 000E lw s0 s1 0 7220 0000

//Set n0 to be 0x0100 001110000000


(for the IF) 15 000F addi n0 n0 1 3801 0001

100100000000
//... 16 0010 sl n0 n0 8 9008 1000
EGRE 426 - Lab 4 - Page 42

if ($t0 > 011010010000


0100hex) then //IF a0,t0 > 0x100 256 17 0011 If ble n0 s0 Else 6907 0111

101001001000
$v0 = $v0 ÷ 8; //v0/8 [SRL>>3] 18 0012 srl t0 t0 3 A483 0011

$v1 = $v1 | $v0; 000111011001


//or //v1 = v1 || v0 19 0013 or t1 t1 t0 1D94 0100

101010000000
//n0 is now 0x00FF 20 0014 subi n0 n0 1 A801 0001

100100000000
//n0 is now 0xFF00 21 0015 sl n0 n0 8 9008 1000

Mem[$a0] = 100000100000
FF00hex; //Store 0xFF00 in a0 22 0016 sw n0 0(s1) 8200 0000

111110000001
} 23 0017 j After F81D 1101

010010000000
else //IF a0,t0 <= 0x100 24 0018 Sneak beq n0 n0 Done 4807 0111

100101101100
$v2 = $v2 × 4; //v2*4 [SLL<<2] 25 0019 Else sl t2 t2 2 96C2 0010

$v3 = $v3 ⊕ $v2; 001101101111


//xor //v3 = v3 XOR v2 26 001A xor t3 t3 t2 36FC 1100

101010000000
//n0 is now 0x00FF 27 001B subi n0 n0 1 A801 0001

Mem[$a0] = 100000100000
00FFhex; //Store 0x00FF in a0 28 001C sw n0 0(s1) 0 8200 0000

//Incriment a0 to nxt 001110100100


$a0 = $a0 + 1; mem location 29 001D After addi s1 s1 1 3A41 0001

100100000001
//reset n0 register 30 001E sl n0 n0 16 9010 0000

111110000000
} 31 001F j Loop F80C 1100

return; 32 0020 Done


EGRE 426 - Lab 4 - Page 43

Appendix J
Instruction types:

16bit Instruction layouts


R-Type
Opcode rs rt rd func
5 3 3 3 2

I-Type
Opcode rs rt immediate
5 3 3 5

J-Type
Opcode addr
5 11

Register layout:

Register Name Purpose


000 N0 Init to all 0's and set to all 0's at end of prog. But can be changed in prog
001 s0 SAVED/Variable registers
010 s1
011 s2
100 t0 TEMP registers
101 t1
110 t2
111 t3
EGRE 426 - Lab 4 - Page 44

Appendix K
Instruction set:

Fun Forma
Instruction Mnemonic Opcode c t Operation

no operation nop 00000 00 N/A all fields: 0

add add 00001 00 R add rd, rs, rt; rd = rs+rt

and and 00010 00 R and rd, rs,rt; rd = rs&rt

or or 00011 00 R or rd, rs,rt; rd = rs|rt

set less than slt 00100 00 R slt rd, rs, rt; if rs < rt, rd = 1, else rd = 0

sub sub 00101 00 R sub rd, rs, rt; rd = rs-rt

exclusive or xor 00110 00 R oxr rd, rs, rt; rd = rs ⊕ rt

add immediate addi 00111 I addi rt, rs, 5; rt = rs+5

and immediate andi 01000 I andi rt, rs, X; rt = rs&X

branch equal beq 01001 I beq rt, rs; if rs == rt then PC = PC+1​+​imm

branch greater than bgt 01010 I bgt rt, rs; if rs > rt then PC = PC+1​+​imm

branch greater than or


equal bge 01011 I bge rt, rs; if rs >= rt then PC = PC+1​+​imm

branch less than blt 01100 I blt rt, rs; if rs < rt then PC = PC+1​+​imm

branch less than or


equal ble 01101 I ble rt, rs; if rs <= rt then PC = PC+1​+​imm

load word lw 01110 I lw rt, rs, imm; rt = data mem addr[imm+rs]

or immediate ori 01111 I ori rt, rs, X; rt = rs&X

store word sw 10000 I sw rt, rs, imm; data mem addr[imm+rs] = rt

set less than immediate slti 10001 I slti rt, rs, imm; if rs < imm , rt = 1, else rt = 0

shift left sl 10010 I sl rt, rs, imm; rt = rs << imm

sra rt, rs, imm; rt = rs >> imm [extend rs based on


shift right arithmetic sra 10011 I original MSB]

shift right logical srl 10100 I srl rt, rs, imm; rt = rs >> imm

sub immediate subi 10101 I subi rt, rs, 5; rt = rs-5

jump j 11111 J j addr; PC = PC+1 +- addr [11bit signed addr]


EGRE 426 - Lab 4 - Page 45

ALU instructions:

ALU cmds Binary

add 0000
subtract 0001
and 0010
or 0011
xor 0100
sll 0101
srl 0110
sra 0111
set less than 1000
branch equal 1001
branch less than 1010
branch less than or equal 1011
branch greater than 1100
branch greater than or
equal 1101
x 1110
x 1111

You might also like