You are on page 1of 9

EEP 308, Expermient 3 8 bit Microprocessor Submitted by:

Ankit Rao(2010EE10653) Ayush Agnihotri(2010EE10147) Surender Gora(2009EE10421) Tanmay Batra(2010EE10483)

Introduction
The central processing unit (CPU) is the portion of a computer system that carries out the instructions of a computer program, to perform the basic arithmetical, logical, and input/output operations of the system. 8-it CPU and ALU architectures are those that are based on registers, address buses, or data buses of that size. Hardwired into a CPU's design is a list of basic operations it can perform, called an instruction set. Such operations may include adding or subtracting two numbers, comparing numbers, or jumping to a different part of a program. Each of these basic operations is represented by a particular sequence of bits; this sequence is called the opcode for that particular operation. The opcode consists of the operation to be performed as well as the operands on which the operation is to be performed. The operands are accessed through registers which are represented in the binary form in the opcode. The actual mathematical operation for each instruction is performed by a subunit of the CPU known as the arithmetic logic unit or ALU. In addition to using its ALU to perform operations, a CPU is also responsible for reading the next instruction from memory, reading data specified in arguments from memory, and writing results to memory.

Software Used
The project will be designed in Xilinx 12.3 using VHDL (Very High Speed Integrated Circuits Hardware Description Language).

Block Diagram

Description
As it is clear from the block diagram, the basic idea is - to fetch an instruction from the RAM and then to decode it to do the corresponding operation by accessing the suitable registers, memory locations and finally writing the result back to the register/memory location. The 16 basic operation implemented are: 1) ADD : It adds two registers. It can also add immediate to a register. 2) ADDI : It adds immediate to the register. 3) SUB : It subtracts two registers. It can also subtract immediate to a register. 4) SUBI : It subtracts immediate from the register. 5) MOVE : It would move value from one register to another. 6) MOVEI : It would move a constant value (immediate) to the register. 7) IN : This instruction reads the data at the specified I/O port and copies it into the accumulator. 8) OUT : This instruction reads the data from the accumulator and copies it into the specified I/O port. 9)JUMP : It would jump to the specified location. 10) CALL : This would call a given function specified in the call. 11) RET : This returns the control to the main program. The above microprocessor is implemented through a finite state machine. The states usedc would be: a) Reset : The finite machine starts executing from the reset state when the reset signal is asserted. On reset the finite state machine initializes all its working variables and control signals. The variables include : PC program counter IR instruction register State the state variable In addition, the content of the memory, i.e. the program for computer to execute is also loaded at this time.

b) Fetch : In the fetch state, the memory content of the location pointed to by the PC is loaded into the instruction register. The PC is then incremented by one to prepare it for fetching the next instruction. If the fetched instruction is a jump instruction, then the PC will be changed accordingly during the execution phase. c) Decode : The content that is stored in the instruction register is decoded according to the encoding that is assigned to the instructions. This is accomplished in VHDL using a CASE statement with the switch condition being the opcode. From the different cases, the state that is responsible for executing the corresponding instruction is assigned to the next state variable. As a result, the instruction will be executed starting at the beginning of the next clock cycle when the FSM enters this new state. d) Execute : The execution state simply sets up the control word, which asserts the appropriate control signals for the datapath to carry out the necessary operations for executing a particular instruction. Each instruction, therefore, has its own execute state. For all the jump instructions, no actions need to be taken by the datapath. It simply determines whether to perform the jump or not depending on the particular jump instruction and by checking on the zero and positive flags. If a jump is needed then the target address is fetched from program memory and then assigned to the PC. At the end of the execute state, the FSM goes back to the fetch state and the cycle repeats for the next instruction.

VHDL Code
-- 8-bit Opcode Processor Design. LIBRARY ieee;

USE ieee.std_logic_1164.all; USE IEEE.std_logic_unsigned.all; -- needed for CONV_INTEGER() ENTITY ctrl IS PORT ( inport : IN STD_LOGIC_VECTOR (7 downto 0); outport : out STD_LOGIC_VECTOR (7 downto 0); clk_ctrl : IN std_logic; rst_ctrl : IN std_logic ); END ctrl; ARCHITECTURE fsm OF ctrl IS TYPE state_type IS (S1,S2,S3,S4,S5,S6,S7,S8,S9,S10,S11,S12,S13,s14); SIGNAL state: state_type; --type ram_type is array (0 to 255) of std_logic_vector(7 downto 0); --signal rm : ram_type:=(others=> (others=>'0')); type memory is array (0 to 255) of std_logic_vector (15 downto 0); signal ram : memory:=(others=> (others=>'0')); type reg is array (0 to 3) of std_logic_vector (7 downto 0); signal r_file : reg:=(others=> (others=>'0')); signal ir : std_logic_vector ( 15 downto 0) := "0000000000000000"; signal pc: std_logic_vector ( 7 downto 0) := "00000000"; signal sp: std_logic_vector ( 7 downto 0) := "11111111"; signal temp: std_logic_vector (3 downto 0) := "0000"; -- Instructions -- memory operand instructions

BEGIN ram(0) <= "0001100000000010"; -- MOVEI ram(1) <= "0000011000000000"; -- MOV -ram(2) <= "1001000000000100"; -- CALL ram(3) <= "0111000000000100"; -- JUMP --ram(3) <= "0011010000100110"; -- ADDI --ram(3) <= "1111100000000010"; -- END ram(4) <= "0011010000100110"; -- ADDI ram(5) <= "0100011000000000"; -- SUB

ram(6) <= "1010000000000000"; -- RETURN ram(7) <= "0010110100000000"; -- ADD --ram(8) <= "1000000000000000"; -- IN --ram(9) <= "0110000000000000"; -- OUT --ram(8) <= "0100111000000000"; -- SUB ram(8) <= "1111100000000010"; -- END --ram(8) <= "0010110100000000"; -- ADD PROCESS (rst_ctrl,clk_ctrl) BEGIN IF (rst_ctrl='1') THEN pc <= "00000000"; state <= S1; -- load program memory with statements -- COUNTER PROGRAM

-- load data memory with constants -ELSIF (clk_ctrl'event and clk_ctrl = '1') THEN CASE state IS WHEN S1 => -- fetch instruction ir <= ram(conv_integer(pc)); state <= S2; WHEN S2 => -- decode instruction case ir(15 downto 12) is WHEN "0000" => state <= S3; -- MOVE WHEN "0001" => state <= S4; -- MOVEI WHEN "0010" => state <= S5; -- ADD WHEN "0011" => state <= S6; -- ADDI WHEN "0100" => state <= S7; -- SUB WHEN "0101" => state <= S8; -- SUBI WHEN "0110" => state <= S9; -- OUT WHEN "0111" => state <= S10; -- JUMP WHEN "1000" => state <= S11; -- IN WHEN "1001" => state <= S12; -- CALL WHEN "1010" => state <= S13; -- RETURN WHEN "1111" => state <= S14; -- END WHEN others => state <= S14; END CASE;

WHEN S3 => -- MOVE r_file(conv_integer(ir(11 downto 10))) <= r_file(conv_integer(ir(9 downto 8))) ; pc <= pc + 1; state <= S1; WHEN S4 => -- MOVEI r_file(conv_integer(ir(11 downto 10))) <= ir(7 downto 0); pc <= pc + 1; state <= S1; WHEN S5 => -- ADD r_file(conv_integer(ir(11 downto r_file(conv_integer(ir(9 downto 8))) ; pc <= pc + 1; state <= S1; 10))) <= r_file(conv_integer(ir(11 downto 10))) +

WHEN S6 => -- ADDI r_file(conv_integer(ir(11 downto 10))) <= r_file(conv_integer(ir(11 downto 10))) + ir(7 downto 0) ; pc <= pc + 1; state <= S1; WHEN S7 => -- SUB r_file(conv_integer(ir(11 downto r_file(conv_integer(ir(9 downto 8))) ; pc <= pc + 1; state <= S1; 10))) <= r_file(conv_integer(ir(11 downto 10))) -

WHEN S8 => -- SUBI r_file(conv_integer(ir(11 downto 10))) <= r_file(conv_integer(ir(11 downto 10))) - ir(7 downto 0) ; pc <= pc + 1; state <= S1; WHEN S9 => -- OUT outport <= r_file(conv_integer(ir(11 downto 10))) ; pc <= pc + 1; state <= S1; WHEN S10 => -- JUMP pc <= pc + ir(7 downto 0) ; state <= S1; WHEN S11 => -- IN r_file(conv_integer(ir(11 downto 10))) <= inport ; PC <= PC + 1; state <= S1; WHEN S12 => -- CALL

sp <= pc +1 ; pc <= ir(7 downto 0) ; state <= S1; WHEN S13 => -- RETURN pc <= sp ; state <= S1; WHEN S14 => -- end pc <= "11111111" ; state <= S14; when others => state <= S14; END CASE; END IF; END PROCESS; END fsm; -- ----------------------------------------------------------- The inputs will be in DirectVHDL Software -- force clk_ctrl 0 0, 1 100 -repeat 200 -- force rst_ctrl 1 0, 0 300 -- run 1000 ns -- Now you can press the simulate big arrow to see results. -- ----------------------------------------------------------

Screen shots of Simulations

You might also like