آموزش FPGA : قسمت شانزدهم
Reset; در قسمت پانزدهم از مجموعه آموزشی FPGA در مورد نحوهی نوشتن ریست در FPGAهای شرکت Xilinx مفصلا صحبت کردیم و از منطق سختافزاری که درون FPGA وجود دارد پرده برداشتیم و نهایتا طبق شماتیک مدار پیادهسازی شده در FPGA به شما توصیه کردیم که هر موقع خواستید از ریست استفاده کنید، آن را با مقدار 1 منطقی مقایسه کنید. در این قسمت قصد داریم به شما توصیه کنیم که نهایتا از ریست استفاده نکنید و به جای آن از راهکاری که عملکردی مشابه دارد استفاده کنید. پس با ما همراه باشید تا باهم یک سری نکات مفید و مهم را مرور کنیم. قبل از اینکه راهکاری جایگزین برای ریست ارائه بدهیم، میخواهیم در مورد Set، که در مقابل Reset قرار دارد صحبت کنیم و این مورد را با استفاده از زبان VHDL در FPGA پیادهسازی کنیم.
Set
Set هم عملکردی تقریبا مشابه با Reset دارد، اما به جای اینکه مقدار 0 منطقی را در فلیپفلاپ یا رجیستر جایگزین کند، مقدار 1 منطقی را جایگزین خواهد کرد (توجه کنید که بعضی از این تعاریف قراردادی هستند و لزومی ندارد که دقیقا یک تعریف علمی از این پارامترها وجود داشته باشد). قبل از توضیحات مربوطه، در ابتدا Set را با استفاده از زبان VHDL توصیف خواهیم کرد سپس توضیحات اضافه را بیان خواهیم نمود.
library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity Flip_Flop is Port ( D : in STD_LOGIC; Clock : in STD_LOGIC; Reset : in STD_LOGIC; Set : 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; if (Reset = '1') then Q <= '0'; end if; if (Set = '1') then Q <= '1'; end if; end if; end process; end Behavioral;
همانطور که در کد بالا واضح و مشخص است تنها عاملی که میتواند باعث فعال شدن perocess شود، کلاک میباشد و این یعنی اینکه مدار ما سنکرون است و مشخصا Reset و Set مدار هم سنکرون است. طبق توضیحات گذشته دوباره Set را با مقدار 1 منطقی مقایسه کردیم و اگر برابر این مقدار بود، آنگاه ارزش رجیستر هر مقداری بود به مقدار 1 تغییر پیدا خواهد کرد. شاید از دوران دانشگاه، از درس مدارات منطقی به یاد داشته باشید که میگفتیم اولویت با Set است یا Reset؟ یعنی اگر به طور همزمان این دو مقدار برابر با یک باشند (طبق کد بالا) کدامین عمل Set یا Reset انجام میشود! اصلا آیا با استفاده از کد VHDL این قابلیت و انعطاف برای ما وجود دارد که تعیین کنیم در ابتدا کدام یک از این اعمال انجام شود و برای این اعمال اولویت تعیین کنیم؟ بله زبان VHDL این انعطاف و قابلیت را به ما میدهد که این موضوع را هموار کنیم. در کد بالا اولویت با Set بود، کدی را در ادامه خواهیم نوشت که اولویت آن با Reset خواهد بود. شما در ابتدا خودتان به تفاوت کوچکی که در کد وجود دارد توجه کنید تا به صورت شهودی متوجه شوید که دلیل اولویت در این امر ناشی از چیست تا ما در ادامه پس از نوشتن کد دوم دلیل را بیان کنیم.
library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity Flip_Flop is Port ( D : in STD_LOGIC; Clock : in STD_LOGIC; Reset : in STD_LOGIC; Set : 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; if (Set = '1') then Q <= '1'; end if; if (Reset = '1') then Q <= '0'; end if; end if; end process; end Behavioral;
اما دلیل اینکه با جابهجایی چند خط اولویت عوض شد چیست؟
در نظر بگیرید که اگر بدون استفاده از ساختارهای شرطی در محیط ترتیبی چندین ارجاع بنویسید، قبل از مرحله سنتز، بقیه ارجاعات توسط نرمافزار حذف خواهند شد و تنها آخرین ارجاع در نظر گرفته خواهد شد. با توجه به نکته طلایی بالا، چون ما با استفاده از ساختار شرطی if این کار را انجام دادیم، حال اگر Set و Reset هر دو برابر با 1 منطقی باشند ارجاع مرتبط با شرط دوم در اولویت است و انجام خواهد شد. در کد اول اولویت با Set است و در کد دوم اولویت با Reset است. همانطور که میدانید ساختار شرطی if ذاتا در ساختار خود دارای اولویت است، یعنی به ترتیب از بالا به پایین اگر یکی از شرطها برقرار باشد شرطهای زیرین دیگر بررسی نمیشوند و این خود یعنی اولویت. در ادامه دو کد بالا را با استفاده از این تکنیک نیز توصیف خواهیم کرد. چون قبلا در این رابطه توضیح دادیم دیگر توضیح اضافهای نخواهیم داد و خودتان برای درک بیشتر به قسمتهای قبلی که مربوط به ساختارهای شرطی است مراجعه کنید.
اولویت با Reset
library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity Flip_Flop is Port ( D : in STD_LOGIC; Clock : in STD_LOGIC; Reset : in STD_LOGIC; Set : 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; if (Reset = '1') then Q <= '0'; elsif (Set = '1') then Q <= '1'; end if; end if; end process; end Behavioral;
اولویت با Set
library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity Flip_Flop is Port ( D : in STD_LOGIC; Clock : in STD_LOGIC; Reset : in STD_LOGIC; Set : 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; if (Set = '1') then Q <= '0'; elsif (Reset = '1') then Q <= '1'; end if; end if; end process; end Behavioral;
اگر از تکنیک بالا و یا در صورت نیاز به جای ریست آسنکرون، از ریست سنکرون استفاده کنید، بنا به دلایلی که پیدا کردن این دلایل را بر عهده خودتان میگذاریم، مدار شما هم سرعت بالاتری خواهد داشت هم منابع کمتری استفاده خواهد کرد. حال که به خوبی با اصول و توصیف فلیپفلاپها و جزئیات آنها آشنا شدیم در قسمت هفدهم با رجیسترها که خود متشکل از چندین فلیپفلاپ در کنار هم هستند آشنا خواهیم شد.