附源代码,一定能实现!
目录
EDA设计练习题:
实验要求如下:
思路分析:
代码
99进制计数器
码转换
顶层文件
特别注意
测试
编译通过
结果展示
RTL视图
技术映射视图
软件:Quartus II 13.0 (64-bit)
语言:VHDL
EDA设计练习题:
采用EDA技术设计一个人数小于100的出勤统计电路,用于小型公司或部门工作、会议、培训等的出勤人数统计,统计对应每个人签到出勤的单个正脉冲信号,统计结果在两位共阳极数码管上显示。
实验要求如下:
1、程序设计:编写考勤电路的完整程序;注明端口名称及意义;
2、仿真验证:程序编辑、编译、仿真;要求展示全部程序、编译成功界面、功能仿真结果波形图;注意仿真图需能够看出来工作过程及实现的功能。
思路分析:
我们的任务是设计小型出勤系统,统计出勤人数,每个人签到都会产生一个正脉冲信号,我们只需要记录下来有多少个正脉冲信号即可,不需要考虑这个正脉冲怎么产生的~这地方是关键!
每个人签到产生一个正脉冲这种情况,我想的是可以用单片机实现,比如说指纹或者人脸识别,对比系统已经存储的数据,如果对比通关,就产生一个多少ms的脉冲信号,然后这个信号交给我们来处理,做成芯片内部的电路,这个说法不一定正确,不要完全相信~~~小声BB……
设计人数小于100的出勤统计电路,那我们就根据输入的脉冲设计考勤电路,实际上就是一个99计数器,99计数器还可以拆分成两个十进制计数器;然后把99计数器的两份拆分开显示到数码管上,这里还需要一个码转换器(BCD到数码管八段码表)
代码
先看一下工程文件
上层文件是 ShiYan8.vhd,两个底层文件,分别是CNT99.vhd(99进制计数器)和code_switch.vhd(码转换器)
99进制计数器
--99进制计数器
library IEEE;
USE IEEE.STD_logic_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_logic_unsigned.ALL;
ENTITY CNT99 IS
PORT( clk : IN std_logic;
clear : IN std_logic;
en : IN std_logic;
cout : out std_logic;
qh : buffer std_logic_vector(3 downto 0);
ql : buffer std_logic_vector(3 downto 0)
);
END CNT99;
ARCHITECTURE behave OF CNT99 IS
BEGIN
cout<='1' when (qh="1001" and ql="1001" and en='1') else '0';
PROCESS (clk,clear)
BEGIN
IF(clear='0') THEN --异步清零信号
qh<="0000";
ql<="0000";
ELSIF (clk'EVENT AND clk = '1') THEN
if(en='1') then
if (ql=9) then
ql<="0000";
if(qh=9) then
qh<="0000";
else
qh<=qh+1;
end if;
else
ql<=ql+1;
end if;
end if; --end if(en)
END IF; --end if clear
END PROCESS;
END behave;
码转换
8421BCD码到八段码转换电路(以共阴极数码管为例)
用CASE-WHEN语句编写码转换电路比较方便,对比C语言中switch-case语句
参考上一篇文章:【FPGA】VHDL:八段码到8421BCD码转换电路
-- 8421BCD码到八段码转换电路(以共阳极数码管为例)
library IEEE;
USE IEEE.STD_logic_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_logic_unsigned.ALL;
-- 实体声明
ENTITY code_switch IS
PORT(
Input_8421BCD : IN STD_logic_vector(3 downto 0);
Output_Yang : OUT STD_logic_vector(7 downto 0)
);
END code_switch;
--结构体说明
ARCHITECTURE behave OF code_switch IS
BEGIN
PROCESS (Input_8421BCD)
BEGIN
--5、8421BCD码到八段码转换电路(以共阴极数码管为例)
CASE Input_8421BCD IS
WHEN "0000" => Output_Yang <= "11000000";
WHEN "0001" => Output_Yang <= "11111001";
WHEN "0010" => Output_Yang <= "10100100";
WHEN "0011" => Output_Yang <= "10110000";
WHEN "0100" => Output_Yang <= "10011001";
WHEN "0101" => Output_Yang <= "10010010";
WHEN "0110" => Output_Yang <= "10000010";
WHEN "0111" => Output_Yang <= "11111000";
WHEN "1000" => Output_Yang <= "10000000";
WHEN "1001" => Output_Yang <= "10010000";
when others => Output_Yang <= "10111111"; --slkdjfkalf
END CASE;
END PROCESS;
END behave;
顶层文件
这里我采用元件例化的方式写这个代码,就把整体拆成了三个文件,也可以合并起来写,但是不好看,代码比较臃肿,不方便移植~
-- 实验8 2023年11月21日09:02:17
-- 小型出勤统计系统设计程序
--ShiYan8.VHD
library IEEE;
USE IEEE.STD_logic_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
USE IEEE.STD_logic_unsigned.ALL;
ENTITY ShiYan8 IS
PORT(CLR: IN STD_LOGIC;
CLK: IN STD_LOGIC;
ENA: IN STD_LOGIC;
DOUT: OUT std_logic;
qh : buffer std_logic_vector(3 downto 0);
ql : buffer std_logic_vector(3 downto 0);
SEG_high, SEG_low: OUT STD_logic_vector(7 downto 0)
);
END ENTITY ShiYan8;
ARCHITECTURE ART OF ShiYan8 IS
COMPONENT CNT99 IS
PORT(
clk : IN std_logic;
clear : IN std_logic;
en : IN std_logic;
cout : out std_logic;
qh : buffer std_logic_vector(3 downto 0);
ql : buffer std_logic_vector(3 downto 0)
);
END COMPONENT CNT99;
COMPONENT code_switch IS
PORT(
Input_8421BCD : IN STD_logic_vector(3 downto 0);
Output_Yang : OUT STD_logic_vector(7 downto 0)
);
END COMPONENT code_switch;
BEGIN
--元件例化
U0:CNT99 PORT MAP (CLK, CLR, ENA, DOUT, qh, ql);
U1:code_switch PORT MAP (qh(3 downto 0), SEG_high(7 downto 0));
U2:code_switch PORT MAP (ql(3 downto 0), SEG_low(7 downto 0));
END ARCHITECTURE ART;
特别注意
工程名要和实体名相同
测试
编译通过
结果展示
看不太清,放大点
再大点
这里可以看到99之后变成了00,说明我们设计的99进制计数器是对的
最下面是数码管8段码展示, 可以对照上面输出的数据,看一下,对比我们写入的码转换语句,数据能对应的上~~~这里也没有问题。
RTL视图
技术映射视图
本代码纯自己手敲,拒绝白嫖!