赞
踩
本文使用VHDL语言设计10进制减法计数器,附带清零和置数功能。将项目分为分频器、计数器、数码管三个部分,采用元器件例化的方式,自顶向下设计。
顶层文件将三个模块元器件例化和元器件映射。
library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity CNT10 is port( CLK,RST,EN: in std_logic; data_hex : out std_logic_vector(7 downto 0); DOUT : out std_logic_vector (3 downto 0); COUT : OUT std_logic; DINT : in std_logic_vector(3 downto 0); DCON : in std_logic; Dtest : out std_logic; DtestMORE : out std_logic_vector(3 downto 0) ); end CNT10; architecture behav of CNT10 is component digital is port( data : IN std_logic_vector(3 downto 0); show : OUT std_logic_vector(7 downto 0); com : OUT std_logic_vector(3 downto 0) ); end component digital; component Counter1 is port( clk : IN std_logic; en : IN std_logic; out1 : out std_logic ); end component Counter1; component count10 is port( signal clk,rst,en : in std_logic; signal DCON : in std_logic; signal DINT : in std_logic_vector(3 downto 0); signal q : inout std_logic_vector(3 downto 0) ); end component count10; signal clk1 : std_logic; signal data_sum : std_logic_vector(7 downto 0); signal data_get : std_logic_vector(3 downto 0); signal cq10 : std_logic_vector(3 downto 0) := (others => '0'); begin part1: Counter1 port map ( clk => CLK, en => EN, out1 => clk1 ); part2: count10 port map ( clk => clk1, rst => RST, en => EN, DCON => DCON, DINT => DINT, q => cq10 ); part3: digital port map ( data => data_get, show => data_sum, com => DOUT ); Dtest <= clk1; DtestMORE <= cq10; data_hex <= data_sum; data_get <= cq10; end behav;
分频器用于将clk时钟信号放大相应倍数,否则由于时钟频率太高,计数值的减少效果看不出。out1为分频后的clk信号。
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use ieee.std_logic_unsigned.all; entity Counter1 is port ( clk : in std_logic; en : in std_logic; out1 : out std_logic ); end Counter1; architecture Behavioral of Counter1 is signal cp : std_logic_vector(25 downto 0) :=(others => '0'); signal clk1 : std_logic := '0'; begin process(clk) begin if clk 'event and clk = '1' then if en = '1' then if cp = "10111110101111000010000000" then cp <= "00000000000000000000000000"; clk1 <= not clk1; else cp <= cp + 1; end if; out1 <= clk1; end if; end if; end process; end Behavioral;
计数器实现从9倒数到0,每秒倒数一次。rst为清零端,DCON为置数端,置数的数据为DINT。
library IEEE; use IEEE.STD_LOGIC_1164.ALL; use ieee.std_Logic_unsigned.all; entity count10 is port( signal clk,rst,en : in std_logic; signal DCON : in std_logic; signal DINT : in std_logic_vector(3 downto 0); signal q : out std_logic_vector(3 downto 0) ); end count10; architecture Behavioral of count10 is signal cq10 : std_logic_vector(3 downto 0) := (others => '0'); begin process(clk,rst,en) begin if rst = '1' then -- 清零 cq10 <= "0000"; elsif clk'event and clk = '1' then if en = '1' then if DCON = '1' then --置数 cq10 <= DINT; elsif cq10 = "0000" then cq10 <= "1001"; else cq10 <= cq10 - '1'; end if; end if; end if; end process; q <= cq10; end Behavioral;
数码管将计数器输出的值转译为数码管的段码而输出。
library IEEE; use IEEE.STD_LOGIC_1164.ALL; entity digital is port( data : IN std_logic_vector(3 downto 0); show : OUT std_logic_vector(7 downto 0); com : OUT std_logic_vector(3 downto 0) ); end digital; architecture Behavioral of digital is begin com <="1110"; --- 选中四个数码管中的最低位 process(data) begin case data is WHEN "0000" => show <= "11000000"; WHEN "0001" => show <= "11111001"; WHEN "0010" => show <= "10100100"; WHEN "0011" => show <= "10110000"; WHEN "0100" => show <= "10011001"; WHEN "0101" => show <= "10010010"; WHEN "0110" => show <= "10000010"; WHEN "0111" => show <= "11111000"; WHEN "1000" => show <= "10000000"; WHEN "1001" => show <= "10010000"; when others => show <= "11111111"; end case; end process; end Behavioral;
创建VHDL Test Bench文件,在代码中begin后加入使能EN<=‘1’;代码。(注意仿真时需要将分频器、计数器赋初值,否则仿真将无数据。当然下载到器件上时却不需要初值,因为板子的高低电平有初值,而仿真却需要人为设定。)
ps:仿真时请修改分频器cp的值,否则无法仿真出。
从仿真波形可以看出从9开始计数到0并循环不断。仿真时分频器设置为2倍频,从dtest参数可以看出,dtest参数的值为分频器的输出(看前面1.1顶层文件)。而dtestmore和data_hex的值对应于数码管所对应的值。
最后,如果需要完整工程的可以去下载:FPGA-VHDL实现十进制减法计数器。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。