آیا تا به حال از شما خواسته شده است که سرعت یک مدار دیجیتال را که خودتان یا شخص دیگری پیادهسازی کرده است افرایش دهید؟
این اتفاقی است که گاه در فرآیند انجام یک پروژه حرفهای اتفاق میافتد و شما باید خودتان را برای چنین روزی آماده کنید.
More...
شاید برایتان جالب باشد که بدانید، در محاسبههای شغلی که برای استخدام نیروی مسلط به پیادهسازی دیجیتال با FPGA انجام میدهم، یکی از سوالاتی که از افراد متقاضی میپرسم، در مورد نحوه افزایش سرعت مدار است.
سوالی که میپرسم معمولا به این صورت است:
فرض کنید مداری طراحی کردهاید که حداکثر سرعت کلاک قابل اعمال به آن برابر با ۸۰MHz است. با توجه به نیازمندیهای مساله، باید بتوانیم کلاکی با فرکانس ۱۲۰MHz به این مدار اعمال کنیم. راهکار شما برای افزایش حداکثر فرکانس کلاک قابل اعمال به این مدار چیست؟
پاسخ به این سوال، در خیلی از موارد میتواند مشخص کننده سطح دانش طراحی دیجیتال و تجربه او در به کار بردن ابزار موجود در پیادهسازی باشد؛ چون جواب کامل به این سوال، نه تنها مستلزم درک درست از بعضی از مفاهیم پایه و مهم در طراحی دیجیتال است، بلکه نیاز به تسلط به ابزارها و نرمافزارهای پیادهسازی برای تشخیص روش صحیح افزایش فرکانس و نحوه اعمال آنها به مدار دارد.
البته در یک جلسه مصاحبه، انتظار شنیدن یک پاسخ کامل برای این پرسش را ندارم و معمولا هم این اتفاق نمیافتد. اما، پاسخی که داده میشود و موضوعاتی که در این پاسخ به آنها اشاره میشود میتواند تا حد زیادی نشان دهنده سطح دانش طراحی و تبحر فرد متقاضی در پیادهسازی بهینه مدارات دیجیتال باشد.
برای دانلود فایل PDF این مقاله، روی دکمه زیر کلیک کنید:
در این مقاله، به دو روش متدوال برای افزایش سرعت مدارات دیجیتال اشاره میکنم. در توضیح هر کدام از این روشها، در مورد نحوه توصیف و پیادهسازی آنها به کمک زبان VHDL هم صحبت میکنم تا بتوانید هر چه زودتر این روشها را به مداراتی که طراحی کردهاید یا در حال طراحی آن است هستید اعمال کنید.
برای آشنایی با زبان VHDL، این برنامه ویدئویی را ببینید.
اما قبل از اینکه در مورد این دو روش و نحوه بکارگیری آنها به کمک زبان VHDL برای پیادهسازی در FPGAها صحبت کنم، اجازه بدید با دو مفهوم مهم در ارتباط با سرعت مدارات دیجیتال آشنا شویم…
مفهوم Latency و Throughput
سیستمیرا تصور کنید که فقط یک ورودی و یک خروجی دارد.
این سیستم، محاسباتی را روی هر کدام از ورودیها انجام میدهد و نتیجه را به خروجی منتقل میکند. در ارتباط با سرعت این سیستم، دو مفهوم را میتوان تعریف کرد:
مفهوم Latency
مدت زمانی که طول میکشد تا محاسبات روی یکی از ورودیها انجام شود و خروجی متناظر با آن آماده شود. مثلا اگر Y1 خروجی متناظر با ورودی X1 باشد، مدت زمانی که بعد از اعمال ورودی X1 به سیستم طول میکشد تا خروجی متناظر با آن یعنی Y1 آماده شود را Latency میگویند.
مفهوم Throughput
در سیستم فوق، تعداد خروجی محاسبه شده در واحد زمان را throughput سیستم میگویند. مثلا ممکن است در این سیستم، مدت زمان لازم برای انجام محاسبات روی یک ورودی مشخص برابر با ۵ ثانیه باشد. اما این سیستم در هر یک ثانیه میتواند دو خروجی تولید کند. بنابراین، در این سیستم مقدار Latency برابر با ۵ ثانیه و مقدار throughput برابر با دو نتیجه در هر ثانیه است.
مقدار throughput در حقیقت متناسب است با فاصله زمانی بین دو خروجی (و البته بین دو ورودی.) در سیستم فوق، با اینکه برای تولید هر خروجی نیاز به ۵ ثانیه زمان است، اما میتوان در هر نیمثانیه، یک ورودی جدید به آن اعمال کرد.
من معمولا برای توضیح مفهوم Latency و throughput از مثال خط تولید ماشین استفاده میکنم. فرض کنید برای ساخت هر ماشین در یک کارخانه تولید خودرو، ۵ ساعت زمان لازم باشد. این خط تولید، در هر نیم ساعت، یک ماشین تولید میکند. بنابراین، در تولید ماشینهای این کارخانه، Latency برابر با ۵ ساعت و throughput برابر با دو ماشین در ساعت است.
حال که با این دو مفهوم مرتبط با سرعت در مدارات دیجیتال به خوبی آشنا شدید، اجازه دهید به سراغ روشهای افزایش سرعت در مدارات دیجیتال برویم.
افزایش سرعت مدارات دیجیتال به کمک پایپلاین کردن
این روش، شاید متدوالترین راه حلی باشد که شما برای افزایش سرعت مدار میتوانید انجام دهید. برای توضیح این روش، باز هم از مثال خط تولید ماشین استفاده میکنم.
فرض کنید برای تولید ماشینها در یک کارخانه، پنج مرحله وجود دارد: تولید شاسی، اتصال چرخها، قرار دادن موتور، اتصال بدنه و رنگ آمیزی. فرض کنید برای هر کدام از این مراحل، یک ساعت زمان لازم است. بنابراین تولید هر ماشین، به ۵ ساعت زمان نیاز دارد.
اگر این خط تولید، فقط دارای یک اپراتور باشد و این اپراتور در هر لحظه فقط بتواند یکی از پنج مرحله فوق را انجام دهد، یعنی در این کارخانه در هر پنج ساعت یک ماشین تولید میشود. بنابراین، مقدار throughput برابر با یک ماشین در هر پنج ساعت است. مقدار latency هم برابر با ۵ ساعت است.
راه افزایش throughput یا سرعت تولید ماشینها در این کارخانه چیست؟
اگر هر مرحله ار مراحل پنجگانه تولید این ماشین دارای یک اپراتور مجزا باشد، میتوان این مراحل را به طور همزمان انجام داد. در این حالت، وقتی اپراتور اول، شاسی را آماده کرد و آن را به اپراتور دوم که مسوول اتصال چرخهاست تحویل داد، خود میتواند همزمان با او، شاسی جدیدی تولید کند.
وقتی اپراتور دوم، چرخها را متصل کرد و به اپراتور سوم که مسوول اتصال موتور است تحویل داد، میتواند یک شاسی جدید آماده شده از اپراتور اول تحویل بگیرد و چرخها را متصل کند.
فکر میکنید در چنین خط تولیدی، مقدار latency و throughput برابر با چه مقادیری هستند.؟
همانطور که احتمالا حدس زده اید، مقدار latency تغییری نکرده است، چون هنوز برای ساخت یک ماشین، نیاز به ۵ ساعت زمان است. به عبارت دیگر، اگر روی یکی از شاسیهای مرحله اول یک علامت قرار دهید، ماشینی که آن شاسی خاص را در خود دارد، پنج ساعت بعد آماده خواهد شد.
اما مقدار throughput افزایش یافته است. در خط تولید جدید، اگر در انتهای خط تولید قرار بگیرید، در هر یک ساعت میتوانید یک ماشین جدید تحویل بگیرید. در این حالت، مقدار throughput پنج برابر بهتر شده است.
به عملی که در این مثال برای بهبود throughput خط تولید انجام شد، پایپلاین کردن گفته میشود. به کمک پایپلاین کردن میتوانید سرعت کلاک مدار را هم بالا ببرید. در حقیقت، مقدار throughput متناسب است با سرعت کلاک.
اما در یک مدار دیجیتال چگونه میتوان سرعت را به کمک این تکنیک افزایش داد؟ کدام بخش از یک مدار بزرگ را باید پایپ لاین کرد تا سرعت کلاک و throughput آن افزایش یابد؟
قبل از اینکه در مورد نحوه افزایش سرعت مدار به کمک روش پایپلاین صحبت کنم، بهتر است ابتدا ببینیم که عامل محدود کننده سرعت کلاک در یک مدار ترکیبی سنکرون چیست.
عامل محدود کننده سرعت کلاک
یک مدار ترکیبی سنکرون دارای رجیسترهایی در بخشهای مختلف آن است که همگی دارای یک ورودی کلاک یکسان هستند. هر بار که سیگنال کلاک فعال شود، مقادیر این رجیسترها میتوانند تغییر کنند.
مدارات ترکیبی در چنین سیستمی، بین رجیسترها قرار دارند. یعنی هر بخش ترکیبی که در این مدار شناسایی کنید، حتما بین دو رجیستر قرار دارد. وقتی کلاک فعال میشود، مقدار رجیسترها تغییر میکند. به عبارت دیگر، ورودی مدارات ترکیبی که بین رجیسترها قرار دارند تغییر میکنند. اثر این تغییر در ورودی مدار ترکیبی، به اندازه تاخیر انتشار یا propagation delay آن بخش از مدار ترکیبی زمان لازم دارد تا به انتهای مدار یا همان رجیستری که در انتهای مدار ترکیبی هست برسد.
اگر قبل از اینکه اثر تغییر یک رجیستر به رجیستری که در انتهای مدار ترکیبی است برسد، کلاک دوباره فعال شود، در عملکرد مدار خطا ایجاد میشود. پس عامل محدود کننده سرعت کلاک یک مدار، تاخیر انتشار مدارات بین رجیسترها هستند.
اما در یک مدار بزرگتر، تعداد زیادی از این مدارات ترکیبی بین رجیسترهای مختلف قرار دارند و تاخیر انتشار هر کدام هم متفاوت است. در این حالت، عامل محدود کننده سرعت کلاک، طولانیترین تاخیر انتشار است. به مسیر مدار ترکیبی از یک رجیستر تا رجیستر دیگر که دارای بیشترین تاخیر انتشار است، مسیر بحرانی یا critical path میگویند.
برای اینکه بتوانید به کمک روش پایپلاین، حداکثر فرکانس کلاک قابل اعمال به یک مدار و در نتیجه throughput آن را افزایش دهید، بابد در ابتدا مسیر بحرانی مدار را پیدا کنید و سپس آن را به کمک روش پایپلاین به چند مسیر کوتاهتر تبدیل کنید.
در عمل برای شکستن یک مسیر بحرانی، باید در بخشهایی از این مسیر، رجیستر قرار دهید تا یک مسیر با تاخیر انتشار طولانی، تبدیل به چند مسیر پشت سر هم اما با تاخیرهای انتشار کوچک شوند. اضافه کردن رجیسترها، مشابه اضافه کردن اپراتورها برای افزایش سرعت تولید در خط تولید ماشین است.
ممکن است الان این سوال برای شما پیش بیاید که در یک مدار بزرگ که به کمک زبان VHDL توصیف شده است، چگونه مسیر بحرانی را پیدا کنیم.
بخشی از این کار را معمولا در اثر تجربه کار پیادهسازی با FPGAها به دست خواهید آورد. اما روش اصولی آن، استفاده از گزارشات نرمافزار سنتز است. اگر از نرمافزار ISE برای پیادهسازی مدار روی FPGA استفاده میکنید، این نرمافزار در هر مرحله از پیادهسازی، گزارشات مفصلی را ارائه میدهد که مطالعه آنها یا حداقل بخشهای مهمی از آن میتواند برای انجام تغییراتی که منجر به بهبود عملکرد مدار شود کمک زیادی به شما میکند.
برای آشنایی با نرمافزار ISE این برنامه ویدئویی را ببینید.
یکی از مواردی که در گزارش سنتز به آن اشاره میشود، مقدار تاخیر انتشار مسیر بحرانی و محل آن است. مقدار این تاخیر با عکس حداکثر فرکانس کلاک قابل اعمال به مدار متناسب است. بنابراین، شما در این گزارش میتوانید دریابید که حداکثر فرکانس کلاکی که میتوانید به مدار اعمال کنید چند است.
اگر این فرکانس کلاک، برای کاربرد مورد نظر شما کم بود و شما نیاز داشتید که فرکانس کلاک بیشتری را به مدار اعمال کنید، باید به سراغ پایپلاین کردن بروید. برای این کار، ابتدا باید ببینید که مسیر بحرانی در کدام بخش از مدار شما است و به عبارت دقیقتر، باید ببینید بین کدام دو رجیستر، بیشترین تاخیر انتشار وجود دارد.
خوشبختانه یکی دیگر از مواردی که در گزارش سنتز به آن اشاره میشود، نام رجیسترهای ابتدا و انتهای مسیر بحرانی است. با اطلاع از نام این رجیسترها متوجه خواهید شد که کدام بخش از مدار دارای بیشترین تاخیر انتشار است و سپس میتوانید برای پایپلاین کردن آن اقدام کنید.
نحوه پایپ لاین کردن مدار در زبان VHDL
برای آشنایی با نحوه پایپلاین کردن یک مدار در زبان VHDL اجازه دهید یک مثال را با هم بررسی کنیم. فرض کنید میخواهیم مدار زیر را به کمک زبان VHDL پیاده سازی کنیم.
این مدار، هر کدام از ورودیهای A و B را به ترتیب در دو ورودی C1 و C2 ضرب میکند و حاصل این دو ضرب را با هم جمع کرده و به خروجی S ارجاع میدهد.
ورودیها در ابتدا به کمک رجیسترهای میانی A_Int، B_Int، C1_Int و C2_Int رجیستر میشوند. خروجی هم ابتدا در رجیستر S_Int بافر میشود و در محیط concurrent به خروجی ارجاع داده میشود.
با توجه به اینکه در این مدار، از یک رجیستر تا رجیستر دیگر، یک عمل جمع و یک عمل ضرب وجود دارد، تاخیر مسیر بحرانی برابر با تاخیر یک عمل ضرب به علاوه تاخیر یک عمل جمع خواهد بود و حداکثر فرکانس کلاک قابل اعمال به این مدار هم برابر با عکس عدد تاخیر انتشار مسیر بحرانی خواهد بود.
اگر حداکثر فرکانس کلاک قابل اعمال به این مدار برای شما قابل قبول نباشد و تصمیم بگیرید که آن را افزایش دهید، میتوانید از روش پایپلاین استفاده کنید. برای این کار میتوانید دو رجیستر یکی در مسیر ورودی A تا خروجی S و دیگری از مسیر ورودی B تا خروجی S بین عمل ضرب و جمع قرار دهید.
در این حالت، تاخیرهایی که بین رجیسترها وجود دارند، یکی تاخیر عمل ضرب است و دیگری تاخیر عمل جمع که مانند مدار اول، دیگر پشت سر هم نیستند و بین آنها رجیستر قرار داده شده است.
حال فکر میکنید، مسیر بحرانی در این مدار کدام است؟
پاسخ این سوال به تاخیر انتشار عمل ضرب و جمع بستگی دارد. مثلا اگر عمل ضرب دارای تاخیر انتشار بیشتری باشد، بنابراین مسیر بحرانی از رجیستر A1_Int تا P1_Int خواهد بود.
برای پیادهسازی این مدار در زبان VHDL کافی است حاصل ضربها را در محیط process ابتدا به یک رجیستر میانی ارجاع دهید و سپس این رجیستر میانی را در یک ارجاع دیگر برای انجام جمع استفاده کنید. این حالت در کد زیر نشان داده شده است.
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use ieee.numeric_std.all; entity Ex3_Pipeline is port ( A : in signed (7 downto 0); B : in signed (7 downto 0); C1 : in signed (3 downto 0); C2 : in signed (3 downto 0); S : out signed (7 downto 0); Clock : in std_logic ); end Ex3_Pipeline; architecture Behavioral of Ex3_Pipeline is signal A_Int : signed (7 downto 0) := (others=>'0'); signal B_Int : signed (7 downto 0) := (others=>'0'); signal C1_Int : signed (3 downto 0) := (others=>'0'); signal C2_Int : signed (3 downto 0) := (others=>'0'); signal P1_Int : signed (11 downto 0):= (others=>'0'); signal P2_Int : signed (11 downto 0):= (others=>'0'); signal S_Int : signed (11 downto 0):= (others=>'0'); begin -- port maps. -- some assignments. S <= S_Int(11 downto 4); Process(Clock) begin if rising_edge(Clock) then --- Sequential Code A_Int <= A; B_Int <= B; C1_Int <= C1; C2_Int <= C2; P1_Int <= A_Int * C1_Int; P2_Int <= B_Int * C2_Int; S_Int <= P1_Int + P2_Int; end if; end process; end Behavioral;
موازی سازی یا Parallelism
بعضی اوقات برای افزایش سرعت پردازش یا throughput مجبور هستید بعضی از ماجولها را چند بار به کار ببرید. به این عمل موازیسازی میگویند.
نکتهای که در اینجا باید به آن توجه کنید این است که در هر طرحی نمیتوان از روش پایپلاین استفاده کرد. گاهی هم ممکن است سیستمیرا پایپلاین کنید، اما هنوز به سرعت دلخواه نرسیده باشید و مجبور باشید از روش موازیسازی استفاده کنید.
در این روش، شما به تعداد لازم باید ماجول مورد نظر را در طرحتان تکرار کنید. بنابراین، این روش نسبت به روش پایپلاین نیاز به سختافزار بسیار بیشتری دارد. در این روش، مسیرهای بحرانی تغییر نمیکنند و در نتیجه حداکثر فرکانس کلاک قابل اعمال به مدار هم تغییر نمیکند، اما میتوان تعداد روردی بیشتری در واحد زمان به سیستم اعمال کرد و در نتیجه throughput افزایش پیدا میکند.
تکنیکهای پیادهسازی با زبان توصیف سختافزاری
دو روش پایپلاین و موازیسازی میتوانند به طور موثری باعث افزایش سرعت و throughput هر مداری شوند. وقتی مداری را طراحی میکنید، حتی قبل از آنکه شروع به پیادهسازی عملی آن کنید، میتوانید در مورد موازیسازی و پایپلاین کردن آن تصمیمگیری کنید و طرحتان را بر این مبنا پیادهسازی کنید.
اما موارد دیگری هم میتوانند سرعت پیادهسازی را تحت تاثیر قرار دهند که مربوط به نحوه توصیف مدار با یک زبان توصیف سختافزاری میشود.
در مقاله دیگری، در مورد تکنیکهایی صحبت خواهم کرد که در هنگام توصیف مدار با زبانهای HDL مثل VHDL و Verilog باید در نظر بگیرید.
اگر تجربهای در زمینه روشهای افزایش سرعت مدار دیجیتال دارید، خوشحال میشوم آنها را با من و دیگر خوانندگان به اشتراک بگذارید.
آیا مقاله چگونه سرعت مدار دیجیتال را افزایش دهیم برای شما مفید بود؟
لطفا نظرتان را در مورد این برنامه در پایین همین پست با دیگران به اشتراک بگذارید. همچنین با کلیک روی هر کدام از دکمههای اشتراک گذاری ابتدای این مطلب و به اشتراکگذاری آن در شبکههای اجتماعی میتوانید افراد بیشتری را در یادگیری این مطالب سهیم کنید.
بسیار بسیار ممنون استاد … خدا انشالله در مسیری که در پیش گرفته اید توفیقتان بدهد…
خواهش میکنم. خوشحالم که این مقاله مورد توجه شما قرار گرفته.
سلام
خیلی ممنونم ازتون استاد ارجمند و گرامی
خیلی زیبا پایپلاین را توضیح دادی تشکر از شما
سلام استاد گرامی
خسته نباشید. ممنون از توضیحات بسیار مفید شما.
من از یک divider ipcore استفاده کردم ک دارای latency هست. با شبیه سازی post-route متاسفانه با هر بار تغییر clk-period، در زمان های متفاوتی جواب میگیرم و این زمان های متفاوت حتی مستقل از تعداد کلاک هستن. یه بار ۲۰ کلاک بعد و یه بار ۴۰ کلاک بعد. امکانش هست منو راهنمایی کنید؟
سلام، ممنون.
در نرمافزار ISE، یک IPی تقسیم کننده وجود دارد که همانطور که گفتید دارای تاخیر یا latency است. مقدار این تاخیر متناسب با عرض بیت سیگنالهای ورودی است. بنابراین اگر عرض بیت را تغییر ندهید، مقدار تاخیر هم تغییر نمیکند.
موفق باشید.
سلام
خسته نباشید.
سوالی داشتم در مورد نحوه پیاده سازی مدار حالت غیر پایپلاین:
طبق توضیحات شما کد زیر بیانگر مدار کشیده شده برای حالت بدون پایپلاین می باشد.
process(clock)
begin
a_int <= a;
b_int <= b;
c1_int <= c1;
c2_int <= c2;
s_int <= (a_int*c1_int) + (b_int*c2_int);
end process;
حال تفاوت کد بالا با کد زیر در چیست؟
architecture….
begin
s_int <= (a_int*c1_int) + (b_int*c2_int);
process(clock)
begin
a_int <= a;
b_int <= b;
c1_int <= c1;
c2_int <= c2;
end process;
باتشکر
سلام،
تفاوت در این است که در کد دوم، خروجی وارد رجیستر نمیشود، بلکه مستقیما به پورت خروجی ماجول متصل میشود. که البته این از دید الگوی استاندارد کدنویسی برای FPGA صحیح نیست.
موفق باشید.
سلام خدا خیرتون بده عالی بود مرسییییییییییییییییییییی
جناب ثقفی ، از اینکه علم خودتون رو به اشتراک میگذارید بسیار سپاسگذارم، سوال من این هست که آیا میشه از کتابخانه openMP در طراحی دیجیتال برای استفاده از مزیت های موازی سازی استفاده کرد؟
خواهش میکنم. متاسفانه من تجربهای در استفاده از کتابخانهای که اشاره کردید ندارم. موفق باشید.
با تشکر از مطالب مفید شما،
مفاهیم بسیار گویا و جالب بیان شدند و از خواندن آنها لذت بردم.
فقط وقتی بلوکی بجز اینترفیس را درون FPGA مینویسیم ترجیح بر استفاده از HLS است که اجرای این مفاهیم در آن بسیار ساده و سریع است.
خواهش میکنم. خوشحالم که برای شما مفید بوده است.
در این مقاله، تاکید بر آموزش مفهومی یکی از تکنیکهای افزایش سرعت مدار در FPGA بوده است و در عمل، بدون تسلط به چنین مفاهیمی، حتی با کمک گرفتن از ابزارهای خودکار پیادهسازی، در بسیاری از موارد امکان رسیدن به نیازمندیهای پروژه بسیار دشوار است.
موفق باشید.