Counter ও Shift Register — সময় ধরে চলমান State
Counters and Shift Registers
Counter হলো সবচেয়ে সরল আকর্ষণীয় FSM — state নিজেই একটা সংখ্যা, transition সবসময় +1 mod N, অর্থাৎ হার্ডওয়্যারে বাস্তবায়িত modular arithmetic। Shift register সেই একই flip-flop chain-কে ভিন্নভাবে সাজিয়ে serial-parallel রূপান্তরের ভিত্তি তৈরি করে।
আগে এটা বুঝি
গত লেসনের শেষে আমরা বলেছিলাম: 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
└───────────┘প্রতিটা flip-flop-এর T=1 (স্থায়ীভাবে বাঁধা), তাই প্রতিটাই তার
নিজের clock input-এ প্রতিটা edge-এ toggle করে। Q0 মূল CLK-এর
অর্ধেক frequency-তে toggle করে, Q1 তার অর্ধেক (মূল CLK-এর ১/৪),
Q2 আরও অর্ধেক (১/৮) — ঠিক binary সংখ্যার প্রতিটা bit যেভাবে
গোনার সময় ভিন্ন frequency-তে বদলায়।
| CLK pulse | Q2 Q1 Q0 | দশমিক |
|---|---|---|
| শুরু | 000 | 0 |
| 1 | 001 | 1 |
| 2 | 010 | 2 |
| 3 | 011 | 3 |
| 4 | 100 | 4 |
| 5 | 101 | 5 |
| 6 | 110 | 6 |
| 7 | 111 | 7 |
| 8 | 000 | 0 (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_pd। Q1 তখনই বদলাতে
শুরু করে যখন 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, গত লেসনের পদ্ধতি অনুসারে ডিজাইন
করা):
এই সূত্রগুলো আসলে 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-তে ব্যবহৃত হয়।
নিজে চালিয়ে দেখুন
Logisim-এ ripple counter-এর glitch নিজে দেখুন
১. উপরের 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 করা যায়।
নিজে বানান
4-bit PISO শিফট রেজিস্টার — Parallel-to-Serial রূপান্তরক
- ৪টা D flip-flop chain করুন — প্রতিটার output পরেরটার D input
- প্রতিটা flip-flop-এর D input-এ একটা MUX যোগ করুন যা "load" মোডে parallel data নেয়, "shift" মোডে আগের flip-flop-এর output নেয়
- একটা load/shift control সিগন্যাল যোগ করুন
- ৪-bit parallel value load করুন, তারপর shift mode-এ ৪টা clock pulse দিয়ে bit-গুলো এক এক করে serial output-এ বের করে আনুন
- 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 (৭)-এ যেতে?
প্রয়োগ
0110 (৬)।
প্রতিটা flip-flop-এর T input-এর মান (T3 T2 T1 T0) কী হওয়া
উচিত পরবর্তী clock edge-এ সঠিকভাবে 0111 (৭)-এ যেতে?বর্তমান Q3Q2Q1Q0 = 0110, অর্থাৎ Q0=0, Q1=1, Q2=1, Q3=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-এর পর?
যুক্তি
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 করতে হবে।
এই সময়ের মধ্যে 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
দিকে সরে?
প্রয়োগ
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 | নতুন input | Q0 | Q1 | Q2 | Q3 |
|---|---|---|---|---|---|
| শুরু | — | 0 | 0 | 0 | 0 |
| 1 | 1 | 1 | 0 | 0 | 0 |
| 2 | 0 | 0 | 1 | 0 | 0 |
| 3 | 1 | 1 | 0 | 1 | 0 |
| 4 | 1 | 1 | 1 | 0 | 1 |
চূড়ান্ত 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-এর ক্লাসিক পাঠ্যপুস্তক আলোচনা