0% found this document useful (0 votes)
6 views29 pages

Comp Arc Group (4) Report

computer Architecture

Uploaded by

blen.girma
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views29 pages

Comp Arc Group (4) Report

computer Architecture

Uploaded by

blen.girma
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 29

College of Electrical and Mechanical Engineering

Department of Electrical and Computer Engineering


Course: Computer Architecture and Organization

Group Members:

1. Eleni Samson ETS0515/14

2. Eyerusalem Gahaw ETS0575/14

3. Etsubdink Dereje ETS0568/14

4. Elsabeth Baye ETS0524/14

5. Blen Girma ETS0397/14

6. Meklit Tilahun ETS/0822/13

7. Eyerusalem Fissha ETS0576/14

Submission Date: January 2, 2025


Computer Architecture and Organization

Table of Contents
Part -1: LMC Programming

1.1) Largest of the Three inputs …………………………………………………………….3


1.11) Flow Chart……………………………………………………………………………4
1.12) Assembly LMC Code…………………………………………………………………4
1.2) Prime numbers………………………………………………………………………….5
1.21) Assembly LMC Code…...……………………………………………………………5
1.22) Explanation…………………………………….…………………………………….6
1.3) Factorial………………………………………………………………………………...7
1.31) Assembly LMC Code…...……………………………………………………………7
1.32) Explanation……………………………………..………………..……………….….8
Part-2: Simulating Cache Mapping, Control Unit and Pipelining

2.1) Cache Mapping Techniques…………………………………………………………….9


2.11) Direct Mapping……………………………………………………………………11
2.12) Associative Mapping………………………………………………………………12
2.13) Set-Associative Mapping………………………………………………………….14
2.2) Microprogrammed Control Unit Implementation………………………………….…16
2.21) Vertical Implementation…………………………………………………………….22
2.22) Horizontal Implementation…………………………………………………………24
2.3) Instruction Pipelining…………………………………………………………………25

2
Computer Architecture and Organization

Part 1: Report on LMC Programming

The following table refers to a memory address in the RAM. The online LMC simulator has 100
different memory addresses in the RAM ranging from 00 to 99.
Mnemonic + Name Description OP code
INP(INPUT) Gets input from user and stores it in the accumulator 901
OUT(OUTPUT) Output the value stored in the accumulator 902
LDA(LOAD) Load the accumulator with the contents of the memory 5xx
address given
STA(STORE) Store the value in the accumulator in the memory 3xx
address given
ADD Add the contents of the memory address to the 1xx
accumulator
SUB(SUBTRACT) Subtract the contents of the memory address from the 2xx
accumulator
BRP (BRANCH IF Jump to the address given if the accumulator is +ve 8xx
POSITIVE)
BRZ (BRANCH IF Jump to the address given if the accumulator is 0 7xx
ZERO)
BRA (BRANCH Jump to the address given 6xx
ALWAYS)
HLT(HALT) Stop the code 000
DAT (DATA Used to associate a label to a free memory address
LOCATION)

Q #1) Write a program on LMC that will accept three numbers and outputs the
largest of the three numbers.
Below, we will create a computer program using LMC that takes three inputs and outputs the largest
of the three given inputs.
The following flowchart describes the steps we followed to implement the LMC program for
finding out which one is the largest number out of the three inputs.

3
Computer Architecture and Organization

Input A

Input B

Input C

False True
B is larger C is larger
(C-B) > 0

(B-A) > 0 (C-A) > 0

False True False True

A is the largest B is the largest A is the largest C is the largest

The LMC program below compares three of the given inputs and outputs the largest of all.

#Input
INP
STA A
INP
STA B
INP
STA C
#Logic
SUB B
BRP CBIG
LDA B
SUB A
BRP BL
BR AL
CBIG: LDA C
SUB A

4
Computer Architecture and Organization

BRP CL
BR AL
#Output
AL: LDA A
OUT
HLT
BL: LDA B
OUT
HLT
CL: LDA C
OUT
HLT
#Data
A: DAT 0
B: DAT 0
C: DAT 0

Q #2) Write a program on LMC to list the prime numbers between 0 and an
input number.
INP
STA num1
INP
STA num2
LDA num1
SUB num2
BRP positive
LDA num2
STA temp
LDA num1
STA num2
LDA temp
STA num1
positive LDA num1
SUB one
BRZ end
LDA num1
BRZ loop
STA div

5
Computer Architecture and Organization

LDA num1
SUB div
LDA div
SUB one
BRZ not_prime
LDA num1
SUB div
BRP loop
Not prime LDA num1
SUB one
STA num1
BRA positive
loop LDA num2
SUB one
STA num2
BRA positive
end HLT
num1 DAT 0
num2 DAT 0
temp DAT 0
div DAT 0
one DAT 1

Here is a quick explanation on how the program works:

1. The program prompts the user to input two numbers, which are stored in memory locations as
num1 and num2, in our case we can set either of the two to be 0.

2. The program then checks which number is larger, and if necessary, swaps their values so that
num1 is the smaller number and num2 is the larger number.

3. The program then enters a loop that starts at num1 and ends at num2. For each number in this
range, the program checks if it is a prime number by dividing it by all numbers between 2 and itself
- 1. If the number is prime, it is outputted to the console.

6
Computer Architecture and Organization

4. The program ends when all numbers between num1 and num2 have been checked.

Note that the program uses the LMC instruction BRP, which branches to the specified address if the
accumulator is positive. This is used to check if num1 is less than or greater than num2. If num1 is
less than num2, the program branches to the label positive. If num1 is greater than num2, the
program proceeds directly to the label positive.

Q# 3) Write a program on LMC to calculate the factorial of an input number.

The following LMC program calculates the factorial of a given number provided by the user.

#Input the number


INP
STA num
# Initialize the factorial variable
LDA num
STA factorial
# Initialize the counter variable
LDA num
STA counter
# Loop to calculate the factorial
LOOP LDA counter
SUB ONE
STA counter
BRZ END
LDA factorial
MUL counter
STA factorial
BRA LOOP
# Output the factorial
LDA factorial
OUT
HLT
num DAT
factorial DAT

7
Computer Architecture and Organization

counter DAT
ONE DAT 1
Here is a quick explanation on how the program works:
1. The code starts by inputting the number and storing it in the memory location num.
2. The factorial variable is initialized with the value of num.
3. The counter variable is also initialized with the value of num.
4. The loop begins with the LOOP label. It subtracts 1 from the counter and checks if it is zero.
If it is zero, the loop ends and the program jumps to the END label.
5. Inside the loop, the factorial variable is multiplied by the counter and the result is stored
back in the factorial variable.
6. The program then jumps back to the LOOP label to repeat the process until
the counter becomes zero.
7. After the loop ends, the program outputs the value of the factorial variable using
the OUT instruction.
8. Finally, the program halts using the HLT instruction.

8
Computer Architecture and Organization

PART II: Simulating Cache Mapping, Control Unit, Pipelining


1.Report on Cache Mapping Simulation
The objectives of this project are:
1. To understand and implement three cache mapping techniques:
• Direct Mapping
• Associative Mapping
• Set-Associative Mapping
2. To simulate cache hits and misses for randomly generated memory block requests.
3. To implement and compare different cache replacement strategies:
• First-In-First-Out (FIFO)
• Random Replacement
4. To provide users with an interactive tool to visualize and experiment with cache operations.

Implementation Details
Programming Language
The program is written in Python due to its simplicity and readability, making it an ideal choice for
simulation projects.
Main Features
1. Direct Mapping:
• A simple mapping technique where each memory block maps to a specific cache line
using the formula:
Cache Index = Block Number % Cache Size
• If the cache line is occupied by a different block, it is overwritten.
2. Associative Mapping:
• Any memory block can be placed in any cache line.
• Replacement occurs when the cache is full, using user-selected strategies:
• FIFO: The oldest block is removed.
• Random: A random block is removed.
3. Set-Associative Mapping:
• Combines direct and associative mapping.
• Cache is divided into sets, and each set can hold a fixed number of blocks.
• Blocks map to a specific set using:
Set Index = Block Number % Number of Sets
• Replacement within a set uses user-selected strategies.

Key Functions
1. Cache Initialization:
• Direct Mapping: Initializes cache lines based on block numbers.
• Associative & Set-Associative Mapping: Initializes cache with sequential memory
blocks.

9
Computer Architecture and Organization

2. Replacement Policy:
• Provides a choice between FIFO and Random replacement strategies when the cache
is full.
3. Simulation:
• Randomly generates memory block requests.
• Determines if the requested block is in cache (hit) or needs to be loaded (miss).
• Updates cache content accordingly.

User Interaction
The program is interactive and provides:
1. Selection of cache mapping techniques.
2. Visualization of cache content after each operation.
3. Replacement strategy selection when the cache is full.

import random

class CacheMapping:
def __init__(self):
self.main_memory = [f"Word-{i}" for i in range(64)] # Simulating main memory
self.cache_size = 8 # Fixed cache size
self.cache = {} # Cache dictionary
self.mapping_type = None # Mapping type
self.replacement_policy = None # Replacement policy
self.associativity = 1 # Default associativity (1 for direct mapping)

def select_mapping_type(self):
print("\n=== Cache Mapping Options ===")
print("1. Direct Mapping")
print("2. Associative Mapping")
print("3. Set-Associative Mapping")
choice = int(input("Select the mapping type (1, 2, or 3): "))
if choice == 1:
self.mapping_type = "Direct"
elif choice == 2:
self.mapping_type = "Associative"
elif choice == 3:
self.mapping_type = "Set-Associative"
self.associativity = int(input("Enter the associativity (e.g., 2 for 2-way set): "))
else:
print("Invalid choice. Defaulting to Direct Mapping.")
self.mapping_type = "Direct"

if self.mapping_type != "Direct":
print("\n=== Replacement Policies ===")
print("1. LRU (Least Recently Used)")
print("2. FIFO (First In, First Out)")
policy_choice = int(input("Select the replacement policy (1 or 2): "))
if policy_choice == 1:
self.replacement_policy = "LRU"
elif policy_choice == 2:
self.replacement_policy = "FIFO"
else:
print("Invalid choice. Defaulting to LRU.")
self.replacement_policy = "LRU"

10
Computer Architecture and Organization

def generate_random_word(self):
return random.choice(self.main_memory)

def simulate_direct_mapping(self, word):


block_index = int(word.split("-")[1]) % self.cache_size
if block_index in self.cache and self.cache[block_index] == word:
print(f"Cache Hit: {word} found in cache slot {block_index}.")
else:
print(f"Cache Miss: {word} not found in slot {block_index}.")
self.cache[block_index] = word
print(f"Loading {word} into cache slot {block_index}.")

def simulate_associative_mapping(self, word):


if word in self.cache.values():
print(f"Cache Hit: {word} found in cache.")
if self.replacement_policy == "LRU":
# Reorder cache to reflect recent usage
self.cache = {k: v for k, v in sorted(self.cache.items(), key=lambda x: x[1] != word)}
else:
print(f"Cache Miss: {word} not found in cache.")
if len(self.cache) >= self.cache_size:
self.replace_cache_block(word)
else:
self.cache[len(self.cache)] = word
print(f"Loading {word} into cache.")

def simulate_set_associative_mapping(self, word):


set_index = int(word.split("-")[1]) % (self.cache_size // self.associativity)
cache_set = {k: v for k, v in self.cache.items() if k[0] == set_index}

if word in cache_set.values():
print(f"Cache Hit: {word} found in set {set_index}.")
else:
print(f"Cache Miss: {word} not found in set {set_index}.")
if len(cache_set) >= self.associativity:
self.replace_cache_block(word, set_index)
else:
self.cache[(set_index, len(cache_set))] = word
print(f"Loading {word} into set {set_index}.")

def replace_cache_block(self, word, set_index=None):


if self.replacement_policy == "LRU":
if self.mapping_type == "Associative":
evicted = next(iter(self.cache))
elif self.mapping_type == "Set-Associative":
evicted = next(k for k in self.cache if k[0] == set_index)
print(f"LRU Replacement: Evicting {self.cache[evicted]} from cache.")
del self.cache[evicted]
elif self.replacement_policy == "FIFO":
evicted = next(iter(self.cache))
print(f"FIFO Replacement: Evicting {self.cache[evicted]} from cache.")
del self.cache[evicted]

print(f"Loading {word} into cache.")


if self.mapping_type == "Set-Associative":
self.cache[(set_index, len(self.cache))] = word
else:
self.cache[len(self.cache)] = word

def display_cache(self):
print("\n=== Cache Content ===")

11
Computer Architecture and Organization

if not self.cache:
print("Cache is empty.")
else:
for slot, word in self.cache.items():
print(f"Slot {slot} -> {word}")

def run(self):
self.select_mapping_type()
for _ in range(5): # Simulate 5 random word requests
word = self.generate_random_word()
print(f"\nProcessor requests: {word}")
if self.mapping_type == "Direct":
self.simulate_direct_mapping(word)
elif self.mapping_type == "Associative":
self.simulate_associative_mapping(word)
elif self.mapping_type == "Set-Associative":
self.simulate_set_associative_mapping(word)
self.display_cache()

# Main Program
if __name__ == "__main__":
cache_mapping = CacheMapping()
cache_mapping.run()

Output
=== Cache Mapping Options ===
1. Direct Mapping
2. Associative Mapping
3. Set-Associative Mapping
Select the mapping type (1, 2, or 3): 1

Processor requests: Word-33


Cache Miss: Word-33 not found in slot 1.
Loading Word-33 into cache slot 1.

=== Cache Content ===


Slot 1 -> Word-33

Processor requests: Word-19


Cache Miss: Word-19 not found in slot 3.
Loading Word-19 into cache slot 3.

=== Cache Content ===


Slot 1 -> Word-33
Slot 3 -> Word-19

Processor requests: Word-29


Cache Miss: Word-29 not found in slot 5.
Loading Word-29 into cache slot 5.

=== Cache Content ===


Slot 1 -> Word-33

12
Computer Architecture and Organization

Slot 3 -> Word-19


Slot 5 -> Word-29

Processor requests: Word-21


Cache Miss: Word-21 not found in slot 5.
Loading Word-21 into cache slot 5.

=== Cache Content ===


Slot 1 -> Word-33
Slot 3 -> Word-19
Slot 5 -> Word-21

Cache Miss: Word-14 not found in slot 6.


Loading Word-14 into cache slot 6.

=== Cache Content ===


Slot 1 -> Word-33
Slot 3 -> Word-19
Slot 5 -> Word-21
Slot 6 -> Word-14
PS C:\Users\WinDows> &
C:/Users/WinDows/AppData/Local/Programs/Python/Python312/python.exe
"c:/Users/WinDows/Downloads/Scoob (2020) [1080p] [WEBRip] [5.1]
[YTS.MX]/OneDrive/Desktop/map.py"

=== Cache Mapping Options ===


1. Direct Mapping
2. Associative Mapping
3. Set-Associative Mapping
Select the mapping type (1, 2, or 3): 2

=== Replacement Policies ===


1. LRU (Least Recently Used)
2. FIFO (First In, First Out)
Select the replacement policy (1 or 2): 1

Processor requests: Word-62


Cache Miss: Word-62 not found in cache.
Loading Word-62 into cache.

=== Cache Content ===


Slot 0 -> Word-62

Processor requests: Word-12


Cache Miss: Word-12 not found in cache.
Loading Word-12 into cache.

=== Cache Content ===


Slot 0 -> Word-62

13
Computer Architecture and Organization

Slot 1 -> Word-12

Processor requests: Word-42


Cache Miss: Word-42 not found in cache.
Loading Word-42 into cache.

=== Cache Content ===


Slot 0 -> Word-62
Slot 1 -> Word-12
Slot 2 -> Word-42

Processor requests: Word-48


Cache Miss: Word-48 not found in cache.
Loading Word-48 into cache.

=== Cache Content ===


Slot 0 -> Word-62
Slot 1 -> Word-12
Slot 2 -> Word-42
Slot 3 -> Word-48

Processor requests: Word-57


Loading Word-57 into cache.

=== Cache Content ===


Slot 0 -> Word-62
Slot 1 -> Word-12
Slot 2 -> Word-42
Slot 3 -> Word-48
Slot 4 -> Word-57
PS C:\Users\WinDows> &
C:/Users/WinDows/AppData/Local/Programs/Python/Python312/python.exe
"c:/Users/WinDows/Downloads/Scoob (2020) [1080p] [WEBRip] [5.1]
[YTS.MX]/OneDrive/Desktop/map.py"

=== Cache Mapping Options ===


1. Direct Mapping
2. Associative Mapping
3. Set-Associative Mapping
Select the mapping type (1, 2, or 3): 3
Enter the associativity (e.g., 2 for 2-way set): 2

=== Replacement Policies ===


1. LRU (Least Recently Used)
2. FIFO (First In, First Out)
Select the replacement policy (1 or 2): 2

Processor requests: Word-20


Cache Miss: Word-20 not found in set 0.

14
Computer Architecture and Organization

Loading Word-20 into set 0.

=== Cache Content ===


Slot (0, 0) -> Word-20

Processor requests: Word-9


Cache Miss: Word-9 not found in set 1.
Loading Word-9 into set 1.

=== Cache Content ===


Slot (0, 0) -> Word-20
Slot (1, 0) -> Word-9

Processor requests: Word-47


Cache Miss: Word-47 not found in set 3.
Loading Word-47 into set 3.

=== Cache Content ===


Slot (0, 0) -> Word-20
Slot (1, 0) -> Word-9
Slot (3, 0) -> Word-47

Processor requests: Word-36


Cache Miss: Word-36 not found in set 0.
Loading Word-36 into set 0.

=== Cache Content ===


Slot (0, 0) -> Word-20
Slot (1, 0) -> Word-9
Slot (3, 0) -> Word-47
Slot (0, 1) -> Word-36

Processor requests: Word-3


Cache Miss: Word-3 not found in set 3.
Loading Word-3 into set 3.

=== Cache Content ===


Slot (0, 0) -> Word-20
Slot (1, 0) -> Word-9
Slot (3, 0) -> Word-47
Slot (0, 1) -> Word-36
Slot (3, 1) -> Word-3
PS C:\Users\WinDows>

15
Computer Architecture and Organization

2) Report on application program that implements microprogrammed control:

Microprogrammed control is a design methodology for implementing the control unit of a


processor. It involves breaking down instructions into smaller steps called microoperations, which
are controlled by microinstructions stored in a control memory. This technique is widely used in
modern processors due to its flexibility and modularity. The report documents the implementation
of a Python program to simulate microprogrammed control, focusing on vertical and horizontal
implementations.
The objectives of this project are:
1. To implement two types of microprogrammed control implementations:
• Vertical Implementation: Compact microinstructions with encoded fields.
• Horizontal Implementation: Parallel control signals with direct activation.
2. To allow user-defined processor specifications:
• Number of registers.
• Number of ALU functions.
• Supported instructions (ADD, SUB, MOVE).
• Optional bus organization (3-, 2-, or 1-bus).
3. To simulate the execution of instructions:
• Generate and display the sequence of microoperations required for each instruction.
4. To display control words and their meanings:
• Represent microoperations as binary control words and decode them to show the
purpose of each bit.
Implementation Details
Programming Language
The program is implemented in Python due to its readability and suitability for simulation tasks.
Main Features
1. Vertical Microprogramming:
• Compact control words with encoded signals.
• Requires decoding logic to interpret and execute microinstructions.
• Efficient memory usage but adds decoding overhead.
2. Horizontal Microprogramming:
• Detailed control words with individual bits for each control signal.
• Allows simultaneous control signal activation but requires larger control memory.
3. User-Defined Processor Specifications:

16
Computer Architecture and Organization

• Allows users to define:


• The number of registers in the processor.
• ALU functions supported (e.g., addition, subtraction).
• Instruction to execute (ADD, SUB, MOVE).
• Optional bus organization for data flow.
4. Microoperations and Control Words:
• Each instruction is broken down into microoperations (e.g., "Load R1 to Bus A").
• Microoperations are represented by control words (binary strings).
• Example:
• 0001000: Load R1 to Bus A
• 0100000: Load R2 to Bus B
• 1000000: Perform addition in ALU
5. Simulation and Execution:
• Randomly generated processor instructions simulate execution.
• Displays the state of registers, buses, and ALU output after each microoperation.
• Provides execution timing for each microoperation.
User Interaction
The program provides an interactive interface allowing users to:
1. Select the implementation type (vertical or horizontal).
2. Define processor specifications or use default values.
3. Execute instructions and observe:
• Microoperation sequences.
• Control words and their decoded meanings.
• Processor state at each step.

def vertical_microprogramming(registers, alu_functions, instruction, num_buses):


# Define micro_operations and their corresponding time
micro_operations = {
'LOAD': ['010', '001', '001', '001'],
'ADD': ['011', '100', '011', '001'],
'SUB': ['011', '101', '011', '001'],
# Add more micro_operations as needed
}

if instruction not in micro_operations:


print(f"Instruction '{instruction}' is not supported.")

17
Computer Architecture and Organization

return

# Generate control word for the given instruction


control_word = ''.join(micro_operations[instruction])

# Display sequence of micro_operations and their corresponding time


print("Sequence of micro_operations:")
for index, microop in enumerate(micro_operations[instruction]):
print(f"Microop {index + 1}: {microop} (time: {index + 1})")

# Display final control word


print("Final control word:")
print(control_word)

def horizontal_microprogramming(registers, alu_functions, instruction, num_buses):


# Define microoperations and their corresponding time
microoperations = {
'LOAD': ['010', '001', '001', '001'],
'ADD': ['011', '100', '011', '001'],
'SUB': ['011', '101', '011', '001'],
# Add more microoperations as needed
}

if instruction not in microoperations:


print(f"Instruction '{instruction}' is not supported.")
return

# Generate control word for the given instruction


control_word = ''
for time in range(len(microoperations[instruction])):
microop = ''
for index in range(len(microoperations)):
if index == time:
microop += '1'
else:
microop += '0'
control_word += microop

# Display sequence of microoperations and their corresponding time


print("Sequence of microoperations:")
for index, microop in enumerate(microoperations[instruction]):
print(f"Microop {index + 1}: {microop} (time: {index + 1})")

# Display final control word


print("Final control word:")
print(control_word)

def main():
# User input
implementation_type = input("Enter implementation type (V for vertical, H for horizontal): ")
registers = int(input("Enter the number of registers: "))
alu_functions = int(input("Enter the number of supported ALU functions: "))
instruction = input("Enter the instruction to execute (e.g., LOAD, ADD, SUB): ").upper()
bus_organization = input("Enter the number of buses (1, 2, or 3): ")

valid_bus_organization = {'1', '2', '3'}


if bus_organization not in valid_bus_organization:
print("Invalid bus organization. Please try again.")
return

18
Computer Architecture and Organization

num_buses = int(bus_organization)

if implementation_type.upper() == 'V':
vertical_microprogramming(registers, alu_functions, instruction, num_buses)
elif implementation_type.upper() == 'H':
horizontal_microprogramming(registers, alu_functions, instruction, num_buses)
else:
print("Invalid implementation type. Please try again.")

if __name__ == '__main__':
main()

Output

Simulation Code (Python)


# Constants for control word definitions (Horizontal)
HORIZONTAL_CONTROL_WORDS = {
"Load R1 to Bus A": "10000001",
"Load R2 to Bus B": "01000010",
"Perform R1 + R2 in ALU": "00110000",
"Perform R1 - R2 in ALU": "00101000",
"Store result in R3": "00000101",
"Move R1 to R2": "00000010",
}
# Encoded control words for Vertical Implementation

19
Computer Architecture and Organization

VERTICAL_CONTROL_WORDS = {
"Load R1 to Bus A": "01",
"Load R2 to Bus B": "02",
"Perform R1 + R2 in ALU": "03",
"Perform R1 - R2 in ALU": "04",
"Store result in R3": "05",
"Move R1 to R2": "06",
}
# Functions for initializing registers and processor state
def initialize_registers(num_registers):
"""Initialize processor registers with user input or default values."""
registers = {}
use_default = input("Do you want to set register values manually? (y/n): ").strip().lower()
for i in range(1, num_registers + 1):
if use_default == 'y':
value = int(input(f"Enter value for R{i}: "))
else:
value = 0
registers[f"R{i}"] = value
return registers
def display_processor_state(state):
"""Display the current state of the processor."""
print("\n--- Processor State ---")
print(f"Registers: {state['registers']}")
print(f"ALU Output: {state['alu_output']}")
print(f"Result Register: {state['result_register']}\n")
# Main execution function
def execute_instruction(processor_state, microops, implementation_type):
"""Simulate the execution of an instruction."""
print("\n=== Executing Instruction ===")
sequence = [] # Store microinstruction sequence with binary codes
for i, microop in enumerate(microops, start=1):

20
Computer Architecture and Organization

binary_code = (
HORIZONTAL_CONTROL_WORDS[microop]
if implementation_type == "horizontal"
else VERTICAL_CONTROL_WORDS[microop]
)
sequence.append(f"{microop} ({binary_code})") # Append microinstruction and binary code
print(f"Step {i}: {microop} | Binary: {binary_code}")
# Simulate the effect of the microoperation
if microop == "Perform R1 + R2 in ALU":
processor_state["alu_output"] = (
processor_state["registers"]["R1"] + processor_state["registers"]["R2"]
)
elif microop == "Perform R1 - R2 in ALU":
processor_state["alu_output"] = (
processor_state["registers"]["R1"] - processor_state["registers"]["R2"]
)
elif microop == "Store result in R3":
processor_state["registers"]["R3"] = processor_state["alu_output"]
processor_state["result_register"] = "R3"
elif microop == "Move R1 to R2":
processor_state["registers"]["R2"] = processor_state["registers"]["R1"]
processor_state["result_register"] = "R2"
# Display processor state after each step
display_processor_state(processor_state)
processor_state["clock"] += 1
# Output the microinstruction sequence
output_microinstruction_sequence(sequence)
def output_microinstruction_sequence(sequence):
"""Output the microinstruction sequence in a single line."""
print("\nMicroinstruction Sequence:")
print(" -> ".join(sequence))
# Main program

21
Computer Architecture and Organization

def main():
"""Main function for the microprogrammed control simulator."""
print("Microprogrammed Control Simulator")
print("1. Vertical Implementation")
print("2. Horizontal Implementation")
implementation_choice = input("Select implementation type (1 for Vertical, 2 for Horizontal):
").strip()
implementation_type = "vertical" if implementation_choice == "1" else "horizontal"
# Get processor specifications
num_registers = int(input("Enter the number of registers: "))
instruction = input("Enter the instruction to execute (ADD/SUB/MOVE): ").strip().upper()
# Initialize processor state
registers = initialize_registers(num_registers)
processor_state = {
"registers": registers,
"clock": 0,
"alu_output": None,
"result_register": None
}
# Determine microoperations based on the instruction
if instruction == "ADD":
microops = [
"Load R1 to Bus A",
"Load R2 to Bus B",
"Perform R1 + R2 in ALU",
"Store result in R3"
]
elif instruction == "SUB":
microops = [
"Load R1 to Bus A",
"Load R2 to Bus B",
"Perform R1 - R2 in ALU",

22
Computer Architecture and Organization

"Store result in R3"


]
elif instruction == "MOVE":
microops = [
"Load R1 to Bus A",
"Move R1 to R2"
]
else:
print("Unsupported instruction. Exiting.")
return
# Execute the instruction
execute_instruction(processor_state, microops, implementation_type)
# Start the Program
main()
Output
Horizontal Implementation

23
Computer Architecture and Organization

Vertical Implentation

24
Computer Architecture and Organization

3) Report on Instruction Pipeline Simulation


The Instruction Pipeline Simulator models the execution of instructions through a CPU pipeline,
demonstrating the parallel processing of multiple instructions. The simulation includes stages that
reflect the core steps of instruction execution in modern processors.
To simulate the instruction pipeline process, showcasing how instructions are fetched, decoded,
executed, and written back over multiple clock cycles while optimizing CPU performance.
Pipeline Stages
1. Fetch: Retrieves the instruction from memory.
2. Decode: Decodes the instruction to determine the operation and operands.
3. Execute: Performs the instruction's computation or operation.
4. Memory: Accesses memory for load or store instructions.
5. Write-back: Writes results to registers or memory.
Simulation Code (Python)

25
Computer Architecture and Organization

class InstructionPipeline:
def __init__(self, instructions):
self.instructions = instructions # List of instructions to execute
self.pipeline_stages = ["Fetch", "Decode", "Execute", "Memory", "Write-back"]
self.pipeline = [] # Current state of the pipeline
self.clock = 0 # Number of clock cycles elapsed
self.completed_instructions = [] # Instructions that have finished execution

def simulate_cycle(self):
"""Simulate one clock cycle of the pipeline."""
self.clock += 1
print(f"\nClock Cycle: {self.clock}")
# Move instructions through the pipeline
for i in range(len(self.pipeline) - 1, -1, -1):
if self.pipeline[i][1] < len(self.pipeline_stages) - 1:
self.pipeline[i][1] += 1
else:
self.completed_instructions.append(self.pipeline.pop(i))
# Fetch a new instruction if available
if len(self.pipeline) < len(self.pipeline_stages) and self.instructions:
self.pipeline.append([self.instructions.pop(0), 0])
# Display the current state of the pipeline
self.display_pipeline()

def display_pipeline(self):
"""Display the current state of the pipeline."""
pipeline_status = ["Empty"] * len(self.pipeline_stages)
for instr, stage in self.pipeline:
pipeline_status[stage] = instr
print("Pipeline State:")
for i, stage in enumerate(self.pipeline_stages):
print(f" {stage}: {pipeline_status[i]}")

26
Computer Architecture and Organization

completed_insts = []
for inst in self.completed_instructions:
completed_insts.append(inst[0])
print(f"Completed Instructions: {completed_insts}")
def simulate(self):
"""Simulate the entire instruction pipeline."""
print("Starting Instruction Pipeline Simulation")
while self.pipeline or self.instructions:
self.simulate_cycle()

if __name__ == "__main__":
instructions =[]
Num_Instructions = int(input("Enter Number of Instructions to be executed: "))
for i in range(Num_Instructions):
instruction = input(f"Enter Instruction {i+1}: ")
instructions.append(instruction)
pipeline = InstructionPipeline(instructions)
pipeline.simulate()
Output

Enter Number of Instructions to be executed: 3 Clock Cycle: 5


Enter Instruction 1: Instruction 1 Pipeline State:
Enter Instruction 2: Instruction 2 Fetch: Empty
Enter Instruction 3: Instruction 3 Decode: Empty
Starting Instruction Pipeline Simulation Execute: Instruction 3
Memory: Instruction 2
Clock Cycle: 1 Write-back: Instruction 1
Pipeline State: Completed Instructions: []
Fetch: Instruction 1 Clock Cycle: 6
Decode: Empty Pipeline State:
Execute: Empty Fetch: Empty
Memory: Empty Decode: Empty

27
Computer Architecture and Organization

Write-back: Empty Execute: Empty


Completed Instructions: [] Memory: Instruction 3
Clock Cycle: 2 Write-back: Instruction 2
Pipeline State: Completed Instructions: ['Instruction 1']
Fetch: Instruction 2 Clock Cycle: 7
Decode: Instruction 1 Pipeline State:
Execute: Empty Fetch: Empty
Memory: Empty Decode: Empty
Write-back: Empty Execute: Empty
Completed Instructions: [] Memory: Empty
Clock Cycle: 3 Write-back: Instruction 3
Pipeline State: Completed Instructions: ['Instruction 1',
'Instruction 2']
Fetch: Instruction 3
Clock Cycle: 8
Decode: Instruction 2
Pipeline State:
Execute: Instruction 1
Fetch: Empty
Memory: Empty
Decode: Empty
Write-back: Empty
Execute: Empty
Completed Instructions: []
Memory: Empty
Clock Cycle: 4
Write-back: Empty
Pipeline State:
Completed Instructions: ['Instruction 1',
Fetch: Empty
'Instruction 2', 'Instruction 3']
Decode: Instruction 3
Execute: Instruction 2
Memory: Instruction 1
Write-back: Empty
Completed Instructions: []

28
Computer Architecture and Organization

29

You might also like