VHDL 数字系统设计与测试
频率计
一、 设计要求
用VHDL完成具有自动校验和测量功能的4位十进制数字频率计的设计,频
率测量范围:1-10KHz,分成两个频段,即1-999Hz,1KHz-10KHz,用三
位数码管显示测量频率,用LED显示表示单位,如亮绿灯表示Hz,亮红灯表示KHz,
且具有超量程报警功能,在超出目前量程档的测量范围时,发出报警信号。
二、 设计思路
计算出单位时间内待测信号的脉冲个数就可得出被测信号的频率
系统方框图如图所示。
测量/校验选
择
test
means
select
CP1
二分频
1Hz时钟源
计数器
CP
NRd
C Q4
Q3
Q2
Q1
送存选择、报警电路
alert
K
锁存器
LD
D3 D2 D1
扫描显示
单位显示
1s
计数器对 CP1 信号进行计数,在 1 秒定时结束后,将计数器结果送锁存器
锁存(锁存信号 LD),再过 0.5s 后将计数器清零(清 0 信号 NRd),为下一次采
样测量做好准备。
顶层引脚说明:
引脚名
方向
功能
scan_clk_top
in
显示控制时钟
test_top
in
校验信号
meas_top
in
测量信号
clk_1Hz_top
in
1Hz 时钟
sel_top
in
测量/校验选择信号
K_top
in
量程选择信号
alert_top
out
报警输出信号
dot_display_top
out
小数点显示信号
data_led_top
out
输出到数码管的数据
select_led_top
out
数码管选通信号
其他在程序中出现的端口信号如 CP_top、LD_top、clk1S_top 等是为了方便
观察分析仿真结果而把中间信号引出。
三、 子模块说明
1)测量/校验模块,选择信号select,被测信号means,测试信号test为输入信号,
CP1为输出信号。
当select=0时,为测量状态,CP1=means;
当select=1时,为校验状态,CP1=test。
2)二分频模块将输入的1Hz时钟信号分频为1秒定时信号(周期为2秒)。
3)计数器模块用于计数开始、清零、锁存。Q4~Q1设置超出量程档测量范围时
发出报警信号alert。若被测信号频率小于1KHz(K=0),则计数器只进行三位十
进制计数,最大显示值为999Hz,如果被测信号频率超过此范围,示警信号驱动
灯光、扬声器报警;若被测信号为1KHz~10KHz(K=1),计数器进行四位十进
制计数,取高三位显示,最大显示值为9.99KHz,如果被测信号频率超过此范围,
报警。
4)送存选择、报警模块对计数器的计数结果进行送存并确定是否发出报警信号。
表1
量程控制
计数器
锁存
小数点位置
报警信号
K
Q4(0)
C
D3 D2 D1
alert
0
0
1
1
0
1
X
X
0
0
0
1
Q3 Q2 Q1
Q3 Q2 Q1
Q4 Q3 Q2
Q4 Q3 Q2
右第一位
右第一位
左第一位
左第一位
0
1
0
1
5)锁存模块输入信号为D3~D1利用LD的上升沿对数据进行锁存,输出信号为
dout3,dout2,dout1,小数点单位显示Y。
6)扫描显示模块输入信号为c3,c2,c1,扫描时钟scan_clk进行扫描,数码管扫
描选择信号selled对数码管进行片选,输出信号q至数码管。
四、 源代码
(1)顶层代码:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
---------------------------------
entity freq_counter_top is
port(
scan_clk_top:in std_logic;
test_top:in std_logic;
meas_top:in std_logic;
clk_1Hz_top:in std_logic;
sel_top:in std_logic;
K_top:in std_logic;
CP:out std_logic;
LD:out std_logic;
clk1S_top:out std_logic;
alert_top:out std_logic;
dot_display_top:out std_logic_vector(2 downto 0);
data_led_top:out std_logic_vector(6 downto 0);
select_led_top:out std_logic_vector(2 downto 0)
);
end freq_counter_top;
-----------------------------------
architecture top_arc of freq_counter_top is
signal CP1_internal:std_logic;
signal CP_internal:std_logic;
signal clk1S_internal:std_logic;
signal C_internal:std_logic;
signal LD_internal:std_logic;
signal Q4_internal,Q3_internal,Q2_internal,Q1_internal:std_logic_vector(3 downto 0);
signal D3_internal,D2_internal,D1_internal:std_logic_vector(3 downto 0);
signal unit_internal:std_logic_vector(3 downto 0);
signal ten_internal:std_logic_vector(3 downto 0);
signal hundred_internal:std_logic_vector(3 downto 0);
signal temp_data_internal:std_logic_vector(3 downto 0);
component Mode_Select
port(test,meas,sel:in std_logic;
CP1:out std_logic);
end component;
component Freq_Divider
port(clk_in:in std_logic;
clk_out:out std_logic);
end component;
component CNT
port(CP,NRd:in std_logic;
Q4,Q3,Q2,Q1:out std_logic_vector(3 downto 0);
C:out std_logic);
end component;
component Send_Alert
port(Q4,Q3,Q2,Q1:in std_logic_vector(3 downto 0);
C,K:in std_logic;
alert:out std_logic;
dot_display:out std_logic_vector(2 downto 0);
OUT3,OUT2,OUT1:out std_logic_vector(3 downto 0));
end component;
component Latcher
port(Din3,Din2,Din1:in std_logic_vector(3 downto 0);
LD:in std_logic;
Dout3,Dout2,Dout1:out std_logic_vector(3 downto 0));
end component;
component SCAN
port(data_unit_in,data_ten_in,data_hundred_in:in std_logic_vector(3 downto 0);
scan_clk:in std_logic;
K:in std_logic;
data_out:out std_logic_vector(3 downto 0);
sel:out std_logic_vector(2 downto 0));
end component;
component DEC_LED
port( data_in:in std_logic_vector(3 downto 0);
led_out:out std_logic_vector(6 downto 0));
end component;
begin
CP_internal<=CP1_internal and clk1S_internal;
LD_internal<=not clk1S_internal;
CP<=CP_internal;
LD<=LD_internal;
clk1S_top<=clk1S_internal;
Mode_Select1:Mode_Select
port map(test=>test_top,meas=>meas_top,sel=>sel_top,CP1=>CP1_internal);
Freq_Divider1:Freq_Divider
port map(clk_in=>clk_1Hz_top,clk_out=>clk1S_internal);
CNT1:CNT
port map(CP=>CP_internal,
NRd=>clk1S_internal,
Q4=>Q4_internal,
Q3=>Q3_internal,
Q2=>Q2_internal,
Q1=>Q1_internal,
C=>C_internal
);