পাঠ ২৬ · ৫৭-এর মধ্যে · মডিউল ৫
Home / Courses / Computer Architecture & Digital Logic / রেজিস্টার ফাইল ও CPU রেজিস্টার

রেজিস্টার ফাইল ও CPU রেজিস্টার

Register file & CPU registers
৭ মিনিট পড়া মধ্যম · Intermediate Python কোডসহ সম্পূর্ণ বাংলায়

এই পাঠে যা শিখবেন

  • রেজিস্টার ফাইল কী, এবং এটি L15-এর রেজিস্টার সার্কিটের সাথে কীভাবে সম্পর্কিত
  • রেজিস্টার কেন মেমরির চেয়ে দ্রুত — এবং মেমরি হায়ারার্কিতে এদের অবস্থান
  • বিশেষ-উদ্দেশ্য রেজিস্টার — PC, IR, SP, flags — এবং প্রতিটির ভূমিকা
  • register-0-হার্ডওয়্যার্ড-টু-জিরো-এর মতো বাস্তব ISA ডিজাইন সিদ্ধান্ত, এবং flags কীভাবে ALU ফলাফল থেকে সেট হয়

১ · রেজিস্টার ফাইল কী

L15-এ আমরা দেখেছি কীভাবে N-টি D ফ্লিপ-ফ্লপ মিলে একটি N-বিট রেজিস্টারএকটি সাধারণ ক্লক শেয়ার করা N-টি D ফ্লিপ-ফ্লপের গ্রুপ, যা একসাথে একটি N-বিট মান সংরক্ষণ করে। তৈরি হয়। রেজিস্টার ফাইল হলো এই ধারণারই বাস্তব, CPU-স্কেল বাস্তবায়ন — একটি ফিক্সড, ছোট সংখ্যক (অনেক RISC ISA-তে যেমন ৩২টি) সাধারণ-উদ্দেশ্য রেজিস্টারকে একটি অ্যাড্রেসযোগ্য অ্যারে হিসেবে সংগঠিত করা, যেখানে read ও write উভয় পোর্ট থাকে — অর্থাৎ L24-এর ইনস্ট্রাকশন ফরম্যাটে থাকা রেজিস্টার-নম্বর ফিল্ড (rd, rs1, rs2) সরাসরি এই অ্যারের একটি নির্দিষ্ট রেজিস্টার নির্বাচন করে।

২ · রেজিস্টার কেন মেমরির চেয়ে দ্রুত

এই প্রশ্নের উত্তর সরাসরি M8-এর মেমরি হায়ারার্কি আলোচনার প্রিভিউ — রেজিস্টার সেই হায়ারার্কির একদম শীর্ষে, সবচেয়ে দ্রুত ক্যাশের চেয়েও দ্রুত। কারণ রেজিস্টারগুলো ফিজিক্যালি CPU চিপের ভেতরেই তৈরি, ঠিক M3-এর একই ফ্লিপ-ফ্লপ প্রযুক্তি দিয়ে — এদের পৌঁছাতে কোনো আলাদা বাস বা ইন্টারকানেক্ট পার হতে হয় না, যেখানে মেমরি একটি সম্পূর্ণ আলাদা, অনেক বড়, এবং অনেক ধীর স্ট্রাকচার (M9-এ বিস্তারিত)। এই কারণেই কম্পাইলার সবসময় চেষ্টা করে যতটা সম্ভব ডেটা রেজিস্টারে রাখতে, মেমরিতে বারবার যাওয়া এড়িয়ে।

৩ · বিশেষ-উদ্দেশ্য রেজিস্টার

সাধারণ-উদ্দেশ্য রেজিস্টার ছাড়াও, প্রতিটি CPU-তে কয়েকটি নির্দিষ্ট, বিশেষ ভূমিকার রেজিস্টার থাকে —

  • Program Counter (PC): পরবর্তী ফেচ করতে হবে এমন ইনস্ট্রাকশনের মেমরি অ্যাড্রেস ধরে রাখে — সরাসরি M6-এর ফেচ স্টেজের ভিত্তি।
  • Instruction Register (IR): ফেচ করার পর বর্তমানে এক্সিকিউট হতে থাকা ইনস্ট্রাকশনটি ধরে রাখে।
  • Stack Pointer (SP): কল স্ট্যাকের শীর্ষের অবস্থান ট্র্যাক করে।
  • Flags/Status রেজিস্টার: কন্ডিশন ফলাফল ধরে রাখে — zero-flag, negative-flag, overflow-flag (সরাসরি L18/L19-এর overflow-detection ধারণার হার্ডওয়্যার-স্থায়ী রূপ, যা branch ইনস্ট্রাকশন পরীক্ষা করতে পারে)।

নিচের কোড সেলে একটি RegisterFile ক্লাস সিমুলেট করা হচ্ছে — N-টি সাধারণ-উদ্দেশ্য রেজিস্টার, একটি আলাদা PC, ও একটি flags ডিকশনারি নিয়ে। লক্ষ্য করুন register 0-কে বাস্তব RISC ISA-এর মতোই হার্ডওয়্যার্ড টু জিরো করা হয়েছে — এতে লেখার চেষ্টা করলেও নিঃশব্দে উপেক্ষিত হয়।

Python
# CPU-এর ভেতরের রেজিস্টার ফাইল -- টয় সিমুলেশন, বাস্তব হার্ডওয়্যার অ্যাক্সেস নয়
class RegisterFile:
    def __init__(self, n_registers=8):
        self.n_registers = n_registers
        self.registers = [0] * n_registers
        self.pc = 0
        self.flags = {"zero": 0, "negative": 0, "overflow": 0}

    def read(self, reg_num):
        if reg_num == 0:
            return 0  # বাস্তব RISC ISA-র মতোই -- register 0 সবসময় 0 পড়ে
        return self.registers[reg_num]

    def write(self, reg_num, value):
        if reg_num == 0:
            return  # হার্ডওয়্যার্ড টু জিরো -- লেখার চেষ্টা নিঃশব্দে উপেক্ষিত হয়
        self.registers[reg_num] = value

    def update_flags(self, alu_result, bits=8):
        """একটি সিমুলেটেড ALU অপারেশনের ফলাফল থেকে flags আপডেট করে"""
        max_signed = 2 ** (bits - 1) - 1
        min_signed = -2 ** (bits - 1)
        self.flags["zero"] = 1 if alu_result == 0 else 0
        self.flags["negative"] = 1 if alu_result < 0 else 0
        self.flags["overflow"] = 1 if (alu_result > max_signed or alu_result < min_signed) else 0

rf = RegisterFile(n_registers=8)

# --- register 0 হার্ডওয়্যার্ড টু জিরো -- write করার চেষ্টা করেও প্রভাব নেই ---
rf.write(0, 999)
print("register 0-তে 999 লেখার চেষ্টার পর read(0):", rf.read(0))

# --- সাধারণ রেজিস্টারে স্বাভাবিক read/write ---
rf.write(3, 42)
print("register 3-এ 42 লেখার পর read(3):", rf.read(3))

# --- ALU ফলাফল অনুযায়ী flags আপডেট -- zero-result কেস ---
rf.update_flags(0)
print("\nALU ফলাফল 0 হলে flags:", rf.flags)

# --- ALU ফলাফল অনুযায়ী flags আপডেট -- negative-result কেস ---
rf.update_flags(-5)
print("ALU ফলাফল -5 হলে flags:", rf.flags)

# --- 8-বিট সাইনড রেঞ্জ ছাড়িয়ে যাওয়া ফলাফল -- overflow কেস ---
rf.update_flags(200, bits=8)
print("ALU ফলাফল 200 (8-বিট সাইনড রেঞ্জের বাইরে) হলে flags:", rf.flags)

    
লক্ষ্য করুন register 0-এ 999 লেখার চেষ্টার পরও read(0) এখনও 0 ফেরত দেয় — এটি কোনো বাগ নয়, বরং একটি ইচ্ছাকৃত হার্ডওয়্যার ডিজাইন সিদ্ধান্ত। অনেক RISC ISA-তে (যেমন MIPS, RISC-V) একটি সবসময়-শূন্য রেজিস্টার থাকা সুবিধাজনক — যেমন কোনো রেজিস্টার শূন্য করতে হলে শুধু "add rd, r0, r0" চালালেই হয়, আলাদা কোনো "clear" ইনস্ট্রাকশন লাগে না।
মূল কথা · Key takeaway

রেজিস্টার ফাইল হলো CPU-এর একদম দ্রুততম, চিপের-ভেতরের স্টোরেজ — L15-এর রেজিস্টার সার্কিটের বাস্তব, অ্যাড্রেসযোগ্য সংস্করণ। সাধারণ-উদ্দেশ্য রেজিস্টারের পাশাপাশি PC, IR, SP ও flags-এর মতো বিশেষ-উদ্দেশ্য রেজিস্টার মিলিয়েই একটি CPU-এর সম্পূর্ণ "state" গঠিত হয় — M6-এর ডেটাপাথ ডিজাইনে এই সবকটি রেজিস্টার একসাথে কাজ করবে।

ভাবনার প্রশ্ন

প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।

প্র ০১ যদি রেজিস্টার এত দ্রুত, তাহলে CPU-তে মাত্র ৮ বা ৩২টি কেন — কেন হাজার হাজার রেজিস্টার রাখা হয় না?

দুটি বাস্তব কারণ — প্রথমত, রেজিস্টার-নম্বর ইনস্ট্রাকশনের একটি ফিক্সড, ছোট বিট-ফিল্ডে (L24-এর rd/rs1/rs2) এনকোড হয়; বেশি রেজিস্টার মানে প্রতিটি রেজিস্টার-ফিল্ডে বেশি বিট লাগবে, যা ইনস্ট্রাকশনের সামগ্রিক আকার বাড়িয়ে দেবে। দ্বিতীয়ত, ফিজিক্যালি বেশি রেজিস্টার মানে বড় রেজিস্টার ফাইল — আর একটি স্টোরেজ যত বড় হয়, তার read/write অ্যাক্সেস তত ধীর হতে থাকে (এই একই নীতি M8-এর ক্যাশ সাইজ বনাম গতির ট্রেডঅফেও প্রযোজ্য)। তাই রেজিস্টার সংখ্যা একটি সচেতন ট্রেডঅফ — যথেষ্ট বেশি যাতে বেশিরভাগ প্রোগ্রাম কাজ চালাতে পারে, কিন্তু ছোট রেখে গতি বজায় রাখা।

প্র ০২ Instruction Register (IR) আর Program Counter (PC) — দুটোই তো ইনস্ট্রাকশনের সাথে সম্পর্কিত। এদের ভূমিকা কীভাবে আলাদা?

PC হলো "পরবর্তী কী ফেচ করব"-এর ঠিকানা — এটি একটি মেমরি অ্যাড্রেস ধরে রাখে, ইনস্ট্রাকশন নিজে নয়। IR হলো "এখন কী এক্সিকিউট করছি"-এর প্রকৃত বিষয়বস্তু — PC যে অ্যাড্রেস নির্দেশ করেছিল, সেখান থেকে ফেচ করা প্রকৃত ইনস্ট্রাকশন বিট প্যাটার্ন এখানে সংরক্ষিত হয়, যাতে ডিকোড ও এক্সিকিউট স্টেজ (M6) এটি ব্যবহার করতে পারে। সাধারণত একটি ইনস্ট্রাকশন ফেচ হওয়ার পরপরই PC পরবর্তী ইনস্ট্রাকশনের অ্যাড্রেসে এগিয়ে যায়, কিন্তু IR ততক্ষণ আগের ইনস্ট্রাকশনই ধরে রাখে যতক্ষণ না সেটির এক্সিকিউশন সম্পূর্ণ হয়।

প্র ০৩ উপরের কোডে update_flags ফাংশনে zero আর negative দুটো flag একই সাথে 1 হতে পারে কি? যুক্তি দিয়ে ব্যাখ্যা করুন।

না, একসাথে দুটোই 1 হতে পারে না — কারণ এই দুটো condition পরস্পর-বর্জনীয় (mutually exclusive)। zero flag সেট হয় শুধু তখনই যখন ফলাফল ঠিক 0, আর negative flag সেট হয় শুধু তখনই যখন ফলাফল 0-এর কঠোরভাবে চেয়ে ছোট (alu_result < 0)। যেহেতু 0 কখনোই নিজের চেয়ে ছোট নয়, একটি ফলাফল একসাথে ঠিক-0 এবং শূন্যের-চেয়ে-ছোট দুটোই হতে পারে না — কোডের if-condition গুলো নিজেরাই এই পারস্পরিক-বর্জনীয়তা নিশ্চিত করে।

অনুশীলন

  1. পরীক্ষা করুন: উপরের কোডে rf.update_flags(127, bits=8) এবং rf.update_flags(128, bits=8) — এই দুটো কল আলাদাভাবে চালালে overflow flag-এ কী ফলাফল আসবে বলে মনে হয় (কোড না চালিয়ে আগে হাতে-কলমে চিন্তা করুন — 8-বিট সাইনড রেঞ্জের সীমা কী)?

    8-বিট সাইনড (two's complement) রেঞ্জ হলো −128 থেকে +127 (L18)। তাই update_flags(127, bits=8) কল করলে 127 ঠিক সর্বোচ্চ সীমায়, তাই overflow = 0 থাকবে। কিন্তু update_flags(128, bits=8) কল করলে 128 এই রেঞ্জের বাইরে (max_signed=127-এর চেয়ে বেশি), তাই overflow = 1 হবে। এটি L18-এর সাইনড-নাম্বার-রেঞ্জ ধারণার সরাসরি প্রয়োগ।

  2. চিন্তা করুন: Stack Pointer (SP)-কে যদি একটি সাধারণ-উদ্দেশ্য রেজিস্টার হিসেবে (বিশেষ কোনো নাম ছাড়া) ব্যবহার করা হতো, তাহলে ফাংশন কল/রিটার্নের মতো কম্পাইলার-জেনারেটেড কোডে কী সমস্যা হতে পারত?

    যদি SP-এর কোনো নির্দিষ্ট, সবার-জানা রেজিস্টার-নম্বর না থাকত, তাহলে প্রতিটি কম্পাইলার, প্রতিটি ফাংশন, এমনকি প্রতিটি লাইব্রেরি কোড ভিন্ন ভিন্ন রেজিস্টারকে "স্ট্যাক পয়েন্টার" হিসেবে বেছে নিতে পারত — দুটো ভিন্ন সোর্স থেকে কম্পাইল করা কোড একসাথে (যেমন একটি লাইব্রেরি কল) কাজ করার সময় একে অপরের স্ট্যাক নষ্ট করে ফেলত। SP-কে একটি সুনির্দিষ্ট, সবার-মেনে-চলা (ISA-level convention) রেজিস্টার-নম্বর হিসেবে রাখলেই বিভিন্ন উৎস থেকে কম্পাইল করা কোড নিরাপদে একে অপরের সাথে আন্তঃক্রিয়া করতে পারে।

আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ

আগের পাঠ
L25 · অ্যাড্রেসিং মোড