وقتی یک طراح سیستم، الگوریتم پردازش سیگنالی را به شما ارائه میدهد تا بر روی FPGA پیادهسازی کنید، شما باید نکات سختافزاری بسیاری را برای پیادهسازی این الگوریتم در نظر بگیرید.
در این مقاله، یک روش ۷-مرحلهای به شما معرفی خواهم کرد که به کمک آن میتوانید به سادگی هر الگوریتم پردازش سیگنالی را در FPGA پیادهسازی کنید.
معمولاً طراحان سیستم با محدودیتهای پیادهسازیِ مربوط به سختافزار آشنا نیستند.
وظیفه شما به عنوان پیادهساز سیستم، این است که با تسلط بر انواع منابع سختافزاری درون FPGA و در نظر گرفتن محدودیتهای موجود، الگوریتم پردازشی را به گونهای پیادهسازی کنید تا بیشترین سرعت و کمترین میزان منابع مصرفی را داشته باشد.
در این مقاله، روش انجام این کار را در قالب یک روش ۷-مرحلهای میآموزید.
More...
این مراحل، شامل موارد زیر هستند:
پیش از شروع مراحل پیادهسازی الگوریتمهای پردازش سیگنال در FPGA، به این سوال پاسخ میدهم که اساساً پردازش سیگنال به چه معناست؟
پردازش سیگنال چیست؟
بهعنوان یک تعریف کلاسیک، پردازش سیگنال عبارت است از تبدیل یا دستکاری یک سیگنال آنالوگ یا دیجیتال.
برای مثال، فرض کنید ما یک سیستم پردازشی مانند شکل زیر داریم و قصد داریم روی سیگنالهای ورودی این سیستم، یک عمل پردازشی انجام دهیم.
اگر احیاناً این سیگنال ورودی آنالوگ باشد، قاعدتاً به یک مبدل آنالوگ به دیجیتال (بلوک ADC) نیاز داریم که سیگنالهای آنالوگ را به دیجیتال تبدیل کند.
سپس، این سیگنال دیجیتال وارد DSP System یا Digital Signal Processing System میشود. در واقع، DSP System، همان سیستم پردازشی است که قصد داریم آن را با FPGA پیادهسازی کنیم.
خروجی این سیستم قاعدتاً به صورت دیجیتال است؛ پس ممکن است همین خروجی دیجیتالی برای ما کفایت کند.
اما ممکن است نیاز داشته باشیم که این خروجی را به یک سیگنال آنالوگ تبدیل کنیم؛ در این صورت، از یک مبدل دیجیتال به آنالوگ (بلوک DAC) استفاده میکنیم.
همانطور که گفته شد، در تعریف کلاسیک، پردازش سیگنال به معنی دستکاری یک سیگنال آنالوگ یا دیجیتال است.
اما منظور از دستکاری سیگنال چیست؟
منظور از دستکاری سیگنال، انجام محاسبات ریاضی بر روی آن است.
بنابراین، میتوان گفت که یک الگوریتم پردازش سیگنال، در حقیقت، مجموعهای از محاسبات ریاضی است.
به این ترتیب، به جای عبارت پر زرق و برق الگوریتم پردازش سیگنال، میتوانیم از عبارت سادهتر مجموعهای از محاسبات ریاضی استفاده کنیم.
پس در واقع هدف ما، پیادهسازی محاسبات ریاضی در FPGA است.
بهکمک این ادبیات، دیگر عبارت "الگوریتم پردازش سیگنال" ما را نمیترساند و از مسئله دور نمیکند.
اکنون بهسراغ توضیح مراحل پیادهسازی الگوریتمهای پردازش سیگنال در FPGA برویم.
مراحل پیادهسازی الگوریتمهای پردازش سیگنال در FPGA
در شکل زیر، یک شمای کلی از مراحل پیادهسازی الگوریتمهای پردازش سیگنال در FPGA را مشاهده میکنید:
همانطور که مشاهده میکنید، برای این کار از دو نرمافزار MATLAB و ISE کمک میگیریم.
مراحلی از نمودار که در بالای خطچین قرار دارد را در نرمافزار متلب و مراحل پایین خطچین را در نرمافزار ISE پیادهسازی میکنیم.
ما در نرمافزار متلب، طی مراحلی که در ادامه مقاله خواهید دید، یک مدل Fixed Point ایجاد میکنیم.
سپس، بر اساس این مدل Fixed Point، کدنویسی ماجول HDL را در نرمافزار ISE انجام میدهیم.
همانطور که در نمودار بالا نیز مشاهده میکنید، به مدل Fixed Point و ماجول HDL، یک مجموعه ورودی یکسان اعمال میکنیم (سمت چپ نمودار).
در نهایت، برای درستیآزمایی ماجول HDL (که قصد داریم آن را بر روی یک FPGA پیادهسازی کنیم)، خروجی ماجول را با خروجی مدل Fixed Point مقایسه میکنیم.
اگر خروجی ماجول HDL، مطابق با خروجی مدل Fixed Point بود، متوجه میشویم که ماجول HDL ما، عملکرد صحیحی دارد و بهدرستی کدنویسی شده است.
در این صورت، میتوانیم آن را بر روی FPGA پیادهسازی کنیم.
در ادامه مقاله، مراحل گام به گام پیادهسازی الگوریتمهای پردازش سیگنال در FPGA را بهصورت مفصلتر شرح خواهم داد.
مرحله اول: تهیه مدل Floating Point
ما الگوریتم پردازش سیگنال را برای پیادهسازی در FPGA، از طراح آن الگوریتم تحویل میگیریم.
ممکن است طراح الگوریتم، فرمول ریاضی مربوط به الگوریتم را در اختیار ما قرار دهد؛ در این صورت باید آن را در نرمافزاری مانند متلب مدلسازی کنیم.
اما ممکن است طراح، الگوریتم را به صورت مدلسازی شده به ما تحویل دهد.
نرمافزار متلب، به صورت پیشفرض از مدل Floating Point برای نمایش مقادیر استفاده میکند.
اما مدل Floating-Point چیست؟
بهطورکلی، برای پیادهسازی اعداد اعشاری در FPGA، دو روش یا سیستم وجود دارد:
اما سیستم نمایش Floating-Point چیست؟
سیستم نمایش Floating Point
در این سیستم، دو استاندارد وجود دارد؛ استاندارد ۳۲ بیتی و استاندارد ۶۴ بیتی.
همانطور که از نام روش Floating Point مشخص است، در این سیستم، محل نقطه اعشاری یا کسری متغیر است.
اکنون سوالی که مطرح میشود این است که مبنای تعیین محل نقطه کسری چیست؟
در پاسخ باید گفت که محل نقطه کسری، بستگی به مقدار لحظهای رجیستر دارد.
مثلاً فرض کنید یک رجیستر ۶۴ بیتی Floating Point داریم و میخواهیم عدد 3.1415 را در آن قرار دهیم.
برای قسمت صحیح این عدد که برابر با 3 است، دو بیت نیاز داریم. برای علامت عدد نیز یک بیت لازم است. به این ترتیب، ۶۱ بیت باقیمانده به قسمت کسری اختصاص پیدا میکند.
البته این یک بیان مفهومی از سیستم Floating Point است و سیستم Floating Point، در عمل بسیار پیچیدهتر است. اما میتوانیم بهصورت مفهومی سیستم Floating Point را به این صورت تعریف کنیم.
به عبارت دیگر، سیستم Floating Point، با توجه به مقدار لحظهای رجیستر، بیشترین عرض بیت ممکن را به قسمت کسری آن مقدار اختصاص میدهد.
در نتیجه، اعداد را با بیشترین دقت ممکن میتواند نمایش دهد. در واقع، این مهمترین حُسن سیستم Floating Point است.
اما معایب سیستم Floating Point چیست؟
این سیستم، برای پیادهسازی سختافزاری معایبی به شرح زیر دارد:
مهمترین عیب این سیستم، کاهش سرعت مدار است.
ما همواره در کار با FPGA سعی داریم از موارد فوق دوری کنیم. بنابراین، سیستم Floating Point، برای پیادهسازی الگوریتمهای پردازش سیگنال، سیستم مطلوبی نیست.
به همین دلیل، سراغ مدل Fixed Point میرویم.
مرحله دوم: تهیه مدل Fixed Point
اما مدل Fixed Point چیست؟
در سیستم Fixed Point، بر خلاف سیستم Floating Point، اصلاً استانداردی وجود ندارد. بلکه، شما به عنوان پیادهساز مدار، عرض بیت هر سیگنال را مشخص میکنید.
در سیستم Fixed Point، عرض بیت رجیسترها به گونهای انتخاب میشود که بیش از دقت موردنیاز ما نباشد.
برای مثال، برای نمایش عدد ۱۷، ما به یک رجیستر پنج بیتی نیاز داریم و نیازی نیست این مقدار را در قالب یک رجیستر ۶۴ بیتی نمایش دهیم.
در واقع، در سیستم Fixed Point، هر مقدار، ضریب یا عملگر، عرض بیت مخصوص به خود را دارد.
پیادهساز سیستم، بسته به نیاز هر سیگنال، برای آن یک استاندارد مخصوص تعریف میکند.
به بیان دیگر، فرد پیادهساز تعیین میکند که عرض بیت هر سیگنال چقدر باشد و نقطه کسری در چه قسمتی از آن قرار بگیرد.
به این ترتیب، مداری که با سیستم Fixed Point پیادهسازی شده است مزایای زیر را دارد:
به همین دلیل، سیستم Fixed Point برای پیادهسازی الگوریتمهای پردازش سیگنال با FPGA بسیار مناسب است.
اما سوالی که مطرح میشود این است که آیا سیستم Fixed Point در کنار تمام مزایایی که دارد، عیبی هم دارد؟
پاسخ این سوال مثبت است.
عیب سیستم Fixed Point این است که دقت آن نسبت به سیستم Floating Point کمتر است.
پس چرا تمایل داریم که الگوریتمها را با سیستم Fixed Point پیادهسازی کنیم؟
پاسخ این است که ما به دقتی، به اندازه دقت سیستم Floating Point نیازی نداریم.
در نتیجه، برای پیادهسازی الگوریتمهای پردازشی در FPGA از سیستم Fixed Point استفاده میکنیم.
بنابراین، باید قبل از پیادهسازی الگوریتم در FPGA، مدل Floating Point را به مدل Fixed Point تبدیل کنیم.
در واقع، باید عرض بیت هر سیگنال یا عملگر را در کمترین عرض ممکن و به صورت بهینه تعیین کنیم.
برای این کار، اگر در مرحله قبل، مدل Floating Point را در محیط سیمولینک متلب ساختهایم، اکنون یک کپی از آن را در همان محیط ایجاد میکنیم و ابزار کوانتیزاسیون را به آن اضافه میکنیم.
در واقع، مدل Fixed Point، همان مدل Floating Point است که در آن ابزار کوانتیزاسیون قرار گرفته است.
اما ابزار کوانتیزاسیون چیست؟
ابزار کوانتیزاسیون، یک بلوک در نرمافزار سیمولینک است که میتواند هر سیگنالی را به نحوی که مطلوب ما است کوانتیزه کند؛ و منظور از کوانتیزاسیون، کاهش عرض بیت بخش کسری سیگنالها است.
در این مرحله، به تکنیکهای مرحله سوم، یعنی تکنیکهای کوانتیزاسیون نیاز داریم.
مرحله سوم: کوانتیزاسیون مدل Fixed Point
همانطور که گفته شد، باید مدل Floating Point را کوانتیزه کنیم تا به مدل Fixed Point برسیم.
اما در عملیات کوانتیزاسیون، برای رسیدن به یک مدل Fixed Point بهینه، باید عرض بیت مقادیر را تا چه میزانی کاهش دهیم؟
محاسبه کمترین عرض بیت
عملیات کوانتیزاسیون مدار و رسیدن به حداقل عرض بیتها را در سه گام به صورت زیر انجام میدهیم:
گام اول: کوانتیزاسیون ورودیهای اصلی مدار
ورودیهای اصلی مدار معمولاً از تراشه دیگری وارد مدار ما میشوند. عرض بیت این نوع سیگنالها، توسط منبعی که از آن نشات میگیرند مشخص میشود.
مثلاً اگر ورودی اصلی مدار، از یک مبدل آنالوگ به دیجیتال وارد مدار شود و این مبدل، سیگنال خروجی با عرض ۱۴ بیت تولید کند، عرض بیت ورودی اصلی ما ۱۴ بیت خواهد بود.
بنابراین، کوانتیزاسیون ورودیهای اصلی بسیار ساده است؛ در واقع، باید منشا آنها را بررسی کنیم و بر اساس آن، عرض بیتشان را در مدل Fixed Point تعیین کنیم.
اکنون بهسراغ گام بعدی، یعنی کوانتیزاسیون ورودیهای داخلی میرویم.
گام دوم: کوانتیزاسیون ورودیهای داخلی
ورودیهای داخلی مدار میتوانند شامل مولدهای موج سینوسی یا ضرایب داخلی باشند.
برای تعیین عرض بیت بهینه برای این ورودیها میتوانیم بهصورت زیرعمل کنیم:
ابتدا عرض بیت ورودی داخلی را به میزان دلخواه کاهش میدهیم.
سپس، خروجی مدار که دارای عرض بیت جدید است را با خروجی آن، قبل از کاهش عرض بیت (مدل Floating Point) مقایسه میکنیم.
اگر نمودار دو خروجی به میزان قابل توجهی از یکدیگر فاصله گرفته بودند، در این مرحله باید عرض بیت را افزایش دهیم.
اما اگر دو نمودار تفاوت محسوسی نداشتند، میتوانیم کاهش عرض بیت را ادامه بدهیم.
در این حالت، به محض فاصله گرفتن دو نمودار، کاهش عرض بیت را متوقف میکنیم.
اگر مدار ما شامل چند ورودی داخلی بود، باید این روش را برای هر ورودی، بهصورت جداگانه، اعمال کنیم.
به این ترتیب، میتوانیم با تقریب خوبی به عرض بیت مناسب برای ورودیهای داخلی برسیم.
پس از این گام، یعنی تعیین عرض بیت ورودیهای داخلی، بهسراغ کوانتیزاسیون عملگرها میرویم.
گام سوم: کوانتیزاسیون عملگرهای ضرب و جمع
در الگوریتمهای پردازش سیگنال، عملگرهای ضرب و جمع به وفور دیده میشوند.
ما باید با توجه به عرض بیت ورودیهای این عملگرها، عرض بیت مناسبی برای خروجی آنها در نظر بگیریم.
این کار برای جلوگیری از وقوع سرریز یا overflow است.
همانطور که میدانید، سرریز یک خطای کشنده است؛ در واقع، پاسخ سیستم را با خطای زیادی مواجه میکند.
فرض کنید سیگنال A دارای عرض بیت صحیح m1 و عرض بیت کسری n1 است. همچنین، فرض کنید، عرض بیت صحیح سیگنال عدد B، برابر با m2 و عرض بیت کسری آن برابر با n2 باشد.
اگر این دو سیگنال را در هم ضرب کنیم، عرض بیت حاصلضرب آنها بهصورت زیر خواهد بود:
A*B = (m1 . n1) * (m2 . n2) = (m1+m2 . n1+n2) = C
بنابراین، سیگنال C که حاصلضرب دو سیگنال A و B است دارای عرض بیت صحیح m1+m2 و عرض بیت کسری n1+n2 است.
در صورتی که اعداد A و B علامتدار باشند، عرض بیت حاصلضرب آنها بهصورت زیر است:
A*B = (s.m1 . n1) * (s.m2 . n2) = (s.m1+m2+1 . n1+n2) = C
به این ترتیب، سیگنال C که حاصلضرب دو سیگنال علامتدار A و B است، دارای عرض بیت صحیح m1+m2+1 و عرض بیت کسری n1+n2 است.
در واقع، در عملیات ضرب دو سیگنال بدون علامت، باید عرض بیت قسمت صحیح حاصلضرب را برابر با عرض بیت قسمت صحیح سیگنال اول، به علاوه عرض بیت قسمت صحیح سیگنال دوم در نظر بگیریم.
اما در عملیات ضرب دو سیگنال علامتدار، عرض بیت قسمت صحیح حاصلضرب، برابر با عرض بیت قسمت صحیح سیگنال اول، به علاوه عرض بیت قسمت صحیح سیگنال دوم، به علاوه مقدار یک خواهد بود.
توجه داشته باشید که عرض بیت قسمت کسری حاصلضرب برای اعداد علامتدار و بدون علامت تفاوتی ندارد و برابر با مجموع عرض بیتهای قسمت کسری دو سیگنال است.
اکنون به سراغ بررسی عرض بیت حاصلجمع میرویم.
برای تعیین عرض بیت خروجی عملیات جمع، باید به چند نکته دقت کنید.
اگر دو سیگنالی که قصد داریم آنها را با هم جمع کنیم، عرض بیت کسری متفاوتی داشته باشند، یعنی نقطه کسری آنها زیر هم قرار نگرفته باشد، حاصل جمع صحیح نخواهد بود.
فرض کنید بخواهیم دو سیگنال علامتدار زیر را با هم جمع کنیم:
توجه کنید که سیگنال دوم منفی است و بهصورت مکمل دو نمایش داده شده است.
برای انجام عملیات جمع فوق، باید به قسمت کسری سیگنالی که دارای عرض بیت کسری کمتری است، بیت صفر اضافه کنیم تا نقاط کسری دو سیگنال زیر هم قرار بگیرند:
توجه داشته باشید که اگر علامت یک سیگنال علامتدار را تکرار کنیم، مقدار آن سیگنال تغییری نمیکند.
بنابراین، برای افزایش عرض بیت قسمت صحیح اعداد علامتدار میتوانیم به این شیوه عمل کنیم.
اما افزودن بیت به یک سیگنال را چگونه در زبان VHDL انجام میدهیم؟
این کار را بهکمک عملگر concatenation انجام میدهیم.
برای یادآوری نحوه عملکرد عملگر concatenation، فرض کنید بخواهیم دو سیگنال زیر را با هم کانکت کنیم:
برای انجام این کار بهصورت زیر عمل میکنیم:
همانطور که مشاهده میکنید، در رجیستر C که رجیستر حاصل concatenation است، بیتهای دو سیگنال A و B به ترتیب در کنار هم قرار گرفتهاند.
بنابراین، بهکمک عملگر concatenation، به سمت راست سیگنالی که عرض بیت کسری کمتری دارد، به میزان لازم بیت صفر اضافه میکنیم.
اما نحوه افزودن بیت به بخش صحیح یک سیگنال در زبان VHDL به چه صورت است؟
برای این کار نیز میتوانیم از عملگر concatenation استفاده کنیم. اما نیازی به استفاده از آن نیست؛ زیرا در عملیات جمع در زبان VHDL، به قسمت صحیح سیگنالی که عرض بیت صحیح کمتری دارد به صورت خودکار به اندازه اختلاف عرض بیت قسمت صحیح دو سیگنال، بیت افزوده میشود.
بنابراین، نیازی نیست که برای افزایش عرض بیت قسمت صحیح اعداد کدنویسی کنیم.
به این ترتیب، در مرحله کوانتیزاسیون، در قالب سه گام، مدل Floating Point را کوانتیزه کرده و به مدل Fixed Point رسیدیم.
توجه داشته باشید که مدل Fixed Point، در واقع همان مدل Floating Point است که در آن ابزار کوانتیزاسیون قرار گرفته است.
تا به اینجای مقاله، سه مرحله از مراحل پیادهسازی الگوریتمهای پردازش سیگنال در FPGA را بررسی کردیم:
۱. ساخت مدل Floating Point
۲. ساخت مدل Fixed Point
۳. رسیدن به حداقل عرض بیتهای ممکن برای سیگنالها بهکمک عملیات کوانتیزاسیون
اکنون به ادامه مراحل پیادهسازی الگوریتم پردازش سیگنال در FPGA میپردازیم.
مرحله چهارم: شبیهسازی مدل Fixed Point و ذخیرهسازی ورودیها و خروجیها
پس از نهایی شدن مدل Fixed Point، آن را در نرمافزار متلب شبیهسازی میکنیم.
در این مرحله، باید در هنگام شبیهسازی، ورودیها و خروجیهای مدل Fixed Point را ذخیره کنیم.
ورودیها و خروجیهای ذخیره شده، در مراحل بعدی، بهکار خواهند آمد.
در واقع، در مراحل بعدی، این دادهها را برای مقایسه مدل Fixed Point و ماجول VHDL پیادهسازی شده استفاده خواهیم کرد.
اکنون وقت آن رسیده است که کد VHDL معادل مدل Fixed Point را بنویسیم.
مرحله پنجم: پیادهسازی مدل VHDL بر مبنای مدل Fixed Point
در این مرحله، مدل Fixed Point حاصل از مرحله سوم را مبنا قرار میدهیم و کد VHDL معادل آن را مینویسیم.
پس از آن، باید از صحت عملکرد ماژول VHDL اطمینان حاصل کنیم.
بنابراین، باید آن را درستیآزمایی کنیم.
مرحله ششم: درستیآزمایی مدل VHDL
برای اطمینان از صحت عملکرد ماجول VHDL، میتوانیم مدار پیادهسازی شده توسط آن را شبیهسازی کنیم.
در واقع، ورودیهایی که در مرحله چهارم در نرمافزار متلب به مدل Fixed Point اعمال کرده بودیم را اکنون به ماژول VHDL اعمال میکنیم.
در این مرحله، باید خروجی شبیهسازی را برای استفاده در مرحله نهایی ذخیره کنیم.
بنابراین، باید در کد VHDL مخصوص شبیهسازی (تستبنچ)، تمهیداتی برای اعمال ورودیهای موردنظرمان به ماجول VHDL، و ذخیره خروجیهای شبیهسازی در نظر بگیریم.
سپس به سراغ مرحله نهایی میرویم.
مرحله هفتم: مقایسه خروجی مدل Fixed Point با خروجی شبیهسازی کد VHDL
در آخرین گام از ۷ گام پیادهسازی الگوریتمهای پردازش سیگنال در FPGA، خروجیهای مدل Fixed Point و مدل VHDL را با هم مقایسه میکنیم.
به این ترتیب، صحت پیادهسازی خود بررسی میکنیم.
در واقع، بررسی میکنیم که آیا مدل VHDL را به درستی و مطابق با مدل Fixed Point طراحی و پیادهسازی کردهایم یا خیر.
اگر خروجی مدل VHDL بر خروجی مدل Fixed Point که در نرمافزار متلب شبیهسازی کرده بودیم منطبق بود، کار پیادهسازی را به درستی انجام دادهایم.
با طی کردن هفت گامی که در این مقاله معرفی کردم، میتوانید هر الگوریتم پردازش سیگنالی را به راحتی در FPGA پیادهسازی کنید.
امیدوارم از خواندن این مقاله هم لذت برده باشید و بتوانید از نکات یاد گرفته شده، در انجام پروژههای پردازش سیگنالتان استفاده کنید.
بسیار عالی
ممنون از سایت خوب تون
با درود،
ممنون و سپاسگزارم.
بسیار مفید و ارزنده بود سپاس فراوان