مدل Fixed Point چیست و چه تفاوتی با مدل Floating Point دارد؟
چرا در طراحی مدارات دیجیتال در FPGA، سعی میکنیم از مدل Fixed Point استفاده کنیم؟
چگونه یک مدل Floating Point را به یک مدل Fixed Point تبدیل کنیم؟
مزایای بسیار مهمی که با پیادهسازی مدل Fixed Point به آنها دست خواهیم یافت، چه هستند؟
در طول این مقاله، با پاسخ به سوالات بالا به نتایجی خواهیم رسید که از مزایای بسیار ارزشمند استفاده از مدل Fixed Point هستند.
More...
ما در مقالهای تحت عنوان "۷ گام پیادهسازی الگوریتمهای پردازش سیگنال در FPGA"، یک روش ۷ مرحلهای برای پیادهسازی الگوریتمهای پردازش سیگنال معرفی کردیم.
مرحله سوم این روش، کوانتیزاسیون مدل Fixed Point نام داشت. در این مقاله، میخواهیم مرحله سوم را همراه با یک مثال و با جزئیات بیشتری شرح دهیم.
در ادامه، برای یادآوری، تعریف مختصری از دو سیستم نمایش Fixed Point و Floating Point ارائه میدهیم، اما بهتر است که قبل از مطالعه این مقاله، مقالهای که در بالا معرفی کردیم را بخوانید.
سیستم نمایش Fixed Point و Floating Point
در سیستم نمایش Floating Point، دو استاندارد ۳۲ و ۶۴ بیتی وجود دارد.
در این سیستم، همانطور که از نامش پیدا است، محل نقطه اعشاری در هر لحظه شناور یا متغیر است.
یعنی، با توجه به مقدار لحظهای رجیستری که عدد مورد نظر ما در آن ذخیره است، نقطه اعشاری، محل یا جایگاه متفاوتی دارد.
برای درک بهتر موضوع، به مثال زیر توجه کنید:
مثلاً فرض کنید یک رجیستر ۶۴ بیتی Floating Point داریم و میخواهیم عدد 3.1415 را در آن قرار دهیم.
برای قسمت صحیح این عدد که برابر با 3 است، دو بیت نیاز داریم. برای علامت عدد نیز یک بیت لازم است. به این ترتیب، ۶۱ بیت باقیمانده، به قسمت اعشاری اختصاص پیدا میکند.
اکنون فرض کنید که دوباره همان رجیستر ۶۴ بیتی را داریم، اما این بار، میخواهیم مقدار 4.1415 را در آن قرار دهیم.
در این حالت، برای قسمت صحیح این عدد که برابر با 4 است، سه بیت نیاز داریم. برای علامت عدد نیز یک بیت لازم است. به این ترتیب، ۶۰ بیت باقیمانده، به قسمت اعشاری اختصاص پیدا میکند.
همانطور که مشاهده کردید، با توجه به اینکه مقدار صحیح عدد چقدر باشد، محل نقطه اعشاری میتواند متفاوت باشد.
اما عملکرد سیستم نمایش Fixed Point چگونه است؟
در سیستم Fixed Point، بر خلاف سیستم Floating Point، هیچ استاندارد از پیش تعریف شدهای وجود ندارد و آن کسی که استاندارد را تعیین میکند، خود ما به عنوان شخص پیادهساز مدار هستیم.
تنها تفاوت بین سیستم نمایش Fixed Point و Floating Point، به تعداد بیتی است که برای نمایش یک عدد اختصاص میدهیم.
هر تفاوت دیگر در این سیستمهای نمایش، نشات گرفته از همین تفاوت تعداد بیتها است.
برای مثال، در سیستم نمایش Fixed Point، برای نمایش عدد 4، به جای اشغال ۳۲ بیت یا ۶۴ بیت، تنها از سه بیت استفاده میکنیم.
ابزاری که ما از آن برای کاهش عرض بیت مدل Floating Point استفاده میکنیم، تا به یک مدل Fixed Point برسیم، ابزار کوانتیزاسیون است.
اما کوانتیزاسیون چیست؟
مفهوم کوانتیزاسیون
کوانتیزاسیون، یک مفهوم اصلی و یکتا دارد، اما ممکن است در جاهای مختلف با تعاریف مختلفی بیان شود.
در ادامه، به کمک یک مثال، کوانتیزاسیون را تعریف میکنیم.
در حوزه الکترونیک، وقتی قرار است از یک سیگنال آنالوگ نمونهبرداری کنیم، و آن را به یک سیگنال دیجیتال تبدیل کنیم، باید مقدار نمونهبرداری شده از سیگنال آنالوگ را به یک عدد دیجیتال نسبت دهیم یا تبدیل کنیم.
همانطور که میدانید بر خلاف سیگنال آنالوگ، سیگنال دیجیتال نمیتواند هر مقداری داشته باشد و سیگنال باید به یک سری اعداد خاص تبدیل شود.
به فرآیند تبدیل مقادیر آنالوگ (دقت نمایش زیاد) به اعداد دیجیتال (دقت نمایش محدود) کوانتیزاسیون گفته میشود.
مثلا فرض کنید میخواهیم یک ولتاژ بین 0 تا 3.3 ولت که آنالوگ است را با چهار بیت به صورت دیجیتال نمایش دهیم. با شرایط موجود، هر سیگنالی بین 0 تا 3.3 ولت، فقط میتواند به یک عدد صحیح دیجیتال، بین 0 تا 15 تبدیل شود.
با انجام این عمل، اصطلاحا میگویند که سیگنال کوانتیزه شده است.
احتمالا حدس زده باشید که با تبدیل سیگنال از حوزه آنالوگ به حوزه دیجیتال، مقداری اختلاف بین مقدار کوانتیزه شده و مقدار واقعی وجود دارد.
به این اختلاف، خطای کوانتیزاسیون گفته میشود.
توضیحات بالا مقدمهای بود تا بتوانیم اتفاقاتی که در تبدیل مدل Floating Point به مدل Fixed Point رخ میدهد را بهتر توضیح دهیم.
کوانتیزاسیون مدل Floating Point
همانند تبدیل از حوزه آنالوگ به حوزه دیجیتال، در تبدیل مدل Floating Point به مدل Fixed Point هم مقداری اختلاف بین عدد Floating Point و عدد Fixed Point وجود دارد.
به این اختلاف نیز خطای کوانتیزاسون گفته میشود.
در اینجا عدد Floating Point، مقدار واقعی و عدد Fixed Point، کوانتیزه شده مقدار واقعی است.
البته خود عدد Floating Point، کوانتیزه شده از یک مقدار آنالوگ است، اما برای ما، مرجع مقدار واقعی، که قرار است آن را کوانتیزه کنیم همین عدد Floating Point است.
پس، با اعمال ابزار کوانتیزاسیون بر روی مدل Floating Point و تبدیل آن به مدل Fixed Point، عرض بیت را کاهش میدهیم و به دنبال آن خطا افزایش مییابد.
ما میگوییم که عرض بیت ۳۲ یا ۶۴ بیتی مدل Floating Point، زیاد است و اصلا نیازی به آن نیست، و باید عرض بیتها را کم کرد.
اما اینکه تا کجا میتوان عرض بیت را کاهش داد، به طوری که خطای کوانتیزاسیون مورد قبول باشد، بحثی است که در مرحله سوم از روش ۷ مرحلهای، میخواهیم انجام دهیم.
خود مرحله سوم، دارای سه مرحله زیر است:
مجددا تاکید میکنم، از آنجا که در مقاله "۷ گام پیادهسازی الگوریتمهای پردازش سیگنال در FPGA"، سه مرحله بالا را به صورت مفصل توضیح دادیم، از توضیح مجدد آنها خودداری کرده و به کمک یک مثال، مراحل بالا از عملیات کوانتیزاسیون را انجام میدهیم.
کوانتیزاسیون بخشهای مختلف یک مدل پردازش سیگنال همراه با مثال
ابتدا به تصویر زیر که مثال مورد نظر ما است توجه کنید:
در تصویر بالا، جایی که کلمه "ورودی" نوشته شده است، منظور ورودی اصلی است. چون این ورودی از بیرون به مدار اعمال شده است، به آن ورودی اصلی میگوییم.
تنها ورودی اصلی در تصویر بالا، همین یک ورودی است که مشخص کردیم.
اکنون سراغ ورودیهای داخلی میرویم.
ورودیهایی داخلی، مولدهایی هستند که درون مدل وجود دارند.
در تصویر بالا، منبع سینوسی و عدد 3.14156، ورودیهای داخلی مدل هستند.
در تصویر بالا، دو عمل ضرب و جمع هم جز عملگرها به حساب میآیند.
هر کدام از سه مرحله بالا، به نحو متفاوتی کوانتیزه میشوند.
اجازه دهید بدون هیچ توضیح اضافهای به سراغ کوانتیزاسیون این سه مرحله برویم.
کوانتیزاسیون ورودیهای اصلی
برای کوانتیزاسیون ورودی اصلی، عرض بیت آن را دانسته فرض میکنیم.
چرا عرض بیت را دانسته فرض میکنیم؟
چون ورودی اصلی یک مدل، در واقع خروجی یک بخش دیگر است و تعیین خروجی بخش دیگر با ما نیست. پس، عرض بیت خروجی آن بخش، هر عددی بود، عرض بیت ورودی ما نیز برابر با همان عدد است.
مثلا فرض کنید که ورودی اصلی مدل ما، از یک ADC، با عرض ۱۴ بیت گرفته شده است.
پس، عرض بیت ورودی اصلی، برابر با عرض بیت ADC، یعنی همان ۱۴ بیت خواهد بود.
معمولا ورودی ولتاژ ADCها بین 1 و 1-، و خروجی آنها به صورت Two's complement (مکمل دو) است.
چون سیستم اعدادی که ما همیشه از آن استفاده میکنیم Two's complement است، پس این نوع خروجی ADC دقیقا همان چیزی است که ما به دنبال آن بودیم.
اکنون با این اطلاعات، ورودی اصلی چگونه کوانتیزه میشود؟
چون ورودی این ADCها معمولا هیچوقت به عدد 1 نمیرسد، پس برای قسمت صحیح آن عددی در نظر نمیگیریم، و از ۱۴ بیت موجود یک بیت را به بیت علامت و ۱۳ بیت دیگر را به قسمت کسری اختصاص میدهیم.
پس، مانند آن چیزی که در تصویر زیر میبینید، عبارت S.0.13 را به ورودی اصلی اختصاص میدهیم:
پس از کوانتیزاسیون ورودیهای اصلی، نوبت ورودیهای داخلی است.
کوانتیزاسیون ورودیهای داخلی
برای کوانتیزاسیون ورودیهای داخلی، یک روش خیلی سرراست و دمدستی وجود دارد، که ما به آن، روش چشمی میگوییم.
روش چشمی در واقع بر مبنای سعی و خطا و به شرح زیر است:
در یک نرمافزار شبیهساز مثل متلب، یک مدل Floating Point از مثال خود ایجاد کرده و همچنین از این مدل ایجاد شده، یک کپی میگیریم و در کنار آن قرار میدهیم.
کوانتیزاسیونی که در مرحله اول به دست آوردیم، یعنی عبارت S.0.13 را بر روی ورودی اصلی یکی از مدلهای Floating Point ایجاد شده، اعمال میکنیم.
مدل دوم Floating Point ایجاد شده که در حال تغییر آن هستیم، دیگر یک مدل Floating Point نیست و با اولین تغییر و کاهش عرض بیت یکی از ورودیهای آن به یک مدل Fixed Point تبدیل میشود.
از اینجای مقاله به بعد، وقتی گفتیم مدل Fixed Point، منظورمان همین مدل Floating Pointای است که در حال تغییر آن هستیم.
اکنون خروجیهای این دو مدل را بر روی اسیلوسکوپ نمایش میدهیم.
تا این لحظه، نمودار زمانی هر دو خروجی باید منطبق بر همدیگر باشند.
وقت آن است که با همان روش چشمی که گفتیم ورودیهای داخلی را کوانتیزه کنیم.
در این مثال، دو ورودی داخلی داریم و چون هر دو ورودی جایگاه یکسانی در مدل دارند، فرقی ندارد که اول کدام ورودی را کوانتیزه کنیم.
فرض کنید ما با ورودی داخلی سینوسی شروع میکنیم.
روش چشمی اینگونه است که عرض بیت سینوس که ۶۴ یا ۳۲ بیت است را به یک عدد دلخواه کاهش میدهیم و خروجی را مشاهده میکنیم.
اگر خروجیهای مدل Fixed Point و مدل Floating Point، بر همدیگر منطبق بودند، میتوانیم عرض بیت را بیشتر از عدد دلخواهی که انتخاب کردیم، کاهش دهیم.
اما اگر خروجیها با هم اختلاف زیادی داشتند، یعنی آن عدد دلخواهی که انتخاب کردیم، عدد مناسبی نبود، باید عرض بیت را کمی افزایش دهیم و دوباره خروجیها را مقایسه کنیم.
این روش را با سعی خطا تکرار میکنیم تا به یک عدد مناسب برسیم.
البته هرچقدر تمرین بیشتری انجام دهید و تجربه بیشتری کسب کنید، در انتخاب آن عدد اولیه بهتر عمل خواهید کرد.
توجه داشته باشید که با کاهش عرض بیت، نمودارهای خروجی مدل Fixed Point و مدل Floating Point، در حال فاصله گرفتن از همدیگر هستند، اینکه این فاصله چقدر باشد و حداکثر خطای قابل قبول برای ما چقدر است، معمولا در سطح سیستمی و توسط طراح الگوریتم مشخص میشود؛ اما در عمده موارد، استفاده از روش چشمی میتواند ما را برای رسیدن به خطای قایل قبول یاری کند.
پس، ما با همان نگاه چشمی و با اختلاف مقدار واقعی و مقدار کوانتیزه شدهای که مورد قبولمان است، عرض بیت ورودیهای داخلی را تعیین میکنیم.
برای مثال، برای ورودی سینوسی، عرض بیت قسمت کسری را چهار بیت در نظر میگیریم و خروجیها را مشاهده میکنیم.
خروجی مطابق تصویر زیر است:
همانطور که مشاهده میکنید، خروجیها اختلاف زیادی دارند و چهار بیت برای این ورودی خیلی کم است.
البته چهار بیت را به عمد انتخاب کردیم تا خروجیها با هم اختلاف زیادی داشته باشند و شما این نتیجه را مشاهده کنید.
با تکرار روش چشمی، برای عرض بیت قسمت کسری ورودی سینوسی، به عدد ۱۱ میرسیم.
همچنین، همین مراحل را برای ورودی ثابت 3.14156 انجام میدهیم و برای عرض بیت کسری این ورودی، به عدد ۶ میرسیم.
پس از اعمال عدد ۱۱ و ۶ به قسمت کسری ورودیهای داخلی، خروجی زیر را بدست میآوریم:
همانطور که از تصویر قابل مشاهده است، هر دو خروجی بر روی همدیگر منطبق هستند، ولی اگر خیلی خوب دقت کنید یک سری خط زرد در تصویر قابل مشاهده است، که نشاندهنده مقداری خطا است.
این مقدار خطا برای ما قابل قبول است و از آن صرفنظر میکنیم.
اکنون عبارت S.0.11 و عبارت S.2.6 را به ورودیهای داخلی مدلی که از قبل داشتیم اعمال میکنیم و به مرحله سوم، یعنی مرحله کوانتیزاسیون عملگرها میرویم.
کوانتیزاسیون عملگرها
ما عبارت S.0.11 و عبارت S.2.6 را داریم که باید در همدیگر ضرب شوند. حاصل خروجی چیست؟
طبق قانون ضرب دو عدد علامتدار در مقاله "۷ گام پیادهسازی الگوریتمهای پردازش سیگنال در FPGA"، حاصل برابر با S.3.17 خواهد بود.
در این مرحله، عبارت S.0.13، و عبارت S.3.17 را داریم که باید با همدیگر جمع شوند.
نقطه کسری این دو عبارت زیر هم قرار ندارند، بنابراین نمیتوانیم این دو عبارت را با هم جمع کنیم.
اما راهحل چیست؟
یا باید تعداد بیتهای S.0.13 را بیشتر کنیم، یا اینکه از تعداد بیتهای S.3.17 کم کنیم.
راهحل صحیح این است که S.3.17 را به S.3.13 تبدیل کنیم، اما چرا؟
در بخشهای مختلف مدل، عرض بیت قسمت کسری، به واسطه عملگرهای ضرب گسترش پیدا میکند، و از طرفی دیگر، عرض بیتهای کسری که بیشتر از عرض بیت کسری ورودی باشد، از نظر ریاضی و محتوایی برای ما ارزشی ندارد.
پس، به عنوان یک قاعده کلی، عرض بیتهای کسری که در اثر عمل ضرب، بیشتر از عرض بیت کسری ورودی شود را در اولین فرصت و بلافاصله پس از عمل ضرب، به عرض بیت ورودی برمیگردانیم.
با اعمال قاعده بالا، به نتیجه زیر میرسیم:
در نهایت عبارت S.0.13 و عبارت S.3.13 را داریم که باید با همدیگر جمع شوند.
اکنون خیلی راحت و طبق قانون جمع دو عدد علامتدار، خروجی برابر با S.4.13 خواهد بود.
ما به دلیل سادگی پیادهسازی مدل Fixed Point، نسبت به مدل Floating Point، سعی میکنیم که از مدل Fixed Point، در پیادهسازیهای خود استفاده کنیم.
همانطور که در این مقاله دیدید، مدل Fixed Point، به مراتب منابع کمتری مصرف میکند و همچنین سرعت بیشتری را برای مدار ایجاد خواهد کرد.
دو مورد بالا از مزایای بسیار ارزشمند مدل Fixed Point هستند.
با دانستن اصول و قواعدی که در این مقاله آموختید، تبدیل یک مدل Floating Point به مدل Fixed Point کار بسیار راحتی است و با همین اصول و قواعد میتوانید هر مدل Floating Point دیگری را به یک مدل Fixed Point تبدیل کنید.