彩灯控制器

一、实验目的

1、学习并掌握Quartus Ⅱ开发系统的基本操作。
2、掌握在Quartus Ⅱ中设计逻辑电路与仿真的方法。
3、初步掌握Vhdl的编程方法。
4、熟悉EDA实验仪。

二、实验电路图

三、实验内容

本实验通过一个节日彩灯的设计实例,详细介绍Quartus II的主要功能、使用方法和设计流程。
本课程所有实验所采用的可编程器件是Altera公司的FPGA芯片EP4CE10E22C8,有144个引脚。
在这个实例中,我们设计一个简单的LED流水彩灯,其中LED的共阴接地,阳极分别与EP4CE10I/O相连,具体的I/O引脚号码参见附录的对照表。I/O输出的电平高低不同,可以控制彩灯的亮灭,其中高为亮,低为灭。

四、实验步骤及要求

1.设计输入

首先理解下面的彩灯控制文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity light is
port(clk: in std_logic;
light: buffer std_logic_vector(7 downto 0));
end light;
architecture behv of light is
constant len: integer:=7;
begin
process(clk)
variable flag: bit_vector(2 downto 0):="000";
begin
if clk'event and clk='1' then
if flag="000" then
light<='1' & light(len downto 1);
if light(1)='1' then
flag:="001";
end if;
elsif flag="001" then
light<=light(len-1 downto 0) & '0';
if light(6)='0' then
flag:="010";
end if;
elsif flag="010" then
light(len downto 4)<=light(len-1 downto 4)&'1';
light(len-4 downto 0)<='1'&light(len-4 downto 1);
if light(1)='1' then
flag:="011";
end if;
elsif flag="011" then
light(len downto 4)<='0'&light(len downto 5);
light(len-4 downto 0)<=light(len-5 downto 0)&'0';
if light(2)='0' then
flag:="100";
end if;
elsif flag="100" then
light(len downto 4)<='1'&light(len downto 5);
light(len-4 downto 0)<='1'&light(len-4 downto 1);
if light(1)='1' then
flag:="101";
end if;
elsif flag="101" then
light<="00000000";
flag:="000";
end if;
end if;
end process;
end behv;

在上面的Vhdl程序中,用了8个LED灯,clk用于控制流水灯的速度,频率不能选择太快,否则人眼反映不过来。
理解上述程序的含义后,我们把它输入到Quartus II系统,步骤如下:

(1)建立工作库文件和编辑设计文件

Quartus II中,任何一项设计都是一项工程(Project),必须为此工程建立一个放置此工程相关文件的文件夹,此文件夹将被EDA软件默认为工作库(Work Library)。一般不同的设计项目最好放在不同的文件夹中,而同一工程的所有文件都必须放在同一文件夹中。
针对本彩灯的设计实例,我们在D盘(或h盘)根目录下建立一个文件夹,取名为light:本例文件名必须为LIGHT.VHD),路径为D:\light(建议你最好先以自己的学号建一个文件夹,再在此文件夹里对每一个实验单独建一个文件夹)。需注意的是:文件夹不能用中文字符命名,也不要有空格,只能用英文字母和数字命名。
打开Quartus II11.0,选择“File”菜单下的“New”命令。在“New”窗口中的“Device Desing Files”选项中选择“Vhdl File”(如图1-1所示)。然后在Vhdl文本编辑窗中输入上面的Vhdl程序。
图1-1  选择编译文件的语言类型

输入完成后,选择“File”菜单下的“Save As”命令,存放到刚才建立的F盘根目录下的light文件夹,保存类型选择Vhdl File(*.vhd),存盘文件名应与实体名一致,即为light.vhd。此时会出现如图1-2所示的对话框“Do you want to create a new project with this file?”。如果单击“是”按钮,则直接创建工程流程。在此,为了下一节熟悉利用“New Project Wizard”工具创建设计文档,我们单击“否”按钮。
图1-2  编辑输入设计文档并存盘

(2)创建工程

1)选择“File”菜单下的“New Project Wizard”,打开新建项目指南(图1-3),将出现如图1-4所示的对话框。

图1-3  打开新建项目向导

图1-4  创建工程light

1-4中最上面一栏指示工作目录即文件夹,本例为D:\light。第二栏为项目的名称,本例也是Light:项目的名称与顶层文件名必须一致,但与文件夹的名称可以不一致。)设置完后,单击“Next”按钮。
注意:每个项目下只能有一个顶层文件,可以有多个非顶层源文件。
2)将设计文件加入工程。一般复杂的电路常常由多个程序组成,利用加入窗口可以将所选择的文件加入到当前项目中。在图1-5中,最上面一栏“File name”用于加入设计文件,可单击右侧的“…”按钮,找到相应的目录下的文件并加入。加入的文件可以有Graphic.BDF、 .GDF)、AHDLVHDLVerilog HDL以及EDIF文件。若单击“Add All”按钮,可将当前目录下的所有VHDL文件加入到此工程。如果单击下面的“User Libraries…”按钮,则打开如图1-6所示的对话框,可以加入用户自己定义的库函数的路径名和文件名。在我们彩灯的例子中,只涉及到一个程序,且文件light.vhd也是顶层文件,所以就不需要加入其他文件了,也不需要加入自定义的库函数。设置完成后,单击“Next”按钮,进行下一步。

图1-5  在工程中加入所有相关文件
图1-6  加入用户自定义的库函数

3)选择目标芯片。首先在“Family”栏中选择Cyclone IVE系列;然后在“Target device”选项框中选择“Specific device selected in ‘Available devices’ list”,即选择一个确定的目标芯片。在“vailable devices”里,我们选择此系列的具体芯片EP4CE10E22C8EP4C表示Cyclone 的第四代系列器件,

4)选定目标芯片后,单击“Next”按钮,将出现图1-7所示的对话框,用于选择其他厂家的仿真器和综合器类型。如果我们不选的话,将使用Quartus II自带的仿真器和综合器。这里不做任何选择。

图1-7  选择仿真器和综合器

5)再次单击“Next”按钮后,出现如图1-8所示的对话框,工程设置统计列出了此项工程的相关设置情况。如项目名、顶层文件名、器件的型号等。最后单击“Finish”按钮,结束该工程的设置,已经成功建立了工程。在左面Project Navigator栏中可以查看该工程的各项文件以及层次结构。

图1-8  工程设置统计
上述若发现有设置错误的地方,可以打开界面上方“Assignments”菜单,点击下拉中的“Settings”对话框,可更改并重新设置一些选项。如利用“General”页面可以重新指定顶层实体,在“Files”页面中可以添加和删除文件。在“Device”中页面可以重新选择芯片等。

2.项目编译

Quartus II的编译器由一系列处理模块构成,这些模块完成对设计项目的检错、逻辑综合、结构综合、输出结果的编译配置、时序分析等功能。在这个过程中将设计项目适配到FPGA/CPLD目标器中,同时产生各种输出文件编译报告,包括器件使用统计、编译设置、RTL级电路显示、器件资源利用率、状态机的实现、方程式、延时分析结构、CPU使用资源等。编译器首先从工程设计文件间的层次结构描述中提取信息,包括每个低层文件中的错误信息,供设计者排除。然后将这些层次构建产生一个结构化的以网表文件表达的电路原理图文件,并把各层次中所有的文件结合成一个数据包,以便更有效地处理。
在编译前,设计者可以通过各种不同的设置,指导编译器使用各种不同的综合和适配技术,以便提高设计项目的工作速度,优化器件的资源利用率。在编译过程中及编译完成后,可以从编译报告窗口中获得所有相关的详细编译结果,以利于设计者及时调整设计方案。
这里我们启动全程编译,可以选择“Processing”菜单下的“Start Compilation”项,也可以单击工具栏上的快捷方式按钮(图1-9所示)。
图1-9  通过工具栏快捷方式进行编译

这里说的全程编译,包括了以上提到的Quartus II对设计输入的多项处理操作,如检错、数据网表文件提取、逻辑综合、适配、装配文件(仿真文件与编程配置文件)生成,以及基于目标器件的工程时序分析等。下面的“Processing”窗口会显示编译过程中的相关信息,如果发现警告和错误,会以深色标记条显示。警告不影响编译通过,但是错误编译不能通过,必须进行修改。双击“Processing”栏中的错误显示条文,会在弹出的对应的Vhdl文件中,光标指示到错误处。在对错误进行修改后,再次进行编译,直至排除所有错误。需要注意的是,尽管警告错误不影响编译,但影响综合的准确度,因此要尽量修改警告错误。
如果程序输入没有错误,将会出现如图1-10所示的编译结果报告。在此界面中,左上角的“Project Navigator”窗口,显示了工程的结构和其中结构模块耗用的逻辑宏单元数。下面的“Status”窗口显示了编译处理流程,包括数据网表建立、逻辑综合、适配、配置文件装配和时序分析。“Compilation Report”栏是编译报告项目选择菜单,单击其中各项,可以详细了解编译与分析结构。例如单击“Flow Summary”项,将在右栏显示硬件耗用统计报告,反映了当前所耗用硬件的相关信息。当前的工程共耗用了24个逻辑宏单元,小于总数的1%,共使用了104个引脚中的9个。如果单击“Timing Analyzer”项中的“+”号,可以打开各个子项目,查看当前工程所有相关时序特性报告。如果单击“Fitter”项中的“+”号,可以打开各个子项目查看当前工程的所有相关硬件特性适配报告。例如其中的“Pin-Out File”,可以查看芯片各个引脚的使用情况。
图1-10  编译报告窗口

3.项目仿真

对工程编译通过之后,需要对其功能和时序进行仿真测试,以了解设计结果是否满足原设计要求,也可以通过仿真检查程序算法的错误。
由于Alter公司在QuartesII9.0以后不再提供仿真功能(但是,第4代的器件又是在QuartesII11.0以上才支持,所以实验必须用11.0进行下载。)下面以QuartesII8.1为例,介绍QuartesII的波形仿真功能。步骤如下:
1)进入QuartesII8.1以后,可以采用打开已存在的项目方式,建立项目,编译后(步骤同上)。选择“File”菜单中的“New”项,在“Verification/Debugging Files”中选择“Vector Waveform File”项,打开波形编辑器。
2)在波形编辑器中引入信号节点。在波形编辑器界面中直接双击“Name”下面的空白区域,即出现一个“Insert Node or Bus”的对话框,如图1-11所示。
图1-11 插入节点对话框

3)点击“Node Finder”按钮,将出现图1-12界面
图1-12  准备输入信号节点
“Filter”框中选择“Pins:all”,然后单击“List”按钮,于是在下面的“Nodes Found”窗口中出现了工程light中的所有端口引脚名,如果此时没有出现端口引脚名,则可以重新编译一下。直接双击信号名即可将我们需要仿真观察的信号加入波形编辑窗口。在这里,把 “clk”、和“light”全部选中。
4)设置仿真时间区域。将仿真时间设置在一个比较合理的时间区域,使得即可以将各种输入情况都能出现,又不会使仿真时间太长。本例中,选择“Edit”菜单中的“End Time…”项,在弹出的窗口中的“Time”栏处输入“100”,单位选择“ms”,将整个仿真区域的时间设为100ms,单击“OK”按钮,再点击“Grid size…”项,设置“Time period”1ms,指观察波形时的标注是1ms提示一次,单击“OK”按钮,结束设置。
5)编辑输入波形(输入激励信号)。单击选中波形编辑窗口的时钟信号名“clk”,使之变成蓝色条,再单击左列的时钟设置键,打开如图1-13所示的窗口,将“clk”的周期设定为1ms“Phase”相位设为默认为零,“Duty cycle”占空比设为默认值50%
设定好时钟信号后,在波形窗口中单击鼠标右键,选择“Zoom”菜单下的“Fit in Window”选项,也可以选择按钮之后,按鼠标的左右按键调整适当的观察比例。
6)设定数据模式。单击信号“light”旁边的“+”号,可以打开该信号的各个分量,查看信号的每一位。如果双击“+”号左边的信号标记,可以打开信号格式设置的对话框,如图1-14所示。
图1-13 时钟设置窗口
图1-14 信号设置窗口
通过“Radix”窗口可以设置信号的格式。我们将信号“light”、设定为二进制“binary”
7)波形文件存盘。选择“File”菜单下的“Save”命令,或直接单击工具栏上的按钮,将会以默认名为light.vwf的波形文件存入文件夹D:\light(默认路径)中。
8)启动仿真器。选中“Processsing”菜单下的“Start Siulation”,或者直接单击工具栏上的快捷方式,直到出现“Simulation was successful”对话框。
图1-15 仿真结构报告窗口

9)观察仿真结果,如图1-15所示。仿真波形文件“Simulation Report”通常会自动弹出。如果没有弹出仿真完成后的波形文件,可以通过“Processing”菜单下的“Simulation Report”命令,打开波形报告。如果无法在窗口展开显示时间轴上的所有波形图,可以在仿真报告窗口中单击鼠标右键,选择“Zoom”项下的“Fit in Window”选项,并通过按钮,调节波形的比例。通过观察波形,看是否达到了我们预定的要求。

10) 应用RTL电路图观察器(本步骤不是必须)
Quartus II可实现硬件描述语言或网表文件(VHDLVerilogBDFTDFEDIFVQM)对应的RTL电路图的生成。选择“Tools”菜单下的“Netlist Viewers|RTL Viewer”项,可以打开工程light各层次的电路结构,如图1-16所示。
双击图形中的有关模块,或者选择左侧各项,可逐层了解各层次的电路结构。对于较复杂的RTL电路,可以利用模块功能过滤器Filter简化电路。用鼠标右键单击目标模块,在弹出的下拉菜单中选择“Filter”|“Sources”“Destinations”,由此产生相应的简化电路。
图1-16 综合后的RTL电路图

4.引脚锁定

注:要在QuartusII11.0下进行
工程编译、仿真都通过后,就可以将配置数据下载到应用系统进行验证。下载之前首先要进行引脚锁定,保证锁定的引脚与实际的应用系统相吻合。
我们使用EDA实验仪进行验证。本实验中,用D101D108代表八个LED灯,引脚分别为143,144,1,2,3,73,7和10,连接8位输出light[7..0],使用CLK5为基本的扫描频率,拨动开关放在4Hz, 引脚为89。以上芯片的引脚序号见附录的表。
下面我们就开始进行引脚的锁定操作。
(1) 确认已经打开了工程light
(2) 打开“Assignments”菜单下的“Pins”命令,打开引脚锁定窗口,这时所有的端口都已存在列表中,如图1-17所示。
(3) 用鼠标双击每个信号对应的“Location”栏中的空白处,在出现的下拉栏中选择对应端口信号名的器件引脚号(例如对应clk,应该选择clk5引脚号是89)。
图1-17  锁定引脚

(4) 引脚锁定完成后,保存,此时必须将工程再编译一次,才能将引脚锁定信息应用到最终的下载文件中,此后就可以将编译好的SOF文件下载到实验系统的FPGA中去了。

5.下载验证

将编译产生的SOF格式下载文件配置到FPGA中,进行硬件测试的步骤如下。
(1) 将USB下载电缆线接好,打开实验箱电源。
(2) 在菜单“Tool”中选择“Programmer”,或直接单击工具栏上的快捷键。
(3) 设置编程模式。若是初次安装的Quartus II,在下载编程前需要选择下载接口方式。单击“Hardware Setup”,可打开如图1-18所示的窗口。在这里,选择“USB-Blaster[USB-0]”,双击鼠标后,关闭该窗口。
图1-18  选择下载接口方式

(4) 设置完成后,单击“Start”按钮,即进入对目标器件FPGA的配置下载操作。当“Progress”显示为100%时,编程成功,可以观察实验面板,进行硬件测试验证。
注意:上述步骤是一个比较完整的过程,并不是每次都要严格按照上述步骤,简单的可以省略仿真,待有错误的时候,用仿真来调试错误。最基本的步骤为设计输入、项目编译、引脚锁定、再编译、下载这五个步骤。

五、实验连线

  1. EP4CE10核心板左下角的JTAG口和USB Blaster下载器连接到电脑上。
  2. 数码管下方的JPLED1开关右拨打开,左边的开关全部上拨。
  3. JP103的拨码开关全部拨向右边,打开实验箱电源。
  4. 将实验板右下方频率选择区中CLK5 接4 HZ。

注意:实验板上CLK1到CLK5 频率源上不能同时连接二个频率。

六、实验结果

在不同的时段,指示灯有不同的显示模式,开始时刻LED流水灯从右到左依次点亮,第二时间段LED流水灯从左到右依次熄灭,第三时间段LED流水从中间向两边点点亮,第四时间段LED流水灯从两边向中间依次熄灭,第五时间段LED流水灯从中间和最左边同时开始向右依次点亮,最后全灭,进人第二次重复循环。

七、本实验其他要求

上述操作完成后将原来程序的8个彩灯改为12个,并在最后增加一种变化,将自己的学号最后3位数字,按二进制方式显示在12个灯上,然后全部熄灭,再进入下一个循环。

我的vhdl代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity light12 is
port(clk: in std_logic;
light: buffer std_logic_vector(11 downto 0));
end light12;
architecture behv of light12 is
constant len: integer:=11;
begin
process(clk)
variable flag: bit_vector(2 downto 0):="000";
begin
if clk'event and clk='1' then
if flag="000" then
light<='1' & light(len downto 1);
if light(1)='1' then
flag:="001";
end if;
elsif flag="001" then
light<=light(len-1 downto 0) & '0';
if light(10)='0' then
flag:="010";
end if;
elsif flag="010" then
light(len downto 6)<=light(len-1 downto 6)&'1';
light(len-6 downto 0)<='1'&light(len-6 downto 1);
if light(1)='1' then
flag:="011";
end if;
elsif flag="011" then
light(len downto 6)<='0'&light(len downto 7);
light(len-6 downto 0)<=light(len-7 downto 0)&'0';
if light(4)='0' then
flag:="100";
end if;
elsif flag="100" then
light(len downto 6)<='1'&light(len downto 7);
light(len-6 downto 0)<='1'&light(len-6 downto 1);
if light(1)='1' then
flag:="101";
end if;
elsif flag="101" then
light<="000000000000";
flag:="110";
elsif flag="110" then
light<="000011000010";
elsif flag="111" then
light<="000000000000";
flag:="000";
end if;
end if;
end process;
end behv;

引脚连接如下