منطق باینری چیست؟
اگر بخواهیم از پایه وارد دنیای Digital Logic و بعداً طراحی CPU، مدار دیجیتال، FPGA و Verilog شویم، یکی از اولین مفاهیمی که باید کاملاً درک کنیم Binary یا دستگاه عددی دودویی است.
کامپیوتر برخلاف انسان که معمولاً با اعداد دهدهی کار میکند، در سطح سختافزار اطلاعات را به شکل حالتهای گسسته پردازش میکند. سادهترین مدل این حالتها دو وضعیت است:
خاموش / روشن
Low / High
False / True
به همین دلیل به این سیستم دودویی یا Binary میگوییم.
Bit چیست؟
کوچکترین واحد اطلاعات دیجیتال را Bit مینامیم. یک بیت فقط میتواند دو حالت داشته باشد:
برای مثال:
2 bit: 00، 01، 10، 11
3 bit: 000 تا 111
4 bit: 0000 تا 1111
اگر تعداد بیتها برابر n باشد، تعداد ترکیبهای ممکن برابر است با:
مثلاً با 8 بیت داریم:
بنابراین یک مقدار 8 بیتی بدون در نظر گرفتن علامت میتواند اعداد 0 تا 255 را نمایش دهد.
Byte چیست؟
هر 8 بیت برابر یک Byte است:
مثلاً:
↑──────↑
8 بیت = 1 بایت
در معماری کامپیوتر، Byte یکی از واحدهای بسیار مهم برای بیان ظرفیت حافظه، Storage و اندازه داده است.
چرا Binary؟
مدارهای دیجیتال معمولاً با سیگنالهایی کار میکنند که در دو محدوده منطقی قرار میگیرند. این موضوع باعث میشود طراحی سیستم با دو حالت منطقی نسبتاً قابل اعتماد و قابل تشخیص باشد.
↓
سطوح منطقی
↓
0 و 1
↓
Logic Gates
↓
مدارهای دیجیتال
↓
CPU / RAM / FPGA / Controller
پس Binary فقط یک روش نوشتن عدد نیست؛ بلکه پایهای برای نمایش و پردازش اطلاعات در سیستمهای دیجیتال است.
دستگاههای عددی مهم
در مهندسی کامپیوتر چند مبنا بسیار مهم هستند:
| مبنا | نام | ارقام | کاربرد |
|---|---|---|---|
| 2 | Binary | 0, 1 | سختافزار و منطق دیجیتال |
| 8 | Octal | 0 تا 7 | نمایش فشرده Binary در بعضی کاربردها |
| 10 | Decimal | 0 تا 9 | محاسبات معمول انسانی |
| 16 | Hexadecimal | 0 تا 9 و A تا F | نمایش فشرده Binary و آدرسها |
مفهوم Base یا مبنا
در یک سیستم عددی با مبنای b، ارزش هر رقم بر اساس توانهای b تعیین میشود.
مثلاً در دهدهی:
در Binary نیز دقیقاً همین ایده وجود دارد، با این تفاوت که مبنا 2 است.
پس:
تبدیل Binary به Decimal
برای تبدیل Binary به Decimal، هر بیت را در توان متناظر 2 ضرب میکنیم.
مثال:
| بیت | 1 | 1 | 0 | 1 | 0 | 1 |
|---|---|---|---|---|---|---|
| توان 2 | 2⁵ | 2⁴ | 2³ | 2² | 2¹ | 2⁰ |
| مقدار | 32 | 16 | 0 | 4 | 0 | 1 |
تبدیل Decimal به Binary
یکی از روشهای استاندارد، تقسیم متوالی بر 2 و نگهداشتن باقیماندهها است.
مثلاً عدد 13:
6 ÷ 2 = 3 باقیمانده 0
3 ÷ 2 = 1 باقیمانده 1
1 ÷ 2 = 0 باقیمانده 1
باقیماندهها را از پایین به بالا میخوانیم:
جدول توانهای 2
| توان | مقدار |
|---|---|
| 2⁰ | 1 |
| 2¹ | 2 |
| 2² | 4 |
| 2³ | 8 |
| 2⁴ | 16 |
| 2⁵ | 32 |
| 2⁶ | 64 |
| 2⁷ | 128 |
| 2⁸ | 256 |
| 2¹⁰ | 1024 |
| 2¹⁶ | 65536 |
| 2³² | 4294967296 |
MSB و LSB چیست؟
در یک عدد باینری، سمت چپترین بیت معمولاً MSB یا Most Significant Bit نام دارد. سمت راستترین بیت نیز LSB یا Least Significant Bit است.
در اعداد بدون علامت، LSB ارزش 2⁰ و بیت بعدی ارزش 2¹ دارد و به همین ترتیب ادامه پیدا میکند.
تبدیل Binary و Hexadecimal
یکی از مهمترین تبدیلها برای برنامهنویسی سطح پایین، FPGA و معماری کامپیوتر، تبدیل Binary به Hexadecimal است. دلیل مهم بودن Hex این است که هر رقم Hex دقیقاً معادل 4 بیت است.
| Binary | Hex |
|---|---|
| 0000 | 0 |
| 0001 | 1 |
| 0010 | 2 |
| 0011 | 3 |
| 0100 | 4 |
| 0101 | 5 |
| 0110 | 6 |
| 0111 | 7 |
| 1000 | 8 |
| 1001 | 9 |
| 1010 | A |
| 1011 | B |
| 1100 | C |
| 1101 | D |
| 1110 | E |
| 1111 | F |
مثلاً:
A D 7 3
بنابراین به جای نوشتن 16 بیت، میتوانیم فقط 4 رقم Hex بنویسیم.
تبدیل Hex به Binary
برعکس حالت قبل نیز بسیار ساده است. هر رقم Hex را با 4 بیت جایگزین میکنیم.
↓
0011 1111 0111 1010₂
پس 2 رقم Hex = 8 بیت = 1 Byte.
تبدیل Binary و Octal
برای Octal، بیتها را از سمت راست به گروههای 3تایی تقسیم میکنیم؛ چون:
مثلاً:
5 6 3₈
بنابراین:
اعداد اعشاری باینری
Binary فقط برای اعداد صحیح نیست. میتوانیم قسمت اعشاری نیز داشته باشیم. در سمت راست نقطه باینری، توانها از 2⁻¹ شروع میشوند.
= 1×2⁻¹ + 0×2⁻² + 1×2⁻³
= 0.5 + 0 + 0.125
= 0.625₁₀
پس:
جمع باینری
قواعد جمع باینری بسیار ساده هستند:
| عمل | نتیجه | Carry |
|---|---|---|
| 0 + 0 | 0 | 0 |
| 0 + 1 | 1 | 0 |
| 1 + 0 | 1 | 0 |
| 1 + 1 | 0 | 1 |
حالت آخر بسیار مهم است:
یعنی نتیجه در همان ستون 0 است و یک Carry به ستون بعدی منتقل میشود.
مثال
+ 0110
──────
10001
در دهدهی:
و:
تفریق باینری
قواعد اصلی:
| عمل | نتیجه |
|---|---|
| 0 − 0 | 0 |
| 1 − 0 | 1 |
| 1 − 1 | 0 |
| 0 − 1 | نیازمند Borrow |
در سختافزار، تفریق معمولاً با روش Two’s Complement به یک جمع تبدیل میشود؛ به همین دلیل مفهوم مکمل دو بسیار مهم است.
One’s Complement
برای بهدستآوردن مکمل یک، تمام بیتها را معکوس میکنیم:
↓ NOT
01001101
یعنی:
1 → 0
Two’s Complement
برای بهدستآوردن Two’s Complement:
- تمام بیتها را معکوس میکنیم.
- یک واحد به نتیجه اضافه میکنیم.
مثلاً:
00101100
مکمل یک:
11010011
+ 1
──────
11010100
پس Two’s Complement عدد 00101100 برابر 11010100 است.
چرا Two’s Complement مهم است؟
فرض کنید میخواهیم:
را با سختافزار انجام دهیم. به جای ساختن یک مدار کاملاً جدا برای تفریق، میتوانیم از مکمل دو استفاده کنیم:
یعنی عملیات تفریق را به یک عملیات جمع تبدیل میکنیم. این ایده در طراحی ALU اهمیت بسیار زیادی دارد.
اعداد بدون علامت و علامتدار
یک رشته بیت بهتنهایی مشخص نمیکند که قرار است عدد مثبت، منفی یا فقط یک الگوی بیتی باشد. نحوه تفسیر آن اهمیت دارد.
مثلاً برای 8 بیت:
Signed Two’s Complement: از −128 تا +127
این تفاوت در برنامهنویسی سطح پایین، معماری CPU و طراحی سختافزار بسیار مهم است.
Overflow چیست؟
وقتی نتیجه یک عملیات از محدودهای که تعداد بیتها اجازه میدهد خارج شود، با مفهوم Overflow مواجه میشویم.
مثلاً در یک عدد Unsigned هشتبیتی، بیشترین مقدار:
اگر یک واحد دیگر اضافه کنیم:
+ 1
────────
1 00000000
اگر فقط 8 بیت را نگه داریم، نتیجه:
است و Carry از محدوده 8 بیت خارج شده است.
Bitwise چیست؟
در برنامهنویسی و سختافزار، گاهی عملیات مستقیماً روی تکتک بیتها انجام میشود. به این عملیات Bitwise Operation میگوییم.
مهمترین عملیات Bitwise عبارتاند از:
OR
XOR
NOT
Shift Left
Shift Right
AND، OR و XOR در Binary
| A | B | AND | OR | XOR |
|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 0 |
| 0 | 1 | 0 | 1 | 1 |
| 1 | 0 | 0 | 1 | 1 |
| 1 | 1 | 1 | 1 | 0 |
در XOR فقط زمانی خروجی 1 است که ورودیها با هم متفاوت باشند.
اگر A ≠ B
Shift چیست؟
در Shift، بیتها به چپ یا راست جابهجا میشوند.
Left Shift
↓
0110
در بسیاری از شرایط، Left Shift یک بیت معادل ضرب در 2 است؛ البته با توجه به اندازه داده و Overflow باید مراقب محدوده باشیم.
Right Shift
↓
0110
در اعداد Unsigned، Right Shift معمولاً اثر تقسیم بر 2 را دارد. برای اعداد Signed، نوع Shift و نحوه پر شدن بیت جدید اهمیت دارد.
ترکیب بیتها و ساخت دادههای بزرگتر
یکی از مفاهیم مهم در طراحی سختافزار این است که چند بیت میتوانند کنار هم قرار بگیرند و یک داده بزرگتر بسازند.
2 Bit → 4 حالت
4 Bit → 16 حالت
8 Bit → 256 حالت
16 Bit → 65,536 حالت
32 Bit → حدود 4.29 میلیارد حالت
برای مثال یک رجیستر 32 بیتی میتواند 32 بیت را همزمان نگهداری کند. در طراحی CPU، اندازه Registerها، ALU، Bus و بسیاری از واحدهای دیگر با تعداد بیتها ارتباط مستقیم دارد.
Nibble چیست؟
هر 4 بیت را یک Nibble مینامیم.
2 Nibble = 1 Byte
به همین دلیل تبدیل Binary و Hexadecimal بسیار راحت است: هر Nibble دقیقاً یک رقم Hex را تشکیل میدهد.
رابطه Binary با حافظه
در مباحث قبلی RAM را بررسی کردیم. حافظه از تعداد زیادی سلول تشکیل شده و هر سلول میتواند داده را نگه دارد. در سطح معماری، معمولاً یک Address مشخص میکند به کدام محل حافظه دسترسی داریم و Data مقدار ذخیرهشده را مشخص میکند.
↓
Memory
↓
Data
خود Address و Data نیز مجموعهای از بیتها هستند. بنابراین Binary مستقیماً با نحوه آدرسدهی و انتقال داده در سیستم ارتباط دارد.
چرا Hexadecimal در مهندسی کامپیوتر خیلی مهم است؟
فرض کنید یک مقدار 32 بیتی داریم:
خواندن این مقدار برای انسان سخت است. اما با تبدیل هر چهار بیت به یک رقم Hex:
نمایش بسیار کوتاهتر و قابلخواندنتر میشود. به همین دلیل در Debuggerها، Memory Addressها، Registerها، Opcodeها و بسیاری از ابزارهای مهندسی کامپیوتر با اعداد Hex زیاد روبهرو میشویم.
یک نکته مهم درباره نمایش داده
یک الگوی بیتی میتواند بسته به نحوه تفسیر، معنیهای متفاوتی داشته باشد. مثلاً:
میتواند بهعنوان یک عدد Unsigned برابر 65 باشد؛ اما همین الگو در ASCII متناظر با یک کاراکتر است.
جمعبندی مفاهیم مهم
| مفهوم | نکته اصلی |
|---|---|
| Bit | کوچکترین واحد دودویی، 0 یا 1 |
| Byte | 8 بیت |
| Nibble | 4 بیت |
| Binary | مبنای 2 |
| Decimal | مبنای 10 |
| Octal | مبنای 8 |
| Hexadecimal | مبنای 16 |
| MSB | باارزشترین بیت |
| LSB | کمارزشترین بیت |
| Carry | انتقال در جمع |
| Borrow | قرض گرفتن در تفریق |
| One’s Complement | معکوس کردن بیتها |
| Two’s Complement | مکمل یک + یک |
| Overflow | خارج شدن نتیجه از محدوده قابل نمایش |
| Bitwise | عملیات مستقیم روی بیتها |
| XOR | خروجی 1 وقتی دو ورودی متفاوت باشند |
نقشه ذهنی این بخش
↓
Bit / Byte / Nibble
↓
Base 2 / 8 / 10 / 16
↓
تبدیل مبناها
↓
جمع و تفریق
↓
One’s Complement / Two’s Complement
↓
Signed / Unsigned / Overflow
↓
Bitwise Operations
↓
Logic Gates
↓
Combinational Circuits
↓
ALU / CPU / FPGA
چرا این مباحث برای FPGA و Verilog مهم هستند؟
وقتی وارد Verilog و FPGA شویم، دیگر فقط با اعداد معمولی سر و کار نداریم. با Bit، Vector، Register، Bus، Binary، Hex، Signed و Unsigned کار خواهیم کرد.
برای مثال ممکن است در Verilog بنویسیم:
logic [7:0] a;
logic [7:0] b;
logic [7:0] result;
assign result = a + b;
اینجا [7:0] یعنی یک مقدار 8 بیتی داریم.
در ادامه مسیر، همین مفهوم ساده به طراحی Register، ALU، Counter، Memory Interface و در نهایت CPU و پروژه FPGA تبدیل میشود.
Binary → Boolean Logic → Logic Gates → Truth Table → SOP/POS → Combinational Circuits → K-Map → Sequential Circuits → Registers/Counter → ALU → CPU → Verilog → FPGA