آموزش FPGA : قسمت دوازدهم

آموزش FPGA : قسمت دوازدهم

در قسمت یازدهم از مجموعه آموزشی FPGA با ساختار شرطی case آشنا شدیم و به مقایسه ساختارهای شرطی در محیط ترتیبی پرداختیم. در نهایت مقایسه‌ای تخصصی در رابطه با این ساختارها ارائه دادیم و نوصیه‌هایی برای هرچه حرفه‌ای‌تر شدن شما بیان کردیم.

در قسمت‌های قبل چندین فیدبک از دوستان داشتیم که گفته بودند اگر کد را به نحو دیگری بنویسیم صحیح‌تر می‌باشد، بله حرف دوستان عزیز کاملا درست بود و ما هم قصد نداریم که سخن قبلیمون که گفته بودیم: همه برابرند، را تکذیب کنیم و اکنون بگوییم: همه برابرند ولی بعضی‌ها برابرترند (اشاره به یک رمان معروف). اکنون می‌خواهیم به شما بگوییم که آن کارهای غیر اصولی که در قسمت‌های قبل انجام می‌دادیم به عمد بود! ولی در این قسمت قصد داریم که کم‌کم از آن کارهای غیر اصولی گذر کرده و شما را با کدنویسی اصولی و حرفه‌ای آشنا کنیم. تنها دلیلی هم که ما در قبل به صورت غیر اصولی کد می‌نوشتیم این بود که شما اشتباهات مختلف را بشناسید و مفهوم را به خوبی درک کنید، حال وقتی به شما کدنویسی اصولی گفته شود قدر عافیت می‌دانید، بالاخره قدر عافیت کسی داند که به مصیبتی گرفتار آید.

قبلا ما مدارات ترکیبی را در محیط ترتیبی توصیف می‌کردیم که کاری اشتباه بود، از این قسمت به بعد دیگر مدرات ترکیبی را در محیط ترتیبی توصیف نخواهیم کرد. دقت بفرمائید که یک مدار ترتیبی در دل خود شامل مدار ترکیبی است، اما ما به صورت مستقیم یک مدار ترکیبی خالص را در محیط ترتیبی توصیف نخواهیم کرد. در ادامه همچنین مقدماتی از بحث کلاک بیان می‌کنیم و نهایتا در این قسمت به توصیف عناصر پایه در FPGA بسنده خواهیم کرد.

در مدارات ترتیبی، خروجی علاوه بر ورودی در همین لحظه به ورودی‌های لحظات قبل نیز بستگی دارد. حال ما برای ساخت چنین مداراتی ابتدا باید به تشریح و ساختن حافظه‌ها که عناصر پایه این مدارات هستند بپردازیم.

حافظه‌ها در دیجیتال و منحصرا در مدارات ترتیبی

در دیجیتال معمولا حافظه‌ها را به دو دسته کلی به صورت زیر تقسیم می‌کنند:

  • لچ
  • فلیپ‌فلاپ

کار حافظه‌ها این است که مقادیر دیجیتال را در خود نگه دارند و این مقادیر تا زمانی که ما تعیین می‌کنیم در حافظه ثابت خواهند ماند. مقادیر دیجیتال ذخیره شده در حافظه چه زمانی و چگونه تغییر می‌کنند؟ جواب این سوال تفاوت بین لچ و فلیپ‌فلاپ را نتیجه می‌دهد، پس با دقت به ادامه توضیحات توجه کنید.

برای اینکه مقداری که در حافظه‌ها ذخیره شده است با مقدار دیگری جایگزین شود، باید یکی از پایه‌های ورودی این حافظه‌ها تحریک شود. حال اینکه این حافظه‌ها حساس به چه نوع تحریکی باشند، مشخص می‌کند که این حافظه لچ است یا فلیپ‌فلاپ. لچ‌ها حساس به سطح سیگنال کلاک و فلیپ‌فلاپ‌ها حساس به لبه‌ی سیگنال کلاک می‌باشند، یعنی اگر قرار باشد مقدار لچ تغییر کند باید یکی از پایه‌های ورودی این لچ، سطح مثبت یا منفی سیگنال کلاک را تشخیص دهد، همچنین برای اینکه مقدار فلیپ‌فلاپ تغییر کند باید یکی از پایه‌های ورودی این فلیپ‌فلاپ لبه‌ی مثبت یا منفی سیگنال کلاک را تشخیص دهد.

پیاده‌سازی با لچ یا فلیپ‌فلاپ؟

اگر مدارات منطقی را به صورت خیلی دقیق بررسی کنیم در جزئیات لچ و فلیپ‌فلاپ تفاوت‌هایی وجود خواهد داشت، اما تفاوت اصلی همان مورد بالا بود که بیان کردیم. همین تفاوت‌ها و یک سری پارامترهای دیگر مربوط به FPGA ها گاها باعث ایجاد مشکلاتی در پیاده‌سازی می‌شود که هم افراد حرفه‌ای و هم خود شرکت xilinx پیشنهاد می‌کند که از لچ در پیاده‌سازی استفاده نکنیم.

ما هم در این مجموعه آموزشی نه به توصیف لچ خواهیم پرداخت و نه از این به بعد در هیچ کدام از مثال‌ها یا پیاده‌سازی‌ها از لچ استفاده خواهیم کرد. بلکه در تمامی مثال‌ها و پیاده‌‌سازی‌ها حافظه مورد استفاده ما فلیپ‌فلاپ خواهد بود.

قبل از اینکه به پیاده‌سازی فلیپ‌فلاپ بپردازیم نیاز است که مقدماتی از توصیف کلاک در FPGA بدانیم، چون برای توصیف فلیپ‌فلاپ نیاز است که لبه‌ی سیگنال کلاک را تشخیص بدهیم.

پیاده‌سازی مدارات ترتیبی در محیط Sequential

فرض کنید می‌خواهیم یک فلیپ‌فلاپ را با استفاده از زبان VHDL توصیف و در نهایت در FPGA پیاده‌سازی کنیم، بدین منظور ابتدا باید یک process ایجاد کنیم، سیگنالی که در لیست حساسیت process قرار خواهد گرفت، چیست؟ همانطور که می‌دانید ذات مدارات ترتیبی وابسته به سیگنال کلاک می‌باشد پس حداقل باید سیگنال کلاک در لیست حساسیت process قرار بگیرد، البته در نهایت به شما خواهیم گفت که در اکثر مواقع فقط همین سیگنال کلاک باید در لیست حساسیت نوشته شود.

وقتی سیگنال کلاک را در لیست حساسیت process نوشتیم، هر تغییری که روی کلاک رخ بدهد process فعال خواهد شد و هر ارجاعی که در این محیط وجود داشته باشد با هر گونه تغییر کلاک انجام می‌شود که این موضوع مطلوب و مدنظر ما نمی‌باشد. برای رفع کردن این مشکل باید بتوانیم لبه‌ی سیگنال کلاک را تشخیص بدهیم تا تغییرات با لبه‌ی کلاک صورت بپذیرند، در اینجا ما قصد داریم که مدار ترتیبی موردنظر با لبه‌ی بالارونده کار کند، پس در ادامه ابتدا با نحوه‌ی تشخیص لبه‌ی بالارونده‌ی کلاک در FPGA آشنا خواهیم شد و سپس فلیپ‌فلاپ حساس به لبه‌ی بالارونده را توصیف خواهیم کرد.

لبه‌ی کلاک

همانطور که گفتیم وقتی در لیست حساسیت process، سیگنال کلاک را قرار می‌دهیم، با هرگونه تغییر کلاک، process فعال می‌شود. حال ما باید پس از فعال شدن process شرطی را قرار بدهیم که یکی لبه‌های کلاک را بررسی کند و زمانی که لبه‌ی کلاک تشخیص داده شد ارجاعات مورد نظر انجام بشوند، به عبارتی دیگر ارجاعات را زیر شرط لبه‌ی کلاک می‌نویسیم تا تمامی ارجاعات سنکرون با لبه‌ی کلاک باشند و مشکلی که در بالا بیان کردیم رفع گردد و با هرگونه تغییر کلاک ارجاعات انجام نشوند.

تشخیص لبه‌ی کلاک

راه‌های مختلفی برای اینکه لبه‌های کلاک را تشخیص بدهیم وجود دارد، در ادامه دو روش به شما معرفی خواهیم کرد و در نهایت یکی از این دو روش را برخواهیم گزید و هر موقع خواستیم لبه‌ی کلاک را تشخیص بدهیم از این راه استفاده خواهیم کرد.

در زبان VHDL قابلیتی به اسم attribute وجود دارد که می‌توانیم با استفاده از این قابلیت لبه‌ی کلاک را تشخیص بدهیم. البته attribute های مختلفی در زبان VHDL وجود دارد که ما با همه‌ی این attribute ها کار نداریم و فقط قصد داریم با استفاده از attribute نوع event لبه‌ی کلاک را تشخیص بدهیم. خروجی attribute نوع event دو مقدار منطقی ‘0’ یا ‘1’ می‌باشد و متناسب با شرایط می‌تواند هر کدام از این دو مقدار منطقی باشد. اگر مقدار سیگنال در process فعلی که فعال شده است، نسبت به آخرین باری که process فعال شده است تغییر کرده باشد، خروجی attribute مقدار ‘1’ منطقی خواهد بود، در غیر این‌صورت خروجی attribute مقدار ‘0’ منطقی خواهد بود.

ابتدا به کد زیر توجه کنید:

if (Clock'event and Clock = '1') then

در کد بالا از event استفاده کردیم و عبارت شرط وقتی برقرار است که هم تغییری روی سیگنال کلاک رخ داده باشد و هم سیگنال کلاک در آن لحظه برابر با ‘1’ باشد و این یعنی لبه‌ی بالارونده‌ی کلاک.

برای توصیف لبه‌ی پایین به کد زیر توجه کنید:

if (Clock'event and Clock = '0') then

در کد بالا عبارت شرط وقتی برقرار است که هم تغییری روی سیگنال کلاک رخ داده باشد و هم سیگنال کلاک در آن لحظه برابر با ‘0’ باشد و این یعنی لبه‌ی پایین‌رونده‌ی کلاک.

روش سرراست‌تر و ساده‌تری برای تشخیص لبه‌ی کلاک وجود دارد که همان روش برگزیده ما خواهد بود و از این به بعد فقط از این روش استفاده خواهیم کرد.

if rising_edge(Clock) then

کد بالا به لبه‌ی بالارونده‌ی کلاک اشاره می‌کند، مشابها همین روش برای لبه‌ی پایین‌رونده‌ی کلاک نیز وجود دارد.

خب حالا که مقدمات کلاک را به خوبی بررسی کردیم و با تمامی زیر و بم آن آشنا شدیم، قصد داریم فلیپ‌فلاپ  را با استفاده از زبان VHDL توصیف کنیم، به کد زیر توجه کنید:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
 
entity Flip_Flop is
    Port (
Clock : in  STD_LOGIC;
D : in  STD_LOGIC;
Q : out  STD_LOGIC
);
end Flip_Flop;
 
architecture Behavioral of Flip_Flop is
 
begin
process (Clock)
begin
 
if rising_edge(Clock) then
Q <= D;
end if;
 
end process;
 
end Behavioral;

کد بالا توصیف یک فلیپ‌فلاپ با استفاده از زبان VHDL می‌باشد، اینکه چرا کد مربوطه منجر به ساخت یک فلیپ‌فلاپ در FPGA می‌شود، سیگنال‌ها در محیط ترکیبی و ترتیبی تبدیل به چه چیزی خواهند شد و ربط سیگنال به حافظه چیست و کلی سوال دیگر را در قسمت سیزدهم بررسی خواهیم کرد، پس با ما همراه باشید.

درباره نویسنده

نویسنده و طراح الکترونیکا هستم . سوالی داشتید در کامنت ها یا پیج های اینستاگرام و تلگرام سایت بپرسید .