মাইক্রোপ্রোগ্রামড কন্ট্রোল
এই পাঠে যা শিখবেন
- মাইক্রোপ্রোগ্রামড কন্ট্রোলের সংজ্ঞা এবং "কন্ট্রোল স্টোর" ও "মাইক্রোইনস্ট্রাকশন" ধারণা
- হার্ডওয়্যার্ড বনাম মাইক্রোপ্রোগ্রামড কন্ট্রোলের নমনীয়তা-বনাম-গতি ট্রেড-অফ
- কেন এই পদ্ধতি ঐতিহাসিকভাবে জটিল CISC ISA (L23) সম্ভব করেছিল
- Python দিয়ে একটি সংযুক্ত (linked) মাইক্রোপ্রোগ্রাম সিমুলেট করে, L29-এর হার্ডওয়্যার্ড টেবিলের সাথে ফলাফল কোড দিয়ে অভিন্ন প্রমাণ করা
১ · মাইক্রোপ্রোগ্রামড কন্ট্রোল — একটি রিকার্সিভ ধারণা
L29-এ দেখেছেন হার্ডওয়্যার্ড কন্ট্রোল কীভাবে ফিক্সড কম্বিনেশনাল লজিক দিয়ে সরাসরি সিগন্যাল তৈরি করে। মাইক্রোপ্রোগ্রামড কন্ট্রোলMicroprogrammed Controlএকটি অভ্যন্তরীণ মেমরিতে সংরক্ষিত মাইক্রোইনস্ট্রাকশন পড়ে কন্ট্রোল সিগন্যাল তৈরি করা। সম্পূর্ণ ভিন্ন একটি দৃষ্টিভঙ্গি নেয় — ফিক্সড সার্কিটের বদলে, কন্ট্রোল সিগন্যালগুলো পড়া হয় একটি ছোট্ট, দ্রুত অভ্যন্তরীণ মেমরি থেকে, যাকে ঐতিহাসিকভাবে বলা হয় "কন্ট্রোল স্টোর"। এই মেমরিতে মাইক্রোইনস্ট্রাকশন-এর একটি সিকোয়েন্স সংরক্ষিত থাকে — প্রতিটি মাইক্রোইনস্ট্রাকশন একটি মাইক্রো-ধাপের জন্য কন্ট্রোল সিগন্যাল মান নির্দিষ্ট করে, এবং একটি মাইক্রোপ্রোগ্রাম কাউন্টার এই সিকোয়েন্সের মধ্য দিয়ে ধাপে ধাপে এগিয়ে যায়।
লক্ষ করার মতো একটি চমৎকার, রিকার্সিভ ধারণা — এটি ঠিক L26-এর নিয়মিত প্রোগ্রামের PC যেভাবে ইনস্ট্রাকশনের মধ্য দিয়ে এগিয়ে যায়, তারই একটি "এক স্তর নিচের" সংস্করণ: দৃশ্যমান ISA-এর ঠিক নিচেই, প্রতিটি ইনস্ট্রাকশনকে বাস্তবায়ন করতে নিজস্ব একটি ছোট্ট "প্রোগ্রাম" চলে।
২ · ট্রেড-অফ — নমনীয়তা বনাম গতি
দ্রুত (বিশুদ্ধ কম্বিনেশনাল লজিক, বাড়তি ক্লক সাইকেল লাগে না), কিন্তু নতুন ইনস্ট্রাকশন যোগ করতে সার্কিট পুনর্ডিজাইন লাগে।
নমনীয় (নতুন/পরিবর্তিত আচরণ যোগ করতে শুধু মাইক্রোকোড রিরাইট, কোনো শারীরিক পুনর্ডিজাইন লাগে না), কিন্তু কন্ট্রোল স্টোর থেকে পড়তে অতিরিক্ত সময় লাগায় সাধারণত ধীর।
এই নমনীয়তাই ঐতিহাসিকভাবে গুরুত্বপূর্ণ — এটি জটিল CISCL23-এ দেখা Complex Instruction Set Computer — কম কিন্তু শক্তিশালী, জটিল ইনস্ট্রাকশন। ISA-কে বাস্তবসম্মত করে তুলেছিল (সরাসরি L23-এর সাথে যুক্ত) — কারণ প্রতিটি জটিল ইনস্ট্রাকশনের জন্য আলাদা হার্ডওয়্যার্ড সার্কিট ডিজাইন করার চেয়ে মাইক্রোকোড লেখা অনেক সহজ ও সস্তা ছিল।
৩ · সমতা যাচাই — একই সিগন্যাল, ভিন্ন বাস্তবায়ন
নিচের কোড সেলে প্রতিটি opcode-এর জন্য একটি ছোট্ট, দুই-ধাপের মাইক্রোপ্রোগ্রাম সংজ্ঞায়িত করা হয়েছে — প্রথম
মাইক্রো-ধাপ ALU-সংক্রান্ত সিগন্যাল সেট করে, দ্বিতীয়টি রেজিস্টার/মেমরি-সংক্রান্ত সিগন্যাল সেট করে "শেষ"
চিহ্নে (next=-1) পৌঁছায়। run_microprogram() এই সিকোয়েন্সের মধ্য দিয়ে হেঁটে
চূড়ান্ত সিগন্যাল সংগ্রহ করে — এরপর সরাসরি L29-এর হার্ডওয়্যার্ড টেবিলের সাথে তুলনা করে প্রমাণ করা হয়েছে যে
দুটো পদ্ধতিই একই চূড়ান্ত ফলাফল দেয়।
# -- মাইক্রোপ্রোগ্রামড কন্ট্রোল সিমুলেশন: control_store একটি Python list -- বাস্তব হার্ডওয়্যারে এটি একটি ROM/মেমরি
def generate_control_signals_hardwired(opcode):
"""L29-এর হার্ডওয়্যার্ড লুকআপ টেবিল -- তুলনার জন্য এখানে হুবহু পুনরায় ব্যবহার করা হলো"""
table = {
'ADD': {'RegWrite': 1, 'MemRead': 0, 'MemWrite': 0, 'ALUOp': 'ADD', 'Branch': 0, 'ALUSrc': 0},
'ADDI': {'RegWrite': 1, 'MemRead': 0, 'MemWrite': 0, 'ALUOp': 'ADD', 'Branch': 0, 'ALUSrc': 1},
'LOAD': {'RegWrite': 1, 'MemRead': 1, 'MemWrite': 0, 'ALUOp': 'ADD', 'Branch': 0, 'ALUSrc': 1},
'STORE': {'RegWrite': 0, 'MemRead': 0, 'MemWrite': 1, 'ALUOp': 'ADD', 'Branch': 0, 'ALUSrc': 1},
'BEQ': {'RegWrite': 0, 'MemRead': 0, 'MemWrite': 0, 'ALUOp': 'SUB', 'Branch': 1, 'ALUSrc': 0},
}
return table[opcode]
# --- কন্ট্রোল স্টোর: প্রতিটি opcode-এর জন্য দুই-ধাপের মাইক্রোইনস্ট্রাকশন সিকোয়েন্স ---
CONTROL_STORE = [
{'ALUOp': 'ADD', 'ALUSrc': 0, 'next': 1}, # 0: ADD ধাপ ১
{'RegWrite': 1, 'MemRead': 0, 'MemWrite': 0, 'Branch': 0, 'next': -1}, # 1: ADD ধাপ ২
{'ALUOp': 'ADD', 'ALUSrc': 1, 'next': 3}, # 2: ADDI ধাপ ১
{'RegWrite': 1, 'MemRead': 0, 'MemWrite': 0, 'Branch': 0, 'next': -1}, # 3: ADDI ধাপ ২
{'ALUOp': 'ADD', 'ALUSrc': 1, 'next': 5}, # 4: LOAD ধাপ ১
{'RegWrite': 1, 'MemRead': 1, 'MemWrite': 0, 'Branch': 0, 'next': -1}, # 5: LOAD ধাপ ২
{'ALUOp': 'ADD', 'ALUSrc': 1, 'next': 7}, # 6: STORE ধাপ ১
{'RegWrite': 0, 'MemRead': 0, 'MemWrite': 1, 'Branch': 0, 'next': -1}, # 7: STORE ধাপ ২
{'ALUOp': 'SUB', 'ALUSrc': 0, 'next': 9}, # 8: BEQ ধাপ ১
{'RegWrite': 0, 'MemRead': 0, 'MemWrite': 0, 'Branch': 1, 'next': -1}, # 9: BEQ ধাপ ২
]
MICROPROGRAM_START = {'ADD': 0, 'ADDI': 2, 'LOAD': 4, 'STORE': 6, 'BEQ': 8}
def run_microprogram(opcode, control_store, start_table):
idx = start_table[opcode]
signals = {'RegWrite': 0, 'MemRead': 0, 'MemWrite': 0, 'ALUOp': None, 'Branch': 0, 'ALUSrc': 0}
print(f"-- opcode={opcode}: মাইক্রোপ্রোগ্রাম শুরু ঠিকানা={idx}")
while idx != -1:
micro = control_store[idx]
for key, value in micro.items():
if key != 'next':
signals[key] = value
shown = {k: v for k, v in micro.items() if k != 'next'}
print(f" মাইক্রো-ইনস্ট্রাকশন[{idx}]: {shown} (পরবর্তী: {micro['next']})")
idx = micro['next']
return signals
print("opcode থেকে থেকে মাইক্রোপ্রোগ্রাম বনাম হার্ডওয়্যার্ড টেবিল -- সমতা যাচাই\n")
all_equal = True
for opcode in ['ADD', 'ADDI', 'LOAD', 'STORE', 'BEQ']:
micro_signals = run_microprogram(opcode, CONTROL_STORE, MICROPROGRAM_START)
hardwired_signals = generate_control_signals_hardwired(opcode)
matches = micro_signals == hardwired_signals
all_equal = all_equal and matches
print(f" মাইক্রোপ্রোগ্রাম ফলাফল : {micro_signals}")
print(f" হার্ডওয়্যার্ড ফলাফল : {hardwired_signals}")
print(f" অভিন্ন? {matches}\n")
assert all_equal, "মাইক্রোপ্রোগ্রাম ও হার্ডওয়্যার্ড কন্ট্রোলের ফলাফল মিলছে না!"
print("সবগুলো opcode-এর জন্য মাইক্রোপ্রোগ্রামড ও হার্ডওয়্যার্ড কন্ট্রোল হুবহু একই সিগন্যাল দিয়েছে -- ")
print("দুটো ভিন্ন বাস্তবায়ন কৌশল, কিন্তু একই সঠিক আচরণ।")
হার্ডওয়্যার্ড ও মাইক্রোপ্রোগ্রামড কন্ট্রোল একই সমস্যার (কন্ট্রোল সিগন্যাল তৈরি) দুটো সম্পূর্ণ ভিন্ন সমাধান — একটি ফিক্সড সার্কিট, অন্যটি একটি অভ্যন্তরীণ প্রোগ্রাম — কিন্তু কোড দিয়ে যাচাই করা গেল যে উভয়ই একই opcode-এর জন্য হুবহু একই আউটপুট দেয়। L31-এ দেখবেন কীভাবে এই কন্ট্রোল সিগন্যালগুলোই একটি মাল্টি-সাইকেল ডেটাপাথের প্রতিটি সাইকেলে বদলে বদলে যায়।
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।
প্র ০১ মাইক্রোপ্রোগ্রাম কাউন্টারকে "নিয়মিত প্রোগ্রামের PC-এর এক স্তর নিচের সংস্করণ" বলা হলো কেন?
একটি নিয়মিত প্রোগ্রামের PC ইনস্ট্রাকশন মেমরির মধ্য দিয়ে ধাপে ধাপে এগিয়ে যায়, প্রতিটি ইনস্ট্রাকশন এক্সিকিউট করতে করতে। মাইক্রোপ্রোগ্রাম কাউন্টার ঠিক একইভাবে কন্ট্রোল স্টোরের মধ্য দিয়ে এগিয়ে যায় — শুধু তার "ইনস্ট্রাকশন" হলো মাইক্রোইনস্ট্রাকশন, যা কোনো ISA-লেভেল কাজ করে না, বরং একটি ISA ইনস্ট্রাকশনকে বাস্তবায়ন করার জন্য কন্ট্রোল সিগন্যাল সেট করে — একটি সিস্টেমের ভেতরে আরেকটি ছোট্ট সিস্টেম।
প্র ০২ একটি নতুন ইনস্ট্রাকশন (ধরুন SUBI — রেজিস্টার থেকে immediate বিয়োগ) যোগ করতে মাইক্রোপ্রোগ্রামড কন্ট্রোলে কী করতে হবে, আর হার্ডওয়্যার্ডে কী করতে হতো?
মাইক্রোপ্রোগ্রামড কন্ট্রোলে CONTROL_STORE-এ দুটো নতুন এন্ট্রি যোগ করে (ALUOp='SUB',
ALUSrc=1 ধাপ, তারপর RegWrite=1 ধাপ) এবং MICROPROGRAM_START-এ একটি নতুন কী যোগ করলেই
যথেষ্ট — কোনো শারীরিক পরিবর্তন লাগে না। হার্ডওয়্যার্ড কন্ট্রোলে (L29) এর জন্য গেট-স্তরের কম্বিনেশনাল
সার্কিটটাই নতুনভাবে ডিজাইন করতে হতো — একটি বাস্তব, ব্যয়বহুল ইঞ্জিনিয়ারিং প্রক্রিয়া।
প্র ০৩
যদি run_microprogram()-এর কোনো opcode-এর জন্য ফলাফল হার্ডওয়্যার্ড টেবিলের সাথে না মিলত, তাহলে কোড সেলের কোন লাইনটি সেটা ধরত?
assert all_equal লাইনটি — লুপের ভেতরে প্রতিটি opcode-এর জন্য matches গণনা করে
all_equal-এর সাথে AND করা হয়েছে, তাই একটিও অমিল থাকলে all_equal False হয়ে
assert ব্যর্থ (fail) হতো, একটি স্পষ্ট এরর মেসেজ দেখিয়ে। এটিই কোড-স্তরের যাচাইয়ের আসল
শক্তি — চোখে ভালো মনে হওয়া টেবিলের বদলে প্রতিটি এন্ট্রি প্রোগ্রাম্যাটিকভাবে নিশ্চিত করা।
অনুশীলন
-
চিন্তা করুন: কেন প্রতিটি opcode-এর মাইক্রোপ্রোগ্রাম দুই ধাপে ভাগ করা হলো, এক ধাপে সব সিগন্যাল সেট না করে?
এটি বাস্তব মাইক্রোপ্রোগ্রামড ডিজাইনের সেই মূল ধারণাটিই তুলে ধরে যে প্রতিটি মাইক্রো-ধাপ একটি একক ছোট্ট "মাইক্রো-অপারেশন"-এর সাথে মিলিয়ে রাখা হয় (এখানে: প্রথমে ALU সেটআপ, পরে রাইট-ব্যাক সেটআপ) — বাস্তব CISC হার্ডওয়্যারে এই বিভাজন প্রায়ই মাল্টি-সাইকেল ডেটাপাথের (L31) প্রকৃত সাইকেল-ধাপগুলোর সাথে সরাসরি মিলে যায়, প্রতিটি মাইক্রো-ধাপ এক ক্লক সাইকেলের সাথে সংযুক্ত থাকে।
-
পরীক্ষা করুন: যদি
CONTROL_STORE-এর index 1 (ADD ধাপ ২)-এর'next'মান ভুলবশত-1-এর বদলে0লেখা হতো, তাহলে কী ঘটত?while idx != -1লুপটি কখনো থামত না — index 0 আবার index 1-এ যেত, যেটা আবার 0-তে ফিরিয়ে দিত, একটি অসীম লুপ তৈরি করে। এটি বাস্তব হার্ডওয়্যারেও গুরুত্বপূর্ণ — একটি ভুলভাবে-সংযুক্ত মাইক্রোপ্রোগ্রাম CPU-কে চিরতরে একটি ইনস্ট্রাকশনেই আটকে রাখতে পারে, তাই কন্ট্রোল স্টোরের প্রতিটি "next" লিংক সাবধানে ডিজাইন ও যাচাই করা জরুরি।
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- কোর্সের সম্পূর্ণ সিলেবাস দেখুন ৫৭টি পাঠ L31-এ এই কন্ট্রোল সিগন্যালগুলো একটি বাস্তব মাল্টি-সাইকেল ডেটাপাথে প্রয়োগ করা হবে।
- হার্ডওয়্যার্ড কন্ট্রোল পুনরায় দেখুন পাঠ ২৯ এই পাঠের মাইক্রোপ্রোগ্রামের ফলাফল সরাসরি L29-এর টেবিলের সাথে তুলনা করে সমতা যাচাই করা হয়েছে।
- ISA কী — RISC বনাম CISC পুনরায় দেখুন পাঠ ২৩ মাইক্রোপ্রোগ্রামড কন্ট্রোলের নমনীয়তাই ঐতিহাসিকভাবে জটিল CISC ইনস্ট্রাকশন সেট সম্ভব করেছিল।
- Operating Systems কোর্স সহোদর কোর্স OS-এর দৃষ্টিতে কন্ট্রোল বাস্তবায়নের কৌশল অদৃশ্য — কিন্তু এই পাঠ দেখায় সেই "স্বচ্ছ" ISA-এর নিচে আসলে কী চলে।