Professional Documents
Culture Documents
1. Introduction 1
2. Objective 2
4. CODES 9
5. SIMULATION RESULTS 18
6. CONCLUSION 19
7. REFERENCES 20
1. INTRODUCTION
The processor is the primary element that carries out the functions of a
computer system. It performs the basic arithmetical, logical, and
input/output operations of the system. The term central processing unit
(CPU) is commonly used to describe a processor. The form, design and
implementation of CPUs have changed dramatically over the years, but their
fundamental operation remains much the same. Inside the processor, there
are some basic elements the work together to make the processor
functional. These are as follows:
1.1 Arithmetic Logic Unit (ALU): This is the main block in the processor and
the most important. The ALU is responsible for performing all the
computations. When the user, for example, enters numbers to be added or
multiplied, this unit does the computation and outputs the result to the
output devices. All the arithmetic operations such as adding, subtraction,
multiplying, or division is performed using this unit. Also, the logical
operations such as ANDing, ORing are done using this unit.
1.2 Control Unit: The control unit is another fundamental part of the CPU.
Essentially, it regulates the flow of information through the processor. The
functions that a control unit performs can vary based on what a particular
CPU was built to do. Mostly, this component receives, decodes, stores
results and manages execution of data that flows through the CPU.
1.3 Registers: These are very small memory locations that are responsible
for holding the data that is to be processed. The most important of these
registers is known as the instruction pointer, which directs the CPU to the
next memory location from where it is to receive information. Another type
of register is the accumulator, which is responsible for storing the results of
the various computations performed by the CPU. The data that is processed
by the CPU is also stored in some of the available registers.
1
2. OBJECTIVE
The scope of this project is to design an 8 bit processor using VHDL. The
processor fetches instructions from the external memory and executes
them. The control unit decodes the instructions and then causes the
appropriate signal interactions to make the processor unit execute the
instruction. The operations that the processor will be supporting are:
2
3. SYSTEM DESCRIPTION AND
DESIGN
3
The primary function of the processor is to execute programs. Now, a
program can be considered to be a sequence of instructions. Thus, in other
words, the basic function of a processor is to execute instructions.
Instruction fetch
Firstly, the instruction to be executed has to be fetched from the memory. A
16-bit address bus is used to access the memory location where the
instruction is stored.
Instruction decode
The processor decodes the instruction to determine what actions are to be
performed. The opcode part of the instruction states what operation is to be
performed on specified operands.
Accept data
In this step, the operands are read and stored in the registers available in the
processor. The 16-bit address lines are used to specify the memory location
or the input device from where the operand is to be read. The operand
reaches the processor via the 8-bit data bus.
Execute instruction
Next, the desired operation is performed in the ALU. The operands, stored in
the registers, are accessed during execution. The final result generated by
the operation is stored in the accumulator.
NOTE: An 8-bit CPU normally uses a 16-bit address bus and an 8-bit data bus.
However, this is not a law and there are exceptions.
4
A detailed illustration of how the other units interact with the processor is as
follows:
5
In our processor design, we have directly taken the opcode and the data as
inputs, irrespective of whether the data is being read from the memory or an
input device. The data is stored in temporary registers, B and C. Then, the
opcode is decoded and the operation that is to be performed is determined.
In the next clock cycle, the operation is performed and the result is stored in
the accumulator. The result is also made available as the output.
0000 MV Accumulator = B
1011 RT Accumulator = 0
6
The following flowchart describes how an operation is performed in the
processor:
7
An illustration of implements the flowchart is as shown below. The
components in the area surrounded by dotted lines constitute the processor.
With this background, we know move on to the VHDL code that implements
the processor.
8
4. CODES
Package containing functions that perform addition (without carry) and
subtraction (without borrow)
library ieee;
use ieee.std_logic_1164.all;
package my_pack is
function add(L,R :std_logic_vector) return std_logic_vector;
function sub(L,R :std_logic_vector) return std_logic_vector;
end my_pack;
package body my_pack is
function add(L,R : std_logic_vector) return std_logic_vector is
variable lv,rv,resv : std_logic_vector(L'length-1 downto 0);
variable cbit: std_logic;
begin
lv := L;
rv := R;
cbit := '0';
for k in 0 to L'left loop
resv(k) := cbit XOR lv(k) XOR rv(k);
cbit := (cbit AND lv(k)) OR (cbit AND rv(k)) OR (lv(k) AND rv(k));
end loop;
return resv;
end add;
function sub(L,R : std_logic_vector) return std_logic_vector is
variable lv,rv,resv : std_logic_vector(L'length-1 downto 0);
variable cbit: std_logic;
begin
lv := L;
rv := not R;
cbit := '1';
for k in 0 to L'left loop
resv(k) := cbit XOR lv(k) XOR rv(k);
cbit := (cbit AND lv(k)) OR (cbit AND rv(k)) OR (lv(k) AND rv(k));
end loop;
return resv;
end sub;
end my_pack;
9
Package containing functions that perform addition (with carry) and subtraction
(with borrow)
library ieee;
use ieee.std_logic_1164.all;
use work.my_pack.all;
package my_pack_adc is
function addc(L,R :std_logic_vector) return std_logic_vector;
function subb(L,R :std_logic_vector) return std_logic_vector;
end my_pack_adc;
package body my_pack_adc is
function addc(L,R : std_logic_vector) return std_logic_vector is
variable lv,rv,resv,s : std_logic_vector(L'length-1 downto 0);
variable resf : std_logic_vector(L'length-1 downto 0);
variable cbit: std_logic;
begin
lv := L;
rv := R;
cbit := '0';
for k in 0 to L'left loop
resv(k) := cbit XOR lv(k) XOR rv(k);
cbit := (cbit AND lv(k)) OR (cbit AND rv(k)) OR (lv(k) AND
rv(k));
end loop;
if(cbit ='0') then s:= "00000000";
else s:="00000001";
end if;
resf:=add(resv,s);
return resf;
end addc;
function subb(L,R : std_logic_vector) return std_logic_vector is
variable lv,rv,resv,s : std_logic_vector(L'length-1 downto 0);
variable resf : std_logic_vector(L'length-1 downto 0);
variable cbit: std_logic;
begin
lv := L;
rv := not R;
cbit := '1';
for k in 0 to L'left loop
resv(k) := cbit XOR lv(k) XOR rv(k);
cbit := (cbit AND lv(k)) OR (cbit AND rv(k)) OR (lv(k) AND rv(k));
10
end loop;
if(cbit ='1') then s:="00000000";
else s:="00000001";
end if;
resf:=sub(resv,s);
return resf;
end subb;
end my_pack_adc;
Package containing functions that perform logical AND, OR, XOR and NOT
library ieee;
use ieee.std_logic_1164.all;
package my_pack02 is
function andl(L,R :std_logic_vector) return std_logic_vector;
function orl(L,R :std_logic_vector) return std_logic_vector;
function xorl(L,R :std_logic_vector) return std_logic_vector;
function notl(L,R :std_logic_vector) return std_logic_vector;
end my_pack02;
package body my_pack02 is
function xorl(L,R : std_logic_vector) return std_logic_vector is
variable lv,rv,resv : std_logic_vector(L'length-1 downto 0);
begin
lv := L;
rv := R;
for k in 0 to L'left loop
resv(k) := lv(k) XOR rv(k);
end loop;
return resv;
end xorl;
function notl(L,R : std_logic_vector) return std_logic_vector is
variable lv,rv,resv : std_logic_vector(L'length-1 downto 0);
begin
lv := L;
for k in 0 to L'left loop
resv(k) :=NOT lv(k);
end loop;
return resv;
end notl;
11
function orl(L,R : std_logic_vector) return std_logic_vector is
variable lv,rv,resv : std_logic_vector(L'length-1 downto 0);
begin
lv := L;
rv := R;
for k in 0 to L'left loop
resv(k) := lv(k) OR rv(k);
end loop;
return resv;
end orl;
function andl(L,R : std_logic_vector) return std_logic_vector is
variable lv,rv,resv : std_logic_vector(L'length-1 downto 0);
begin
lv := L;
rv := R;
for k in 0 to L'left loop
resv(k) := lv(k) AND rv(k);
end loop;
return resv;
end andl;
end my_pack02;
library ieee;
use ieee.std_logic_1164.all;
package my_pack03 is
function inc(L :std_logic_vector) return std_logic_vector;
function drc(L :std_logic_vector) return std_logic_vector;
end my_pack03;
package body my_pack03 is
function inc(L : std_logic_vector) return std_logic_vector is
variable lv,rv,resv : std_logic_vector(L'length-1 downto 0);
variable cbit: std_logic;
begin
lv := L;
rv := "00000001";
cbit := '0';
for k in 0 to L'left loop
resv(k) := cbit XOR lv(k) XOR rv(k);
12
cbit := (cbit AND lv(k)) OR (cbit AND rv(k)) OR (lv(k) AND rv(k));
end loop;
return resv;
end inc;
function drc(L : std_logic_vector) return std_logic_vector is
variable lv,rv,resv : std_logic_vector(L'length-1 downto 0);
variable cbit: std_logic;
begin
lv := L;
rv := not "00000001";
cbit := '1';
for k in 0 to L'left loop
resv(k) := cbit XOR lv(k) XOR rv(k);
cbit := (cbit AND lv(k)) OR (cbit AND rv(k)) OR (lv(k) AND rv(k));
end loop;
return resv;
end drc;
end my_pack03;
library work;
library ieee;
use ieee.std_logic_1164.all;
use work.my_pack03.all;
entity inc_8 is
port( P: in std_logic_vector (7 downto 0);
R: out std_logic_vector (7 downto 0));
end inc_8;
architecture DF of inc_8 is
begin
R <= drc(P);
end DF;
library ieee;
use ieee.std_logic_1164.all;
package my_pack04 is
function mov(L,R :std_logic_vector) return std_logic_vector;
end my_pack04;
package body my_pack04 is
function mov(L,R : std_logic_vector) return std_logic_vector is
variable resv : std_logic_vector(L'length-1 downto 0);
13
begin
resv := L;
return resv;
end mov;
end my_pack04;
library work;
library ieee;
use ieee.std_logic_1164.all;
use work.my_pack02.all;
entity mov_8 is
port( P,Q : in std_logic_vector (7 downto 0);
R: out std_logic_vector (7 downto 0));
end mov_8;
architecture DF of mov_8 is
begin
R <= mov(p);
end DF;
Main code that implements the processor, using the functions described
previously
library work;
library ieee;
use ieee.std_logic_1164.all;
use work.my_pack02.all;
use work.my_pack03.all;
use work.my_pack04.all;
use work.my_pack.all;
use work.my_pack_adc.all;
entity processor is
port (B,C :in std_logic_vector(7 downto 0);
op :in std_logic_vector(3 downto 0);
Rst,clk :in std_logic;
done :out std_logic;
acc :out std_logic_vector(7 downto 0));
end processor;
14
signal state : t_state;
begin
process(Rst,clk,op)
constant cnt:std_logic_vector(7 downto 0):=(others=>'0');
variable resl: std_logic_vector(7 downto 0);
variable temp1:std_logic_vector(7 downto 0);
variable temp2:std_logic_vector(7 downto 0);
variable k:natural;
begin
if (Rst = '1') then
state<=dt;
elsif (clk ='1' and clk'event) then
case state is
when dt =>
resl:= (others=>'0');
temp1 := B;
temp2 := C;
if (op="0000") then
state<=mv;
elsif(op="0001") then
state <=inc;
elsif(op="0010") then
state <=drc;
elsif(op="0011") then
state <=add;
elsif(op="0100") then
state <=sub;
elsif(op="0101") then
state <=adc;
elsif(op="0110") then
state <=subb;
elsif(op="0111") then
state <=andl;
elsif(op="1000") then
state <=orl;
elsif(op="1001") then
state <=xorl;
elsif(op="1010") then
state <=notl;
else
state<=dt;
end if;
15
when add=>
resl := add(temp1,temp2);
state<=dt;
acc<=resl;
done<='1';
when sub=>
resl := sub(temp1,temp2);
state<=dt;
acc<=resl;
done<='1';
when subb=>
resl := subb(temp1,temp2);
state<=dt;
acc<=resl;
done<='1';
when adc=>
resl := addc(temp1,temp2);
state<=dt;
acc<=resl;
done<='1';
when inc=>
resl := inc(temp1);
state<=dt;
acc<=resl;
done<='1';
when drc=>
resl := drc(temp1);
state<=dt;
acc<=resl;
done<='1';
when andl=>
resl := andl(temp1,temp2);
state<=dt;
acc<=resl;
done<='1';
16
when orl=>
resl := orl(temp1,temp2);
state<=dt;
acc<=resl;
done<='1';
when xorl=>
resl := xorl(temp1,temp2);
state<=dt;
acc<=resl;
done<='1';
when notl=>
resl := notl(temp1);
state<=dt;
acc<=resl;
done<='1';
when mv=>
acc<=temp1;
state<=dt;
done<='1';
when rt=>
acc<=(others=>'0');
done<='1';
state<=dt;
end case;
end if;
end process;
end behv;
17
5. SIMULATION RESULTS
NOTE: ‘W/O Carry’ and ‘W/O borrow’ stand for ‘Without Carry’ and ‘Without
Borrow’ respectively. ‘W Carry’ and ‘W borrow’ stand for ‘With Carry’ and
‘With Borrow’ respectively.
18
6. CONCLUSION
The code worked and generated results as expected. This can be verified
from the simulation results that have been obtained. Thus, we can say that
the objective has been successfully realised. The code can further be
extended to included additional functionalities such as comparing two 8-bit
numbers, right or left shifting, and so on.
19
7. REFERENCES
20