三位BCD计数器的设计

来源:互联网 发布:银行贴现金额算法 编辑:程序博客网 时间:2024/05/21 11:08


目的

1. 进一步掌握VHDL语言的基本结构及设计的输入方法。

2. 学习七段数码管显示译码器的设计。


内容

1. 设计实现一个3位BCD计数器,将其结果显示在7段码显示器HEX2—0上。

2. 通过使用DE2-115上的50MHZ时钟信号来驱动计数器,使其每隔一秒进行计数。

3. 使用按钮KEY0作为电路的清零信号。


原理

异步递增二进制计数器递增计数器就是每输入一个脉冲就进行一次加1运算,而二进制计数是输入脉冲个数与自然二进制数有对应关系。异步计数器是在做加1计数 时是采取从低位到高位逐位进位的方式工作的。因此其中的各个触发器不是同步翻转的。按照二进制加法计数规则,每一位如果已经是1,则再计入1时应变为0, 同时向高位发出进位信号,使高位翻转。若使用下降沿动作的触发器(此时该触发器应接成计数状态,例如JK触发器使J=K=1)组成计数器,只要将低位触发 器的Q端接到高位触发器的时钟输入端即可。当低位由 时,Q端的下降沿正好可以作为高位的时钟信号CP。


操作

1.创建一个Quartus II 工程,用来在DE2-115上实现预期电路。

2.写出预期电路的VHDL代码。

3.将VHDL文件包含进工程并编译。

4.仿真电路来检测其功能。

5.分配引脚。

6.重新编译并将其下载进FPGA芯片中。

7.通过观测显示器的显示来证实电路是否准确。


参考程序

bcd_counter顶层文件 :

  LIBRARY ieee;
  USE ieee.std_logic_1164.all;
  ENTITY bcd_counter IS
  PORT (CLOCK_50  : IN STD_LOGIC;
         KEY   : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
         HEX2  : OUT STD_LOGIC_VECTOR(6 DOWNTO 0);
         HEX1  : OUT STD_LOGIC_VECTOR(6 DOWNTO 0);
         HEX0  : OUT STD_LOGIC_VECTOR(6 DOWNTO 0)
    );

 END bcd_counter;
 ARCHITECTURE trans OF bcd_counter IS
 COMPONENT seg7_lut IS
 PORT (idig  : IN STD_LOGIC_VECTOR(3 DOWNTO 0);

oseg  : OUT STD_LOGIC_VECTOR(6 DOWNTO 0) 
       );
 END COMPONENT;
 COMPONENT counter10 IS
 PORT (en: IN STD_LOGIC;
       clk: IN STD_LOGIC;
       rst_n : IN STD_LOGIC;
       q: OUT STD_LOGIC_VECTOR(3 DOWNTO 0)
       );
  END COMPONENT;
  COMPONENT div IS
  PORT(clk : in std_logic;
        clk1:out std_logic
       ); 

END COMPONENT;
SIGNAL clk_1hz    : STD_LOGIC;
SIGNAL cnt        : STD_LOGIC_VECTOR(11 DOWNTO 0);
SIGNAL e1         : STD_LOGIC;

SIGNAL e2         : STD_LOGIC;
SIGNAL e3         : STD_LOGIC;
 -- Declare intermediate signals for referenced outputs
SIGNAL HEX2_xhdl2 : STD_LOGIC_VECTOR(6 DOWNTO 0);
SIGNAL HEX1_xhdl1 : STD_LOGIC_VECTOR(6 DOWNTO 0);
SIGNAL HEX0_xhdl0 : STD_LOGIC_VECTOR(6 DOWNTO 0);
 BEGIN
 -- Drive referenced outputs
  HEX2 <= HEX2_xhdl2;
  HEX1 <= HEX1_xhdl1;
  HEX0 <= HEX0_xhdl0;

e1 <= '1';
  e2 <= cnt(3) AND cnt(0);
  e3 <= e2 AND (cnt(7) AND cnt(4));
  u0 : div PORT MAP (clk1  => clk_1hz, clk  => CLOCK_50 );
  u1 : counter10 PORT MAP (en => e1, clk => clk_1hz, rst_n => KEY(0), 

q=> cnt(3 DOWNTO 0) );
u2 : counter10 PORT MAP (en => e2,clk => clk_1hz,rst_n => KEY(0), 

q => cnt(7 DOWNTO 4));
u3 : counter10 PORT MAP (en => e3, clk=> clk_1hz, rst_n => KEY(0),

 q => cnt(11 DOWNTO 8) );
h0 : seg7_lut PORT MAP (idig => cnt(3 DOWNTO 0), oseg => HEX0_xhdl0);
h1 : seg7_lut PORT MAP (idig => cnt(7 DOWNTO 4), oseg => HEX1_xhdl1 );
h2 : seg7_lut PORT MAP (idig => cnt(11 DOWNTO 8), oseg => HEX2_xhdl2);
END trans;

--seg7_lut.vhd

LIBRARY ieee;
USE ieee.std_logic_1164.all;
ENTITY seg7_lut IS
PORT (idig: IN STD_LOGIC_VECTOR(3 DOWNTO 0);

oseg: OUT STD_LOGIC_VECTOR(6 DOWNTO 0));
END seg7_lut;
ARCHITECTURE trans OF seg7_lut IS
BEGIN
PROCESS (idig)
BEGIN
CASE idig IS
  WHEN "0001" =>oseg <= "1111001";
  WHEN "0010" =>oseg <= "0100100";
  WHEN "0011" =>oseg <= "0110000";
  WHEN "0100" =>oseg <= "0011001";
  WHEN "0101" =>oseg <= "0010010";
  WHEN "0110" =>oseg <= "0000010";
  WHEN "0111" =>oseg <= "1111000";
  WHEN "1000" =>oseg <= "0000000";
  WHEN "1001" =>oseg <= "0011000";
  WHEN "1010" =>oseg <= "0001000";
  WHEN "1011" =>oseg <= "0000011";
  WHEN "1100" =>oseg <= "1000110";
  WHEN "1101" =>oseg <= "0100001";
  WHEN "1110" =>oseg <= "0000110";
  WHEN "1111" =>oseg <= "0001110";
WHEN OTHERS =>oseg <= "1000000";
END CASE;
END PROCESS;
END trans;

--Div.vhd

LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_arith.all;
USE ieee.std_logic_unsigned.all;
entity  div  is
port(clk : in std_logic;
    clk1:out std_logic);
end div;
architecture mix of  div is
signal  count :integer range 0 to 49999999;
--严格来说是从0-49999999,刚好50000000个计数值,正好将50M的时钟分为1Hz的时钟
begin
clk_div_proc:process(clk)
begin
if rising_edge(clk) then
   if count=49999999 then
     count<=0;
   else
     count<=count+1;
   end if;
  if count>24999999 then---占空比50%
       clk1<='1';
   else clk1<='0';
  end if;
end if;
end process clk_div_proc;
end mix;

---counter10.vhd

 

LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;
ENTITY counter10 IS
PORT (en  : IN STD_LOGIC;
      clk  : IN STD_LOGIC;
      rst_n : IN STD_LOGIC;
      q  : OUT STD_LOGIC_VECTOR(3 DOWNTO 0)
      );
 END counter10;
ARCHITECTURE trans OF counter10 IS
 -- Declare intermediate signals for referenced outputs
SIGNAL q_xhdl3: STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN
-- Drive referenced outputs
q <= q_xhdl3;
PROCESS (clk, rst_n)
BEGIN
IF ((NOT(rst_n)) = '1') THEN
   q_xhdl3 <= "0000";
ELSIF (clk'EVENT AND clk = '1') THEN
   IF ((NOT(en)) = '1') THEN
     q_xhdl3 <= q_xhdl3;
    ELSIF (q_xhdl3 = "1001") THEN
      q_xhdl3 <= "0000";
    ELSE
      q_xhdl3 <= q_xhdl3 + "0001";
    END IF;
END IF;
END PROCESS;
END trans;


问题及解决

文件名必须与VHDL文件中的设计实体名保持一致。

总结:这次课程设计虽然在功能上完全实现了课题的要求,即实现了三位BCD计数器的设计的全部要求,但是相应的不足之处还应该考虑到。虽然是细节问题,但往往可以决定成败,试着理解程序。 




1 0