您的当前位置:首页正文

VHDL 彩灯控制电路的设计与实现

2020-12-16 来源:独旅网
VHDL 彩灯控制电路的设计与实现

一、 实验目的

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 -

因篇幅问题不能全部显示,请点此查看更多更全内容