一、 实验目的
1.进一步了解时序电路设计方法
2.熟悉状态机的设计方法
二、 实验所用仪器及元器件
1、 计算机
2、 直流稳压电源
3、 数字系统与逻辑设计实验开发板
三、 实验内容
用VHDL语言设计并实现一个彩灯控制(8个发光二极管)电路,仿真并下载验证其功能。彩灯有两种工作模式,可以通过拨码开关或者按键进行切换。
(1) 单点移动模式:一个点在8个发光二极管上来回的亮
(2) 幕布模式:从中间两个点,同时向两边一次点亮直至全亮,然后再向中间点灭,依次往复
四、 设计思路与过程
根据实验要求,需要实现在拨码开关或者按键的控制下实现两种状态机的转换。
首先,确定输入输出变量:
输入:拨码开关a:实现两种模式的转换;
时钟clk::提供有效时钟沿;
输出:8维向量b:连接8个发光二极管。
其次,确定电路工作状态
因为在单点移动模式和幕布模式都要满足灯来回亮,共计工作状态23种:
a=0时,实现单点移动模式,工作状态有s0~s13共14种状态;
a=1时,实现幕布模式,工作状态有s14~s22共9种状态。
再次,大致确定VHDL编写思路
确定好输入输出变量和电路状态后,考虑结构体中需要的进程需要完成以下两个功能——分频和实现状态机,故我使用了4个进程。其功能分别如下:
P0:分频,将实验板上提供的50MHz的时钟信号,即输入clk分为频率为1Hz的低频信号clk_out,以便观察现象;
P1:为当前状态储存的下一状态;
- 1 -
P2:当时钟有效沿到来时,当前状态转入下一状态;
(P1、P2共同实现状态机的转换)
P3:控制LED灯的输出,达到实验要求效果
具体程序如下。
五、 VHDL程序
library ieee;
use ieee.std_logic_1164.all;
entity light is
port (
clk: in std_logic;
a: in std_logic;
b:out std_logic_vector(7 downto 0));
end light;
architecture light_1 of light is
2 - -
type
is(s0,s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12,s13,s14,s15,s16,s17,s18,s19,s20,s21,s22);
state_type
signal current_state,next_state: state_type;
signal clk_out:std_logic;
signal tmp: integer range 0 to ;
begin
p0:process(clk) begin
if clk'event and clk='1' then
if tmp= then
tmp<=0;
else
tmp<=tmp+1;
end if;
--分频器,把50MHz的时钟clk分为1Hz的时钟clk_out
- 3 -
if tmp= then
clk_out<='1';
else
clk_out<='0';
end if;
end if;
end process;
p1:process(current_state,a) --当前状态在开关函数a作用下所储存的下一状态
begin
case current_state is
when s0=> if(a='0') then next_state<=s1;
else next_state<=s14; end if;
when s1=> if(a='0') then next_state<=s2;
else next_state<=s14; end if;
4 - -
when s2=> if(a='0') then next_state<=s3;
else next_state<=s14; end if;
when s3=> if(a='0') then next_state<=s4;
else next_state<=s14; end if;
when s4=> if(a='0') then next_state<=s5;
else next_state<=s14; end if;
when s5=> if(a='0') then next_state<=s6;
else next_state<=s14; end if;
when s6=> if(a='0') then next_state<=s7;
else next_state<=s14; end if;
when s7=> if(a='0') then next_state<=s8;
else next_state<=s14; end if;
when s8=> if(a='0') then next_state<=s9;
else next_state<=s14; end if;
- 5 -
when s9=> if(a='0') then next_state<=s10;
else next_state<=s14; end if;
when s10=> if(a='0') then next_state<=s11;
else next_state<=s14; end if;
when s11=> if(a='0') then next_state<=s12;
else next_state<=s14; end if;
when s12=> if(a='0') then next_state<=s13;
else next_state<=s14; end if;
when s13=> if(a='0') then next_state<=s0;
else next_state<=s14; end if;
when s14=> if(a='1') then next_state<=s15;
else next_state<=s0; end if;
when s15=> if(a='1') then next_state<=s16;
else next_state<=s0; end if;
6 - -
when s16=> if(a='1') then next_state<=s17;
else next_state<=s0; end if;
when s17=> if(a='1') then next_state<=s18;
else next_state<=s0; end if;
when s18=> if(a='1') then next_state<=s19;
else next_state<=s0; end if;
when s19=> if(a='1') then next_state<=s20;
else next_state<=s0; end if;
when s20=> if(a='1') then next_state<=s21;
else next_state<=s0; end if;
when s21=> if(a='1') then next_state<=s22;
else next_state<=s0; end if;
when s22=> if(a='1') then next_state<=s14;
else next_state<=s0; end if;
- 7 -
end case;
end process;
p2:process(clk_out) --时钟clk_out作用下的状态转换函数
begin
if(clk_out'event and clk_out='1') then
current_state<=next_state;
end if;
end process;
p3:process(current_state) begin
case current_state is
when s0=>b<=\"\";
when s1=>b<=\"\";
when s2=>b<=\"\";
-
8 - 当前状态所对应的输出函数
--
when s3=>b<=\"\";
when s4=>b<=\"\";
when s5=>b<=\"\";
when s6=>b<=\"\";
when s7=>b<=\"\";
when s8=>b<=\"\";
when s9=>b<=\"\";
when s10=>b<=\"\";
when s11=>b<=\"\";
when s12=>b<=\"\";
when s13=>b<=\"\";
when s14=>b<=\"\";
when s15=>b<=\"\";
when s16=>b<=\"\";
- 9 -
when s17=>b<=\"\";
when s18=>b<=\"\";
when s19=>b<=\"\";
when s20=>b<=\"\";
when s21=>b<=\"\";
when s22=>b<=\"\";
end case;
end process;
end light_1;
六、 仿真波形
10 - -
说明:为了仿真需要,在进行仿真事,将分频部分p0去掉,直接用clk作用进程p2
其中:
End time=2ms
a period time=60us
clk period time=2us
七、 故障及问题分析
本次实验整体比较顺利,但仍旧出现了几个问题:
开始并未设置分频器,clk的频率为50MHz,这个频率过高,若是直接用于提供时钟,不但不能看清现象,还会因为周期过短(可能会短于电路的延迟时间),导致输出错误。故加了一个50M的分频器,使作用的有效时钟信号为1Hz。
- 11 -
其他未出现什么问题,顺利地完成了实验。
八、 总结和结论
本学期数电实验共完成了4次实验,分别完成了以下四项任务:
➢ 对实验板的熟悉;
➢ 对Quarter 的初步认识,并熟悉掌握其图形编译功能;
➢ 对Quarter的进一步了解,初步结识VHDL语言,并用其实现了简单的计数器和译码器的功能,为最后一次实验打下基础;
➢ 进一步熟悉VHDL语言,并用其实现实际电路设计;
纵观四次实验,让我感触颇深的就是,预习对实验的重要性。QuarterII对我们来说是一个全新的东西,一切操作都得从头来学,好在它的界面友善,操作简单易懂,只是在编写VHDL程序的时候,需要事先学习其语言习惯。如果预习充分,就能很顺利地完成实验任务,还留有时间思考其它问题,完成额外的题目。
实验要想仿真并下载成功,需要注意的细节很多,如,引脚设置、输入变量的周期设置等。在第三次实验时,我犯了个很愚蠢的错误——锁定引脚后没有让程序再运行compilation一遍,导致的结果就是,仿真完全正确,但下载到实验板上怎么就不能正确工作,白白耽误了很长时间。所以按部就班的操作是很必要的。
实验中还有一些细节,在预习时并未注意,只有去实验室实际操作时才发现。如第三次实验实现7段数码译码器并用数码显示管显示时,预习时,并不知道,通过用一个八维向量c来控制8个数码显示管亮
12 - -
的管子的数量;再如第四次实验,预习的时候并不知道,板子上提供的时钟是50MHz,必须通过分频才能看清实验现象,就临场模仿书上例子做了分频器。
四次实验,对我最有启发的是第四次实验。完成这次实验,需要思考实验需要完成的具体部分,将功能分成块,通过几个process分别完成。这种设计方法对我很有启发。相信在完成更大型的电路时,这种思想将起到很关键的作用。
本学期的数电实验,完成了理论与实验的结合,将一些很抽象的理论概念具体地体现出来,如,门的延迟对输出波形的影响,冒险现象的产生原因等等。与此同时,我们学会了仿真工具QuarterII,初步掌握了VHDL语言,为理论学习提供了便利。这些都使数字电路的学习更具趣味性,同时更可以增强我们的动手动脑能力,从而达到学以致用的目的。
附录:第二、三次实验编程部分及仿真波形
1. 用QuarterII原理图输入法实现一个全加器,仿真验证其功能,并下载到实验板上测试,要求用拨码开关(SW1~SW3)作为输入,发光二极管(LD1~LD2)作为输出。
2. 用VHDL语言设计实现一个7段数码管译码器。
实验内容及要求:在QuartusII平台上设计程序和仿真题目要求,并下载到实验板上验证实验结果。
a) 用拨码开关输入二进制数0000~1001;
b) 用数码显示管显示译码结果
3. 用VHDL语言设计并实现一个8421码十进制计数器。
- 13 -
实验内容及要求:在QuartusII平台上设计程序和仿真题目要求,并下载到实验板上验证实验结果,用发光二极管显示计数值。
➢ 实验1 QuarterII原理图:
➢ 实验1仿真波形
14 - -
➢ 实验2 VHDL语言
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY seg1 IS
PORT(
a:IN STD_LOGIC_VECTOR (3 downto 0);
b:OUT STD_LOGIC_VECTOR (6 downto 0);
c:OUT STD_LOGIC_VECTOR (5 downto 0)
);
end seg1;
ARCHITECTURE seg_m OF seg1 IS
BEGIN
PROCESS(a)
BEGIN
- 15 -
CASE a IS
WHEN \"0000\" => b<=\"\"; --0
WHEN \"0001\" => b<=\"\"; --1
WHEN \"0010\" => b<=\"\"; --2
WHEN \"0011\" => b<=\"\"; --3
WHEN \"0100\" => b<=\"\"; --4
WHEN \"0101\" => b<=\"\"; --5
WHEN \"0110\" => b<=\"\"; --6
WHEN \"0111\" => b<=\"\"; --7
WHEN \"1000\" => b<=\"\"; --8
WHEN \"1001\" => b<=\"\"; --9
WHEN OTHERS => b<=\"\";
END CASE;
c<=\"\";
16 - -
END PROCESS;
END;
➢ 实验1仿真波形图
➢ 实验3 VHDL程序
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY count1 IS
PORT(
- 17 -
clk,clear: IN STD_LOGIC;
q: OUT STD_LOGIC_VECTOR(3 DOWNTO 0)
);
end count1;
ARCHITECTURE a OF count1 IS
SIGNAL q_temp: STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN
PROCESS(clk)
BEGIN
IF(clk'event and clk='1') THEN
IF CLEAR='0' THEN
q_temp<=\"0000\";
ELSIF q_temp=\"1001\" THEN
q_temp<=\"0000\";
18 - -
ELSE
q_temp<=q_temp+1;
END IF;
END IF;
END PROCESS;
q<=q_temp;
END a;
➢ 实验3仿真波形
- 19 -
因篇幅问题不能全部显示,请点此查看更多更全内容