এই পর্বে যা শিখবেন
- Parallel-load register, load enable কেন mux দিয়ে আর clock gating কেন ঝুঁকির, আর synchronous বনাম asynchronous clear
- চার রকম shift register, universal shift register-এর mode, আর serial ↔ parallel রূপান্তর হাতে-কলমে
- Ring, Johnson আর LFSR-এর state sequence, Johnson decode, maximal-length sequence-এর কারণ আর ব্যবহার (CRC, scrambling, BIST)
- Ripple counter-এর waveform, frequency division, জমে ওঠা delay আর glitch; সর্বোচ্চ clock frequency-র হিসাব
- JK, T আর D flip-flop দিয়ে synchronous counter নকশা — binary, mod-6, BCD আর ইচ্ছেমতো sequence — আর Verilog-এ counter ও shift register
১ · Register — একসাথে clock পাওয়া কয়েকটি flip-flop
পর্ব ১৫-এ (Latch আর flip-flop) আপনি এক বিটের স্মৃতি দেখেছেন: একটি D flip-flop clock-এর উঠন্ত ধারে (rising edge) D-এর মান নিয়ে পরের ধার পর্যন্ত Q-তে ধরে রাখে। কিন্তু CPU এক বিট নিয়ে কাজ করে না — একটি সংখ্যা ৮, ৩২ বা ৬৪ বিটের। সমাধান সোজা: n টি D flip-flop পাশাপাশি বসান, সবার clock-এ একই তার দিন। এই দলটিই একটি n-বিটের register.
রেলস্টেশনের প্ল্যাটফর্মে আটটি দরজার একটি ট্রেন দাঁড়িয়ে আছে। বাঁশি বাজলে (clock edge) আটটি দরজা দিয়ে একসাথে যাত্রী ওঠেন, তারপর দরজা বন্ধ — পরের বাঁশি পর্যন্ত ভেতরের যাত্রী বদলায় না। প্ল্যাটফর্মে কে দাঁড়িয়ে আছেন (D input) তা যতই বদলাক, ভেতরের ছবি (Q output) বদলায় শুধু বাঁশির মুহূর্তে। Register ঠিক এই ট্রেনের কামরা: সব বিট একই মুহূর্তে নেয়, একই সাথে ধরে রাখে।
এমন register-কে বলা হয় PIPO (parallel-in, parallel-out): n টি বিট একসাথে ঢোকে, n টি বিট একসাথে পড়া যায়। এই পর্বে লেখার রীতি: register-এর বিট Q3Q2Q1Q0 এভাবে লেখা হবে, বাঁয়ে MSB; কোনো চলকের উল্টো A′ (prime) দিয়ে, আর কোডে ~A বা কোডের output-এ A'. XOR লেখা হবে ⊕ দিয়ে। Q+ মানে পরের clock edge-এর পরের মান (next state).
Load enable — নতুন মান নেবে কি না
সাধারণ register প্রতিটি clock edge-এ D নেয়। কিন্তু CPU-র ৩২টি register-এর মধ্যে এক cycle-এ সাধারণত একটিতেই লেখা হয় — বাকিদের পুরোনো মান রাখতে হবে। তাই দরকার একটি load enable (LD বা EN) সংকেত: EN = 1 হলে নতুন মান, EN = 0 হলে পুরোনো মান থেকে যাবে। এর দুটি উপায় আছে:
ঠিক উপায় — mux দিয়ে feedback
প্রতিটি flip-flop-এর D-র সামনে একটি 2:1 mux (পর্ব ১২): Di = EN′·Qi + EN·Xi. EN = 0 হলে নিজের পুরোনো Q-ই আবার D-তে ফিরে যায়, তাই clock edge এলেও মান বদলায় না। Clock অক্ষত থাকে, প্রতিটি flip-flop ঠিক একই মুহূর্তে clock পায়।
ঝুঁকির উপায় — clock আটকানো
Clock-কে একটি AND gate দিয়ে EN-এর সাথে AND করা: clock gating. EN = 0 হলে clock-ই পৌঁছায় না। দেখতে সস্তা, কিন্তু (১) AND gate-এর delay-তে এই register-এর clock বাকিদের চেয়ে দেরিতে আসে (skew), আর (২) clock 1 থাকার সময় EN বদলালে gate-এর output-এ একটি ছোট বাড়তি pulse — একটি ভুয়া clock edge — তৈরি হতে পারে।
দ্বিতীয় সমস্যাটি ভয়ংকর, কারণ flip-flop সেই ভুয়া ধারেও মান নিয়ে নেয়। পর্ব ১৮-এ (Timing আর clock) clock skew আর setup-hold নিয়ম দেখার পর এর আসল ঝুঁকি পরিষ্কার হবে। তবে বাস্তব chip-এ clock gating একেবারে নিষিদ্ধ নয় — বিদ্যুৎ বাঁচাতে এটি খুব প্রচলিত, কিন্তু তখন একটি latch আর AND মিলিয়ে বানানো বিশেষ “integrated clock gating” সেল ব্যবহার করা হয়, যাতে clock 0 থাকার সময়েই শুধু enable বদলাতে পারে। নিজে হাতে AND gate বসিয়ে clock আটকানো নতুনদের একটি প্রচলিত ভুল। FPGA-তে প্রতিটি flip-flop-এ সাধারণত একটি তৈরি clock enable pin থাকে — যা ভেতরে আসলে mux-এর কাজই করে।
Clear — synchronous না asynchronous
চালু হওয়ার মুহূর্তে flip-flop-এর মান অনির্দিষ্ট (0 বা 1 যা খুশি)। তাই প্রায় সব register-এ একটি clear বা reset থাকে, যা সব বিটকে 0 করে। দুই রকম:
- Synchronous reset: reset = 1 হলেও মান বদলায় পরের clock edge-এ। আসলে এটি D-র সামনে আরেকটি gate: Di = reset′·(পরের মান)। Clock চলতে হবে, নইলে reset কাজ করে না। সুবিধা: সবকিছু clock-এর ছন্দে, তাই timing বিশ্লেষণ সহজ।
- Asynchronous reset: flip-flop-এর ভেতরের একটি আলাদা pin (প্রায়ই active-low, CLR′) — চাপলেই সঙ্গে সঙ্গে Q = 0, clock-এর অপেক্ষা নেই। Power-on বা জরুরি অবস্থায় সুবিধাজনক, clock না চললেও কাজ করে। ঝুঁকি: reset ছাড়ার মুহূর্তটি clock edge-এর খুব কাছে পড়লে বিভিন্ন flip-flop ভিন্ন cycle-এ জেগে উঠতে পারে — তাই বাস্তবে reset সাধারণত asynchronous-ভাবে চাপা হয় কিন্তু ছাড়া হয় clock-এর সাথে মিলিয়ে (reset synchronizer পর্ব ১৭-এ, তার পেছনের metastability পর্ব ১৮-এ)।
পরীক্ষায় প্রায়ই একটি ৪-বিট register-এর ছবি আঁকতে বলা হয়, যেখানে প্রতিটি flip-flop-এর আগে একটি 2:1 mux (load) আর তার আগে বা পরে clear-এর gate. মনে রাখার সূত্র: অগ্রাধিকার clear > load > hold — প্রায় সব বাণিজ্যিক IC-তে এবং অংশ ৮-এর Verilog-এ এই ক্রম।
২ · Shift register — প্রতি clock-এ এক ঘর সরে
এবার flip-flop-গুলোকে পাশাপাশি না বসিয়ে একটি শিকলে জুড়ুন: প্রথমটির Q যায় দ্বিতীয়টির D-তে, দ্বিতীয়টির Q তৃতীয়টির D-তে, এভাবে। সবার clock একই। প্রতিটি clock edge-এ প্রতিটি flip-flop তার বাঁ পাশের প্রতিবেশীর পুরোনো মান নেয় — ফলে পুরো বিটের সারি এক ঘর সরে যায়। এটিই shift register.
ব্যাংকের কাউন্টারে চারটি চেয়ারের সারি। প্রতিবার ঘণ্টা বাজলে সবাই একসাথে এক চেয়ার সামনে সরেন: একদম সামনের জন কাউন্টারে চলে যান (output), আর পেছনের খালি চেয়ারে নতুন একজন বসেন (serial input). কেউ দুই চেয়ার লাফিয়ে যান না, কারণ সবাই ঘণ্টার মুহূর্তে নিজের সামনের চেয়ারটি দেখে সরেন — ঠিক যেমন edge-triggered flip-flop পাশেরটির পুরোনো মান নেয়। Latch দিয়ে এই শিকল বানালে enable খোলা থাকার সময় মান একসাথে কয়েক ঘর দৌড়ে যেত — এজন্যই shift register-এ edge-triggered flip-flop লাগে।
চার রকম — ডেটা কীভাবে ঢোকে আর বের হয়
| ধরন | ঢোকে | বের হয় | কাজ |
|---|---|---|---|
| SISO | এক বিট করে (serial) | এক বিট করে, শেষ ঘর থেকে | n clock-এর delay line |
| SIPO | এক বিট করে | n টি বিট একসাথে | serial → parallel (receiver) |
| PISO | n টি বিট একসাথে (load) | এক বিট করে | parallel → serial (transmitter) |
| PIPO | n টি বিট একসাথে | n টি বিট একসাথে | সাধারণ register (অংশ ১) |
PISO-তে প্রতিটি flip-flop-এর সামনে একটি 2:1 mux লাগে: load = 1 হলে বাইরের parallel বিট, load = 0 হলে প্রতিবেশীর বিট। নিচের stepper-এ একটি ৪-বিট SIPO register-এ serial লাইনে 1011 পাঠানো হচ্ছে — MSB আগে, প্রতি clock-এ বাঁয়ে সরানো (shift left), নতুন বিট ঢোকে Q0-তে:
| Clock edge | |
| Serial in (এই edge-এ) | |
| Q3 Q2 Q1 Q0 | |
| Q3 থেকে বেরোল | |
| Parallel পড়া |
- শুরু। Reset-এর পর চারটি flip-flop-ই 0. Serial লাইনে পাঠানো হবে 1, 0, 1, 1 — প্রতি clock-এ একটি বিট, MSB আগে।
- ১ নম্বর edge, serial in = 1. সবাই একসাথে বাঁয়ে সরল: Q3 নিল Q2-এর পুরোনো 0, Q2 নিল Q1-এর 0, Q1 নিল Q0-এর 0, আর Q0 নিল serial-এর 1. ফল 0001.
- ২ নম্বর edge, in = 0. আগের 1 এক ঘর বাঁয়ে Q1-এ গেল, Q0-তে নতুন 0: ফল 0010.
- ৩ নম্বর edge, in = 1. ফল 0101. খেয়াল করুন, প্রথম বিটটি এখন Q2-তে — প্রতি clock-এ ঠিক এক ঘর।
- ৪ নম্বর edge, in = 1. ফল 1011 — পাঠানো সংখ্যাটি পুরোটা register-এ। চার clock-এ চার বিট এল; এখন চারটি Q একসাথে পড়লেই parallel মান পাওয়া যায়। এটাই serial → parallel রূপান্তর।
- ৫ নম্বর edge, in = 0. কেউ পড়ে না নিলে সারি সরতেই থাকে: Q3 থেকে প্রথম পাঠানো 1 বেরিয়ে গেল, register-এ 0110. Q3-কে output ধরলে এটি SISO — ঢোকানো বিট ঠিক ৪ clock পরে বেরোয়, অর্থাৎ n-বিটের SISO একটি n clock-এর delay line.
Universal shift register — এক chip, চার mode
একটি universal shift register প্রতিটি flip-flop-এর সামনে একটি 4:1 mux বসায়, আর দুটি mode বিট S1S0 ঠিক করে D-তে কী যাবে: নিজের মান (hold), বাঁ প্রতিবেশী (shift right), ডান প্রতিবেশী (shift left), নাকি বাইরের parallel বিট (load). ডিজিটাল লজিক ল্যাবের পরিচিত 74194 (৪-বিট bidirectional universal shift register) এমনই একটি chip; প্রচলিত datasheet অনুযায়ী এর mode 00 = hold, 01 = shift right, 10 = shift left, 11 = parallel load, আর সঙ্গে একটি asynchronous, active-low clear — তবে ল্যাবে বসানোর আগে নির্মাতার datasheet-এ pin আর mode মিলিয়ে নিন।
কোথায় লাগে
- Serial ↔ parallel: একটি তার দিয়ে বিট একটির পর একটি পাঠানো সস্তা; CPU-র ভেতরে কাজ হয় একসাথে ৮ বা ৩২ বিটে। UART-এর transmitter একটি PISO (UART সাধারণত LSB আগে পাঠায়), receiver একটি SIPO. SPI-তে দুই পাশে দুটি shift register মিলে একটি বড় আংটির মতো — প্রতি clock-এ এক বিট বেরোয়, এক বিট ঢোকে (বেশিরভাগ ক্ষেত্রে MSB আগে, তবে configurable). বিস্তারিত পর্ব ৫১-এ (I/O আর bus). দ্রুত লিংকের SerDes (serializer/deserializer) এই ধারণারই বহু-গিগাবিটের রূপ।
- Delay line: n-বিটের SISO একটি সংকেতকে ঠিক n clock দেরি করায় — digital filter-এ বা ডেটাকে অন্য পথের সাথে সময় মেলাতে।
- ২ দিয়ে গুণ-ভাগ: বাঁয়ে এক ঘর সরিয়ে 0 ঢোকালে unsigned সংখ্যা ২ গুণ (0110 = ৬ → 1100 = ১২), ডানে সরালে ২ দিয়ে ভাগ, ভাগশেষ বাদ (0110 → 0011 = ৩)। Signed সংখ্যার ডান shift-এ খালি ঘরে sign বিট বসাতে হয় — arithmetic shift (পর্ব ০৬); 0 বসালে logical shift. বাঁয়ে সরাতে গিয়ে MSB-র 1 হারালে overflow.
৩ · Ring আর Johnson counter — শিকলের শেষ মাথা শুরুতে
Shift register-এর শেষ output আবার প্রথম input-এ ফিরিয়ে দিলে বিটগুলো ঘুরতে থাকে, বাইরে থেকে কিছু দিতে হয় না। প্রতিটি clock-এ register একটি নির্দিষ্ট state থেকে পরের state-এ যায়, আর কয়েক clock পরে শুরুতে ফেরে — অর্থাৎ এটি একটি counter, যদিও binary-তে গোনে না। দুই রকম feedback:
- Ring counter: Q0 সরাসরি ফেরে Q3-এ (ডানে সরানো ধরে)। শুরুতে ঠিক একটি 1 বসিয়ে দিলে (1000) সেটি ঘুরতে থাকে: 1000 → 0100 → 0010 → 0001 → 1000. n টি flip-flop-এ n টি state, আর প্রতিটি state one-hot — decode করতে কোনো gate লাগে না, প্রতিটি Q নিজেই একটি “এখন আমার পালা” সংকেত। বিনিময়ে flip-flop বেশি লাগে: ১০টি state-এর জন্য ১০টি।
- Johnson counter (twisted-ring বা Möbius counter): Q0-এর উল্টো Q0′ ফেরে Q3-এ। 0000 থেকে শুরু করলে বাঁ দিক থেকে 1 ভরতে থাকে, পুরো ভরে গেলে 0 ভরতে থাকে: n টি flip-flop-এ ২n টি state.
| Clock | Ring (Q3Q2Q1Q0) | Johnson (Q3Q2Q1Q0) | Johnson decode (২-input AND) |
|---|---|---|---|
| ০ | 1000 | 0000 | Q3′·Q0′ |
| ১ | 0100 | 1000 | Q3·Q2′ |
| ২ | 0010 | 1100 | Q2·Q1′ |
| ৩ | 0001 | 1110 | Q1·Q0′ |
| ৪ | 1000 (আবার শুরু) | 1111 | Q3·Q0 |
| ৫ | 0100 | 0111 | Q3′·Q2 |
| ৬ | 0010 | 0011 | Q2′·Q1 |
| ৭ | 0001 | 0001 | Q1′·Q0 |
কেন মাত্র দুটি বিট দেখলেই Johnson state চেনা যায়? প্রতিটি বৈধ Johnson state-এ 1-গুলো একটি টানা দল, আর 0-গুলো আরেকটি টানা দল — অর্থাৎ সারিতে (শেষ মাথা আর শুরুকে পাশাপাশি ধরে, একটি বৃত্তের মতো) বড়জোর দুটি “সীমানা” থাকে। প্রতিটি state-কে চেনানো যায় তার একটি নির্দিষ্ট সীমানা দিয়ে: যেমন 1100-এ Q2 = 1 আর Q1 = 0 — এমন “1-এর পরেই 0” ঠিক এই জায়গায় আর কোনো বৈধ state-এ নেই। দুটি প্রান্তিক state (0000 আর 1111)-এ ভেতরে কোনো সীমানা নেই, তাই সেখানে প্রান্তের দুটি বিট Q3 আর Q0 দেখা হয়। ফলে n যত বড়ই হোক, প্রতিটি decode gate ২-input — binary counter-এ যেখানে n-input AND লাগত। দ্রুত আর glitch-কম decode-এর জন্যই Johnson counter জনপ্রিয় (যেমন বহু-ধাপের timing সংকেত বানাতে)।
অব্যবহৃত state-এর ফাঁদ: ৪-বিট Johnson counter ১৬টি সম্ভাব্য state-এর মধ্যে ব্যবহার করে ৮টি। বাকি ৮টি (যেমন 0100, 1010) নিজেরাই একটি আলাদা ৮-state-এর চক্র বানায় — noise বা ভুল power-on-এ সেখানে পড়লে counter আর কখনো মূল চক্রে ফেরে না। Ring counter-এর অবস্থা আরও খারাপ: 0000 বা 1100-এর মতো state-এ পড়লে সেখানেই আটকে থাকে বা ভুল চক্রে ঘোরে। তাই দুটিকেই চালুর সময় ঠিক state-এ বসাতে হয় (reset/preset), অথবা feedback-এ বাড়তি gate দিয়ে self-starting (self-correcting) নকশা করতে হয়। অংশ ৬-এ এই প্রশ্নটি সাধারণভাবে দেখবেন।
নিচের simulator প্রথমে অংশ ২-এর SIPO/SISO, PISO আর দ্বিমুখী shift চালায়, তারপর ৪-বিট ring আর Johnson counter-এর পুরো sequence, প্রতিটি Johnson state-এর ২-input decode (নিজে খুঁজে বের করে), আর অব্যবহৃত state-এর চক্র দেখায়:
// 4-bit shift register (r[0] = Q3 ... r[3] = Q0), then ring and Johnson counters.
const s = (r) => r.join("");
const left = (r, sin) => [...r.slice(1), sin]; // Q3 <- Q2 <- Q1 <- Q0 <- sin
const right = (r, sin) => [sin, ...r.slice(0, 3)]; // sin -> Q3 -> Q2 -> Q1 -> Q0
let r = [0, 0, 0, 0], out = [];
console.log("SIPO/SISO: serial in 1,0,1,1 (MSB first) at Q0, shift left");
for (const b of [1, 0, 1, 1, 0, 0, 0, 0]) { // 4 more clocks push it out (SISO)
out.push(r[0]); r = left(r, b);
console.log(` in=${b} Q3..Q0=${s(r)} shifted out of Q3=${out.at(-1)}`);
}
r = [1, 0, 1, 1]; out = []; // PISO: parallel load, then shift
for (let c = 0; c < 4; c++) { out.push(r[0]); r = left(r, 0); }
console.log(`PISO: load 1011, 4 left shifts, serial out = ${out.join(",")}`);
r = [0, 1, 1, 0];
const steps = [["L", left], ["R", right], ["R", right]];
console.log(`bidirectional from 0110 (=6): ` + steps.map(([n, f]) =>
{ r = f(r, 0); return `${n}->${s(r)}(=${parseInt(s(r), 2)})`; }).join(" "));
const seq = (start, fb) => { let q = start, a = [];
do { a.push(q); q = right(q, fb(q)); } while (s(q) !== s(start)); return a; };
const ring = seq([1, 0, 0, 0], (q) => q[3]); // Q0 back to Q3
const john = seq([0, 0, 0, 0], (q) => 1 - q[3]); // NOT Q0 back to Q3
console.log(`ring (${ring.length} states): ${ring.map(s).join(" ")}`);
console.log(`Johnson (${john.length} states): ${john.map(s).join(" ")}`);
const pairs = [[0, 3], [0, 1], [1, 2], [2, 3]], nm = ["Q3", "Q2", "Q1", "Q0"];
for (const q of john) { // 2-input AND that is 1 only here
const [i, j] = pairs.find(([i, j]) =>
john.filter((o) => o[i] === q[i] && o[j] === q[j]).length === 1);
const lit = (k) => nm[k] + (q[k] ? "" : "'");
console.log(` ${s(q)} decoded by ${lit(i)}.${lit(j)}`);
}
const used = new Set(john.map(s)), bad = [];
for (let v = 0; v < 16 && bad.length === 0; v++) { const q = v.toString(2).padStart(4, "0");
if (!used.has(q)) bad.push(...seq([...q].map(Number), (x) => 1 - x[3])); }
console.log(`unused Johnson states form their own loop: ${bad.map(s).join(" ")}`);আউটপুট (নির্ধারিত — প্রতিবার একই):
SIPO/SISO: serial in 1,0,1,1 (MSB first) at Q0, shift left
in=1 Q3..Q0=0001 shifted out of Q3=0
in=0 Q3..Q0=0010 shifted out of Q3=0
in=1 Q3..Q0=0101 shifted out of Q3=0
in=1 Q3..Q0=1011 shifted out of Q3=0
in=0 Q3..Q0=0110 shifted out of Q3=1
in=0 Q3..Q0=1100 shifted out of Q3=0
in=0 Q3..Q0=1000 shifted out of Q3=1
in=0 Q3..Q0=0000 shifted out of Q3=1
PISO: load 1011, 4 left shifts, serial out = 1,0,1,1
bidirectional from 0110 (=6): L->1100(=12) R->0110(=6) R->0011(=3)
ring (4 states): 1000 0100 0010 0001
Johnson (8 states): 0000 1000 1100 1110 1111 0111 0011 0001
0000 decoded by Q3'.Q0'
1000 decoded by Q3.Q2'
1100 decoded by Q2.Q1'
1110 decoded by Q1.Q0'
1111 decoded by Q3.Q0
0111 decoded by Q3'.Q2
0011 decoded by Q2'.Q1
0001 decoded by Q1'.Q0
unused Johnson states form their own loop: 0010 1001 0100 1010 1101 0110 1011 0101
প্রথম চার লাইন stepper-এর সাথে হুবহু মেলে: 0001, 0010, 0101, 1011. পরের চার clock-এ serial in = 0 দিলে বেরোনো বিটগুলো 1, 0, 1, 1 — পাঠানো সংখ্যাটি ঠিক ৪ clock পরে একই ক্রমে বেরিয়ে এল (SISO delay line). PISO-তে 1011 load করে চারবার সরালে serial out 1,0,1,1 — MSB আগে। দ্বিমুখী অংশে L->1100(=12) মানে ৬ × ২ = ১২, তারপর দুবার ডানে (=6) আর (=3) — ২ দিয়ে ভাগ। Ring-এ ৪টি, Johnson-এ ৮টি state, আর decode-এর তালিকা ওপরের টেবিলের সাথে মিলে যায় — script নিজে প্রতিটি state-এর জন্য এমন একটি বিটজোড়া খুঁজেছে, যার মান আর কোনো বৈধ state-এ নেই। শেষ লাইন সতর্কবার্তাটি প্রমাণ করে: বাকি আটটি state (0010 1001 0100 …) নিজেদের মধ্যেই ঘোরে।
৪ · LFSR — XOR-এর feedback আর ছদ্ম-এলোমেলো সংখ্যা
Ring counter-এ feedback ছিল একটি তার, Johnson-এ একটি NOT. এবার feedback-এ কয়েকটি নির্দিষ্ট ঘরের (যাদের বলে tap) XOR দিন। এই circuit-এর নাম LFSR — linear feedback shift register. “Linear” কারণ XOR হলো mod-2 যোগ, আর পুরো circuit-টি mod-2 গণিতে একটি রৈখিক (linear) রূপান্তর। এখানে যে রূপটি দেখব তাকে বলে Fibonacci LFSR: বাঁয়ে সরানো, আর নতুন Q0 = tap-গুলোর XOR.
কোন ঘরে tap, তা লেখা হয় একটি feedback polynomial দিয়ে। এই পর্বের রীতি: ঘরগুলোর নম্বর ১ থেকে n, serial input-এর দিক থেকে (stage k = Qk−1); xn + xk + 1 মানে stage n আর stage k-এর XOR. উদাহরণ: x4 + x3 + 1 → নতুন Q0 = Q3 ⊕ Q2. (বই আর tool ভেদে ঘর গোনার দিক আর polynomial লেখার রীতি আলাদা হয় — কেউ উল্টো polynomial লেখেন; তুলনা করার আগে রীতি মিলিয়ে নিন।)
কাজ করা উদাহরণ — ৪-বিট, x4 + x3 + 1, seed 0001
| Clock | Q3Q2Q1Q0 | Q3 ⊕ Q2 (নতুন Q0) | Clock | Q3Q2Q1Q0 | Q3 ⊕ Q2 |
|---|---|---|---|---|---|
| ০ | 0001 | 0 | ৮ | 0101 | 1 |
| ১ | 0010 | 0 | ৯ | 1011 | 1 |
| ২ | 0100 | 1 | ১০ | 0111 | 1 |
| ৩ | 1001 | 1 | ১১ | 1111 | 0 |
| ৪ | 0011 | 0 | ১২ | 1110 | 0 |
| ৫ | 0110 | 1 | ১৩ | 1100 | 0 |
| ৬ | 1101 | 0 | ১৪ | 1000 | 1 |
| ৭ | 1010 | 1 | ১৫ | 0001 (আবার শুরু) | — |
প্রতিটি সারিতে নতুন state = আগের state বাঁয়ে সরিয়ে শেষে XOR-এর বিট: যেমন 0100 → (Q3 ⊕ Q2 = 0 ⊕ 1 = 1) → 1001. ১৫ clock পরে seed 0001-এ ফিরে এল, আর মাঝে 0000 বাদে ১৫টি ভিন্ন state-এর প্রতিটি ঠিক একবার এসেছে। এমন সর্বোচ্চ দৈর্ঘ্যের চক্রকে বলে maximal-length sequence (m-sequence), দৈর্ঘ্য ২n − ১.
কেন ২n − ১, আর কেন সব tap কাজ করে না
০-এর ফাঁদ: সব বিট 0 হলে যেকোনো XOR-ও 0, তাই 0000 থেকে পরের state আবার 0000 — চিরকাল আটকে থাকে। তাই LFSR কখনো 0 seed দিয়ে শুরু করা যায় না, আর সর্বোচ্চ চক্রে বাকি ২n − ১টি state থাকতে পারে, বেশি নয়।
চক্র কেন হয়ই: প্রতিটি state-এর পরের state নির্দিষ্ট, আর আগের state-ও একটিই (বাঁয়ে সরানোর সময় যে MSB হারাল, তা feedback বিট থেকে উল্টো হিসাব করে ফিরে পাওয়া যায়, কারণ stage n সবসময় tap-এ থাকে)। অর্থাৎ next-state function একটি এক-এক (one-to-one) ম্যাপ — তাই সব state কয়েকটি বন্ধ চক্রে ভাগ হয়ে যায়, কোনো “লেজ” থাকে না।
কোন tap-এ একটিই বড় চক্র: mod-2 বীজগণিতে দেখানো যায়, চক্রটি পুরো ২n − ১ দৈর্ঘ্যের হয় ঠিক তখন, যখন feedback polynomial একটি primitive polynomial — মোটামুটি বললে, এমন polynomial যা ছোট polynomial-এর গুণফল নয় এবং যার “ক্রম” সর্বোচ্চ। x4 + x3 + 1 আর x4 + x + 1 primitive; কিন্তু x4 + x2 + 1 = (x2 + x + 1)2 (mod 2-এ) — ভাঙা যায় বলে এটি ১৫টি state-কে ৬, ৬ আর ৩ দৈর্ঘ্যের তিনটি চক্রে ভাগ করে। পূর্ণ প্রমাণ finite field (Galois field) তত্ত্বের বিষয়; পরীক্ষায় সাধারণত tap দিয়ে sequence লিখে period গুনতে বলা হয়, যা নিচের simulator করে:
// Fibonacci LFSR: shift left, new Q0 = XOR of the tapped stages.
// Stage k = Q(k-1); polynomial x^n + x^k + 1 taps stages n and k.
function run(n, taps, seed) {
const states = [];
let q = seed;
do {
states.push(q);
let fb = 0;
for (const k of taps) fb ^= (q >> (k - 1)) & 1; // read stage k
q = ((q << 1) | fb) & ((1 << n) - 1); // shift left, feed back
} while (q !== seed);
return states;
}
const bin = (v, n) => v.toString(2).padStart(n, "0");
function report(n, taps, seed = 1) {
const st = run(n, taps, seed), max = 2 ** n - 1;
const poly = taps.map((k) => (k > 1 ? `x^${k}` : "x")).join(" + ") + " + 1";
console.log(`${n}-bit, ${poly}: period ${st.length} ` +
(st.length === max ? "= 2^n - 1, MAXIMAL" : `< ${max}, not maximal`));
return st;
}
const s4 = report(4, [4, 3]);
console.log(" states: " + s4.map((v) => bin(v, 4)).join(" "));
console.log(" output bit Q3: " + s4.map((v) => (v >> 3) & 1).join(""));
const ones = s4.filter((v) => (v >> 3) & 1).length; console.log(` ones: ${ones}, zeros: ${15 - ones}`);
report(4, [4, 1]);
const s5 = report(5, [5, 3]);
console.log(" first 8 states: " + s5.slice(0, 8).map((v) => bin(v, 5)).join(" "));
report(4, [4, 2]); // x^4 + x^2 + 1 = (x^2 + x + 1)^2
const seen = new Set(), loops = []; // split all 15 non-zero states
for (let v = 1; v < 16; v++) if (!seen.has(v)) {
const c = run(4, [4, 2], v); c.forEach((x) => seen.add(x)); loops.push(c.length);
}
console.log(` x^4 + x^2 + 1 splits the 15 non-zero states into loops of ${loops.join(", ")}`);
console.log(` seed 0000 with any taps -> period ${run(4, [4, 3], 0).length} (stuck forever)`);আউটপুট (নির্ধারিত):
4-bit, x^4 + x^3 + 1: period 15 = 2^n - 1, MAXIMAL
states: 0001 0010 0100 1001 0011 0110 1101 1010 0101 1011 0111 1111 1110 1100 1000
output bit Q3: 000100110101111
ones: 8, zeros: 7
4-bit, x^4 + x + 1: period 15 = 2^n - 1, MAXIMAL
5-bit, x^5 + x^3 + 1: period 31 = 2^n - 1, MAXIMAL
first 8 states: 00001 00010 00100 01001 10010 00101 01011 10110
4-bit, x^4 + x^2 + 1: period 6 < 15, not maximal
x^4 + x^2 + 1 splits the 15 non-zero states into loops of 6, 6, 3
seed 0000 with any taps -> period 1 (stuck forever)
প্রথম লাইনের state-এর তালিকা ওপরের টেবিলের হুবহু। Output বিট Q3-এর ধারা 000100110101111 দেখতে এলোমেলো, আর এক period-এ ones: 8, zeros: 7 — m-sequence-এ 1 সবসময় 0-এর চেয়ে ঠিক একটি বেশি (২n−1 বনাম ২n−1 − ১), কারণ সব অশূন্য state একবার করে আসে। x4 + x + 1 আর ৫-বিটের x5 + x3 + 1-ও maximal (period 31). কিন্তু x4 + x2 + 1-এ period 6 < 15, আর ১৫টি state ভেঙে যায় 6, 6, 3-এ — কোন seed দিয়ে শুরু করলেন তার ওপর নির্ভর করে আপনি এর একটিতে ঘুরবেন। শেষ লাইন: seed 0000 নিজের সাথেই চক্র (period 1).
LFSR কোথায় কাজে লাগে
ছদ্ম-এলোমেলো সংখ্যা
খুব কম hardware-এ (n টি flip-flop আর এক-দুটি XOR) প্রতি clock-এ একটি নতুন pseudo-random বিট। Test pattern, noise, game-এর পুরোনো hardware-এ বহুল ব্যবহৃত। কিন্তু নিরাপত্তার কাজে একা LFSR কখনো নয় — মাত্র ২n টি output বিট দেখেই পুরো tap আর state বের করা যায়।
CRC
নেটওয়ার্ক frame বা ফাইলের CRC হিসাবের hardware একটি LFSR, যার tap ঠিক CRC-র generator polynomial; ডেটার বিট feedback-এ XOR হয়ে ঢোকে। Polynomial ভাগের গণিত দেখুন কম্পিউটার নেটওয়ার্কস কোর্সের error detection পর্বে।
Scrambling
দ্রুত serial লিংকে অনেকক্ষণ টানা 0 বা 1 গেলে receiver clock হারিয়ে ফেলে, আর একই ধারা বারবার গেলে নির্দিষ্ট frequency-তে শক্তি জমে। ডেটাকে LFSR-এর ধারার সাথে XOR করে (scrambler) পাঠানো হয়, অন্য প্রান্তে একই LFSR দিয়ে আবার XOR করে ফেরত — PCIe, Ethernet-এর মতো লিংকে এমন scrambler আছে।
BIST
Built-in self-test: chip-এর ভেতরে একটি LFSR পরীক্ষার input বানায়, আরেকটি LFSR-ধাঁচের circuit (MISR) output-গুলোকে একটি ছোট “signature”-এ চেপে আনে। কারখানায় বা চালুর সময় signature মিললে circuit ঠিক আছে।
আরেকটি রূপ — Galois LFSR: এখানে XOR-গুলো আলাদা করে feedback বানায় না; শেষ বিটটি সরাসরি কয়েকটি ঘরের মাঝখানে XOR হয়ে ঢোকে। একই polynomial-এ একই period পাওয়া যায় (state-এর ক্রম আলাদা), কিন্তু প্রতিটি পথে বড়জোর একটি XOR — তাই দ্রুত। CRC hardware প্রায়ই এই রূপে বানানো হয়।
৫ · Asynchronous (ripple) counter — সস্তা, কিন্তু delay জমে
এবার সত্যিকারের binary counter. সবচেয়ে সরল নকশাটি পর্ব ১৫-এর T flip-flop দিয়ে: T = 1 রাখলে প্রতিটি সক্রিয় clock edge-এ Q উল্টে যায় (toggle). ধরুন flip-flop-গুলো নামন্ত ধারে (falling edge, 1 → 0) সক্রিয়। প্রথমটির clock-এ আসল clock, আর প্রতিটি পরের flip-flop-এর clock-এ আগেরটির Q. তাহলে Q1 উল্টায় যখনই Q0 1 থেকে 0-তে নামে — ঠিক যেমন binary যোগে নিচের ঘর 1 থেকে 0 হলে carry যায় ওপরের ঘরে। T flip-flop না থাকলে J = K = 1 রাখা JK flip-flop একই কাজ করে।
এখানে flip-flop-গুলো একই clock পায় না — প্রতিটি আগেরটির output দেখে চলে, তাই এটি asynchronous, আর বদল ঢেউয়ের মতো এক ঘর থেকে পরের ঘরে ছড়ায় বলে নাম ripple counter. Delay উপেক্ষা করলে ৩-বিটের waveform এমন (প্রতিটি “↓” clock-এর নামন্ত ধার):
count 0 1 2 3 4 5 6 7 0
CLK __‾‾__‾‾__‾‾__‾‾__‾‾__‾‾__‾‾__‾‾__
↓ ↓ ↓ ↓ ↓ ↓ ↓ ↓
Q0 ____‾‾‾‾____‾‾‾‾____‾‾‾‾____‾‾‾‾__ f/2
Q1 ________‾‾‾‾‾‾‾‾________‾‾‾‾‾‾‾‾__ f/4
Q2 ________________‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾__ f/8
দুটি জিনিস চোখে পড়ে। প্রথমত, প্রতিটি Q নিচেরটির অর্ধেক হারে ওঠানামা করে — Q0-এর frequency clock-এর অর্ধেক, Q1-এর এক-চতুর্থাংশ। অর্থাৎ n টি stage-এর ripple counter একটি f/২n frequency divider, আর প্রতিটি output-এর duty cycle ঠিক ৫০% (অর্ধেক সময় 1). দ্বিতীয়ত, Q2Q1Q0 একসাথে পড়লে 0, 1, 2 … 7 — binary-তে গোনা। Down counter বানাতে প্রতিটি পরের stage-এর clock-এ Q-এর বদলে Q′ দিন (অথবা উঠন্ত-ধারের flip-flop-এ Q দিন): তখন নিচের বিট 0 থেকে 1-এ উঠলে ওপরেরটি উল্টায় — ঠিক বিয়োগের borrow.
সমস্যা — delay জমে, আর মাঝপথে ভুল মান
বাস্তবে প্রতিটি flip-flop clock পাওয়ার পর Q বদলাতে কিছু সময় নেয় — তার propagation delay tpd. Ripple counter-এ দ্বিতীয় flip-flop জানতেই পারে না যে তাকে উল্টাতে হবে, যতক্ষণ না প্রথমটি উল্টে যায়। সবচেয়ে খারাপ ক্ষেত্রে (যেমন 011 → 100 বা 111 → 000) সবগুলো stage একের পর এক উল্টায়, তাই চূড়ান্ত মান স্থির হতে লাগে n × tpd. এর মাঝের সময়ে counter কিছু সত্যিকারের কিন্তু ভুল মান দেখায় — নিচের stepper-এ tpd = ১০ ns ধরে দেখুন:
| সময় | |
| যা ঘটল | |
| Q2 Q1 Q0 | |
| দেখানো মান |
- শুরু। Counter 011 = ৩-এ স্থির। পরের clock edge-এ এটি 100 = ৪ হওয়ার কথা — তিনটি বিটই বদলাবে, তাই এটি সবচেয়ে খারাপ ধরনের বদলগুলোর একটি।
- t = 0: clock নামল। কিন্তু কোনো output সঙ্গে সঙ্গে বদলায় না — Q0-এর flip-flop-কে আরও ১০ ns সময় দিতে হবে।
- t = 10 ns: Q0 উল্টাল 1 থেকে 0. Register এখন 010 = ২ দেখাচ্ছে — একটি ভুল মান। আর Q0-এর এই নামাটাই Q1-এর clock edge; Q1 এখন তার নিজের ১০ ns গুনছে।
- t = 20 ns: Q1 উল্টাল 1 থেকে 0. এখন 000 = ০ — আরেকটি ভুল মান। Q1-এর নামা Q2-কে clock দিল।
- t = 30 ns: Q2 উল্টাল 0 থেকে 1. অবশেষে 100 = ৪, স্থির। মোট সময় ৩ × ১০ = ৩০ ns = n × tpd. এর আগে কেউ count পড়লে ভুল পেতেন।
- Decoder-এর চোখে। ধরুন একটি AND gate “count = 0” (Q2′Q1′Q0′) চিনছে। t = 20 থেকে 30 ns-এর মধ্যে সে 000 দেখে ১০ ns-এর একটি 1-pulse দেয়, অথচ counter কখনো সত্যিই ০-তে যায়নি — একটি glitch. এই সংকেত দিয়ে কিছু reset বা trigger হলে ভুল ঘটবে। সমাধান: count স্থির হওয়ার পরে পড়া (strobe), অথবা synchronous counter (অংশ ৬)।
এই হিসাব থেকেই পরীক্ষার প্রচলিত সূত্র: counter-এর মান প্রতি cycle-এ অন্তত একবার স্থির হয়ে পড়ার মতো থাকতে হলে clock period T ≥ n·tpd (আর output decode করলে তার সাথে decoder gate-এর delay). তাই
যেমন ৪-বিট, tpd = ১০ ns, decode না করলে: ১ / ৪০ ns = ২৫ MHz. শুধু frequency ভাগ করতে চাইলে (প্রতিটি Q আলাদাভাবে ব্যবহার) এই সীমা খাটে না — প্রথম flip-flop যত দ্রুত toggle করতে পারে, ততটাই যথেষ্ট; তখন delay শুধু output-গুলোর মধ্যে সময়ের গরমিল (skew) বানায়। নিচের C program পুরো ৮টি গোনার প্রতিটি বদল সময়সহ ছাপে, ক্ষণস্থায়ী মানগুলো চিহ্নিত করে, আর “count = 6” decoder কতবার ভুল pulse দিল গোনে:
#include <stdio.h>
/* 3-bit ripple (asynchronous) up counter. Stage 0 toggles TPD ns after
each clock edge; stage i+1 toggles TPD ns after stage i falls 1 -> 0. */
#define N 3
#define TPD 10 /* flip-flop delay in ns */
int main(void) {
unsigned q = 0, false6 = 0; /* q = Q2 Q1 Q0 */
printf("time(ns) Q2Q1Q0 value\n");
for (int clk = 1; clk <= 8; clk++) {
int t = clk * 100; /* one active clock edge every 100 ns */
unsigned target = (q + 1) % (1u << N);
for (int stage = 0; stage < N; stage++) {
unsigned old = (q >> stage) & 1u;
t += TPD;
q ^= 1u << stage; /* this flip-flop toggles now */
printf("%6d %u%u%u %u%s\n", t, (q >> 2) & 1u, (q >> 1) & 1u,
q & 1u, q, q == target ? "" : " <- transient");
if (q == 6 && target != 6) false6++;
if (old == 0) break; /* 0 -> 1: no falling edge, ripple stops */
}
}
printf("decoder for 6 (Q2.Q1.Q0') gave %u false pulse(s)\n", false6);
printf("worst settle = %d x %d = %d ns -> f_max about %d MHz\n",
N, TPD, N * TPD, 1000 / (N * TPD));
return 0;
}আউটপুট (নির্ধারিত — সময়গুলো simulate করা, যন্ত্রের ঘড়ি থেকে নয়):
time(ns) Q2Q1Q0 value
110 001 1
210 000 0 <- transient
220 010 2
310 011 3
410 010 2 <- transient
420 000 0 <- transient
430 100 4
510 101 5
610 100 4 <- transient
620 110 6
710 111 7
810 110 6 <- transient
820 100 4 <- transient
830 000 0
decoder for 6 (Q2.Q1.Q0') gave 1 false pulse(s)
worst settle = 3 x 10 = 30 ns -> f_max about 33 MHz
প্রতিটি clock edge ঘটে ১০০ ns অন্তর (১০০, ২০০, …), আর প্রতিটি লাইনে ঠিক একটি flip-flop উল্টায়। ১ → ২ আর ৫ → ৬-এ একটি করে ক্ষণস্থায়ী মান (0 আর 4), ৩ → ৪-এ দুটি (2 আর 0, stepper-এর মতো), আর ৭ → ০-এ দুটি (6 আর 4). শেষেরটি গুরুত্বপূর্ণ: t = ৮১০ ns-এ counter ১০ ns-এর জন্য 110 দেখায়, তাই “count = 6” decoder 1 false pulse দিল — অথচ ৬২০ ns-এর আসল ৬ ঠিকই চিনেছিল। দুটিকে আলাদা করার কোনো উপায় decoder-এর নেই। শেষ লাইন: সবচেয়ে খারাপ স্থির হওয়ার সময় ৩ × ১০ = ৩০ ns, তাই মান পড়ার জন্য clock সর্বোচ্চ প্রায় 33 MHz (১/৩০ ns ≈ ৩৩.৩ MHz).
৬ · Synchronous counter নকশা — excitation table থেকে সমীকরণ
সমাধানটি নীতিগত: সব flip-flop একই clock পাবে (synchronous counter), আর কোন flip-flop এই edge-এ উল্টাবে বা কী মান নেবে, তা ঠিক করবে একটি combinational circuit — present state থেকে। তখন সব বিট একই মুহূর্তে (একটি tpd পরে) বদলায়, মাঝপথের ভুল মান প্রায় থাকে না, আর ইচ্ছেমতো যেকোনো sequence বানানো যায় — শুধু 0, 1, 2… নয়।
Excitation table — এক লাইনের স্মরণ
পর্ব ১৫-এর excitation table উল্টো প্রশ্নের উত্তর দেয়: Q থেকে Q+-এ যেতে input কী হতে হবে? এখানে শুধু সারাংশ:
| Q → Q+ | D | T | J | K |
|---|---|---|---|---|
| 0 → 0 | 0 | 0 | 0 | x |
| 0 → 1 | 1 | 1 | 1 | x |
| 1 → 0 | 0 | 1 | x | 1 |
| 1 → 1 | 1 | 0 | x | 0 |
অর্থাৎ D = Q+, T = Q ⊕ Q+, আর JK-তে দুটি x (don't care) — যেমন 0 → 1-এ J = 1 দিলেই হয়, K = 0 (set) বা 1 (toggle) দুটোতেই Q+ = 1. এই বাড়তি x-গুলোর জন্যই JK নকশায় সমীকরণ প্রায়ই সবচেয়ে ছোট হয়।
নকশার রেসিপি
- State আর flip-flop: M টি state-এর জন্য n = ⌈log2 M⌉ টি flip-flop (mod-6-এ ৩টি)।
- State table: প্রতিটি present state-এর পাশে next state. অব্যবহৃত state-এর next state = don't care (আপাতত)।
- Flip-flop input-এর কলাম: প্রতিটি বিটের Q → Q+ দেখে excitation table থেকে D, T বা J, K লিখুন।
- K-map: প্রতিটি input-এর জন্য একটি K-map (পর্ব ০৯), অব্যবহৃত state আর JK-র x সব don't care; সরল SOP বের করুন।
- যাচাই: সমীকরণে প্রতিটি অব্যবহৃত state বসিয়ে দেখুন সে কোথায় যায় — কয়েক clock-এর মধ্যে মূল চক্রে ফিরলে counter self-starting; না ফিরলে lock-out, নকশা ঠিক করতে হবে।
কাজ করা উদাহরণ ১ — ৩-বিট synchronous binary up counter
0 → 1 → … → 7 → 0. Binary যোগ মনে করুন: বিট i উল্টায় ঠিক তখন, যখন তার নিচের সব বিট 1 (carry আসছে)। তাই T flip-flop দিয়ে K-map ছাড়াই উত্তর: T0 = 1, T1 = Q0, T2 = Q1Q0, আর সাধারণভাবে Ti = Qi−1···Q0. JK দিয়ে একই: Ji = Ki = Ti. নিচের designer K-map পদ্ধতিতেও ঠিক এটিই পায়।
গতির হিসাব: এখন clock period-এর সীমা হলো একটি flip-flop-এর delay + AND gate-এর delay + পরের flip-flop-এর setup time (পর্ব ১৮): T ≥ tpd,FF + tAND + tsetup. ধরুন ১০ + ৫ + ৫ = ২০ ns → ৫০ MHz, n যত বড়ই হোক (যতক্ষণ প্রতিটি AND একটি স্তরে বানানো যায়)। একই flip-flop-এ ৪-বিট ripple counter-এর মান পড়তে লাগত ৪০ ns (২৫ MHz). খুব চওড়া counter-এ (যেমন ৬৪ বিট) AND gate-এর fan-in অনেক বড় হয়, তখন adder-এর carry-lookahead-এর মতো (পর্ব ১১) কৌশলে AND-গুলো ভাগে ভাগে বানানো হয়।
কাজ করা উদাহরণ ২ — mod-6 counter, D flip-flop দিয়ে
0 → 1 → 2 → 3 → 4 → 5 → 0; state 6 (110) আর 7 (111) অব্যবহৃত। D = Q+, তাই next state-এর বিটগুলোই D-র কলাম:
| Present Q2Q1Q0 | Next Q2+Q1+Q0+ = D2 D1 D0 |
|---|---|
| 000 (০) | 001 |
| 001 (১) | 010 |
| 010 (২) | 011 |
| 011 (৩) | 100 |
| 100 (৪) | 101 |
| 101 (৫) | 000 |
| 110, 111 | xxx (don't care) |
K-map-এ don't care ব্যবহার করে: D0 = 1 সারি ০, ২, ৪-এ → D0 = Q0′. D1 = 1 সারি ১, ২-এ: m2-কে m6 (x)-এর সাথে জুড়ে Q1Q0′, আর m1-এর কোনো 1 বা x প্রতিবেশী নেই (m0, m3, m5 সবই 0) → D1 = Q1Q0′ + Q2′Q1′Q0. D2 = 1 সারি ৩, ৪-এ: m3 + m7 → Q1Q0, m4 + m6 → Q2Q0′ → D2 = Q1Q0 + Q2Q0′.
Self-starting যাচাই: 110-এ D2 = 0 + 1 = 1, D1 = 1 + 0 = 1, D0 = 1 → 111. আবার 111-এ D2 = 1 + 0 = 1, D1 = 0 + 0 = 0, D0 = 0 → 100 = ৪, যা মূল চক্রে। তাই 6 → 7 → 4 — দুই clock-এর মধ্যে counter নিজেই ঠিক হয়ে যায়: self-starting. এবার একই counter JK দিয়ে, শুধু Q2-এর input-গুলো ধাপে ধাপে:
| যা দেখছি | |
| তথ্য | |
| Q2 = 0 সারি | |
| Q2 = 1 সারি | |
| সমীকরণ |
- Q2-এর বদলগুলো। State table থেকে শুধু Q2 কলাম: ০, ১, ২-এ সে 0-ই থাকে; ৩ → ৪-এ 0 থেকে 1 হয়; ৪ → ৫-এ 1 থাকে; ৫ → ০-তে 1 থেকে 0.
- Excitation table প্রয়োগ। প্রতিটি বদলের জন্য J2, K2 কী হবে, পর্ব ১৫-এর টেবিল থেকে। লক্ষ করুন, প্রতিটি সারিতে একটি input সবসময় x — নকশাকারের জন্য বাড়তি স্বাধীনতা।
- J2-এর K-map. Q2 = 0 থাকা অবস্থায় (state ০–৩) J2 = 0, 0, 0, 1 — শুধু state ৩ (m3)-এ 1. Q2 = 1 অবস্থায় (৪, ৫) J2 = x, আর অব্যবহৃত ৬, ৭-ও x. কলামের ক্রম 00 01 11 10, তাই m3 বসে তৃতীয় কলামে।
- J2-এর দল। একমাত্র 1 (m3, ০১১) তার নিচের m7 (১১১, x)-এর সাথে জোড়া বানায়: Q2 বাদ পড়ে, থাকে J2 = Q1·Q0. আরও বড় দল সম্ভব নয়, কারণ m1 আর m2 শূন্য।
- K2-এর K-map. K2 গুরুত্বপূর্ণ শুধু যখন Q2 = 1: state ৪-এ 0, state ৫ (m5)-এ 1; বাকি সব x. m5-কে m1, m3, m7 (সব x)-এর সাথে চারের দল বানালে টিকে থাকে শুধু Q0 = 1 শর্ত: K2 = Q0. m4 (0) দলের বাইরে, তাই ঠিক আছে।
- যাচাই। State 110-এ J2 = Q1Q0 = 0, K2 = Q0 = 0 → hold, Q2 = 1 থাকে; 111-এ J2 = K2 = 1 → toggle, Q2 = 0. বাকি বিটের সমীকরণসহ (J1 = Q2′Q0, K1 = Q0, J0 = K0 = 1) পুরো counter-এ 6 → 7 → 0 — self-starting. নিচের designer ঠিক এই সমীকরণগুলোই দেয়।
হাতের এই পদ্ধতিটি যন্ত্রে চালানো যায়। নিচের designer যেকোনো ৩-বিট sequence আর flip-flop-এর ধরন (D, T বা JK) নেয়, excitation table থেকে প্রতিটি input-এর 1 আর don't care বের করে, প্রতিটি সম্ভাব্য prime implicant-এর সমষ্টি খুঁজে সবচেয়ে ছোট SOP বাছে (brute force — ৩ চলকে মুহূর্তে হয়), তারপর circuit-টি simulate করে sequence নিশ্চিত করে, আর প্রতিটি অব্যবহৃত state কোথায় যায় তা দেখায়:
// Synchronous counter designer: state sequence + flip-flop type -> minimal SOP inputs.
const N = 3, NAME = ["Q2", "Q1", "Q0"], ALL = [...Array(2 ** N).keys()];
const EXC = { D: (q, n) => [n], T: (q, n) => [q ^ n], // excitation tables
JK: (q, n) => (q === 0 ? [n, "x"] : ["x", 1 - n]) };
const FF = { D: (q, i) => i[0], T: (q, i) => q ^ i[0], JK: (q, i) => (q ? 1 - i[1] : i[0]) };
const hit = (c, s) => (s & c.m) === c.v, bit = (x, k) => (x >> (N - 1 - k)) & 1;
const text = (c) => NAME.map((nm, k) => (bit(c.m, k) ? nm + (bit(c.v, k) ? "" : "'") : "")).join("") || "1";
function minimise(on, dc) { const imp = []; // brute force over prime implicants; cube {m: bits used, v: values}
for (let m = 0; m < 2 ** N; m++) for (let v = 0; v < 2 ** N; v++)
if ((v & ~m) === 0 && ALL.every((s) => !hit({ m, v }, s) || on.has(s) || dc.has(s))) imp.push({ m, v });
const pr = imp.filter((a) => !imp.some((b) => b !== a && (b.m & a.m) === b.m && (a.v & b.m) === b.v));
let best = { pick: [], cost: Infinity };
for (let set = 0; set < 2 ** pr.length; set++) {
const pick = pr.filter((_, k) => (set >> k) & 1);
const cost = pick.reduce((t, c) => t + 10 + NAME.filter((_, k) => bit(c.m, k)).length, 0);
if ([...on].every((s) => pick.some((c) => hit(c, s))) && cost < best.cost) best = { pick, cost };
}
return best.pick;
}
function design(seq, type) {
const next = new Map(seq.map((s, i) => [s, seq[(i + 1) % seq.length]])), eq = [];
for (let k = 0; k < N; k++) for (let p = 0; p < (type === "JK" ? 2 : 1); p++) {
const on = new Set(), dc = new Set(); for (const s of ALL) { const x = next.has(s) ? EXC[type](bit(s, k), bit(next.get(s), k))[p] : "x";
if (x === "x") dc.add(s); else if (x) on.add(s); }
eq.push({ k, cubes: minimise(on, dc), name: (type === "JK" ? "JK"[p] : type) + (N - 1 - k) });
}
const step = (s) => ALL.slice(0, N).reduce((t, _, k) => t | FF[type](bit(s, k),
eq.filter((e) => e.k === k).map((e) => +e.cubes.some((c) => hit(c, s)))) << (N - 1 - k), 0);
console.log(`${seq.join("->")}->${seq[0]}, ${type}: ` + eq.map((e) => `${e.name} = ${e.cubes.map(text).join(" + ") || "0"}`).join(", "));
const un = ALL.filter((s) => !next.has(s)).map((s) => { const path = [s];
while (!next.has(path.at(-1)) && path.indexOf(step(path.at(-1))) < 0) path.push(step(path.at(-1)));
return path.join("->") + (next.has(path.at(-1)) ? " ok" : `->${step(path.at(-1))} LOCK-OUT`); });
console.log(` sequence ${seq.every((s, i) => step(s) === next.get(s)) ? "confirmed" : "WRONG"}; unused: ${un.join(", ") || "none"}`);
}
for (const [q, t] of [[[0, 1, 2, 3, 4, 5, 6, 7], "T"], [[0, 1, 2, 3, 4, 5], "D"], [[0, 1, 2, 3, 4, 5], "JK"], [[0, 3, 5, 6], "JK"], [[0, 3, 5, 6], "D"]]) design(q, t);আউটপুট (নির্ধারিত):
0->1->2->3->4->5->6->7->0, T: T2 = Q1Q0, T1 = Q0, T0 = 1
sequence confirmed; unused: none
0->1->2->3->4->5->0, D: D2 = Q1Q0 + Q2Q0', D1 = Q1Q0' + Q2'Q1'Q0, D0 = Q0'
sequence confirmed; unused: 6->7->4 ok, 7->4 ok
0->1->2->3->4->5->0, JK: J2 = Q1Q0, K2 = Q0, J1 = Q2'Q0, K1 = Q0, J0 = 1, K0 = 1
sequence confirmed; unused: 6->7->0 ok, 7->0 ok
0->3->5->6->0, JK: J2 = Q0, K2 = Q0', J1 = 1, K1 = 1, J0 = Q1', K0 = Q1'
sequence confirmed; unused: 1->6 ok, 2->0 ok, 4->3 ok, 7->5 ok
0->3->5->6->0, D: D2 = Q0, D1 = Q1', D0 = Q2'
sequence confirmed; unused: 1->7->4->2->1 LOCK-OUT, 2->1->7->4->2 LOCK-OUT, 4->2->1->7->4 LOCK-OUT, 7->4->2->1->7 LOCK-OUT
প্রথম লাইন উদাহরণ ১-এর T2 = Q1Q0, T1 = Q0, T0 = 1. দ্বিতীয়টি উদাহরণ ২-এর D-সমীকরণ হুবহু, আর 6->7->4 ok হাতের যাচাইয়ের সাথে মেলে। তৃতীয়টি stepper-এর J2 = Q1Q0, K2 = Q0, সাথে J1 = Q2'Q0, K1 = Q0. লক্ষ করুন, একই mod-6 counter-এ D আর JK নকশায় অব্যবহৃত 6-এর পথ আলাদা (6->7->4 বনাম 6->7->0) — don't care কীভাবে বসল, তার ওপর নির্ভর করে। চতুর্থ আর পঞ্চম লাইন একটি ইচ্ছেমতো sequence 0 → 3 → 5 → 6 → 0: JK নকশায় প্রতিটি অব্যবহৃত state এক clock-এই চক্রে ঢোকে। কিন্তু D নকশার সমীকরণ যতই সুন্দর হোক (D2 = Q0, D1 = Q1', D0 = Q2'), অব্যবহৃত চারটি state নিজেদের মধ্যে 1->7->4->2->1 চক্রে ঘোরে — LOCK-OUT. Power-on-এ 1, 2, 4 বা 7-এ পড়লে counter আর কখনো আসল sequence-এ ফিরবে না।
Lock-out কীভাবে সারাবেন: অব্যবহৃত state-গুলোকে আর don't care না রেখে নিজে একটি next state দিন — যেমন 1, 2, 4, 7 সবগুলো → 0. তখন K-map-এ ওই ঘরগুলো 0 বা 1 হয়ে যায়, সমীকরণ একটু বড় হয়, কিন্তু counter নিশ্চিতভাবে self-starting. বিকল্প হলো একটি নির্ভরযোগ্য reset দিয়ে চালুর সময় 000-এ বসানো — তবে noise-এ পরে বিপথে গেলেও ফেরার উপায় রাখাই নিরাপদ নকশা। পরের পর্বের (পর্ব ১৭, Finite state machine) সব নকশায় এই প্রশ্নটি আবার আসবে।
BCD (mod-10) counter: ৪টি flip-flop, state ০ থেকে ৯, আর ১০ থেকে ১৫ অব্যবহৃত। একই রেসিপিতে T flip-flop দিয়ে পাওয়া যায় T0 = 1, T1 = Q3′Q0, T2 = Q1Q0, T3 = Q3Q0 + Q2Q1Q0 — অনুশীলন ১-এ পুরো সমাধান আর self-starting যাচাই। এমন counter দিয়ে ঘড়ি, ক্যালকুলেটর বা মিটারে দশমিক অঙ্ক গোনা হয়, আর প্রতিটি অঙ্কের output সরাসরি 7-segment decoder-এ (পর্ব ১২) যায়।
৭ · আরও counter, আর বাস্তবে কোথায় গুনছে
Up/down counter — একটি mode input
একটি mode বিট M যোগ করুন: M = 0 হলে ওপরে, M = 1 হলে নিচে গোনা। Up-এ বিট i উল্টায় যখন নিচের সব বিট 1; down-এ যখন নিচের সব বিট 0 (borrow). তাই ৩-বিটে up/down counter-এর T-সমীকরণ:
যাচাই (script দিয়ে): M = 0-তে 0, 1, 2, … 7, 0; M = 1-এ 0, 7, 6, … 1, 0. লিফটের তলার সূচক বা ক্রিকেট স্কোরবোর্ডের “বল বাকি” — দুই দিকেই গোনা লাগে এমন যেকোনো জায়গায় এই নকশা।
Parallel load আর mod-N — 74163-এর কৌশল
বাস্তব counter IC-তে register-এর মতোই parallel load থাকে: LOAD সক্রিয় হলে counter বাইরের একটি সংখ্যা নিয়ে নেয়, তারপর সেখান থেকে গোনে। ল্যাবের পরিচিত 74163 (৪-বিট synchronous binary counter) প্রচলিত datasheet অনুযায়ী synchronous clear, synchronous load, দুটি count-enable (ENP, ENT) আর একটি ripple carry output (RCO, count 1111 আর ENT = 1 হলে 1) দেয়; RCO পরের chip-এর ENT-তে দিয়ে ৮, ১২ বা ১৬ বিট জোড়া যায়। এর জুড়ি 74161-এ clear asynchronous — নকশায় এই পার্থক্যটাই আসল (pin আর সক্রিয়-নিম্ন সংকেত datasheet-এ মিলিয়ে নিন)।
পরীক্ষার প্রিয় প্রশ্ন — mod-10 বানান: synchronous clear (74163)-এ count ৯ (1001) চিনে clear দিন: পরের edge-এ 0000, তাই ০–৯. Asynchronous clear (74161)-এ ৯ চিনলে counter ৯-এই সঙ্গে সঙ্গে মুছে যেত — তাই চিনতে হয় ১০ (1010), যা কয়েক ns-এর জন্য দেখা দিয়ে মিলিয়ে যায় (আবার সেই glitch-ধাঁচের ক্ষণস্থায়ী state). এজন্য synchronous clear বা load দিয়ে mod-N বানানো বেশি নিরাপদ।
Gray-code counter
পর্ব ০৪-এর (সংখ্যা পদ্ধতি) Gray code-এ পরপর দুটি মানে ঠিক একটি বিট বদলায়: 000, 001, 011, 010, 110, 111, 101, 100. এই sequence-কে অংশ ৬-এর designer-এ দিলেই একটি Gray-code counter পাওয়া যায়। লাভ: প্রতি গোনায় একটিই flip-flop বদলায়, তাই বিদ্যুৎ কম আর ভিন্ন clock-এর অংশ থেকে counter পড়লেও বড় ভুল হয় না — পড়ার মুহূর্তে বড়জোর পুরোনো বা নতুন মান, মাঝের কোনো আজব মান নয়। Asynchronous FIFO-র pointer এভাবেই এক clock domain থেকে আরেকটিতে পাঠানো হয় (ভাবনার প্রশ্ন ০৫; পর্ব ১৮)।
Frequency divider — ঘড়ির ৩২,৭৬৮ Hz থেকে ১ Hz
হাতঘড়ি বা দেয়ালঘড়ির quartz crystal সাধারণত ৩২,৭৬৮ Hz-এ কাঁপে। সংখ্যাটি বেছে নেওয়ার কারণ: ৩২,৭৬৮ = ২১৫. তাই ১৫টি T flip-flop-এর একটি ripple counter শেষ stage-এ ঠিক ১ Hz দেয় — প্রতি সেকেন্ডে এক টিক। এখানে ripple-এর delay কোনো সমস্যা নয়, কারণ কেউ পুরো count পড়ছে না, শুধু শেষ বিটটি ব্যবহার হচ্ছে; আর ripple counter-এ বেশিরভাগ flip-flop খুব কম বদলায় বলে বিদ্যুৎ খরচ নগণ্য — ব্যাটারির ঘড়ির জন্য আদর্শ। ২-এর ঘাত নয় এমন ভাগের জন্য (÷N) একটি mod-N counter লাগে; তখন output-এর duty cycle ৫০% না-ও হতে পারে।
CPU আর microcontroller-এর ভেতরে counter
- Program counter: একটি ৩২-বিট register, যার পরের মান প্রায় সবসময় PC + 4 (RV32I-এ প্রতিটি instruction ৪ byte; compressed extension থাকলে কখনো + 2), আর branch-jump-এ একটি নতুন ঠিকানা load. অর্থাৎ এটি “parallel load-সহ counter”, শুধু ১-এর বদলে ৪ যোগ — বাস্তবে একটি adder আর একটি mux দিয়ে। পুরো ছবি পর্ব ৩২-এ (Single-cycle datapath), যেখানে register file-ও আসবে।
- Timer আর watchdog: microcontroller-এর timer একটি prescaler (frequency divider) আর একটি counter, যা নির্দিষ্ট মানে পৌঁছালে interrupt দেয় — LED জ্বালানো-নেভানো থেকে motor-এর PWM পর্যন্ত। Watchdog একটি counter যা software-কে নিয়মিত reset করতে হয়; software আটকে গেলে counter শেষ সীমায় পৌঁছে পুরো chip reset করে দেয়। বিস্তারিত পর্ব ৫৬-এ।
- Performance counter: CPU-র ভেতরে cycle, instruction, cache miss গোনার ৬৪-বিট counter — RISC-V-তে যেমন
mcycleআরminstret. পর্ব ০৩-এ CPI মাপার সময় আপনি এদের সংখ্যাই ব্যবহার করেছেন।
৮ · Verilog-এ counter আর shift register, আর ল্যাবের IC
পর্ব ১৪-এ (Verilog-এর পরিচয়) আপনি always @(posedge clk) আর non-blocking assignment (<=) দেখেছেন। এই পর্বের সব block এই দুটি দিয়েই কয়েক লাইনে লেখা যায়। নিচে synthesizable Verilog-2001 (চালানো যায় না — উদাহরণ): একটি ৪-বিট counter (asynchronous active-low reset, load, enable আর terminal count), একটি ৮-বিট shift register (synchronous reset, enable), আর একটি ৪-বিট LFSR:
// উদাহরণ — synthesizable Verilog-2001
module counter4 (
input wire clk, rst_n, // rst_n: asynchronous, active-low
input wire load, en, // priority: reset > load > count
input wire [3:0] d,
output reg [3:0] q,
output wire tc // terminal count: q == 15 while enabled
);
always @(posedge clk or negedge rst_n)
if (!rst_n) q <= 4'd0;
else if (load) q <= d;
else if (en) q <= q + 4'd1; // no final else: q simply holds
assign tc = en & (q == 4'd15);
endmodule
module shift8 (
input wire clk, rst, // rst: synchronous, active-high
input wire en, sin,
output reg [7:0] q, // parallel out (SIPO)
output wire sout // serial out (SISO)
);
always @(posedge clk)
if (rst) q <= 8'd0;
else if (en) q <= {q[6:0], sin}; // shift left, serial in at bit 0
assign sout = q[7];
endmodule
module lfsr4 (input wire clk, rst, output reg [3:0] q); // x^4 + x^3 + 1
always @(posedge clk)
if (rst) q <= 4'b0001; // never seed with 0000
else q <= {q[2:0], q[3] ^ q[2]};
endmodule
তিনটি বিষয় খেয়াল করুন। (১) else if (en)-এর পরে কোনো else নেই, তবু এখানে অনিচ্ছাকৃত latch তৈরি হয় না — clock-চালিত block-এ “কিছু না বলা” মানে flip-flop আগের মান রাখবে, আর synthesis tool ঠিক অংশ ১-এর load-enable mux বানায় (অথবা flip-flop-এর clock-enable pin ব্যবহার করে)। Clock আটকানো হয় না। (২) Sensitivity list-এ negedge rst_n থাকলেই reset asynchronous; shift8-এর মতো শুধু posedge clk থাকলে synchronous. (৩) {q[6:0], sin}-এর concatenation-ই পুরো shift — আর non-blocking <=-এর কারণে সব বিট একসাথে পুরোনো মান পড়ে, ঠিক hardware-এর মতো। এখানে blocking = দিয়ে বিটগুলো একটি একটি লিখলে simulation আর hardware-এর আচরণ আলাদা হয়ে যেতে পারত।
ল্যাবের পরিচিত IC
বিশ্ববিদ্যালয়ের ল্যাবে প্রায়ই 74-series chip দিয়ে এই block-গুলো জোড়া হয়। নিচের বর্ণনা প্রচলিত datasheet অনুযায়ী; পরিবার (74LS, 74HC ইত্যাদি) আর নির্মাতাভেদে খুঁটিনাটি আলাদা হতে পারে, তাই বসানোর আগে datasheet মিলিয়ে নিন:
| IC | কাজ | মনে রাখার বিষয় |
|---|---|---|
| 74164 | ৮-বিট SIPO shift register | দুটি serial input (AND করা), asynchronous clear |
| 74165 | ৮-বিট PISO shift register | parallel load দিয়ে বোতাম বা switch পড়ে serial-এ পাঠানো |
| 74595 | ৮-বিট SIPO + output latch | shift চলার সময় output স্থির থাকে; LED বা display চালাতে খুব প্রচলিত |
| 74194 | ৪-বিট universal shift register | S1S0 দিয়ে hold, right, left, load (অংশ ২) |
| 7493 / 7490 | ৪-বিট ripple binary / decade counter | asynchronous — অংশ ৫-এর glitch এখানে দেখা যায় |
| 74161 / 74163 | ৪-বিট synchronous binary counter | 161-এ asynchronous clear, 163-এ synchronous clear; দুটিতেই load, ENP, ENT, RCO |
| 74193 | ৪-বিট synchronous up/down counter | up আর down-এর জন্য আলাদা clock input |
আরও গভীরে: আধুনিক chip-এ shift register-এর সবচেয়ে বড় ব্যবহারটি চোখে পড়ে না — scan chain. কারখানায় পরীক্ষার সময় chip-এর প্রায় সব flip-flop-কে একটি বিশেষ mode-এ একটি দীর্ঘ shift register-এ জুড়ে দেওয়া হয়, যাতে বাইরে থেকে serial-ভাবে যেকোনো state ঢুকিয়ে এক clock চালিয়ে ফল আবার serial-ভাবে বের করে আনা যায়; LFSR-ভিত্তিক BIST আর pattern compression এর সাথে মিলে কাজ করে। JTAG (IEEE 1149.1) এই ধরনের shift-register-ভিত্তিক test access-এর একটি পরিচিত মান। FPGA-তে একটি LUT প্রায়ই নিজেই একটি ছোট shift register (যেমন ১৬ বা ৩২ ধাপের) হিসেবে কাজ করতে পারে, যা delay line-কে প্রায় বিনা খরচে বানায় — নির্দিষ্ট ক্ষমতা পরিবারভেদে আলাদা।
পরীক্ষা ও ইন্টারভিউতে এই বিষয়ে প্রায়ই যা জিজ্ঞেস করা হয়:
- n-বিট ring আর Johnson counter-এ কয়টি state? — ring-এ n, Johnson-এ ২n; ২n-এর বাকিগুলো অব্যবহৃত, তাই reset বা self-correcting feedback লাগে।
- Ripple counter-এর সর্বোচ্চ clock frequency? — fmax = ১ / (n·tpd + tdecode); synchronous-এ ১ / (tpd + tgate + tsetup), n-এর ওপর প্রায় নির্ভর করে না।
- Load enable-এর জন্য clock gating কেন খারাপ? — clock skew আর enable বদলের সময় ভুয়া clock pulse; mux দিয়ে পুরোনো মান ফেরানোই নিরাপদ।
- n-বিট LFSR-এর সর্বোচ্চ period? — ২n − ১ (0 বাদ), শুধু primitive feedback polynomial-এ।
- Self-starting counter কী? — যেকোনো অব্যবহৃত state থেকে কয়েক clock-এ নিজেই মূল sequence-এ ফেরে; নকশার শেষে প্রতিটি অব্যবহৃত state বসিয়ে যাচাই করতে হয়।
৯ · AI-এর যুগে — sequence নিজে simulate করে যাচাই
“JK flip-flop দিয়ে mod-6 counter নকশা করুন” লিখলে AI চ্যাটবট কয়েক সেকেন্ডে টেবিল আর সমীকরণ দেয় — প্রায়ই নিখুঁত দেখতে, কিন্তু একটি K-map দল ভুল, বা excitation table-এর x বসানো উল্টো। অব্যবহৃত state যাচাই সে প্রায়ই বাদই দেয়। এই পর্বের বিষয়ে সাধারণ ভুলগুলো:
| AI প্রায়ই যা ভুল করে | কীভাবে ধরবেন |
|---|---|
| JK excitation-এ J আর K-এর x উল্টে ফেলা; T নকশায় T = Q+ লিখে ফেলা | প্রতিটি সারিতে Q → Q+ নিজে দেখে excitation table মেলান |
| K-map-এ ভুল দল, অথবা অব্যবহৃত state-কে don't care না ধরা | সমীকরণে প্রতিটি present state বসিয়ে next state হিসাব করুন (এই পর্বের designer-এ) |
| Self-starting যাচাই বাদ দেওয়া বা ভুল দাবি করা | প্রতিটি অব্যবহৃত state থেকে কয়েক clock চালিয়ে দেখুন কোথায় যায় |
| LFSR-এর tap আর polynomial-এর রীতি মিশিয়ে ফেলা, period ভুল বলা | রীতি লিখে দিন (কোন ঘর stage 1), তারপর পুরো sequence গুনে period বের করুন |
| Ripple counter-এর fmax-এ n দিয়ে গুণ করতে ভুলে যাওয়া | সবচেয়ে খারাপ বদলটি (সব বিট উল্টায়) সময়সহ হাতে লিখুন |
Verilog-এ blocking = দিয়ে shift register, বা নিজে AND দিয়ে clock gating | Simulation-এ waveform দেখুন; clocked block-এ <= আর enable-এর জন্য if |
| 74-series chip-এর pin বা clear-এর ধরন বানিয়ে বলা | সবসময় নির্মাতার datasheet |
AI-কে শুধু উত্তর না চেয়ে প্রতিটি ধাপ আর simulation চাইলে ভুল সহজে ধরা পড়ে:
AI-এর উত্তর হাতে পেলে — যাচাইয়ের চেকলিস্ট
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিয়ে নিজে কিছুক্ষণ ভাবুন — তারপর “→ উত্তর” চাপুন।
প্র ০১প্রথম দিকের কিছু stored-program computer-এর মূল মেমরি ছিল পারদ-ভরা নলের ভেতর দিয়ে চলা শব্দ-তরঙ্গ। এটি কীভাবে আসলে একটি বিশাল shift register, আর আজ এই ধারণা কোথায় টিকে আছে?
১৯৪০-এর দশকের শেষে মেমরি বানানো ছিল কম্পিউটার নির্মাতাদের সবচেয়ে কঠিন সমস্যা। Vacuum tube দিয়ে প্রতিটি বিটের জন্য flip-flop বানানো খুব দামি আর অবিশ্বাস্য ছিল। একটি জনপ্রিয় সমাধান ছিল acoustic delay line: পারদ-ভরা একটি নলের এক মাথায় একটি crystal বিদ্যুৎ-সংকেতকে শব্দ-তরঙ্গে বদলায়, তরঙ্গটি ধীরে (তারের তুলনায়) নল দিয়ে চলে, অন্য মাথায় আরেকটি crystal সেটিকে আবার বিদ্যুতে ফেরায়। সেই সংকেত পরিবর্ধন করে আবার শুরুর মাথায় পাঠানো হতো। ১৯৪৯ সালে কাজ শুরু করা Cambridge-এর EDSAC আর পরে UNIVAC I-এর মতো যন্ত্রে এমন মেমরি ব্যবহার হয়।
এই পর্বের ভাষায় এটি হুবহু একটি SISO shift register যার output আবার input-এ ফেরে — অর্থাৎ একটি ring. নলের ভেতরে যেকোনো মুহূর্তে কয়েকশো বিট “ভ্রমণ” করছে; প্রতিটি বিট একটি নির্দিষ্ট সময় পরপর শেষ মাথায় আসে। এর বড় সীমাবদ্ধতা: random access নেই। একটি নির্দিষ্ট word পড়তে হলে সেটি নলের শেষ মাথায় না আসা পর্যন্ত অপেক্ষা করতে হতো — গড়ে অর্ধেক চক্রের সময়। তাই সেই যুগের প্রোগ্রামাররা instruction আর ডেটা এমনভাবে সাজাতেন যাতে পরের দরকারি word ঠিক সময়মতো বেরিয়ে আসে; পরের drum memory-তেও একই ধরনের “অনুকূল স্থান-নির্ধারণ” প্রোগ্রামিং-এর অংশ ছিল।
১৯৫০-এর দশকে magnetic core memory এসে random access দেয়, আর delay line মূল মেমরি থেকে বিদায় নেয়। কিন্তু serial ধারণাটি হারায়নি। কিছু পুরোনো video terminal-এ পর্দার অক্ষর রাখা হতো shift register-ভিত্তিক মেমরিতে, কারণ পর্দা এমনিতেই ক্রমানুসারে আঁকা হয়। আর আজকের প্রতিটি দ্রুত লিংক — PCIe, USB, SATA, Ethernet — chip-এর ভেতরের চওড়া parallel ডেটাকে একটি SerDes-এর shift register দিয়ে serial-এ পাঠায়, কারণ খুব বেশি গতিতে অনেক তারকে একসাথে সময় মেলানো (skew) প্রায় অসম্ভব হয়ে যায়।
মূল উপলব্ধি: Shift register হলো “সময়কে মেমরি হিসেবে ব্যবহার করা” — ডেটা এক জায়গায় বসে থাকে না, চলতে চলতে মনে থাকে। এটি সস্তা কিন্তু ক্রমানুসারী; আর যেখানে ডেটা এমনিতেই ক্রমে আসে (লিংক, display, filter), সেখানে আজও এটিই সেরা সমাধান।
প্র ০২প্রায় সব quartz ঘড়ির crystal ঠিক ৩২,৭৬৮ Hz-এ কাঁপে কেন — ১০,০০০ বা ১,০০,০০০ Hz নয় কেন? এই একটি সংখ্যার পেছনে কোন কোন প্রকৌশল-সমঝোতা লুকিয়ে আছে?
প্রথম বাণিজ্যিক quartz হাতঘড়ি হিসেবে সাধারণত Seiko-র Astron-কে ধরা হয়, যা ১৯৬৯ সালের শেষে জাপানে বাজারে আসে। তারপর এক দশকের মধ্যে quartz ঘড়ি সস্তা হয়ে যান্ত্রিক ঘড়ির বাজার বদলে দেয়। এর হৃদয় একটি ছোট quartz crystal, যা বিদ্যুৎ দিলে খুব স্থির একটি frequency-তে কাঁপে, আর একটি CMOS chip সেই কাঁপুনিকে ভাগ করে প্রতি সেকেন্ডে একটি pulse বানায়, যা motor-এর কাঁটা এক ঘর এগোয় বা display-র সংখ্যা বদলায়।
৩২,৭৬৮ = ২১৫ — এটাই প্রথম কারণ। অংশ ৭-এর মতো ১৫টি T flip-flop-এর একটি সরল ripple counter-ই ঠিক ১ Hz দেয়; কোনো mod-N যুক্তি, তুলনা বা reset-এর gate লাগে না। ১০,০০০ Hz নিলে ÷১০,০০০-এর জন্য কয়েকটি mod-10 counter লাগত — বেশি gate, বেশি বিদ্যুৎ।
দ্বিতীয় কারণ বিদ্যুৎ। CMOS-এ dynamic power মোটামুটি frequency-র সমানুপাতিক (পর্ব ০২)। প্রথম flip-flop প্রতি সেকেন্ডে ৩২,৭৬৮ বার উল্টায়, দ্বিতীয়টি তার অর্ধেক, তৃতীয়টি এক-চতুর্থাংশ — মোট বদল প্রায় প্রথমটির দ্বিগুণ মাত্র। Frequency যত কম, বিদ্যুৎ তত কম, আর একটি ছোট বোতাম-ব্যাটারি বহু বছর চলে। তাহলে আরও কম, যেমন ১,০২৪ Hz কেন নয়? কারণ তৃতীয় সমঝোতা: crystal-এর আকার। সাধারণ tuning-fork আকৃতির crystal-এ frequency কম হলে crystal লম্বা হতে হয়; ৩২ kHz-এর কাছাকাছি crystal হাতঘড়িতে ধরার মতো ছোট, আবার মানুষের কানে শোনার সীমার (প্রায় ২০ kHz) ওপরে, তাই কোনো গুনগুন শব্দ শোনা যায় না। এই তিন শর্তের মিলনবিন্দুতে ২-এর ঘাত ২১৫ বসে যায়।
আজ একই crystal প্রায় প্রতিটি computer আর phone-এর real-time clock (RTC)-এ, আর অনেক microcontroller-এর কম-বিদ্যুতের “ঘুমের ঘড়ি”-তে। মূল CPU-র GHz clock আসে আলাদা, দ্রুত crystal আর PLL থেকে; কিন্তু তারিখ আর সময় গোনে এই নিঃশব্দ ১৫-ধাপের ভাগফল।
মূল উপলব্ধি: একটি “জাদুর সংখ্যা” আসলে কয়েকটি প্রকৌশল-সীমার ছেদবিন্দু — hardware-এর সরলতা (২-এর ঘাত), বিদ্যুৎ (কম frequency) আর ভৌত আকার। Counter-এর নকশা এখানে পুরো পণ্যের নকশা ঠিক করে দিয়েছে।
প্র ০৩LFSR এত সস্তায় এত “এলোমেলো” ধারা দেয় যে GPS, PCIe থেকে mobile ফোনের পুরোনো encryption পর্যন্ত এটি ব্যবহার হয়েছে। তাহলে শুধু LFSR দিয়ে গোপন তথ্য রক্ষা করা কেন বিপজ্জনক?
LFSR-এর গণিত গভীরভাবে গড়ে ওঠে ১৯৫০-৬০-এর দশকে; Solomon Golomb-এর ১৯৬৭ সালের বই Shift Register Sequences এই বিষয়ের একটি মূল গ্রন্থ হিসেবে পরিচিত। Golomb দেখান, maximal-length sequence-এর পরিসংখ্যান অনেকটা মুদ্রা ছোড়ার মতো: 1 আর 0 প্রায় সমান, টানা একই বিটের দলের দৈর্ঘ্যের বণ্টন এলোমেলো ধারার মতো, আর ধারাটি নিজের সরানো কপির সাথে প্রায় মেলে না (autocorrelation কম)। এই শেষ গুণটি যোগাযোগে অমূল্য।
যেমন GPS-এর civilian C/A code: প্রতিটি উপগ্রহ দুটি ১০-বিটের LFSR-এর output XOR করে বানানো একটি ১,০২৩ chip দীর্ঘ “Gold code” পাঠায়। Receiver জানে কোন উপগ্রহের কোন code, আর নিজের কপি সরিয়ে সরিয়ে মিলিয়ে দেখে — যে সরণে মিল সর্বোচ্চ, তা থেকে সংকেত পৌঁছানোর সময়, আর তা থেকে দূরত্ব। একই frequency-তে সব উপগ্রহ একসাথে পাঠালেও code আলাদা বলে আলাদা করা যায়। PCIe-র প্রথম দিকের প্রজন্মে একটি ১৬-বিট LFSR scrambler আর ১০ Gb/s Ethernet-এ একটি self-synchronizing scrambler — দুটিই অংশ ৪-এর ধারণা।
কিন্তু “এলোমেলো দেখায়” আর “অনুমান করা যায় না” এক কথা নয়। LFSR পুরোপুরি linear, তাই একটি n-বিটের LFSR-এর output থেকে মাত্র ২n টি টানা বিট পেলেই Berlekamp–Massey algorithm দিয়ে পুরো feedback polynomial আর state বের করা যায় — তারপর ভবিষ্যতের সব বিট জানা। তাই নিরাপত্তার নকশায় কখনো একা LFSR ব্যবহার করা হয় না। GSM ফোনের A5/1 cipher তিনটি LFSR (১৯, ২২ আর ২৩ বিট) অনিয়মিতভাবে clock করে linearity ভাঙার চেষ্টা করেছিল, তবু গবেষকরা পরে এর গুরুতর দুর্বলতা দেখান, আর নতুন প্রজন্মের নেটওয়ার্কে শক্তিশালী algorithm আনা হয়।
প্রতিরক্ষার শিক্ষাটি পরিষ্কার: scrambling, CRC, test pattern বা simulation-এর জন্য LFSR চমৎকার; কিন্তু চাবি, password বা token বানাতে operating system-এর cryptographically secure random generator (যেমন Linux-এ getrandom) আর প্রমাণিত cipher (যেমন AES) ব্যবহার করুন।
মূল উপলব্ধি: LFSR-এর শক্তি আর দুর্বলতা একই জায়গা থেকে আসে — linearity. এটাই একে সস্তা, দ্রুত আর গণিতে বিশ্লেষণযোগ্য করে, আবার এটাই আক্রমণকারীর কাছে পুরো ভবিষ্যৎ খুলে দেয়।
প্র ০৪প্রথম IBM PC-র system timer সেকেন্ডে প্রায় ১৮.২ বার “টিক” দিত — এমন অদ্ভুত সংখ্যা কোথা থেকে এল? আর মহাকাশযান থেকে কারখানার যন্ত্র পর্যন্ত watchdog counter কেন অপরিহার্য?
১৯৮১ সালের IBM PC-তে Intel-এর 8253 (পরে PC/AT-এ 8254) programmable interval timer ছিল — তিনটি স্বাধীন ১৬-বিট down counter-এর একটি chip. এর input clock ছিল প্রায় ১.১৯৩১৮২ MHz, যা board-এর একটি ১৪.৩১৮১৮ MHz crystal-কে ১২ দিয়ে ভাগ করে আসত (ওই crystal নিজে টেলিভিশনের রঙের সংকেতের frequency-র ৪ গুণ — সস্তা আর সহজলভ্য বলে)। Channel 0-কে সবচেয়ে বড় ভাজক ৬৫,৫৩৬ দিয়ে চালালে interrupt আসে ১,১৯৩,১৮২ / ৬৫,৫৩৬ ≈ ১৮.২০৬৫ বার প্রতি সেকেন্ডে — DOS-এর সময় গোনার টিক। অর্থাৎ একটি “অদ্ভুত” সংখ্যা আসলে একটি crystal, দুটি ভাগ আর একটি ১৬-বিট counter-এর সর্বোচ্চ মানের ফল — ঠিক এই পর্বের frequency divider.
Timer নির্দিষ্ট সময় পরপর কাজ করায়; watchdog উল্টো কাজ করে — সে অপেক্ষা করে কিছু না ঘটার জন্য। Software নিয়মিত তাকে reset করে (“kick” বা “feed” করা)। কোনো bug-এ software আটকে গেলে counter শেষ সীমায় পৌঁছে পুরো system reset করে দেয়। দূরের, মানুষের নাগালের বাইরের যন্ত্রে এটি শেষ রক্ষাকবচ। ১৯৯৭ সালে মঙ্গলে নামা Mars Pathfinder বারবার নিজে থেকে reset হচ্ছিল — পরে জানা যায় কারণ ছিল একটি priority inversion (একটি OS-এর scheduling সমস্যা, দেখুন অপারেটিং সিস্টেম কোর্স), আর reset-গুলো ঘটাচ্ছিল একটি watchdog-ধাঁচের timer যা দেখছিল একটি জরুরি কাজ সময়মতো শেষ হয়নি। Reset-এর কারণে যান হারায়নি; প্রকৌশলীরা পৃথিবী থেকে software-এ একটি setting বদলে সমস্যা মেটান।
ভালো watchdog নকশার কয়েকটি নিয়ম এই পর্বের ভাষাতেই বোঝা যায়: watchdog-এর নিজের clock মূল clock থেকে আলাদা হওয়া উচিত (মূল clock থেমে গেলে watchdog-ও থামলে সে কিছুই ধরবে না); counter-কে software যেন ভুল করে বন্ধ করতে না পারে (অনেক microcontroller-এ একবার চালু করলে বন্ধ করা যায় না); আর “window” watchdog খুব তাড়াতাড়ি kick করলেও reset দেয়, যাতে একটি লুপে আটকে বারবার kick করা software-ও ধরা পড়ে।
মূল উপলব্ধি: একটি সরল counter সময়ের দুই রকম পাহারাদার — timer বলে “এখন কাজের সময়”, watchdog বলে “এতক্ষণে কাজ হয়ে যাওয়ার কথা ছিল”। নির্ভরযোগ্য system দুটিকেই hardware-এ রাখে, কারণ software নিজের ভুল নিজে সবসময় ধরতে পারে না।
প্র ০৫দুটি ভিন্ন clock-এ চলা অংশের মধ্যে ডেটা পাঠাতে asynchronous FIFO ব্যবহার হয়, আর তার read-write pointer প্রায় সবসময় Gray code-এ গোনা হয়। Binary counter-এর pointer পাঠালে ঠিক কী ভুল হতে পারত?
আধুনিক chip-এ অনেক clock domain: CPU core হয়তো ৩ GHz-এ, মেমরি controller আরেক frequency-তে, USB বা camera interface আরেকটিতে। এক domain থেকে আরেকটিতে ডেটা পাঠানোর প্রচলিত উপায় একটি asynchronous FIFO — একটি ছোট মেমরি, যার একদিকে লেখক নিজের clock-এ লেখে, অন্যদিকে পাঠক নিজের clock-এ পড়ে। FIFO খালি না ভরা, তা বুঝতে প্রত্যেককে অন্যের pointer (একটি counter) দেখতে হয় — অর্থাৎ একটি বহু-বিটের মান ভিন্ন clock-এর flip-flop দিয়ে ধরতে হয়।
এখানে অংশ ৫-এর সমস্যা নতুন রূপে আসে। ধরুন লেখকের binary pointer 0111 থেকে 1000-এ যাচ্ছে — চারটি বিটই বদলাচ্ছে। পাঠকের clock edge ঠিক এই বদলের মুহূর্তে পড়লে প্রতিটি বিট আলাদাভাবে পুরোনো বা নতুন মান ধরতে পারে, কারণ তারগুলোর delay সামান্য আলাদা। ফলে পাঠক 1111, 0000, 1010 — যেকোনো আজব মান দেখতে পারে, যা কখনো আসল pointer ছিল না। FIFO তখন ভুল করে “ভরা” বা “খালি” ভেবে ডেটা হারাতে বা পুরোনো ডেটা আবার পড়তে পারে। তার ওপর প্রতিটি বিটের flip-flop metastability-র ঝুঁকিতেও পড়ে (পর্ব ১৮)।
Gray-code pointer-এ প্রতি গোনায় ঠিক একটি বিট বদলায় (পর্ব ০৪)। তাই ভুল মুহূর্তে ধরলেও পাঠক পায় হয় পুরোনো মান, নয় নতুন মান — দুটিই সত্যিকারের pointer, মাঝের কোনো আজব মান নয়। পুরোনো মান পেলে FIFO শুধু একটু রক্ষণশীল হয় (এক cycle পরে বোঝে নতুন ডেটা এসেছে), কোনো ডেটা নষ্ট হয় না। প্রতিটি বিট আবার দুই ধাপের synchronizer flip-flop দিয়ে পার করা হয়, যাতে metastability মিলিয়ে যাওয়ার সময় পায়। এই নকশাটি শিল্পে এত প্রচলিত যে verification-এর tool-গুলো clock domain crossing-এ “বহু-বিটের binary মান সরাসরি পার হচ্ছে” দেখলে সতর্কবার্তা দেয়।
একটি সূক্ষ্মতা: Gray-এর এই সুবিধা পেতে FIFO-র গভীরতা সাধারণত ২-এর ঘাত রাখা হয়, কারণ শেষ মান থেকে শুরুতে ফেরার সময়ও যেন ঠিক একটি বিট বদলায় (100 → 000). Johnson counter-ও একই “একবারে এক বিট” গুণের, কিন্তু অনেক বেশি flip-flop লাগে; ring counter-এ অবশ্য প্রতি ধাপে দুটি বিট বদলায় (1000 → 0100), তাই সেটি এই কাজে চলে না।
মূল উপলব্ধি: Counter-এর কোড বেছে নেওয়া শুধু gate-এর খরচের প্রশ্ন নয় — কে, কখন, কোন clock-এ মানটি পড়বে, তার প্রশ্নও। এক বিট বদলের নিয়মটি অসমলয় জগতে নিরাপত্তার গ্যারান্টি হয়ে দাঁড়ায়।
অনুশীলন
পরীক্ষার খাতার মতো করে পুরো ধাপ লিখে সমাধান করুন, তারপর উত্তর মিলিয়ে দেখুন। অংশ ৩, ৪ আর ৬-এর simulator-এ নিজের উত্তর যাচাইও করতে পারেন।
-
Counter নকশা (circuit লিখুন): T flip-flop দিয়ে একটি synchronous BCD (mod-10) up counter নকশা করুন — state table, প্রতিটি T-এর কলাম, সরল সমীকরণ। তারপর দেখান counter self-starting কি না (state ১০ থেকে ১৫)।
৪টি flip-flop (Q3 = MSB). T = Q ⊕ Q+; প্রতিটি present state-এর পাশে T3T2T1T0:
Q3Q2Q1Q0 -> next : T3 T2 T1 T0 0000 -> 0001 : 0 0 0 1 0001 -> 0010 : 0 0 1 1 0010 -> 0011 : 0 0 0 1 0011 -> 0100 : 0 1 1 1 0100 -> 0101 : 0 0 0 1 0101 -> 0110 : 0 0 1 1 0110 -> 0111 : 0 0 0 1 0111 -> 1000 : 1 1 1 1 1000 -> 1001 : 0 0 0 1 1001 -> 0000 : 1 0 0 1 1010-1111 : x x x x (don't care)T0 = 1 (সব সারিতে 1). T1: 1 সারি ১, ৩, ৫, ৭-এ, কিন্তু ৯-এ 0 — Q0 = 1 আর Q3 = 0: T1 = Q3′Q0 (m11, m13, m15 don't care হলেও m9 = 0 বলে Q3′ লাগবে)। T2: 1 সারি ৩, ৭-এ; m11, m15 (x) সহ চারের দল: T2 = Q1Q0. T3: 1 সারি ৭ আর ৯-এ; m9 + m11 + m13 + m15 → Q3Q0, আর m7 + m15 → Q2Q1Q0: T3 = Q3Q0 + Q2Q1Q0.
Self-starting যাচাই (সমীকরণে বসিয়ে, script দিয়েও যাচাই করা): ১০ (1010) → T = 0001 → 1011 (১১); ১১ (1011) → T = 1101 → 0110 (৬); ১২ (1100) → 1101 (১৩); ১৩ (1101) → T = 1001 → 0100 (৪); ১৪ (1110) → 1111 (১৫); ১৫ (1111) → T = 1101 → 0010 (২)। অর্থাৎ 10 → 11 → 6, 12 → 13 → 4, 14 → 15 → 2 — প্রতিটি অব্যবহৃত state বড়জোর দুই clock-এ মূল চক্রে ফেরে: self-starting.
-
Johnson counter (decode আর কোড): একটি ৫-বিট Johnson counter (Q4 … Q0, ডানে সরে, Q4 ← Q0′), শুরু 00000. (ক) কয়টি state, কয়টি অব্যবহৃত? (খ) state 11100, 00111 আর 00000 চেনার ২-input gate লিখুন। (গ) একটি ÷১০ বানাতে ring, Johnson আর binary counter-এ কতটি flip-flop লাগে? (ঘ) Johnson counter-এর Verilog-এর মূল লাইনটি লিখুন।
(ক) ২n = ১০টি state: 00000, 10000, 11000, 11100, 11110, 11111, 01111, 00111, 00011, 00001. অব্যবহৃত ২৫ − ১০ = ২২টি.
(খ) প্রতিটি state-এর 1-এর দল আর 0-এর দলের সীমানা দেখুন। 11100-এ Q2 = 1-এর ঠিক পরে Q1 = 0 → Q2·Q1′. 00111-এ Q3 = 0-এর পরে Q2 = 1 → Q3′·Q2. 00000-এ ভেতরে সীমানা নেই, তাই দুই প্রান্ত → Q4′·Q0′. (দশটি বৈধ state-এর অন্য কোনোটিতে এই জোড়াগুলো একই মান পায় না — script দিয়ে যাচাই করা।)
(গ) Ring: ১০টি (প্রতি state-এ একটি)। Johnson: ৫টি (২n = ১০)। Binary (mod-10): ⌈log2 ১০⌉ = ৪টি। কম flip-flop মানে বেশি decode-এর gate — binary-তে প্রতিটি state চিনতে ৪-input AND, Johnson-এ ২-input, ring-এ কোনো gate নেই।
(ঘ)
always @(posedge clk) if (rst) q <= 5'b0; else q <= {~q[0], q[4:1]};— ডানে সরানো, আর বাঁয়ের নতুন বিট Q0-এর উল্টো। -
LFSR-এর period (output অনুমান করুন): এই পর্বের রীতিতে (বাঁয়ে সরে, নতুন Q0 = tap-এর XOR) (ক) ৩-বিট LFSR, x3 + x2 + 1 (নতুন Q0 = Q2 ⊕ Q1), seed 001 — পুরো sequence আর period লিখুন। এটি maximal কি? (খ) ৪-বিট, x4 + x2 + 1 (নতুন Q0 = Q3 ⊕ Q1), seed 0001 — period কত?
(ক) 001 → (0 ⊕ 0 = 0) 010 → (0 ⊕ 1 = 1) 101 → (1 ⊕ 0 = 1) 011 → (0 ⊕ 1 = 1) 111 → (1 ⊕ 1 = 0) 110 → (1 ⊕ 1 = 0) 100 → (1 ⊕ 0 = 1) 001. Period ৭ = ২৩ − ১ — maximal; 000 বাদে সাতটি state-ই এসেছে।
(খ) 0001 → 0010 → 0101 → 1010 → 0100 → 1000 → 0001. Period ৬ — ১৫-এর অনেক কম, কারণ x4 + x2 + 1 = (x2 + x + 1)2, primitive নয়। অন্য seed নিলে অন্য চক্রে পড়বেন: 0011 থেকে আরেকটি ৬-এর চক্র, 0110 থেকে ৩-এর চক্র — অংশ ৪-এর simulator-এর
6, 6, 3. -
Ripple counter-এর গতি (numerical): একটি ৪-বিট ripple up counter-এর প্রতিটি flip-flop-এর tpd = ১৫ ns. (ক) 0111 থেকে 1000-এ যাওয়ার পথে সময়সহ প্রতিটি ক্ষণস্থায়ী মান লিখুন। (খ) Output একটি decoder (delay ১০ ns) দিয়ে পড়া হলে সর্বোচ্চ clock frequency কত? (গ) একই flip-flop-এ synchronous counter (AND delay ৫ ns, setup ৫ ns) কত দ্রুত চলতে পারে? (ঘ) ১ MHz clock থেকে এমন কয়টি stage-এর ripple divider ১ kHz-এর সবচেয়ে কাছের ২-এর ঘাতের ভাগ দেয়, আর output frequency ঠিক কত?
(ক) t = ১৫ ns: Q0 নামে → 0110 (৬); t = ৩০ ns: Q1 নামে → 0100 (৪); t = ৪৫ ns: Q2 নামে → 0000 (০); t = ৬০ ns: Q3 ওঠে → 1000 (৮), স্থির। তিনটি ভুল মান: ৬, ৪, ০.
(খ) T ≥ ৪ × ১৫ + ১০ = ৭০ ns → fmax = ১ / ৭০ ns ≈ ১৪.৩ MHz.
(গ) T ≥ ১৫ + ৫ + ৫ = ২৫ ns → ৪০ MHz — প্রায় তিন গুণ দ্রুত, আর বিট বাড়লেও (AND এক স্তরে থাকলে) এটি বদলায় না।
(ঘ) ১,০০০ ভাগের কাছের ২-এর ঘাত ২১০ = ১,০২৪, তাই ১০টি stage; output = ১,০০০,০০০ / ১,০২৪ ≈ ৯৭৬.৬ Hz. ঠিক ১ kHz চাইলে একটি mod-1000 counter (যেমন তিনটি BCD counter জুড়ে) লাগবে।
নিজেকে যাচাই করুন
ভুল হলে কারণসহ ব্যাখ্যা পাবেন, আবার চেষ্টাও করতে পারবেন।
ক্রমএকটি synchronous counter নকশার ধাপগুলো সঠিক ক্রমে সাজান (▲▼ চেপে সরান)
- State-এর সংখ্যা থেকে flip-flop-এর সংখ্যা ঠিক করা
- Present state আর next state-এর state table লেখা
- Excitation table দিয়ে প্রতিটি flip-flop input-এর কলাম বের করা
- অব্যবহৃত state-কে don't care ধরে K-map-এ সমীকরণ সরল করা
- প্রতিটি অব্যবহৃত state বসিয়ে self-starting কি না যাচাই করা
- Circuit আঁকা আর simulate করে sequence মিলিয়ে দেখা
একটি ৪-বিট Johnson (twisted-ring) counter-এ কয়টি ভিন্ন state থাকে?
- ৪টি
- ৮টি
- ১৫টি
- ১৬টি
একটি ৫-stage ripple (asynchronous) counter-এর প্রতিটি flip-flop-এর propagation delay ২০ ns. Decoder-এর delay উপেক্ষা করলে count নির্ভরযোগ্যভাবে পড়ার জন্য সর্বোচ্চ clock frequency কত?
- ৫০ MHz
- ১০ MHz
- ২ MHz
- ১০০ MHz
একটি হাতঘড়ির ৩২,৭৬৮ Hz crystal থেকে ১ Hz-এর pulse পেতে ÷২ করা T flip-flop-এর কয়টি stage লাগবে?
- ১৫টি
- ১৬টি
- ৩২টি
- ১০টি
একটি ৬-বিট LFSR-এর feedback polynomial primitive হলে state sequence-এর period কত হবে?
- ৬৪
- ৩২
- ৬৩
- ৩৬
Synchronous counter নকশায় একটি JK flip-flop-কে Q = 1 থেকে Q+ = 0-তে নিতে J আর K কী হতে হবে (x = don't care)?
- J = x, K = 1
- J = 0, K = 1
- J = 1, K = x
- J = x, K = 0
একটি register-এ load enable (EN) যোগ করতে হবে: EN = 1 হলে input X নেবে, EN = 0 হলে পুরোনো মান রাখবে। কোন নকশাটি নিরাপদ ও প্রচলিত?
- Clock-কে EN-এর সাথে একটি AND gate দিয়ে মেলানো
- EN = 0 হলে asynchronous clear চালু করা
- Flip-flop-এর বদলে latch ব্যবহার করে EN-কে latch-এর enable-এ দেওয়া
- প্রতিটি D-র সামনে 2:1 mux: D = EN′·Q + EN·X
শব্দকোষ
লেখার মধ্যে ডটেড দাগ দেওয়া শব্দে মাউস রাখুন বা চাপুন — অর্থ দেখাবে। এই পর্বের সব নতুন শব্দ এখানে একসাথে:
মনে রাখুন
- Register = একই clock-এর n টি flip-flop; load enable হয় mux দিয়ে (D = EN′Q + EN·X), clock আটকে নয়; clear synchronous (পরের edge-এ) বা asynchronous (সঙ্গে সঙ্গে)।
- Shift register: SISO (delay), SIPO (serial → parallel), PISO (parallel → serial), PIPO; universal register-এ hold, left, right, load; বাঁয়ে সরানো ×২, ডানে ÷২.
- Ring: n টি state, Johnson: ২n টি (প্রতিটি ২-input gate-এ decode); LFSR: primitive polynomial-এ ২n − ১, seed কখনো 0 নয়; ব্যবহার CRC, scrambling, BIST, pseudo-random.
- Ripple counter: f/২n divider, কিন্তু delay n·tpd আর মাঝপথে ভুল মান; fmax = ১/(n·tpd + tgate). ৩২,৭৬৮ Hz → ১৫ stage → ১ Hz.
- Synchronous counter: state table → excitation (D = Q+, T = Q ⊕ Q+, JK-তে x) → K-map → অব্যবহৃত state যাচাই; binary-তে Ti = Qi−1···Q0. PC, timer, watchdog, performance counter — সবই counter.
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- পর্ব ১৭ · Finite state machine — Moore, Mealy আর state diagram থেকে circuitপরবর্তী পর্বInput-সহ sequential circuit নকশা — counter-এর রেসিপির সম্প্রসারণ।
- পর্ব ১৫ · Latch আর flip-flop — SR, D, JK, T আর edge-triggeringএই মডিউলেCharacteristic ও excitation table, edge-triggering আর asynchronous reset.
- কম্পিউটার আর্কিটেকচার ও ডিজিটাল লজিক · কোর্স হোম৬২টি পর্বপুরো কোর্সের রোডম্যাপ — লজিক গেট থেকে multicore.
- কম্পিউটার ফান্ডামেন্টালস · সিকোয়েন্সিয়াল সার্কিটঝালিয়ে নিনFlip-flop, register আর counter-এর সহজ, ছবিসহ পরিচয়।
- কম্পিউটার নেটওয়ার্কস · Error detectionপাশের ট্র্যাকCRC-র polynomial ভাগ — যার hardware একটি LFSR.
- C প্রোগ্রামিং · Bitwise operationসফটওয়্যারের দিকShift আর XOR দিয়ে software-এ LFSR আর বিটের কাজ।