A 4-bit CPU is implemented using TTL components and was based on micro-programmed control. The system implements 12 basic arithmetic, logic and control instructions with a 4 bit data bus and an 8 bit address bus. This project was done during 2nd year at IIT Guwahati
1. DEPARTMENT OF COMPUTER SCIENCE AND
ENGINEERING
IIT Guwahati
CS 223: HARDWARE LABORATORY
LAB REPORT
DESIGN AND FABRICATION OF
4 BIT PROCESSOR
Group 16
Name Roll No
Priyatham Bollimpalli 10010148
Pydi Prasanna Sai Kamanuru 10010150
Revanth Bhattaram 10010153
Sunku Vinesh Reddy 10010167
Under the guidance of
Dr. S. B. Nair & Dr. Hemangee Kapoor
Date of Completion: 11th
March 2012
Date of Submission: 13th
March 2012
2. BASIC DESIGN CHARACTERISTICS
Single Bus Architecture
4 bit data bus
8 bit address bus
Micro-programmed Control Unit
Micro-instruction length:16 bits
12 types of instructions
Storage Capacity: 256 X 4 bits RAM
2 General Purpose Registers (B and C)
Recursion Depth:8
The CPU architecture is Micro-programmed control based with of 12 instructions
in the EPROM. Each instruction is identified by a unique opcode which is fetched
from the RAM throughout the execution of the program. There are two general
purpose registers and 2 registers A (Accumulator) and temp register which are not
manipulated by the assembly programmer. The ALU is of 4 bits and the stack is of
4 bits.
The specific details of Hardware Organization and Control Unit are as follows:
3. COMPONENTS USED
Following components are used for the CPU Design
S.No Chip No. Description Number
1. 4-Input Dip Switch 1
2. 8-Input Dip Switch 1
3. 7-Segment Display Unit 3
4. 74181 4 bit ALU 1
5. 2732 EPROM 2
6. 2114 1K x 4 bit RAM 1
7. 7447 BCD 7 Segment Decoder 3
8. 74161 4-Bit Binary Counter with Synchronous load
and Asynchronous Clear
2
9. 7495 4 bit PIPO register 5
10. 74194 4 bit register with clear 3
11. 74191 4-Bit Bidirectional Counter 1
12. 74157 Quad 2 to 1 MUX 6
13. 74153 Dual 4 to 1 MUX 3
14. 74126 Quad Tristate Buffers 14
15. 74367 Hex Tristate Buffers 4
16. 74163 4-Bit Binary Counter with Synchronous load
and Synchronous Clear
1
17. 74154 4 to 16 Decoder 2
18. 7404 Hex Inverter 4
19. 7408 Quad 2 input AND 1
20. 7432 Quad 2 input OR 1
The use of each individual component was discussed below.
Before the discussion, first we note that for the entire processor there is only one
main clock. For those components which require positive edge triggering, this
clock is given but the main clock is inverted with the help of HEX inverter and is
given to the components which require negative edge triggering.
For making the contents of the register (R, say) retain its value, the below design
is implemented for one bit.
Figure : Input and Output gating for 1 Register bit
4. DIP SWITCHES:
Initially the program must be loaded into the RAM. So we should write into the
RAM by giving appropriate bits. The DIP switches serve this purpose by making
the user to give external input and to write into the RAM as and when required by
disabling the internal address and data bus.
BCD 7 SEGMENT DECODER (7447):
This takes 4 binary inputs and the outputs a,b,c,d,e,f,g,h are fed into the 7-
segment display so that the user can see the output in the 7-segment display as
decimal number.
Three chips are required as for 4 bits one chip is required. So for the data bus 1 is
required and for the address bus 2 are required.
7-SEGEMENT DISPLAY UNIT:
Asevensegmentdisplay,asitsnameindicates,iscomposedofsevenelements.Individuallyon
oroff,theycanbecombinedtoproducesimplifiedrepresentationsoftheArabicnumerals
5. 4-BIT ALU (74181):
The ALU requires 6 bits for controlling the operations – S0,S1,S2,S3,Cn,M.We are
using ALU for the operations ADD, SUB, AND, OR, NOT. So we are reducing the
number of control signals by using the combinational logic to get 4 control
signals. One of the input comes from the A register(Accumulator) and the other
comes from the data bus. The result is stored in the temp register. ALU is
asynchronous in nature.
EPROM (2732):
It is 4KB memory device. Since we need 16 microinstructions and each EPROM has
only 8 outputs we require 2 such IC’s. All the micro instructions for each of the 12
instructions are programmed into EPROM after initially erasing it in UV light.
6. RAM (2114):
The memory is divided into 2 parts –
1. code/data segment
2. Stack segment
If the upper four bits are 1111 then we are accessing the stack segment of the
memory. The lower 4-bits are given by SPL bidirectional counter depending on the
control signals.
And if the 4-upper bits are other than ‘1111’then we are accessing the data
segment. All the data is stored concerned with the operations of the CPU is kept
at these locations. Since the size of stack we are using is 4 bits the bottom part of
the RAM with higher nibble as 15H is used for stack.
Size of the RAM which we are using is 1K x 4 bits.
We require only 256 K memory locations. So, two of the address bits are
grounded. Now the size of our address bus is 8 from which the RAM takes its input
address. It takes the 4-bit data to write in a particular location from the data bus.
RAM gives the data of a particular location given in address bus as output to the
data bus.
For entering a program into RAM we use the DIP switches.
4-BIT COUNTER WITH ASYNCHRONOUS CLEAR (74161):
We are using this component for the Program counter.2 IC’s are used – one for
higher nibble and the other for lower nibble. (PCH and PCL)
Both registers (PCH & PCL) take their inputs from data bus when their
synchronous load is enabled. They have asynchronous clear signals.
They should be cleared manually whenever required. They have positive edge
triggered clock. ‘P enable’ and ‘T enable’ are two signals which are to be high in
order to make the registers count.
Whenever a PC++ signal comes PCL should be incremented and that of PCH
depends on PCL. These counters have carry output which is ‘1’ when ‘T enable’
signal is present and the count in that particular counter is ‘1111’. PCH should be
7. incremented depending on the count control signal and carry output of PCL. So,
we gave the higher bit as clock to PCH.
4-BIT COUNTER WITH SYNCHRONOUS CLEAR (74163):
We are using this for μ-PC (The program counter for the micro programmed
control).We are using this so that the counter does not immediately resets to zero
if the clear signal is given to it. This is required so that the last instruction in the
microinstruction will be executed and then the counter will be cleared.
4 BIT PIPO REGISTER (7495):
We are using 5 IC’s – one for each of the registers B, C, Temp and 2 for MAR
(MARH and MARL – two nibbles). This register takes its input from the data bus. Its
outputs are via the tri state buffer.
4 BIT REGISTER WITH CLEAR (74194):
We are using 3 IC’s – one for A register, one for opcode register and one for
operand register. We need this because initially before execution these registers
need to be cleared. This register has a positive edge triggered clock.
8. 4-BIT BIDIRECTIONAL COUNTER (74191):
We are using this for the Stack. We are assuming that our stack segment can have
a maximum of 16 locations and we are fixing the stack segment address higher 4
bits to ‘1111’. So, we are using only one bidirectional counter SPL.
SPL has the control signals connected to count enable and up/down signals
accordingly which it will up count, down count, do nothing.
Initially SPL should be reset manually by giving inputs ‘0000’ and enabling the load
signal. The output of SPL is connected to the Address bus via tri-state buffer. The
higher 4-bits are also connected to address bus through a tri-state buffer. This has
positive edge triggered clock.
TRISTATE BUFFERS (74126 and 74367):
As given in the Figure-1, the tristates are required to control the operation out of
a component.
74126:
This IC has four tri state buffers.
We used them as follows:
5 – Bout,Cout,Tempout,MARout
3 – for DIP connections to the address and data bus
2 – for the program counter(PC)
1 – for StackHout signal
9. 74367:
This IC has six tri state buffers in it. The function of tri state buffer is to just make
the input appear as output if the strobe controlling it is enabled. 4 tri-state
buffers are controlled by 1 strobe and 2 tri state buffers are controlled by another
strobe. So, the control signals are connected to the strobes of these buffers to
enable particular output into data bus and address bus.
We used them for PCLout,PCHout,MARLout,MARHout connections to the databus
and StackLout connection to the address bus.
QUAD 2 to 1 MUX (74157):
As given in the Figure-1, the muxes are required for retaining the value.
So we used 6 of them for Ain,Bin,Cin,Tempin,MARLin,MARHin
DUAL 4 to 2 MUX (74153):
They are used to implement the combinational circuit which was used in the
design of the CPU.We need 2 muxes for S1.S2 logic and another for the reduction
10. in the 2 bits of the ALU control signals(The logic and their details are explained
later)
4 to 16 DECODER (74154):
Since there are many control signals we group them into 2 categories such that 2
signals can never occur together. For example Ain and Bin can never occur
together as ours is single bus architecture.
Hence we are using 2 decoders – one for the in signals and the other for out
signals. The output from the EPROM are fed into these decodes and appropriately
we get the required control signals to perform the required instructions.
HEX INVERTER (7404):
The outputs of the decoders are active low. But we need high signals for
activating the appropriate signals in the components. Hence we will invert the
output obtained from the decoder. For this 3 IC’s are used. Another IC is used for
inverting the clock so that then it would be fed into the components which
require negative edge triggering.
11. QUAD 2 input AND and OR (7408 and 7432):
7404:
7432
:
We require the AND gate for the combinatorial circuit for S1, S2 signals.
We are using OR gate for using the Stack out signal which is in both Decoder-1 and
Decoder-2.So to use if either of the signal is high, we are taking OR of the both.
12.
13. The Architecture has been explained in the Component Description which gives a
more elaborate idea after looking at the Architecture Diagram.
Explanation Of Two Control Signals S1 And S2 Which help in
Operand Decoding
We have added two muxes and an operand register to take control of the last two
bits in the Decoder1 and Decoder2 to decode the operand and perform the
operations.
DECODER1
------------------
The Last two bits of the decoder1 coming from the EEPROM are connected to two
4 X 1 Muxes and the then 4bits of the operand register are connected in the
fashion shown in the Diagram.
The First two bits are respectively anded with s1 and act as Select lines for the
two 4 X 1 Muxes.
Regular Case (s1 = 0 or s1 = D)
-------------------------------------------
When s1 is zero, the regular two bits are shown
Special Case (s1 = 1 or s1 = A)
-------------------------------------------
When s1 is one, then depending on the last two bits of the EEPROM either the
first two bits of the operand register or the last two bits of the operand register
are output or 00 if they the two bits are 00.
Note-
--------
If the two bits output are 01 then Bin is activated.
If the two bits output are 10 then Cin is activated.
Decoder2
--------------
Everything is the same about the two muxes used for this as well but,
Note-
-------
If the two bits output are 01 then Bout is activated
If the two bits output are 10 then Cout is activated
Note - The format of the operand is further discussed in the report which helps us
understand thoroughly about s1 and s2 meanwhile keep a note on the notes given
above.
Take a look at the Two Mux Diagrams for the above explanation.
15. The outputs from the EEPROM are fed into the decoders to get the appropriate
control signals.
The control signals are as follows for the two decoders:
Decoder1 Decoder2
0000 ( Stack Decrement / None ) 0000 (None)
0001 ( Bin ) 0001 (Bout)
0010 ( Cin ) 0010 (Cout)
0011 ( Ain ) 0011 (TEMPout)
0100 ( TEMPin ) 0101 (PCLout)
0101 (MARLin) 0111 (PCHout)
0110 (MARHin) 1000 (Pcounter)
0111 (OPCODEin) 1001 (PCout)
1000 (OPERANDin) 1011 (StackEN)
1001 (PCLin) 1100 (Stack Out)
1010 (PCHin) 1101 (MARLout)
1011 (MARout) 1110 (MARHout)
1100 (StackUp)
1101 (StackOut)
The control signals for the ALU are given as follows:
16. So finally for the control signals are obtained as given below
17. Control Signals which correspond to 16bit output of
the 2 EEPROMS
Decoder1 | Decoder2 | ALU Control | CS R/W( Ram Control Signals) | S1 S2
S1 , S2 When Put to D means Deactivated And A means Activated.
Micro Instructions For Operations
MicroInstructions Of Operations In Detail
A) START Opcode – 0000
Fetch Opcode of the first instruction which triggers the sequence of instructions.
1. Opcode in | PC out | ALU – None | Ram Read | D D
0111 | 1001 | 0000 | 01 | 00
B) HALT/STOP Opcode – 1100
1. Do nothing, u pc keeps on cycling down throughout the time doing nothing.
0000 | 0000 | 0000 | 01 | 00
The next 15 micro instructions are the same as well.
C) LOAD Opcode – 0010
Program Structure for load
0010 (load opcode)
R00 (Register Operand tells which register to be loaded into )
//0100 represents register B
//1000 represents register C
XXXX (Represents Binary value that has to be loaded into the register)
Equivalent Assembly Code - load R00 XXXX
Micro Instructions
1. Pcincr
None | PcCounter/Incr | None | Ram Read | D D
0000| 1000 | 0000 | 01 | 00
2. Fetch Operand and feed it to Operand Register
Operand in | Pcout | None | Ram Read | D D
1000 | 1001 | 0000 | 01 | 00
18. 3. PcIncr
None | PcCounter/Incr | None | Ram Read | D D
0000| 1000 | 0000 | 01 | 00
4. Put value in Apt Register as per operand.
Opreg1 in | Pcout | None | Ram Read | A D
0001 | 1001 | 0000 | 01 | 10
5. PcIncr
None | PcCounter/Incr | None | Ram Read | D D
0000| 1000 | 0000 | 01 | 00
6. Fetch Opcode for Next Instruction And Run it
Opcode in | Pcout | None | Ram Read | D D
0111 | 1001 | 0000 | 01 | 00
D)STORE Opcode – 0011
Instruction Structure
0111 (Store Opcode )
XXXX (Lower Nibble Address in binary of the location to store)
XXXX (Higher Nibble Address in binary of the location to store)
R00 ( Tells The register to store )
//0100 represents register B
//1000 represents register C
Assembly Equivalent code – Store [XXXXH], R00
1. PcIncr
None | PcCounter/Incr | None | Ram Read | D D
0000| 1000 | 0000 | 01 | 00
2. Fetch Lower Nibble Address Into MARL
MARLin | Pcout | None | Ram Read | DD
0101 | 1001 | 0000 | 01 | 00
3. PcIncr
None | PcCounter/Incr | None | Ram Read | D D
0000| 1000 | 0000 | 01 | 00
4. Fecth Higher Nibble Address Into MARH
MARHin | Pcout | None | Ram Read | DD
0110 | 1001 | 0000 | 01 | 00
5. PcIncr
None | PcCounter/Incr | None | Ram Read | D D
0000| 1000 | 0000 | 01 | 00
19. 6. Fetch Operand and feed it to Operand Register.
Operand in | Pcout | None | Ram Read | D D
1000 | 1001 | 0000 | 01 | 00
7. Store Value in RAM
MARout | Opreg1out | None | Ram Write | D A
1011 | 0001 | 0000 | 00 | 01
8. PcIncr
None | PcCounter/Incr | None | Ram Read | D D
0000| 1000 | 0000 | 01 | 00
9. Fetch Opcode for Next Instruction And Run it
Opcode in | Pcout | None | Ram Read | D D
0111 | 1001 | 0000 | 01 | 00
E) ADD Opcode – 0001
Instruction Structure
0001 ( Opcode )
R1R2 (Represents Which two registers to Add )
//0110 (Add B,C )
///1001 (Add C,B )
Assembly Language Equivalent – Add R1R2
Micro Instructions
1. PcIncr
None | PcCounter/Incr | None | Ram Read | D D
0000| 1000 | 0000 | 01 | 00
2. Fetch Operand From RAM
Operandin | Pcout | None | Ram Read | DD
1000 | 1001 | 0000 | 01 | 00
3. Load Register1 Value into Accumulator
Ain | Opreg1out | None | Ram Read | DA
0011 | 0001 | 0000 | 01 | 01
4. Put Register2 Value in the Data bus and Add and Store it in Temp
Tempin | Opreg2 out | ADD | Ram read | DA
0100 | 0010 | 1001 | 01 | 01
5. Store Value in Reg1 by putting temp value on databus
Opreg1in | Tempout | None | Ram read | AD
0001 | 0011 | 0000 | 01 | 10
6. PcIncr
None | PcCounter/Incr | None | Ram Read | D D
20. 0000| 1000 | 0000 | 01 | 00
7. Fetch Opcode for Next Instruction And Run it
Opcode in | Pcout | None | Ram Read | D D
0111 | 1001 | 0000 | 01 | 00
Note-
All the Operations Following Operations Follow the Same Micro Instrcutions
Except the 4th
one where The ALU Control Signals are altered.
Subtract
Opcode – 0100 ALU Control – 0110
And
Opcode – 0101 ALU Control – 1011
Or
Opcode – 0110 ALU Control – 1110
F) NOT Opcode – 0111
Instruction Structure
0111 ( Opcode )
R00 (Register Whose value should be complemented )
//0100 (Represents B )
//1000 (Represents C )
1. PcIncr
None | PcCounter/Incr | None | Ram Read | D D
0000| 1000 | 0000 | 01 | 00
2. Fetch Operand From RAM
Operandin | Pcout | None | Ram Read | DD
1000 | 1001 | 0000 | 01 | 00
3. Put Register1 Value in the Data bus and NOT and Store it in Temp
Tempin | Opreg1 out | NOT | Ram read | DA
0100 | 0001 | 0000 | 01 | 01
4. Store Value in Reg1 by putting temp value on databus.
Opreg1in | Tempout | None | Ram read | AD
0001 | 0011 | 0000 | 01 | 10
5. PcIncr
None | PcCounter/Incr | None | Ram Read | D D
0000| 1000 | 0000 | 01 | 00
6. Fetch Opcode for Next Instruction And Run it
Opcode in | Pcout | None | Ram Read | D D
21. 0111 | 1001 | 0000 | 01 | 00
G) MOVE Opcode – 1011
Instruction Structure
1011 (Opcode )
R1R2
//0110 Moves Value of C to B
//1001 Moves Value of B to C
Equivalent Assembly Code- MOVE R1,R2
1. PcIncr
None | PcCounter/Incr | None | Ram Read | D D
0000| 1000 | 0000 | 01 | 00
2. Fetch Operand From RAM
Operandin | Pcout | None | Ram Read | DD
1000 | 1001 | 0000 | 01 | 00
3. Put R2 Value into R1
Opreg1in | Opreg2out | None | Ram Read | AA
0001 | 0010 | 0000 | 01 | 11
4. PcIncr
None | PcCounter/Incr | None | Ram Read | D D
0000| 1000 | 0000 | 01 | 00
5. Fetch Opcode for Next Instruction And Run it
Opcode in | Pcout | None | Ram Read | D D
0111 | 1001 | 0000 | 01 | 00
H) JUMP Opcode ( 1000 )
Instruction Structure
1000 (Opcode )
XXXX (Lower Nibble Of the 8-Bit Address we have to jump in binary )
XXXX (Higher Nibble of the 8-Bit Address we have to jump in binary )
Assembly equivalent code- JMP XXH
Micro Instructions
1. PcIncr
None | PcCounter/Incr | None | Ram Read | D D
0000| 1000 | 0000 | 01 | 00
2. Store Lower Nibble in MARL
MARLin | Pcout | None | Ram Read | DD
22. 0101 | 1001 | 0000 | 01 | 00
3. PcIncr
None | PcCounter/Incr | None | Ram Read | D D
0000| 1000 | 0000 | 01 | 00
4. Store Higher Nibble in MARH
MARHin | Pcout | None | Ram Read | DD
0110 | 1001 | 0000 | 01 | 00
5. Transfer Values of MAR into PC in two clock cycles
i)PCLin | MARLout | None | Ram Read | DD
1001 | 1101 | 0000 | 01 | 00
ii) PCHin | MARHout | None | Ram Read | DD
1010 | 1110 | 0000 | 01 | 00
6. PC Value being loaded , Fetch Opcode for Next Instruction And Run it
Opcode in | Pcout | None | Ram Read | D D
0111 | 1001 | 0000 | 01 | 00
I) CALL
Instruction Structure
1001 (Call Opcode )
XXXX (Lower Nibble Address in binary we are calling)
XXXX (Higher Nibble Address in binary we are calling)
Store Register Values into Stack
1) Stackout | Bout | None | Ram Write | DD
1101 | 0001 | 0000 | 00 | 00
2) Stack Dec | Stack Enable | None | Ram Read | DD
0000 | 1011 | 0000 | 01 | 00
3) Stackout | Cout | None | Ram Write | DD
1101 | 0010 | 0000 | 00 | 00
4) Stack Dec | Stack Enable | None | Ram Read | DD
0000 | 1011 | 0000 | 01 | 00
5) PcIncr
None | PcCounter/Incr | None | Ram Read | D D
0000| 1000 | 0000 | 01 | 00
6) Lower Nibble Address to MARL
MARLin | Pcout | None | Ram Read | DD
0101 | 1001 | 0000 | 01 | 00
7) PcIncr
None | PcCounter/Incr | None | Ram Read | D D
0000| 1000 | 0000 | 01 | 00
25. MERITS
1. Custom Design
2. Micro programmed Architecture allows great flexibility in the design. The
instructions can be easily changed by just re-writing the Microinstruction codes
in the EPROM.
3. This architecture has depth 8 multiple call support (length of stack segment:
16 words)
4. Greater flexibility and faster implementation of machine code. Rather than
using accumulator based instructions, direct addressing is used. Using little
combinational logic(S1,S2 circuit) we minimized the microinstructions. For
example Add B,C and Add C,B have the same set of microinstructions even
though they are different.(In the former the result is stored in B while in the
later it is stored in C)
5. Flexibility to increase the instruction set
Current implementation of Call is as Follows
We would put all the contents of the system registers and Program Counter into
the Stack and call the address given and return when return is encountered.
Issues Faced – We won't be able to implement nested calls and the cost of
implementation for a single call as well is expensive for a single call as well.
Scope for Improvement
1. We can add an instruction that would help the programmer load the initial value
into the Stack Pointer.
2. We can Also Add two instructions such as Push and Pop flexibly that would help
the programmer take care of the system registers while he is in nested or
independent calls by taking control over the stack.