Foundationপ্রথম নীতি থেকে
LEVEL 2লেসন ১৩/১৬মাঝারি৫০ মিনিট

Counter ও Shift Register — সময় ধরে চলমান State

Counters and Shift Registers

Counter হলো সবচেয়ে সরল আকর্ষণীয় FSM — state নিজেই একটা সংখ্যা, transition সবসময় +1 mod N, অর্থাৎ হার্ডওয়্যারে বাস্তবায়িত modular arithmetic। Shift register সেই একই flip-flop chain-কে ভিন্নভাবে সাজিয়ে serial-parallel রূপান্তরের ভিত্তি তৈরি করে।

এই লেসন শেষে আপনি পারবেন

  • T flip-flop থেকে একটা asynchronous (ripple) counter তৈরি করে তার timing waveform ট্রেস করতে পারবেন
  • Ripple counter-এর glitch সমস্যা চিহ্নিত করে synchronous counter কীভাবে সেটা সমাধান করে তা ব্যাখ্যা করতে পারবেন
  • Modulo-N (non-power-of-2) counter ডিজাইন করতে পারবেন
  • SISO, SIPO, PISO, PIPO shift register-এর মধ্যে পার্থক্য করে বাস্তব ব্যবহার চিহ্নিত করতে পারবেন
  • LFSR-এর মূল ধারণা এবং একটা বাস্তব ব্যবহারের ক্ষেত্র বলতে পারবেন

আগে যা বোঝা থাকা দরকার

আগে এটা বুঝি

গত লেসনের শেষে আমরা বলেছিলাম: FSM-এর সবচেয়ে সরল, সবচেয়ে ব্যবহারিক প্রয়োগ হলো counter — যেখানে state নিজেই একটা সংখ্যা, আর transition সবসময় “+1 mod N”। এটা সরাসরি Level 0-এর [[modular-arithmetic]]-এর একটা হার্ডওয়্যার রূপ — সেই “ঘড়ির গণিত” (৯টা বাজে, ৫ ঘণ্টা যোগ করলে ২টা বাজে) এখন সিলিকনে বাস্তবায়িত।

আজ আমরা counter বানাবো, তার একটা বাস্তব সমস্যা দেখব ও সমাধান করব, আর তারপর একই flip-flop chain-কে সামান্য ভিন্নভাবে সাজিয়ে সম্পূর্ণ ভিন্ন একটা ব্যবহারিক device — shift register — তৈরি করব।

মূল ধারণা

T Flip-Flop থেকে Ripple Counter

আগের লেসনে আমরা দেখেছিলাম T flip-flop-এর নিয়ম: T=1 হলে প্রতি clock edge-এ output toggle করে (Q_next = Q XOR T)। যদি T সবসময় 1 রাখা হয়, flip-flop প্রতিটা clock edge-এ toggle করবে — অর্থাৎ output frequency হবে input clock frequency-র অর্ধেক

এটাই ripple counter-এর মূল কৌশল: প্রতিটা bit-এর clock তার আগের bit-এর output

CLK ──►[T FF]──┬──►[T FF]──┬──►[T FF]
      Q0=LSB    │  Q1       │  Q2=MSB
                 └───────────┘
3-bit ripple (asynchronous) counter — প্রতিটা T flip-flop-এর clock তার আগেরটার output।

প্রতিটা flip-flop-এর T=1 (স্থায়ীভাবে বাঁধা), তাই প্রতিটাই তার নিজের clock input-এ প্রতিটা edge-এ toggle করে। Q0 মূল CLK-এর অর্ধেক frequency-তে toggle করে, Q1 তার অর্ধেক (মূল CLK-এর ১/৪), Q2 আরও অর্ধেক (১/৮) — ঠিক binary সংখ্যার প্রতিটা bit যেভাবে গোনার সময় ভিন্ন frequency-তে বদলায়।

CLK pulseQ2 Q1 Q0দশমিক
শুরু0000
10011
20102
30113
41004
51015
61106
71117
80000 (wrap — mod 8!)

8-এ পৌঁছে 000-এ ফিরে যাওয়া — এটাই computer-representation/unsigned-integers লেসনের wraparound, এবার হার্ডওয়্যারে ঘটতে দেখা।

ভেতরে কী ঘটছে

Ripple-এর সমস্যা — এবং Synchronous সমাধান

“Ripple” নামটা এসেছে একটা প্রকৃত সমস্যা থেকে — ঠিক combinational-adders লেসনের ripple-carry adder-এর মতোই।

প্রতিটা T flip-flop-এর একটা বাস্তব propagation delay আছে (clock-and-timing লেসন)। CLK থেকে Q0 বদলাতে সময় লাগে t_pdQ1 তখনই বদলাতে শুরু করে যখন Q0 বদলায় — অর্থাৎ Q1 বদলায় 2·t_pd পরে (মূল CLK edge থেকে)। Q2 বদলায় 3·t_pd পরে। এই cumulative delay-ই “ripple”

বাস্তব সমস্যা: count = 3 (011) থেকে count = 4 (100)-এ যাওয়ার সময়, তিনটা bit-ই বদলাচ্ছে, কিন্তু একই মুহূর্তে না। খুব সংক্ষিপ্ত একটা সময়ের জন্য (কয়েক t_pd), output হতে পারে 010, তারপর 000, তারপর অবশেষে সঠিক 100 — একটা বাস্তব, ক্ষণস্থায়ী glitch, যা কোনো downstream logic যদি ঠিক সেই মুহূর্তে count পড়ে, ভুল মান দেখতে পারে।

সমাধান — Synchronous counter: প্রতিটা flip-flop একই, সত্যিকারের system CLK থেকে সরাসরি clock পায় (আগেরটার output থেকে না)। প্রতিটা flip-flop-এর T input এখন একটা combinational function of বর্তমান count (FSM-এর next-state logic, গত লেসনের পদ্ধতি অনুসারে ডিজাইন করা):

T0=1(সবসময় toggle)T_0 = 1 \quad (\text{সবসময় toggle}) T1=Q0(toggle শুধু Q0=1 হলে)T_1 = Q_0 \quad (\text{toggle শুধু } Q_0=1 \text{ হলে}) T2=Q0Q1(toggle শুধু দুইটাই 1 হলে)T_2 = Q_0 \cdot Q_1 \quad (\text{toggle শুধু দুইটাই } 1 \text{ হলে})

এই সূত্রগুলো আসলে binary addition-এর carry logic-এরই প্রতিফলন — T_n = 1 শুধু তখনই যখন সব নিচের bit 1 (ঠিক যেমন carry propagate হয় শুধু সব নিচের bit 1 থাকলে, combinational-adders লেসনের generate/propagate ধারণার সরাসরি প্রতিধ্বনি)। সব flip-flop একই মুহূর্তে বদলায় (একই CLK edge, শূন্য cumulative delay) — কোনো intermediate glitch state নেই।

উদাহরণ

Modulo-10 (BCD) Counter

সব counter power-of-2 মডুলাসে গুনতে হবে এমন কোনো নিয়ম নেই। একটা digital clock/calendar display-তে একক digit ০-৯ (mod 10) গোনে।

কৌশল: একটা 4-bit binary counter (mod 16 স্বাভাবিকভাবে) নিন, কিন্তু যখনই count 1010 (দশমিক ১০)-এ পৌঁছায়, একটা বাড়তি সার্কিট জোরপূর্বক সব flip-flop reset করে 0000-এ ফিরিয়ে দেয় — count 1010, 1011, …, 1111 কখনো “স্থিরভাবে” দেখা যায় না (শুধু একটা ক্ষণস্থায়ী মুহূর্তের জন্য 1010 দেখা যায়, সাথে সাথেই reset হয়ে যায়)।

NAND(Q3, Q1) → asynchronous clear সব flip-flop-এ
              (কারণ শুধু count=1010-এই Q3=1 এবং Q1=1 একসাথে,
               0000-1001 রেঞ্জে কখনো না)

এই “early reset” কৌশলটাই বাস্তব 74LS90-এর মতো ক্লাসিক BCD counter IC-তে ব্যবহৃত হয়।

নিজে চালিয়ে দেখুন

EXPERIMENT

Logisim-এ ripple counter-এর glitch নিজে দেখুন

Logisim Evolution বা Digital· ২০ মিনিট

১. উপরের diagram অনুযায়ী 3-bit ripple counter বানান (৩টা T flip-flop, প্রতিটার clock আগেরটার output) ২. Logisim-এর “gate delay” simulation mode সক্রিয় করুন (বাস্তব propagation delay মডেল করার জন্য) ৩. Count 011-এ পৌঁছান, একটা clock pulse দিন, আর output-কে nanosecond-স্তরের resolution-এ পর্যবেক্ষণ করুন ৪. লক্ষ্য করুন 100-এ পৌঁছানোর আগে output সংক্ষিপ্তভাবে অন্য মান (যেমন 010 বা 000) দেখাতে পারে ৫. এবার একই সার্কিট synchronous ভার্সনে (সব flip-flop একই CLK-এ, derived T logic সহ) বানিয়ে একই পরীক্ষা করুন — কোনো intermediate glitch দেখা উচিত না

এটা কী প্রমাণ করে

ripple counter-এ count=3→4 transition-এ সত্যিই একটা ক্ষণস্থায়ী ভুল intermediate অবস্থা দেখা যায় — একটা timing-sensitive simulation দিয়ে verify করা যায়।

নিজে বানান

BUILD IT

4-bit PISO শিফট রেজিস্টার — Parallel-to-Serial রূপান্তরক

Logisim / Digital · ●●○○○
  1. ৪টা D flip-flop chain করুন — প্রতিটার output পরেরটার D input
  2. প্রতিটা flip-flop-এর D input-এ একটা MUX যোগ করুন যা "load" মোডে parallel data নেয়, "shift" মোডে আগের flip-flop-এর output নেয়
  3. একটা load/shift control সিগন্যাল যোগ করুন
  4. ৪-bit parallel value load করুন, তারপর shift mode-এ ৪টা clock pulse দিয়ে bit-গুলো এক এক করে serial output-এ বের করে আনুন
  5. Output sequence verify করুন — MSB না LSB আগে বের হচ্ছে তা নিশ্চিত করুন আপনার ডিজাইন অনুযায়ী

এই সার্কিটটাই বাস্তবে UART transmitter-এর মূল ভিত্তি — একটা byte (parallel, CPU-এর ভেতরে) কে এক এক bit করে একটা তারের মধ্য দিয়ে পাঠানো (serial)। computer-representation/serialization-binary-formats লেসনে আমরা serialization-কে একটা software/format ধারণা হিসেবে আলোচনা করেছিলাম — এই সার্কিটটা সেই একই ধারণার আক্ষরিক, ভৌত বাস্তবায়ন: parallel in-memory data-কে একটা flat, ক্রমিক (serial) bit-stream-এ রূপান্তর।

বাস্তব সিস্টেমে

Counter ও Shift Register যেখানে সর্বত্র

  • Program Counter (PC) — প্রতিটা CPU-র সবচেয়ে গুরুত্বপূর্ণ counter — পরবর্তী instruction-এর ঠিকানা ধরে রাখে, প্রতি cycle-এ বৃদ্ধি পায় (অথবা branch-এ jump করে)। Level 3-এ (CPU Architecture) কেন্দ্রীয় ভূমিকা পালন করবে।

  • UART/SPI serial communication — PISO (transmit) আর SIPO (receive) shift register হার্ডওয়্যার-স্তরে serial protocol-এর ভিত্তি, প্রতিটা মাইক্রোকন্ট্রোলারে বাস্তবায়িত।

  • ডিজিটাল ঘড়ি/calendar display — mod-60 (সেকেন্ড/মিনিট), mod-24 (ঘণ্টা), mod-12/mod-10 (BCD digit) counter-এর সমষ্টি।

  • CRC checksum hardware — LFSR-ভিত্তিক সার্কিট নেটওয়ার্ক ইন্টারফেস কার্ডে সরাসরি হার্ডওয়্যারে CRC গণনা করে, প্রতিটা ইথারনেট প্যাকেটে (Level 7-এ বিস্তারিত)।

  • PRNG (pseudo-random number generator) — সাধারণ, দ্রুত, কম hardware-খরচের randomness দরকার হলে (যেমন কিছু পুরনো গেম কনসোল, বা hardware test pattern generation) LFSR ব্যবহৃত হয় — cryptographically নিরাপদ না, কিন্তু অত্যন্ত সস্তা ও দ্রুত।

  • Odometer — একটা গাড়ির যান্ত্রিক (এখন ডিজিটাল) odometer একটা mod-10 counter chain-এরই ভৌত রূপ, দশকের পর দশক ধরে ব্যবহৃত।

যে ভুলগুলো সবাই করে

“Ripple counter সবসময় খারাপ, কখনো ব্যবহার করা উচিত না।”

Ripple counter কম gate লাগে (প্রতিটা flip-flop-এর জন্য শুধু নিজের T=1, কোনো বাড়তি combinational logic না) — যেখানে গতি/glitch-মুক্ততা গুরুত্বপূর্ণ না (যেমন একটা slow-frequency LED blink counter, বা একটা frequency divider যেখানে শুধু চূড়ান্ত output-এ আগ্রহ, intermediate glitch কোনো সমস্যা তৈরি করে না), ripple counter এখনও একটা যুক্তিসঙ্গত, সস্তা পছন্দ। “সবসময় খারাপ” ভুল — প্রসঙ্গ-নির্ভর trade-off, ঠিক ripple-carry adder-এর মতো।

“Shift register শুধু 'ডেটা এক ঘর সরানোর' একটা কৌশল, তেমন গুরুত্বপূর্ণ কিছু না।”

Shift register আসলে অনেক ব্যবহারিক সার্কিটের গোপন ভিত্তি — serial communication (UART/SPI), LFSR-ভিত্তিক CRC/PRNG, এমনকি কিছু সরল delay line হিসেবেও (একটা signal-কে N clock cycle বিলম্বিত করা, শুধু N-stage shift register দিয়ে)। এই মডিউলের প্রায় প্রতিটা আগের concept-ই (D flip-flop, clock timing) এখানে সরাসরি একটা concrete, ব্যাপকভাবে ব্যবহৃত application-এ রূপ নেয়।

বুঝেছেন কি না দেখুন

1

একটা 4-bit synchronous up-counter-এ বর্তমান count 0110 (৬)। প্রতিটা flip-flop-এর T input-এর মান (T3 T2 T1 T0) কী হওয়া উচিত পরবর্তী clock edge-এ সঠিকভাবে 0111 (৭)-এ যেতে?

প্রয়োগ

T0=1 (সবসময়),T1=Q0,T2=Q0Q1,T3=Q0Q1Q2T_0 = 1 \text{ (সবসময়)}, \quad T_1 = Q_0, \quad T_2 = Q_0 \cdot Q_1, \quad T_3 = Q_0 \cdot Q_1 \cdot Q_2

বর্তমান Q3Q2Q1Q0 = 0110, অর্থাৎ Q0=0, Q1=1, Q2=1, Q3=0

T0=1T_0 = 1 T1=Q0=0T_1 = Q_0 = 0 T2=Q0Q1=01=0T_2 = Q_0 \cdot Q_1 = 0 \cdot 1 = 0 T3=Q0Q1Q2=011=0T_3 = Q_0 \cdot Q_1 \cdot Q_2 = 0 \cdot 1 \cdot 1 = 0

T3T2T1T0 = 0001 — শুধু Q0 toggle করবে।

যাচাই: Q0 টগল করে 0→1, বাকি সব অপরিবর্তিত → নতুন count 0111 (৭) ✓ — সঠিক, কারণ 0110→0111 শুধু LSB বদলায়।

2

একটা 8-bit ripple counter-এর প্রতিটা flip-flop-এর propagation delay 5ns। সবচেয়ে খারাপ ক্ষেত্রে (worst-case), সঠিক, স্থিতিশীল count value পাওয়ার আগে সর্বোচ্চ কত সময় লাগতে পারে একটা single clock edge-এর পর?

যুক্তি

Ripple counter-এ সিগন্যাল একটা flip-flop থেকে পরেরটায় ক্রমান্বয়ে propagate করে — worst case হলো যখন সব ৮টা bit toggle করে (যেমন 11111111 → 00000000)।

সেই ক্ষেত্রে MSB (bit 7)-এর toggle নির্ভর করে bit 6-এর উপর, যা নির্ভর করে bit 5-এর উপর, … এভাবে ধারাবাহিকভাবে bit 0 পর্যন্ত — পুরো chain-টাই propagate করতে হবে।

worst-case delay=8×5ns=40ns\text{worst-case delay} = 8 \times 5\text{ns} = 40\text{ns}

এই সময়ের মধ্যে output অস্থিতিশীল/glitchy থাকতে পারে। এটা সরাসরি clock-and-timing লেসনের max-frequency সূত্রের সাথে সংযুক্ত — যদি এই counter-এর output কোনো পরবর্তী synchronous circuit-এর input হয়, সেই পরবর্তী circuit-এর clock period অন্তত এই 40ns ripple delay + তার নিজের setup time যোগ করে নির্ধারণ করতে হবে, নাহলে ভুল (এখনও ripple করা) মান পড়ে ফেলার ঝুঁকি থাকে।

3

আপনাকে একটা mod-60 counter ডিজাইন করতে বলা হয়েছে (ঘড়ির সেকেন্ড/মিনিট গণনার জন্য)। সরাসরি বাইনারিতে গুনলে কত bit লাগবে, আর “early reset” কৌশল কোথায় trigger করবে?

ডিজাইন

60 পর্যন্ত গুনতে (0-59) প্রয়োজন \lceil \log_2 60 \rceil = 6 bit (যেহেতু 2^5=32 \lt 60 \le 2^6=64)।

Early reset trigger হবে যখন count 111100 (দশমিক ৬০)-এ পৌঁছায় — তখনই সব flip-flop force-reset করে 000000-এ ফিরিয়ে দিতে হবে, মডিউলো-১০ উদাহরণের মতো একই কৌশলে (নির্দিষ্ট bit combination detect করে asynchronous clear ট্রিগার করা)।

ব্যবহারিক নোট: 60 মান ৬-bit-এর সর্বোচ্চ সম্ভাব্য (63)-এর চেয়ে কম, তাই 60 থেকে 63 পর্যন্ত ৪টা মান কখনো “স্থিরভাবে” দেখা যাবে না (early reset-এর কারণে) — ঠিক BCD counter-এর 10-15 রেঞ্জের মতো একই নীতি, শুধু মডুলাস ভিন্ন।

বাস্তব ডিজিটাল ঘড়িতে এই mod-60 counter সাধারণত দুইটা BCD digit counter (mod-6 আর mod-10) হিসেবে বাস্তবায়িত হয় (“৫৯” প্রদর্শনের জন্য), একটা একক 6-bit binary counter হিসেবে না — কারণ display সরাসরি decimal digit-ভিত্তিক (seven-segment display), binary থেকে decimal-এ রূপান্তর বাড়তি জটিলতা যোগ করত।

4

একটা 4-bit SIPO shift register-এ (Serial-In, Parallel-Out) সিরিয়ালি 1, 0, 1, 1 (এই ক্রমে, প্রথমে 1) ইনপুট দেওয়া হলো, চারটা clock pulse-এ। চূড়ান্ত parallel output (Q3 Q2 Q1 Q0) কী হবে, যদি নতুন bit সবসময় Q0-তে ঢোকে আর প্রতিটা bit একধাপ করে Q0→Q1→Q2→Q3 দিকে সরে?

প্রয়োগ

প্রতিটা clock pulse-এ: নতুন bit Q0-তে ঢোকে, আর আগের সব bit এক ঘর ডানে (higher index-এ) সরে যায়।

Pulseনতুন inputQ0Q1Q2Q3
শুরু0000
111000
200100
311010
411101

চূড়ান্ত output: Q3 Q2 Q1 Q0 = 1011

লক্ষ্য করুন — যেই bit প্রথম ঢুকেছিল (1), সেটাই এখন সবচেয়ে দূরে (Q3-এ, সবচেয়ে বেশিবার shift হয়েছে)। এটাই SIPO-এর মূল আচরণ: serial stream-এর প্রথম bit শেষ পর্যন্ত সবচেয়ে significant অবস্থানে “সরে যায়” — একটা UART receiver ঠিক এই প্যাটার্নে আসা byte পুনর্গঠন করে।

এরপর কী

আমরা এখন module-এর প্রায় সব building block পেয়ে গেছি: gate, adder, MUX, ALU, flip-flop, register, FSM, counter, shift register — combinational আর sequential logic-এর একটা সম্পূর্ণ টুলবক্স।

কিন্তু একটা প্রশ্ন এখনও বাকি: এই টুকরোগুলো দিয়ে গণনার মধ্যবর্তী মান তো রাখা যায় (register), কিন্তু একটা প্রোগ্রামের পুরো ডেটা (হাজার হাজার, লক্ষ লক্ষ byte) কোথায় থাকে? পরের লেসনে আমরা memory-র ভেতরে ঢুকব — SRAM ও DRAM cell কীভাবে physically একটা bit ধরে রাখে, আর কেন দুইটার মধ্যে density, গতি, আর খরচের এত বড় পার্থক্য।

আরও পড়ুন

  • Digital Design and Computer Architecture, §3.5 — Counters and Shift Registers — Sarah Harris, David Harris · Ripple বনাম synchronous counter ডিজাইনের প্রামাণ্য তুলনা
  • Digital Logic and Computer Design, Ch. 6 — M. Morris Mano · Shift register ও LFSR-এর ক্লাসিক পাঠ্যপুস্তক আলোচনা