شمارنده BCD با FPGA

شمارنده BCD با FPGA

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

شمارنده‌ها انواع متفاوتی دارند، اما عملکرد کلی آن‌ها به یک صورت است و شما با تغییرات کوچکی در هر یک از آن‌ها می‌توانید آن را به نوع دیگری تبدیل کنید.

ما در ادامه قصد داریم که با استفاده از زبان VHDL یک شمارنده BCD را توصیف کنیم. شمایی که در حال خواندن این مقاله هستید به احتمال زیاد با BCD و همینطور شمارنده BCD به خوبی آشنا هستید. اما به صورت مختصر در ادامه به شرح این موضوع خواهیم پرداخت.

BCD یا همان Binary Coded Decimal، نوعی کد برای تبدیل اعداد دهدهی به دودویی می‌باشد. اعداد در دنیای دیجیتال به صورت دودویی یا همان باینری می‌باشند. اما اعدادی که ما روزانه با آن‌ها سر و کار داریم و در دنیای واقعی به صورت دهدهی یا دسیمال می‌باشند. پس لازم است که ما این تبدیل اعداد را انجام بدهیم.

برای اعداد در مبنای 10، ما ده عدد متفاوت داریم یعنی از 0 تا 9. حال اگر بخواهیم این اعداد را در مبنای 2 نشان بدهیم نیاز به چند بیت داریم؟

برای این کار نیاز به چهار بیت داریم. با چهار بیت می‌توان شانزده حالت مختلف را نشان داد. ما از ده حالت آن استفاده می‌کنیم و بقیه‌ی حالات آن عملا بدون استفاده باقی می‌مانند.

پس متوجه شدیم که در BCD هر عدد دسیمال با چهار بیت به صورت باینری نمایش داده می‌شود.

برای توضیحات بیشتر می‌توانید به این لینک در ویکی‌پدیا مراجعه کنید.

به طور کلی شمارنده توصیف شده‌ی ما همانند تصویر زیر است:

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

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

سپس اگر ریست فعال نبود و همچنین ماژول فعال بود، با هر لبه بالارونده کلاک یک واحد به شمارنده اضافه می‌شود. با یک شرط چک می‌شود که اگر بیشتر از 9 شد دوباره به مقدار 0 ریست شود.

ما کد دیگری را نیز برای اینکه شمارنده BCD را بر روی سون سگمنت نشان دهیم نوشتیم.

کد زیر همان عملکرد کد بالا است با این تفاوت که در هر State معادل سون سگمنت آن نیز نوشته شده است و در نهایت آن را به صورت عملی بر روی برد نمایش خواهیم داد.

توجه کنید که چون سون سگمت‌هایی که بر روی برد ALINX قرار  دارند، آند مشترک هستند، هر سگمت با 0 منطقی روشن می‌شود. شما متناسب با بردتان می‌توانید این مقادیر را تغییر دهید.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;

entity Counter_BCD is
Port (
Clock : in STD_LOGIC;
Scan_Sig : out unsigned (5 downto 0);
Seven_Seg : out unsigned (7 downto 0)
);
end Counter_BCD;

architecture Behavioral of Counter_BCD is

signal Seven_Segment_Int : unsigned (7 downto 0) := (others=>'0');
signal BCD_Int : unsigned (3 downto 0) := (others=>'0');
signal One_Sec_Counter : unsigned (25 downto 0) := (others=>'0');

begin

Seven_Seg <= Seven_Segment_Int;
Scan_Sig <= "111110";

process(Clock)
begin

if rising_edge(Clock) then

One_Sec_Counter <= One_Sec_Counter + 1;

if (One_Sec_Counter = to_unsigned(50000000,26)) then

BCD_Int <= BCD_Int + 1;
One_Sec_Counter <= (others=>'0');

end if;

if (BCD_Int = to_unsigned(10,4)) then

BCD_Int <= (others=>'0');

end if;

case BCD_Int is

when "0000" =>
Seven_Segment_Int <= "11000000";

when "0001" =>
Seven_Segment_Int <= "11111001";

when "0010" =>
Seven_Segment_Int <= "10100100";

when "0011" =>
Seven_Segment_Int <= "10110000";

when "0100" =>
Seven_Segment_Int <= "10011001";

when "0101" =>
Seven_Segment_Int <= "10010010";

when "0110" =>
Seven_Segment_Int <= "10000010";

when "0111" =>
Seven_Segment_Int <= "11111000";

when "1000" =>
Seven_Segment_Int <= "10000000";

when "1001" =>
Seven_Segment_Int <= "10010000";

when others =>
Seven_Segment_Int <= (others=>'0');
end case;

end if;

end process;

end Behavioral;

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

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