Microprocessor Design
In this lab you will implement a General Purpose Processor (GPP) using
techniques we've learned so far. A GPP unlike a Single Purpose Processor
can accomplish various tasks via programs written in an Instruction Set
that the microprocessor can recognize. Most processors are built
from a controller, dataptath and memory.
For the purposes of this lab we
will deviate from this processor architecture and have the memory integrated
into the controller.
A few things to note:
- Each instruction has its own unique address.
- An instruction translated into two things: OPCODE (which is the action to be taken) and
ADDRESS (what to take the action on--it's poorly named for reasons that will be clear soon).
- Sometimes, an instruction requires the CPU to 'jump' to another instruction. It has to indicate the
address of the instruction to be 'jumped to.' This requires eight bits, and therefore cannot fit in the
regular ADDRESS space. Therefore, another 'instruction' is added--but it is only an address--not actually
an instruction which the CPU is to take action on. Hopefully, this will be clearer when you look at the instruction set below.
- The OPCODE and ADDRESS are both 4 bits wide. This means we
have a datapath that is 4 bits. The
input of the datapath and output is only 4-bits
wide. This means the ALU and registers are also 4-bits wide.
The General Purpose Processor we will be building will have to recognize
the instruction set found below:
| INSTRUCTION |
OPCODE |
FUNCTION |
| MOVA Rd |
0000|dd00 |
Accumulator = Register [dd] |
| MOVR Rd |
0001|dd00 |
Register [dd] = Accumulator |
| LOAD Mem * |
0010|mmmm |
Accumulator = Memory[mmmm] |
| LOADI Imm |
0011|iiii |
Accumulator = Immediate |
| STORE Mem *,# |
0100|mmmm |
Memory[mmmm] = Accumulator |
| JZ Address |
0101|0000
aaaa|aaaa |
if (Acc == 0)
PC = Address[aaaa] // goto address
else
NOP // do nothing |
| JMP Address |
0110|0000
aaaa|aaaa |
PC = Address[aaaa] |
| ADD Rd |
0111|dd00 |
Accumulator = Accumulator + Register[dd] |
| ANDR Rd |
1001|dd00 |
Accumulator = Accumulator AND Register[dd] |
| INV |
1011|0000 |
Accumulator = NOT Accumulator |
| SHR |
1010|0000 |
Accumulator = Accumulator >> 1 |
| SUB Rd # |
1000|dd00 |
Accumulator = Accumulator - Register[dd]
|
| HALT |
1111|1111 |
Stop execution |
* Note: Memory location 0 is actually some pins on the DIP switch of the XS40 board.
So in essence we don't have Data Memory. You can use this instruction as
a select on a MUX to pick the input port.
# Optional at this point. You DO NOT HAVE TO IMPLEMENT THESE 2
INSTRUCTIONS but are included so you can see what a complete instruction
set might look like.
The following diagram shows you a potential datapath. It is suggested, but not required, that you use it:
As you can see, the number of bits used for the ALU control signal is not specified. This is left up to you to define.
You need to determine how many functions you need and how many bits will be necessary.
Also note: In order to load something directly from 'immediate' to the accumulator, you need to go through the register file.
In order to do this, the register file needs to set the output equal to the input when the READ signal is low. In other words, the
output will only be equal to a register when the READ enable is high, otherwise it will be equal to the input.
Although it is not shown, clk is connected to the synchronous components (Register File and Accumulator).
The following file contains VHDL code for a controller of a microprocessor that only
operates on 2 instructions: LOADI and HALT.
Assignment
- Take a look at the controller files above and become familiarized with
the structure of it. Your TA will give you a quick lecture on
processor design and what you might need for your controller and
datapath.
- Implement the instruction set, one instruction at a time in your
controller. In other words, grow your design one
function/instruction at a time. Make sure the instruction works.
Test it
by hard-coding in 1 instruction, and simulate it.
- When you have implemented all the instructions, write an algorithm that follows
the one's count algortihm. The one's count
algorithm counts how many 1's appear in a n-bit binary number.
So for the number 0110, the output should be 2.
- Implement the one's count algorithm inside your microprocessor.
Basically you are writing an assembly code program program for your microprocessor.
- Once you have a working simulation that tests at least three cases, show it to your TA.
- Download the design using the DIP switch as the 'memory location'
that holds the four bit number that the ones count algorithm will work on.
- Here is a link to the DIP switch PINS for the XESS board: http://www.cs.ucr.edu/content/esd/labs/general/DIPconnect.gif
- Here is a link to the overall pin connections for the XESS 40: http://www.xess.com/prgmdl40.html