1
FPGA与CPLD实验报告
159030004杨文忠
实验一、正弦波的产生
一、实验目的:
1.学习QuartusII的使用; 2.掌握宏单元模块定制ROM; 3. 掌握VHDL语言中的元件例化; 4. 掌握VHDL语言中的计数器的设计; 5.掌握SignalTap II的使用。
二、实验条件:
1. 装有QuartusII13.0的电脑一台; 2. EP4CE15F17C8实验开发板一套。
三、实验原理:
1. 使用查表的方式计算正弦值,使用MATLAB产生ROM所需的正弦波mif文件;
2. 程序中根据计数器的值进行查表输出,并用modelsim和SignalTap II观察输出的结果。 3.使用MATLAB产生mif文件的程序如下: WIDTH=8; DEPTH=1024;
ADDRESS_RADIX=DEC; DATA_RADIX=DEC; CONT
ENT BEGIN 0:128; 1:129; 2:130;
…(数据略去) 1021:126; 1022:126; 1023:127; End;
保存为mif格式文件,或者直接使用Mif_Maker2010产生mif文件。 四、实验内容:
1. 使用宏单元模块定制ROM,操作步骤如下:
Tools -> MegaWizars Plug-In Manager[page 1] -> Create a new custom megafunction variation -> Next -> MegaWizars Plug-In Manager[page 2a] -> Installed Plug-In -> I/O ->Memory Complier -> ROM:1-PORT
设置好参数后,将定制的Files添加到工程中,调用Modelsim观察正选波形,观察之前需设计相应参数,时钟设置为100ns。
2. 使用SignalTap II逻辑分析仪分析FPGA产生的正弦波信号, SignalTap II的使用步骤
2
如下:
Tools ->SignalTap II Logic Analyzer ->设置好之后,直接点击运行即可。 五、实验总结:
通过本次实验学会了怎么使用使用宏单元模块定制ROM,并学会了如何使SignalTap II。 六、实验代码:
library ieee; --正弦信号发生器源文件 use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity sinwave is
port (clk:in std_logic; --信号源时钟 dout:out std_logic_vector(7 downto 0));--8位波形数据输出 end;
architecture dacc of sinwave is
component data_rom PORT ( address : IN STD_LOGIC_VECTOR (9 DOWNTO 0);--10位地址信号 clock : IN STD_LOGIC := '1'; q : OUT STD_LOGIC_VECTOR (7 DOWNTO 0) );
end component;
signal q1:std_logic_vector(9 downto 0):=\设定内部节点作为地址计算器 begin
process(clk) begin
if clk'event and clk ='1' then q1<=q1+1;--q1作为地址发生器计算器 end if;
end process;
u1:data_rom port map(address=>q1,q=>dout,clock=>clk);--例化 end;
3
实验二、数字钟的设计
一、实验目的:
1.熟练掌握QuartusII的使用; 2.掌握宏单元模块定制ROM; 3. 掌握VHDL语言中的元件例化; 4. 掌握VHDL语言中的数字钟的设计; 5.练习使用VHDL写状态机程序。
二、实验条件:
1. 装有QuartusII13.0的电脑一台; 2. EP4CE15F17C8实验开发板一套。
三、实验原理:
1. EP4CE15F17C8开发板的系统时钟是50MHz,通过分频方式产生1Hz的标准秒脉冲,通过把三个计数器级联,分别对电子钟的秒分时进行计数,计数器的模分别为60,60,24;
2. 对计数结果进行二进制到8421BCD码的转换,通过译码器把BCD码转换成七段码,显示是通过位码控制来进行动态显示的; 3. 本开发板使用的按键是独立式按键,总共有六个按键,上下键完成状态间的切换,左右键完成数字的加减,中间键为确认键,还有一个单独的复位键; 5. 通过按键来完成当前时间和闹钟的时间调整。 四、实验内容: 1. 计数器的设计
在本次实验中使用了较多的计数器,通过编写通用计数器,再在主程序中多次例化,以达到精简代码的目的。本计数器定义了置数使能和置数值输入口来完成当前时钟时间的调节。 时钟的位数和模值可通过具体的例化原件来进行初始化。
entity counter is
generic (bitwidth:integer:=4;moda:integer:=12); port (clk,en,en_set:in std_logic;
d :in std_logic_vector(bitwidth-1 downto 0); cout:out std_logic;
counterout :out std_logic_vector(bitwidth-1 downto 0)); end entity;
计数器的cout是计数进位端,作为下一级计数器的计数使能端,此处需要注意本级的进位端不能作为下一级的时钟信号使,因为进位端的毛刺会使计数结果出现错误。
2. 按键去抖程序的设计
实验中需要对按键进行消抖处理,消抖的程序是直接采用计数器计数的形式,等计数器达到一定的值时,将相应的按键使能信号置为有效位。
设置计数器的最大计数值为5000000,当按键按下时间到100ms时,将按键使能信号置位。
调节时间和闹钟时间的程序采用状态机的方法设计。状态转换如下
4
现key_rst_en key_ok_en key_up_en key_down_en key_left_en key_right_en 态 S0 S1 S2 S3 S4 S5 S5 S5 S5 S5 S5 S1 S5 S5 S5 S5 S0 S4 S1 S2 S3 S0 S0 S2 S3 S4 S1 S0 S1 S2 S3 S4 S0 S1 S2 S3 S4 S0是空闲状态,在没有按键按下时在此状态,S1是分钟调节状态,S2是小时调节状态,S3是闹钟分钟调节状态,S4是闹钟小时调节状态,S5是置数使能端使能状态,此状态停留一个系统时钟后自动返回S0状态。 3. 译码器的设计
本设计的译码器包括两类译码器:(1)将二进制数转换成8421BCD码;(2)将BCD码转换成七段码。
4.在调节时间的时候为了显示现在正在调节的时间,在程序中加入显示控制端,显示控制端共四位,说明如下: 调节内容 分钟调节 小时调节 闹铃分钟调节 闹铃小时调节 disply_ctrl 1010 1011 1110 1111 当正在调节时间时,让秒显示00,当调节闹铃时间时,让秒显示55,在主程序中显示控制程序如下:
if disply_ctrl(3 downto 2)=\有键按下 hour_display<=hour_set; minute_display<=minute_set; second_display<=\
elsif disply_ctrl(3 downto 2)=\ hour_display<=hour_alarm; minute_display<=minute_alarm; second_display<=\ else
hour_display<=hour; minute_display<=minute; second_display<=second; end if;
为了便于观察正在设置的是分钟还是小时,使正在设置的部分以2Hz的频率闪烁显示,处理方法如下:
case cnt8 is
when \
bt <= \ else
bt <= \

