《VHDL硬件描述语言与数字逻辑电路设计》课程设计报告
实验台号: 16号
姓 名: 陈洁
学 号: 0704040216
专 业: 通信工程
班 级: 2班
指导老师: 管志利老师
湖南科技大学课程设计材料
一、课程设计的目的和任务:
1,熟悉软件编程环境,熟练使用max-plus2软件的各项功能;
2,编写VHDL语言程序,熟悉程序编写调试的一般过程,通过具体实验巩固所学VHDL语言程序的理论知识;
3,了解编译与仿真的作用与意义;
4,熟练掌握简单的VHDL语言语句与程序结构。踏实的完成此次课程设计的教学将为学生进一步深入了解电子产业的发展与内容,积极投身于工程技术的开发与研究特别是EDA技术的发展奠定一定的基础。
二、设计的基本要求:
1.熟悉数字电路及相关专业课程的基本知识并能联系具体程序
2.正确操作使用VHDL语言相关软件,能编译,调试,仿真VHDL语言程序
3.设计数字电路,编写程序,实现电路功能。
三、课程设计内容:
1.设计60进计数器:设计一个BCD码60进计数器。要求实现同步,异步两种情况,且规定个位显示0~9,十位显示0~5,均用4位二进制数表示。在此基础上试用VHDL语言描述中小规模集成电路74LS169。
2.循环彩灯控制器:设计一个循环彩灯控制器,该控制器控制红,绿,黄三个发光管循环点亮。要求红发光管亮3秒,绿发光管亮2秒,黄发光管亮1秒。
3,抢答器的程序设计:设计一个二人抢答器,用两灯来表示两人抢答的顺序,从而来表示是谁抢答到了
四、课程设计方案及源程序:
1.设计60进计数器:
1)设计思想:两个同步计数器,一个实现个位计数,一个实现十位计数,当个位计数到9时,十位的计数器加一,并个位计数器清零,继续自加,如此循环,直到十位到5,即计数到59,一端口输出高电平,十位和个位计数器清零,如此循环。
2)源程序:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY bcd60count IS
PORT(clk,bcd1wr,bcd10wr,cin:STD_LOGIC;
CO:OUT STD_LOGIC;
datain:IN STD_LOGIC_VECTOR(3 DOWNTO 0);
bcd1:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);
bcd1m:OUT STD_LOGIC_VECTOR(2 DOWNTO 0));
END ENTITY bcd60count;
ARCHITECTURE rtl OF bcd60count IS
SIGNAL bcd1n:STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL bcd10n:STD_LOGIC_VECTOR(2 DOWNTO 0);
BEGIN
bcd1<=bcd1n;
bcd1m<=bcd10n;
PROCESS(clk,bcd1wr)IS
BEGIN
IF(bcd1wr='1')THEN
bcd1n<=datain;
ELSIF(clk'EVENT AND clk='1')THEN
IF(cin='1')THEN
IF(bcd1n=9)THEN
bcd1n<="0000";
ELSE
bcd1n<=bcd1n+1;
END IF;
END IF;
END IF;
END PROCESS;
PROCESS(clk,bcd10wr)IS
BEGIN
IF(bcd10wr='1')THEN
bcd10n<=datain(2 DOWNTO 0);
ELSIF(clk'EVENT AND clk='1')THEN
IF(cin='1' AND bcd1n=9)THEN
IF(bcd10n=5)THEN
bcd10n<="000";
ELSE
bcd10n<=bcd10n+1;
END IF;
END IF;
END IF;
END PROCESS;
PROCESS(bcd10n,bcd1n,cin)IS
BEGIN
IF(cin='1' AND bcd1n=9 AND bcd10n=5)THEN
co<='1';
ELSE
co<='0';
END IF;
END PROCESS;
END ARCHITECTURE rtl;
2.循环彩灯控制器:
1)设计思想:一个六秒计数器,并通过一个控制器分别分给红发光管亮3秒,绿发光管亮2秒,黄发光管亮1秒。
2)源程序:
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY cycle_color_light IS
PORT (clk_in: IN STD_LOGIC;
R: OUT STD_LOGIC;
G: OUT STD_LOGIC;
Y: OUT STD_LOGIC);
END cycle_color_light;
ARCHITECTURE behave OF cycle_color_light IS
SIGNAL counter6: STD_LOGIC_VECTOR(2 DOWNTO 0);
BEGIN
p1:PROCESS (clk_in)
BEGIN
IF (clk_in' EVENT AND clk_in='1') THEN
counter6<="000";
IF (counter6="101") THEN
counter6<="000";
ELSE
counter6<=counter6+1;
END IF;
END IF;
END PROCESS p1;
p2:PROCESS (counter6)
BEGIN
IF (counter6="000" OR counter6="001" OR counter6="010") THEN
R<='1';
G<='0';
Y<='0';
ELSIF (counter6="011" OR counter6="100") THEN
R<='0';
G<='1';
Y<='0';
ELSIF (counter6="101") THEN
R<='0';
G<='0';
Y<='1';
ELSE
NULL;
END IF;
END PROCESS p2;
END behave;
3,抢答器的程序设计:
源程序:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity qiangda is
port(start,clk,clr:in std_logic;
sel:in std_logic_vector(1 downto 0);
led1,led2:out std_logic);
end qiangda;
architecture rtl of qiangda is
signal suo:std_logic;
begin
process(start,clk,clr)
begin
if(clr='1')then
led1<='0';
led2<='0';
suo<='0';
elsif (clk'event and clk='1') then
if(start='1') then
if(suo='0')then
case sel is
when "01"=>led1<='1';led2<='0';suo<='1';
when "10"=>led2<='1';led1<='0';suo<='1';
when others=>null;
end case;
end if;
end if;
end if;
end process;
end rtl;
五、课程设计结果及分析
1.设计60进计数器
仿真图分析:仿真图形的分析:该图data10十位是从000开始,data1个位是从0000开始,直到1001就清零,十位进1,如此进行下去,直到59,清零.
2.循环彩灯控制器:
仿真图分析:仿真图形分析:y黄灯发光1秒,g绿灯发光2秒,r红灯发光3秒,如此循环,实现程序
3.抢答器
仿真图分析:当sel1和sel2进行抢答时,若1抢到则led1亮,sel2抢先抢到,则led2亮,若同时抢到则两灯同时亮.
六、心得体会
在这学期的实验中,在收获知识的同时,还收获了阅历,收获了成熟,在此过程中,我们通过查找大量资料,请教老师,以及不懈的努力,不仅培养了独立思考、动手操作的能力,在各种其它能力上也都有了提高。更重要的是,在实验课上,我们学会了很多学习的方法。而这是日后最实用的,真的是受益匪浅。要面对社会的挑战,只有不断的学习、实践,再学习、再实践。而且,这对于我们的将来也有很大的帮助。以后,不管有多苦,我想我们都能变苦为乐,找寻有趣的事情,发现其中珍贵的事情。就像中国提倡的艰苦奋斗一样,我们都可以在实验结束之后变的更加成熟,会面对需要面对的事情。
第二篇:VHDL红外接收课程设计报告
VHDL课程设计报告
——版权归原作者所有
一、 题目要求
(1)、红外遥控系统的设计
红外遥控系统由发射编码和接收解码两个部分组成,本课程设计要求制作发射编码电路板(遥控器)以及编写程序在EDA实验板上实现接收解码,具体说明如下:
1、发射编码部分
发射编码部分要求使用指定的元器件在万用板上完成红外遥控器的制作,该部分电路原理图参照《PT2248数据手册》,制作前请详细阅读《红外遥控器制作说明》,制作时要求元器件在万用板上排列整齐,布局合理,焊接良好,各按键功能正常,均能发送编码。
2、接收解码部分
接收解码用VHDL语言编写程序,在EDA实验板上实现解码,要求具有以下功能:
(1)基本要求:
(a)将一体化红外接收解调器的输出信号解码(12个单击键、6个连续键,单击键编号为7-18,连续键编码为1-6),在EDA实验板上用七段数码管显示出来;
(b)当按下遥控器1—6号连续键时,在EDA实验板上用发光二极管点亮作为连续键按下的指示,要求遥控器上连续键接下时指示灯点亮,直到松开按键时才熄灭,用于区别单击键。
(c)EDA实验板上设置四个按键,其功能等同于遥控器上的1—4号按键,当按下此四个按键时七段数码管分别对应显示“1”、“2”、“3”、“4”。
(d)每当接收到有效按键时,蜂鸣器会发出提示音。
(2)扩展功能:(能完成的加分)
通过遥控器跳线改变用户码,EDA实验板上用三个发光二极管正确显示发送端的用户码。
二、设计分析
1)、流水灯程序:
测试各发光二极管的程序。程序中只要依次给要闪亮的灯输入低电平即可。
2)、
测试8位数码管的程序。CD4511可以将4位二进制编码转换成对应的7段显像管编码输出。真值表如下:
程序中只要将8位数码管显示控制端全部置1,即可保持数码管显示状态,依
次将“0000”-“1001”输送给CD4511就可以实现对8位数码管的动态扫描。时钟由晶振分频后得到。
3)、矩阵键盘扫描程序
测试键盘输入的程序。程序实现了显示0-4输入的输出显示。键盘输入行由“0111”到“1110”,列也是由“0111”到“1110”,直接翻译成对应的二进制编码输入CD4511译码显示。
4)、接收译码程序
本次实验的最主要程序。发射端编码方式已经在《红外遥控器制作说明及编码规则简要说明》中给出,要接收发射端发射的编码最关键的问题是发射段频率和接收段频率不一致的现象。发射端频率为38KHz,程序中设计的接收端频率为2.048MHz的8分频,即8KHz。
发射端每四个周期代表一个二进制编码,时间为1/38KHz*16*4=1.684ms,四个周期的时间换算成接收端周期数为1.684ms/(1/8KHz)=13.47。一个周期占13.47/4=3.37,三个周期占13.47/4*3=10.1,由于编码中一个周期的低电平代表“1”,三个周期的低电平代表“0”,再考虑到同步的问题,取(10.1+3.37)/2=6.77作为判断“0”、“1”的分界线,即当检测到超过7个接收端周期的低电平后即可认为接收到的是“0”,否则为“1”。
翻译出编码信号后根据编码的规则,分析用户和所显示的数字即可。
三、系统模块的划分以及各模块的功能描述
程序采用单进程,划分为接收编码信号及翻译模块和输出显示模块。
接收编码信号模块分为从键盘接收信号和从发射板接收信号,从键盘接收到的信号直接
翻译对应的二进制编码输出到显示模块;从发射板接收到的信号需要进行译码,每次接收13位周期的信号,如果前7个周期都为低电平,即可认为接收到“1”,否则为“0”。译码后根据编码的规则进行翻译,翻译成对应的二进制编码输出。当检测到收到的信号为1~6时,相应的彩灯发亮指示连续按键。
输出显示模块主要是对每一位显像管分别的输出进行控制,根据翻译出的二进制编码分别将各位的编码输入到CD4511,驱动显像管显示。
四、程序仿真
(1)键盘仿真
各信号描述:
Qrset:复位信号
Qinf:串行信号输入信号
Qck:时钟信号
Qjian:
键盘输入信号(7代表输入0111,即输入1,同理B代表2,D代表3,E代表4)
Qbit:片选信号,指示某个显像管显示
Qnum:二进制编码信号,输入CD4511编码
Qcon:彩灯显示信号
Qusr:用户信号(程序中全部将用户设为111)
Qbeep:蜂鸣信号
此图是测试键盘输入的仿真,键盘依次输入7、B、D、E(即1,2,3,4)在二进制编码端识别出1、2、3、4。相应的彩灯也被置为低电平
(2)发射板仿真
各信号含义与上面相同。
该仿真是测试接收发射端信号的仿真。图中仿真发射端编码为11110010000,从仿真结果可以看到。Qbit片选信号正确的在两个显像管间切换。Qnum也根据片选信号的不同相应的显示0和1(显示十位时是0,个位为1)。Qcon(6)是连续信号的显示灯,接收到1后该显示灯发光一段时间,之后会熄灭,因为连续信号会不停的发送编码信号,所以显示效果为连续灯常亮;而其他非连续信号输入时该灯不会亮。Qcon(5 downto 0)正确显示了接收到1信号时应该亮的指示灯。Quser显示用户为111。
五、设计体会及心得
本次实验锻炼了我们动手的能力,进一步熟练了焊接技巧。对布板的重要性有了更深刻
的认识,基本消除了以前常发生的飞线现象。
最重要的是本次实验让我们对信号远程传输的发射和接收有了具体的了解,对如何使用VHDL来实现硬件的功能有了初步了解。掌握了CD4511、74LS224、74HC4040、max7000等芯片的用法和各管脚的分布。
实验中得到各位老师的帮助,尤其是反复的取拿器件,浪费了老师很多时间,再此表示感谢~~
六、源程序
--XIANSHI.VHD 负责各显像管的显示
library ieee;
use ieee.std_logic_1164.all;
entity xianshi is
port (
acode : in std_logic_vector (4 downto 0); --翻译出的编码
aclk : in std_logic; --时钟信号
abit : out std_logic_vector(1 downto 0); --片选信号
anum : out std_logic_vector (3 downto 0) --编码输入CD4511
);
end xianshi;
architecture behav of xianshi is
begin
process (aclk)
variable a : std_logic ;
begin
if rising_edge (aclk) then
a:=not a;
if a='0' then
anum <= "000" & acode(4); --十位
abit <= "10";
else
anum <= acode(3 downto 0); --个位
abit <= "01";
end if;
end if;
end process;
end behav;
--OK.VHD 提供上层接口
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity ok is
port (
qclk : in std_logic;
qreset : in std_logic;
qinf : in std_logic;
qjian : in std_logic_vector(3 downto 0);
qbit : out std_logic_vector (1 downto 0);
qnum : out std_logic_vector (3 downto 0);
qcon : out std_logic_vector (6 downto 0);
quser: out std_logic_vector (2 downto 0);
qbeep: out std_logic);
end ok;
architecture behav of ok is
component fenxi is
port (
clk : in std_logic;
inf : in std_logic;
reset : in std_logic;
jian : in std_logic_vector(3 downto 0);
code : out std_logic_vector(4 downto 0);
con : out std_logic_vector (6 downto 0);
user: out std_logic_vector (2 downto 0);
beep: out std_logic );
end component fenxi;
component xianshi is
port (
acode : in std_logic_vector (4 downto 0);
aclk : in std_logic;
abit : out std_logic_vector(1 downto 0);
anum : out std_logic_vector (3 downto 0)
);
end component xianshi;
signal s : std_logic_vector(4 downto 0);
begin
t1: fenxi port map(
qclk,qinf,qreset,qjian,s,qcon,quser,qbeep
);
t2: xianshi port map(
s,qclk,qbit,qnum
);
end behav;
--FENXI.VHD
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity fenxi is
port (
clk : in std_logic; --时钟信号
inf : in std_logic; --串行输入信号
reset : in std_logic; --复位信号
jian : in std_logic_vector(3 downto 0); --键盘输入信号
code : out std_logic_vector(4 downto 0); --二进制编码,输入CD4511显像
con : out std_logic_vector (6 downto 0); --彩灯控制信号
user: out std_logic_vector (2 downto 0); --用户端信号
beep: out std_logic ); --蜂鸣信号
end fenxi;
architecture behav of fenxi is
type statetype is (s0, s1, s2,sk,t0,action);
signal state : statetype ;
constant beeptime : integer := 28 ;
begin
st: process (clk,inf)
variable cnt1,cnt2,cnta : integer range 0 to 30; -- ,cnta
variable reg : std_logic_vector(11 downto 0);
variable temp : std_logic_vector (4 downto 0);
variable tempcon : std_logic_vector (6 downto 0);
begin
-------------------------------------------------------------------------------------------------
-- 检测键盘输入和开始远程端接收部分
if reset= '1' then
state <= s0; code <= "00000"; con <= "1111111"; user <="111";
elsif rising_edge (clk) then
case state is
when s0 =>
if inf = '0' then
reg:="000000000000"; tempcon:="1111111"; temp:="00000";
cnt1:=0; cnt2:=0; cnta := 0;
state <= sk;
elsif jian = "0111" then
code <= "00001"; beep<='1'; con <= "1011111"; user <="111";
elsif jian = "1011" then
code <= "00010"; beep<='1'; con <= "1101111"; user <="111";
elsif jian = "1101" then
code <= "00011"; beep<='1'; con <= "1110111"; user <="111";
elsif jian = "1110" then
code <= "00100"; beep<='1'; con <= "1111011"; user <="111";
else
state <= s0;beep<='0';con (6) <= '1';
end if;
--------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------
----译码部分,检测发射端的发射信号
when sk =>
if inf = '0' then
state <= s1;
else
state <= sk;
end if;
when s1 =>
if inf = '0' then
cnt1:=cnt1 + 1;
state <= s1;
elsif inf='1' then
state <= s2;
end if;
when s2 =>
cnt2:=cnt2 + 1; -- 计算已记多少位数
if cnt1 < 7 then
reg:=reg(10 downto 0) & '0';
else
reg:=reg(10 downto 0) & '1';
end if;
if cnt2 = 12 then state <= t0;
else cnt1:= 0 ;
state <= sk;
end if;
--------------------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------------------
--译码部分,对译码之后的信号进行相应的译码输出
when t0 =>
beep <= '1' ;
case reg(8 downto 0) is
--continuous 1~6------------
when "100100000" => --1
temp := "00001";
when "100010000" => --2
temp := "00010";
when "100001000" => --3
temp := "00011";
when "100000100" => --4
temp := "00100";
when "100000010" => --5
temp := "00101";
when "100000001" => --6
temp := "00110";
---single 7~18---------
when "010100000" => --7
temp := "00111";
when "010010000" => --8
temp := "01000";
when "010001000" => --9
temp := "01001";
when "010000100" => --10
temp := "10000";
when "010000010" => --11
temp := "10001";
when "010000001" => --12
temp := "10010";
when "001100000" => --13
temp := "10011";
when "001010000" => --14
temp := "10100";
when "001001000" => --15
temp := "10101";
when "001000100" => --16
temp := "10110";
when "001000010" => --17
temp := "10111";
when "001000001" => --18
temp := "11000";
when others =>
temp := "00000";
end case;
user <= reg(11 downto 9);
tempcon := not reg(8) & not reg (5 downto 0);
state <= action ;
--------------------------------------------------------------------------------------------------
when action =>
con <= tempcon;
code <= temp;
cnta := cnta+1;
if cnta = beeptime then
beep <= '0';
state <= s0 ;
else
state <= action ;
end if;
when others =>
state <= s0;
end case;
end if;
end process st;
end behav;