شمارنده BCD با FPGA

0
21
شمارنده BCD با FPGA

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

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

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

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

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

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

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

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

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

شمارنده BCD
BCD

 

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

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

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

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity bcd_counter1 is
port (
i_clk : in std_logic;
i_rstb : in std_logic;
i_sync_reset : in std_logic;
i_count_ena : in std_logic;
o_bcd : out std_logic_vector(3 downto 0));
end bcd_counter1;

architecture rtl of bcd_counter1 is
signal r_count : unsigned(3 downto 0);

begin

o_bcd <= std_logic_vector(r_count);
p_count : process(i_clk,i_rstb)
begin
if(i_rstb='0') then
r_count <= (others=> '0');
elsif(rising_edge(i_clk)) then
if(i_sync_reset='1') then
r_count <= (others=> '0');
elsif(i_count_ena='1') then
if(r_count = 9) then
r_count <= (others=> '0');
else
r_count <= r_count + 1;
end if;
end if;
end if;
end process p_count;

end rtl;

 

شما در پروژه‌هایتان می‌توانید با الگوبرداری از کد بالا هر شمارنده دیگر و حتی تایمر را پیاده‌سازی کنید.

ما کد دیگری را نیز برای اینکه شمارنده 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;

 

ویدئوی زیر  تست این کد را بر روی FPGA نشان می‌دهد

منبع : سیسوگ

برای این مقاله نظر بگذارید:

لطفا دیدگاه خود را بنویسید
لطفا نام خود را وارد کنید