欢迎访问有用文档网!

当前位置: 有用文档网 > 述职报告 >

EDA技术及应用实验报告

| 浏览次数:

 《EDA 技术及应用》实验报告

 实验一

 点亮 LED 设计 一、实验目的

 通过此实验让用户逐步了解、熟悉和掌握 FPGA 开发软件 QuartusII 的使用方法及 Verilog HDL 的编程方法。

 本实验力求以详细的步骤和讲解让读者以最快的方式了解 EDA 技术开发以及软件的使用,从而快速入门并激起读者对 EDA 技术的兴趣。

 二、实验容

 SmartSOPC 实验箱上有 8 个发光二极管 LED1~8,并分别与 FPGA 的 50、53~55、176 和 47~49 引脚相连。本实验的容是建立可用于控制 LED 亮/灭的简单硬件电路,要求点亮 SmartSOPC 实验箱上的 4 个发光二极管(LED1、LED3、LED5 和 LED7)。

 三、实验原理

 FPGA 器件同单片机一样,为用户提供了许多灵活独立的输入/输出 I/O 口(单元)。FPGA 每个 I/O 口可以配置为输入、输出、双向 I/O、集电极开路和三态门等各种组态。作为输出口时,FPGA 的 I/O 口可以吸收最大为 24mA 的电流,可以直接驱动发光二极管 LED 等器件。所以只要正确分配并锁定引脚后,在相应的引脚上输出低电平“0”,就可以实现点亮该发光二级管的功能。

 四、实验步骤

 1、启动 Quarters II 建立一个空白工程,命名为 led_test.qpf。然后分别建立图形设计文件,命名为 led_test.bdf,以及文本编辑文件 led1.v,将他们都添加进工程中。

 2、对工程进行设计。在 led1.v 中输入程序代码,并保存,进行综合编译,若在编译中发现错误,则找出并更正错误,直至编译成功为止。从设计文件中创建模块,由 led1.v 生成名为 led1.bsf 的模块符号文件。在 led_test.bdf 中任意空白处双击鼠标左键,将 symbol 对话框中 libraries:project 下的 led1 模块添加到图形文件led_test.bdf 中,加入输入、输出引脚,双击各管脚符号,进行管脚命名。完整的顶层模块原理图如下图所示。选择目标器件并进行引脚锁定。将未使用的管脚设置为三态输入。

 led[7..0]OUTPUTled[7..0]led1inst 3、设置编译选项并编译硬件系统。将 led_test.bdf 设置为顶层实体。对该工程文件进行全程编译处理。若在编译过程中发现错误,则找出并更正错误,直到编译成功为止。

 4、下载硬件设计到目标 FPGA。将产生的 led_test.sof 输出对 FPGA 进行配置。

 5、观察 LED 的状态。

 五、实验程序 //利用连续赋值 assign 语句实现 module led1(led);

 //模块名 led1 output[7:0] led;

  //定义输出端口、 assign led =8"b10101010;

  //输出 0xAA endmodule //利用过程赋值语句实现(暂时已屏蔽)

 /* module led1(led);

 //模块名 led1 output[7:0] led;

  //定义输出端口 reg[7:0] led;

 //定义寄存器 always

  //过程 1,无敏感变量 begin

  led = 8"b10101010;

  //输出 0xAA end endmudule*/

 六、思考题

 写出使用 QuartusII 软件开发工程的完整的流程。

 实验二 流水灯实验

  一、实验目的 通过此实验让用户进一步了解、熟悉和掌握 CPLD/FPGA 开发软件的使用方法及 Verilog HDL 的编程方法。学习简单时序电路的设计和硬件测试。

 二、实验容 本实验的容是建立可用于控制 LED 流水灯的简单硬件电路,要求在SmartSOPC 实验箱上实现 LED1~LED8 发光二极管流水灯显示。

 三、实验原理 1、在 LED1~LED8 引脚上周期性的输出流水数据,如原来输出的数据是 11111100则表示点亮 LED1、LED2,流水一次后,输出的数据应该为 11111000,而此时则应点亮 LED1~LED3 三个 LED 发光二极管,就可以实现 LED 流水灯。为了观察方便,流水速率最好在 2Hz 左右。在 QuickSOPC 核心板上有一个 48MHz 的标准时钟源,该时钟脉冲 Clock 与芯片的 28 管脚相连。为了产生 2Hz 的时钟脉冲,在此调用了一个分频模块(int_div 模块,位于光盘中 EDA_Component 目录下),通过修改分频系数来改变输出频,当分频系数为 24x10^6 时,输出即为 2Hz 的频率信号。

 2、Int_div 分频模块说明:int_div 模块是一个占空比为 50%的任意整数分频器。输入时钟为 clock,输出时钟为 clk_out。其中 F_DIV 为分频系数,分频系数围为1~2^n (n=F_DIV_WIDTH),若要改变分频系数,改变参数F_DIV 和F_DIV_WIDTH到相应围即可。在本例中输入时钟为 48MHz,要得到 2Hz 的信号,所以分频系数为 48x10^6/2=24x10^6;对于分频系数为 24x10^6 的数需要一个 25 位宽的计数器即可。

 四、实验步骤

 1、启动 Quarters II 建立一个空白工程,命名为 led_water.qpf。

 2、新建 Verilog HDL 源程序文件 ledwater.v,输入程序代码并保存,进行综合编译,若在编译中发现错误,则找出并更正错误,直至编译成功为止。

 3、从设计文件中创建模块,由 ledwater.v 生成名为 ledwater.bsf 的模块符号文件。

 4、将光盘中 EDA_Component 目录下的 int_div.bsf 和 int_div.v 拷贝到工程目录。

 5、新建图形设计文件命名为 led_water.bdf 并保存。在空白处双击鼠标左键,分别将 symbol 对话框中 libraries:project 下的 ledwater 和 int_div 模块放在图形文

 件 led_water.bdf 中,加入输入、输出引脚,双击各管脚符号,进行管脚命名。双击 int_div 的参数框,并修改参数,将 F_DIV 的值改为 24000000,F_DIV_WIDTH的值改为 25. 完整的顶层模块原理图如下图所示。

 VCCclockINPUTled[7..0]OUTPUTclk led[7..0]ledwaterinst1F_DIV 24000000F_DIV_WIDTH 25Parameter Valueclock clk_outint_divinst 6、选择目标器件并进行引脚锁定。将未使用的管脚设置为三态输入。

 7、将 led_water.bdf 设置为顶层实体。对该工程文件进行全程编译处理。若在编译过程中发现错误,则找出并更正错误,直到编译成功为止。

 8、将产生的 led_water.sof 输出对 FPGA 进行配置。

 9、更改分频模块(int_div)的分频系数,并重新编译下载,观察流水灯的变化。

 五、实验程序 module ledwater (led,clk);

 //模块名 ledwater output[7:0] led;

 //定义 LED 输出口 input

  clk;

 //定义时钟输入口 reg[8:0]

 led_r;

 //定义输出寄存器 assign led = led_r[7:0];

 //寄存器输出 always (posedge clk)

  //在时钟上升沿触发进程 begin

  led_r <= led_r << 1;

 //是,则输出左移一位

  if(led_r == 9"d0)

  //循环完毕吗?

  led_r <= 9"b111111111;

 //是,则重新赋初值 end endmodule

 六、思考题

 本实验顶层采用了图形输入的方式,若采用文本输入方式,如何编写顶层文件?写出相应程序。

  实验三

 键盘、 LED 发光实验 一、实验目的

 通过此实验让用户进一步了解、熟悉和掌握 CPLD/FPGA 开发软件的使用方法及 Verilog HDL 的编程方法,熟悉以 Verilog HDL 文件为顶层模块的设计。学习和体会分支条件语句 case 的使用方法及 FPGA I/O 口的输出控制。

 二、实验容

 SmartSOPC 实验箱上有 8 个发光二极管 LED1~8 和 8 个按键 KEY1~KEY8。

 本实验的容要求在SmartSOPC实验箱上完成对8个按键KEY1~KEY8进行监控,

 一旦有按键输入判断其键值,并点亮相应的发光二极管,如若 KEY3 按下,则点亮 LED1~LED3 发光二极管。

 三、实验原理 FPGA 的所有 I/O 控制块允许每个 I/O 口引脚单独配置为输出口,不过这种配置是系统自动完成的,一旦该 I/O 口被设置为输入口使用时(如定义 key0 为输入引脚:input key0;)该 I/O 控制模块将直接使三态缓冲区的控制端接地,使得该I/O 口引脚对外呈高阻态,这样该 I/O 口引脚即可用作专用输入引脚。只要正确分配并锁定引脚后,一旦在 KEY1~KEY8 中有按键输入,在检测到键盘输入的情况下,继续判断其键值并做出相应的处理。

 四、实验步骤 1、启动 Quarters II 建立一个空白工程,命名为 keyled.qpf。

 2、新建 Verilog HDL 源程序文件 keyled.v,输入程序代码并保存,进行综合编译,若在编译中发现错误,则找出并更正错误,直至编译成功为止。

 3、选择目标器件并进行引脚锁定。将未使用的管脚设置为三态输入。

 4、对该工程文件进行全程编译处理。若在编译过程中发现错误,则找出并更正错误,直到编译成功为止。

 5、将产生的 keyled.sof 输出对 FPGA 进行配置。按下不同按键观察 LED 发光管的状态。

 五、实验程序

 module keyled(key,led);

 //模块名 keyled input[7:0]

 key;

  //定义键盘输入口 output[7:0] led;

  //定义发光管输出口 reg[7:0] led_r;

  //定义寄存器 reg[7:0] buffer_r;

 assign led = led_r;

  //输出键值

 always(key)

 //过程 1 begin

 buffer_r = key;

  //读取键值

 case(buffer_r)

  8"b11111110:led_r = 8"b11111110; //是键 KEY1,则给寄存器赋值 0xfe

  8"b11111101:led_r = 8"b11111100; //是键 KEY2,则给寄存器赋值 0xfc

  8"b11111011:led_r = 8"b11111000; //是键 KEY3,则给寄存器赋值 0xf8

 8"b11110111:led_r = 8"b11110000; //是键 KEY4,则给寄存器赋值 0xf0

  8"b11101111:led_r = 8"b11100000; //是键 KEY5,则给寄存器赋值 0xe0

  8"b11011111:led_r = 8"b11000000; //是键 KEY6,则给寄存器赋值 0xc0

  8"b10111111:led_r = 8"b10000000; //是键 KEY7,则给寄存器赋值 0x80

  8"b01111111:led_r = 8"b00000000; //是键 KEY8,则给寄存器赋值 0x00

  default: led_r = 8"b11111111; //否则给寄存器赋值 0xff

 endcase end endmodule 六、思考题 能否用 if 语句改写本实验程序?如果能,写出相应程序。

  实验四

 静态数码管显示实验 一、实验目的

 学习 7 段数码管显示译码器的设计,进一步了解、熟悉和掌握 FPGA 开发软件 Quartus II 的使用方法及 Verilog HDL 的编程方法,学习 LPM 兆功能模块的调用。

 二、实验容 SmartSOPC 实验箱上有 2 个 4 位动态共阳极数码管 LED12 和 LED13。其中8 个位码 DIG0~DIG7 和 8 位段码 SEG0~SEG7 分别与 FPGA 相应的引脚相连。这样,只要 DIG0~DIG7 上一直输出低电平“0”,则 8 个数码管将显示相同的数码(因为 8 个 LED 数码管的段码线分别接到了同一引脚上),这样 8 位动态的 LED数码管就变成了静态的 LED。

 本实验的容是建立 7 段译码显示模块,用于控制 LED 数码管的静态显示。要求在 SmartSOPC 实验箱上的数码管依次显示 0~9 和 A~F16 个字符。

 三、实验原理 数码管 LED 显示是工程项目中使用较广的一种输出显示器件。常见的数码管有共阴和共阳 2 种。共阴数码管是将 8 个发光二极管的阴极连接在一起作为公共端,而共阳数码管是将 8 个发光二极管的阳极连接在一起作为公共端。公共端常被称作位码,而将其他的 8 位称作段码。数码管有 8 个段分别为:h、g、f、e、d、c、b 和 a(h 为小数点),只要公共端为高电平“1”,某个段输出低电平“0”则相应的段就亮。

 本实验通过分频模块 int_div 分频得到 1Hz 的频率信号,加载于 4 位计数器的时钟输入端,计数循环输出 0~9、A~F16 个数。最后通过七段译码模块译码后在数码管上显示出来。

 四、实验步骤

 1、启动 Quarters II 建立一个空白工程,命名为 sled.qpf。

 2、新建 Verilog HDL 源程序文件 decl7s.v,输入程序代码并保存,进行综合编译,若在编译中发现错误,则找出并更正错误,直至编译成功为止。

 3、从设计文件中创建模块,由 decl7s.v 生成名为 decl7s.bsf 的模块符号文件。

 4、将光盘中 EDA_Component 目录下的 int_div.bsf 和 int_div.v 拷贝到工程目录。

 5、添加 4 位计数器兆功能模块。

 6、新建图形设计文件命名为 sled.bdf 并保存。在空白处双击鼠标左键,分别将symbol 对话框中 libraries:project 下的 counter、decl7s 和 int_div 模块放在图形文件 sled.bdf 中,在 symbol 对话框中 Name:输入 gnd,添加 gnd 符号。加入输入、输出引脚,双击各管脚符号,进行管脚命名。双击 int_div 的参数框,并修改参数,将 F_DIV 的值改为 48000000,F_DIV_WIDTH 的值改为 26。完整的顶层模块原理图如下图所示。

 VCCclockINPUTseg[7..0]OUTPUTdig[7..0]OUTPUTup counterclockq[3..0]counterinstd[3..0] seg[7..0]decl7sinst1GNDF_DIV 48000000F_DIV_WIDTH 26Parameter Valueclock clk_outint_divinst2数码管位码输出数码管段码输出 7、选择目标器件并进行引脚锁定。将未使用的管脚设置为三态输入。

 8、将 sled.bdf 设置为顶层实体。对该工程文件进行全程编译处理。若在编译过程中发现错误,则找出并更正错误,直到编译成功为止。

 9、将产生的 sled.sof 输出对 FPGA 进行配置。观察 LED 显示状态。

 五、实验程序 module decl7s(d,seg);

  //模块名 decl7s input[3:0] d;

  //输入 4 位二进制码 output[7:0] seg;

 //七段译码输出 reg[7:0] seg_r;

  //定义数码管输出寄存器

 assign seg = seg_r;

 //输出数码管译码结果

  always (d) begin

 case(d)

 //七段译码

  4"h0:seg_r = 8"hc0;

 //显示 0

  4"h1:seg_r = 8"hf9;

 //显示 1

  4"h2:seg_r = 8"ha4;

 //显示 2

  4"h3:seg_r = 8"hb0;

 //显示 3

  4"h4:seg_r = 8"h99;

 //显示 4

  4"h5:seg_r = 8"h92;

 //显示 5

  4"h6:seg_r = 8"h82;

 //显示 6

  4"h7:seg_r = 8"hf8;

 //显示 7

  4"h8:seg_r = 8"h80;

 //显示 8

  4"h9:seg_r = 8"h90;

 //显示 9

  4"ha:seg_r = 8"h88;

 //显示 a

  4"hb:seg_r = 8"h83;

 //显示 b

  4"hc:seg_r = 8"hc6;

 //显示 c

  4"hd:seg_r = 8"ha1;

 //显示 d

  4"he:seg_r = 8"h86;

 //显示 e

  4"hf:seg_r = 8"h8e;

 //显示 f

 endcase end endmodule 六、思考题 1.本实验采用的是共阳极数码管,若采用共阴极数码管,有什么不同?

 2.如何显示 HHHHHHHH 和 PPPPPPPP?

 实验五

 动态数码管显示实验 一、实验目的

 学习动态扫描显示的原理及电路的设计。

 二、实验容

 本实验的容是建立数码管动态扫描显示模块,具体容如下:

 1、在 SmartSOPC 实验箱上完成 LED 数码管的动态显示“1~8”8 个数字; 2、放慢扫描速度演示动态显示的原理过程。

 三、实验原理

 一个 FPGA 的片子如果带动多个(比如说 8 个)数码管,选用静态显示的话,管脚很容易不够用,于是大多采用动态显示的方式。本次采用共阳极的数码管,其中每个数码管的 8 个段:h、g、f、e、d、c、b 和 a(h 为小数点)都分别连接到 SEG0~SEG7,8 个数码管分别由 8 个选通信号 DIG0~DIG7 来选择。被选通的数码管显示数据,其余关闭。如果在某一时刻 DIG2 为低电平“0” ,其余选通信号为高电平“1” ,这时仅 DIG2 对应的数码管显示来自段码信号端的数据,其余 7 个数码管呈现关闭状态。根据这种电路状态,如果希望 8 个数码管显示希望的数据,就必须使得 8 个选通信号 DIG0~DIG7 分别被单独选通,并在此同时,在段信号输入口加上希望在该对应数码管上显示的数据,于是随着选通信号的扫描就能实现扫描显示的目的。虽然每次只有一个 LED 显示,但只要扫描显示速率足够快,由于人的视觉余辉效应,使我们仍会感觉所有的数码管都在同时显示。

 四、实验步骤

 1、启动 Quarters II 建立一个空白工程,命名为 dled.qpf。

 2、新建 Verilog HDL 源程序文件 scan_led.v,输入程序代码并保存,进行综合编

 译,若在编译中发现错误,则找出并更正错误,直至编译成功为止。

 3、从设计文件中创建模块,由 scan_led.v 生成名为 scan_led.bsf 的模块符号文件。

 4、将光盘中 EDA_Component 目录下的 int_div.bsf 和 int_div.v 拷贝到工程目录。

 5、添加常量兆功能模块。

 6、新建图形设计文件命名为 dled.bdf 并保存。在空白处双击鼠标左键,分别将symbol 对话框中 libraries:project 下的 constant、scan_led 和 int_div 模块放在图形文件 dled.bdf 中,加入输入、输出引脚,双击各管脚符号,进行管脚命名。双击 int_div 的参数框,并修改参数,将 F_DIV 的值改为 48000,F_DIV_WIDTH的值改为 16。完整的顶层模块原理图如下图所示。

 VCCclockINPUTdig[7..0]OUTPUTseg[7..0]OUTPUT30541989632constantinst1clk_1kd[31..0]dig[7..0]seg[7..0]scan_ledinst2F_DIV 48000F_DIV_WIDTH 16Parameter Valueclock clk_outint_divinst 7、选择目标器件并进行引脚锁定。将未使用的管脚设置为三态输入。

 8、将 dled.bdf 设置为顶层实体。对该工程文件进行全程编译处理。若在编译过程中发现错误,则找出并更正错误,直到编译成功为止。

 9、将产生的 sled.sof 输出对 FPGA 进行配置。观察 LED 数码管上的数字是否为“12345678” ,然后把分频模块的参数改为 F_DIV:24000000,F_DIV_WIDTH:25,再重新编译下载,观察这次 LED 数码管上的显示数据,可以看到数据“12345678”动起来了,这正是动态扫描的方法和过程。

 五、实验程序

 module scan_led(clk_1k,d,dig,seg);

 //模块名 scan_led input clk_1k;

  //输入时钟 input[31:0] d;

  //输入要显示的数据 output[7:0] dig;

 //数码管选择输出引脚 output[7:0] seg;

 //数码管段输出引脚

 reg[7:0] seg_r;

  //定义数码管输出寄存器 reg[7:0] dig_r;

  //定义数码管选择输出寄存器

 reg[3:0] disp_dat;

 //定义显示数据寄存器 reg[2:0]count;

  //定义计数寄存器

 assign dig = dig_r;

 //输出数码管选择 assign seg = seg_r;

 //输出数码管译码结果

  always (posedge clk_1k)

 //定义上升沿触发进程 begin

 count <= count + 1"b1; end

 always (posedge clk_1k)

 begin

 case(count)

 //选择扫描显示数据

  3"d0:disp_dat = d[31:28];

 //第一个数码管

  3"d1:disp_dat = d[27:24];

 //第二个数码管

  3"d2:disp_dat = d[23:20];

 //第三个数码管

  3"d3:disp_dat = d[19:16];

 //第四个数码管

  3"d4:disp_dat = d[15:12];

 //第五个数码管

  3"d5:disp_dat = d[11:8];

 //第六个数码管

  3"d6:disp_dat = d[7:4];

  //第七个数码管

  3"d7:disp_dat = d[3:0];

  //第八个数码管

 endcase

 case(count)

 //选择数码管显示位

  3"d0:dig_r = 8"b01111111;

 //选择第一个数码管显示

  3"d1:dig_r = 8"b10111111;

 //选择第二个数码管显示

  3"d2:dig_r = 8"b11011111;

 //选择第三个数码管显示

  3"d3:dig_r = 8"b11101111;

 //选择第四个数码管显示

  3"d4:dig_r = 8"b11110111;

 //选择第五个数码管显示

  3"d5:dig_r = 8"b11111011;

 //选择第六个数码管显示

  3"d6:dig_r = 8"b11111101;

 //选择第七个数码管显示

  3"d7:dig_r = 8"b11111110;

 //选择第八个数码管显示

 endcase

 end

 always (disp_dat) begin

 case(disp_dat)

 //七段译码

 4"h0:seg_r = 8"hc0;

 //显示 0

  4"h1:seg_r = 8"hf9;

 //显示 1

  4"h2:seg_r = 8"ha4;

 //显示 2

  4"h3:seg_r = 8"hb0;

 //显示 3

  4"h4:seg_r = 8"h99;

 //显示 4

  4"h5:seg_r = 8"h92;

 //显示 5

  4"h6:seg_r = 8"h82;

 //显示 6

  4"h7:seg_r = 8"hf8;

 //显示 7

  4"h8:seg_r = 8"h80;

 //显示 8

  4"h9:seg_r = 8"h90;

 //显示 9

  4"ha:seg_r = 8"h88;

 //显示 a

  4"hb:seg_r = 8"h83;

 //显示 b

  4"hc:seg_r = 8"hc6;

 //显示 c

  4"hd:seg_r = 8"ha1;

 //显示 d

  4"he:seg_r = 8"h86;

 //显示 e

  4"hf:seg_r = 8"h8e;

 //显示 f

 endcase end endmodule 六、思考题

 说出数码管动态显示的原理。

  实验六

 按键去抖动实验 一、实验目的

 学习按键去抖动电路的硬件设计。

 二、实验容 本实验的容是建立按键消抖模块。通过 SmartSOPC 实验箱上的按键 KEY1(经过消抖)或 KEY2(没有消抖)控制数码管显示数字。对比有加消抖和没有加消抖模块电路的区别。

 三、实验原理 作为机械开关的键盘,在按键操作时,由于机械触点的弹性及电压突跳等原因,在触点闭合或开启的瞬间会出现电压抖动,实际应用中如果不进行处理将会造成误触发。

 由于这里是低电平表示按键按下,所以按键去抖动的关键在于提取稳定的低电平状态,虑除前沿、后沿抖动毛刺。对于一个按键信号,可以用一个脉冲对他进行取样,如果连续三次取样为低电平,可以认为信号已经处于键稳定状态,这时输出一个低电平按键信号。继续取样的过程中如果不能满足连续三次取样为低,则认为键稳定状态结束,这时输出变为高电平。一通道的消抖电路原理图如下:

 CLRNDPRNQDFFinstCLRNDPRNQDFFinst1CLRNDPRNQDFFinst2VCCkey_inINPUTVCCclockINPUTkey_outOUTPUTOR3inst3

 四、实验步骤 1、启动 Quarters II 建立一个空白工程,命名为 key_debounce.qpf。

 2、将上图所示消抖电路用 Verilog HDL 语言描述出来,并拓展多个通道。新建Verilog HDL 源程序文件 debounce.v,输入程序代码并保存,进行综合编译,若在编译中发现错误,则找出并更正错误,直至编译成功为止。

 3、从设计文件中创建模块,由 debounce.v 生成名为 debounce.bsf 的模块符号文件。

 4、将光盘中 EDA_Component 目录下的 int_div.bsf 和 int_div.v 拷贝到工程目录。

 5、添加 4 位计数器兆功能模块。

 6、新建图形设计文件命名为 key_debounce.bdf 并保存。在空白处双击鼠标左键,分别将 symbol 对话框中 libraries:project 下的 counter、debounce、decl7s 和int_div模块放在图形文件 debounce.bsf 中,在symbol对话框中 Name:输入gnd,添加 gnd 符号,输入 and2,添加与门。加入输入、输出引脚,双击各管脚符号,进行管脚命名。双击 int_div 的参数框,并修改参数,将 F_DIV 的值改为 240000,F_DIV_WIDTH 的值改为 18。完整的顶层模块原理图如下图所示。

 VCCclockINPUTVCCkey1INPUTVCCkey2INPUTseg[7..0]OUTPUTdig[7..0]OUTPUTF_DIV 240000F_DIV_WIDTH 18Parameter Valueclock clk_outint_divinstKEY_WIDTH 1Parameter Valueclkkey_in[KEY_WIDTH-1..0]key_out[KEY_WIDTH-1..0]debounceinst1AND2inst2up counterclockq[3..0]counterinst3d[3..0] seg[7..0]decl7sinst4GND数码管位码输出数码管段码输出i 消抖后的信号输出 7、选择目标器件并进行引脚锁定。将未使用的管脚设置为三态输入。

 8、将 key_debounce.bdf 设置为顶层实体。对该工程文件进行全程编译处理。若在编译过程中发现错误,则找出并更正错误,直到编译成功为止。

 9、将产生的 key_debounce.sof 输出对 FPGA 进行配置。分别连续按 KEY1 或KEY2 观察数码管显示状态,看数值是否连续递增,比较前后两次操作有何不同。

  五、实验程序 module debounce(clk,key_in,key_out);

 //按键消抖模块 input clk;

 //系统时钟输入 input[KEY_WIDTH-1:0] key_in;

  //外部按键输入 output[KEY_WIDTH-1:0]key_out;

 //按键消抖输出 reg[KEY_WIDTH-1:0]dout1,dout2,dout3; //寄存器

  parameter KEY_WIDTH = 8;

 //参数

 assign key_out = (dout1 | dout2 | dout3); //按键消抖输出

 always (posedge clk) begin

 dout1 <= key_in;

 dout2 <= dout1;

 dout3 <= dout2;

 end endmodule

  六、思考题 比较下面两段程序的异同,并画出电路结构图。

 always ( posedge clk) begin

  dout1<=key_in;

 //非阻塞赋值

  dout2<=dout1;

  dout3<=dout2; end

 always ( posedge clk) begin

  dout1<=key_in;

 //阻塞赋值

  dout2<=dout1;

  dout3<=dout2; end

 实验七

 硬件电子琴实验 一、实验目的 学习利用蜂鸣器和按键设计硬件电子琴。

 二、实验容 在 SmartSOPC 实验箱上实现一个简易电子琴。按下 KEY1~KEY7 分别表示中音 DO、RE、MI、FA、SOL、LA、SI;按住 KEY8 再按 KEY1~KEY7 分别表示高音的 DO、RE、MI、FA、SOL、LA、SI。

 三、实验原理 乐曲演奏的原理是:由于组成乐曲的每个音符的频率值(音调)及其持续时间(音长)是乐曲演奏的 2 个基本数据,因此需要控制输出到扬声器的激励信号的频率高低和该频率信号持续的时间。频率的高低决定了音调的高低,而乐曲的简谱与各音名的频率之间也有固定的对应关系。所有不同频率的信号都是从同一基准频率分频而得来的,由于音阶频率多为非整数,而分频系数又不能为小数,故必须将计算的到的分频数进行四舍五入取整,基准频率和分频系数应综合考虑加以选择,从而保证音乐不会走调。如在 48MHz 时钟下,中音 1(对应的频率值为 523.3Hz)的分频系数应该为:48000000/(2*523.3)=0xb327,这样只需对系统时钟进行 45863 次分频即可得到所要的中音 1。至于其他音符,同样可求出对应的分频系数,这样利用程序可以很轻松地得到对应的乐声。

 四、实验步骤 1、在 Quarters II 中建立一个工程项目文件 beep1.qpf。并在该项目下新建 Verilog HDL 源程序文件 beep1.v,输入程序代码并保存,进行综合编译,若在编译中发现错误,则找出并更正错误,直至编译成功为止。

 2、选择目标器件并进行引脚锁定。将未使用的管脚设置为三态输入。

 3、对该工程文件进行全程编译处理。若在编译过程中发现错误,则找出并更正错误,直到编译成功为止。

 4、将产生的 beep1.sof 输出对 FPGA 进行配置。按下按键 KEY1~KEY8 就可以开始使用电子琴来演奏音乐了。

 五、实验程序 module beep1(clk,key,beep,led);

  //模块名称 beep1

 input clk;

 //系统时钟 48MHz

 input[7:0]key;

  //按键输入 output beep;

  //蜂鸣器输出端

 output[7:0]led;

  //LED 输出

 reg beep_r;

 //寄存器 reg[15:0]count,count_end; reg[7:0]key_r;

 always(posedge clk) begin

 count <= count + 1"b1;

 //计数器加 1

  if((count == count_end)&(!(count_end == 16"hffff)))

 begin

  count <= 16"h0;

  //计数器清零

  beep_r <= !beep_r;

 //取反输出信号

 end end

 always (key) begin

 key_r = key;

 //取键值

 case(key_r)

  8"b11111110:count_end = 16"hb327;

 //中音 1 的分频系数值

  8"b11111101:count_end = 16"h9fa0;

 //中音 2 的分频系数值

  8"b11111011:count_end = 16"h8e32;

 //中音 3 的分频系数值

  8"b11110111:count_end = 16"h8637;

 //中音 4 的分频系数值

  8"b11101111:count_end = 16"h7794;

 //中音 5 的分频系数值

  8"b11011111:count_end = 16"h6a88;

 //中音 6 的分频系数值

  8"b10111111:count_end = 16"h5ee8;

 //中音 7 的分频系数值

  8"b01111110:count_end = 16"h59ab;

 //高音 1 的分频系数值

  8"b01111101:count_end = 16"h4fce;

 //高音 2 的分频系数值

  8"b01111011:count_end = 16"h471a;

 //高音 3 的分频系数值

  8"b01110111:count_end = 16"h431c;

 //高音 4 的分频系数值

  8"b01101111:count_end = 16"h3bca;

 //高音 5 的分频系数值

  8"b01011111:count_end = 16"h3544;

 //高音 6 的分频系数值

  8"b00111111:count_end = 16"h2f74;

 //高音 7 的分频系数值

  default:count_end = 16"hffff;

 endcase end

 assign beep =beep_r;

  //输出音乐 assign led =key_r;

 //输出按键状态 endmodule 六、思考题 举例说明产生不同音符的原理。

 实验八

 数字时钟设计 一、实验目的 学习数字时钟的硬件设计。

 二、实验容 在 SmartSOPC 实验箱上完成一个可以计时的数字时钟,其显示时间围是00:00:00~23:59:59,,且该时钟具有暂停计时和清零等功能。

 三、实验原理 一个完整的时钟应由 3 部分组成:秒脉冲发生电路、计数显示部分和时钟调整部分。一个时钟的准确与否主要取决于秒脉冲的精确度。为了保证时钟计时准确我们对系统时钟 48MHz 进行了 48000000 分频,从而得到 1Hz 的秒脉冲。至于显示部分与 LED 数码管原理相同,而校时电路用户可以自由发挥,如定义 3 个按键 keystart、keymon 和 keyadd,分别用于控制时钟的计时开始、调整功能选择和加 1 处理,从而完成对现在时间的调整。本实验的校时电路在此仅仅完成了

 暂停、清零等基本功能。

 四、实验步骤 1、在 Quarters II 中建立一个工程项目文件 clock.qpf。并在该项目下新建 Verilog HDL 源程序文件 clock.v,输入程序代码并保存,进行综合编译,若在编译中发现错误,则找出并更正错误,直至编译成功为止。

 2、选择目标器件并进行引脚锁定。将未使用的管脚设置为三态输入。

 3、对该工程文件进行全程编译处理。若在编译过程中发现错误,则找出并更正错误,直到编译成功为止。

 4、将产生的 clock.sof 输出对 FPGA 进行配置。观察数码管的显示状态。按下按键 KEY1、KEY2 观察数字钟上的时间有什么变化。

 五、实验程序 module clock(clk,key,dig,seg);

 //模块名 clock input clk;

  //输入时钟 input[1:0] key;

 //输入按键 output[7:0] dig;

  //数码管选择输出引脚 output[7:0] seg;

  //数码管段输出引脚

 reg[7:0] seg_r;

 //定义数码管输出寄存器 reg[7:0] dig_r;

 //定义数码管选择输出寄存器 reg[3:0] disp_dat;

  //定义显示数据寄存器 reg[24:0]count;

 //定义计数寄存器 reg[23:0]hour;

 //定义现在时刻寄存器 reg sec,keyen;

 //定义标志位 reg[1:0]dout1,dout2,dout3;

  //寄存器 wire[1:0]key_done;

  //按键消抖输出

 assign dig = dig_r;

  //输出数码管选择 assign seg = seg_r;

  //输出数码管译码结果

  //秒信号产生部分 always (posedge clk)

 //定义 clock 上升沿触发 begin

 count = count + 1"b1;

 if(count == 25"d24000000)

 //0.5S 到了吗?

 begin

  count = 25"d0;

 //计数器清零

 sec = ~sec;

  //置位秒标志

 end end

 //按键消抖处理部分 assign key_done = (dout1 | dout2 | dout3); //按键消抖输出

 always (posedge count[17]) begin

 dout1 <= key;

 dout2 <= dout1;

 dout3 <= dout2;

 end

 always (negedge key_done[0]) begin

 keyen = ~keyen;

  //将琴键开关转换为乒乓开关 end

 //数码管动态扫描显示部分 always (posedge clk)

 //count[17:15]大约 1ms 改变一次 begin

 case(count[17:15])

 //选择扫描显示数据

  3"d0:disp_dat = hour[3:0];

  //秒个位

  3"d1:disp_dat = hour[7:4];

  //秒十位

  3"d2:disp_dat = 4"ha;

 //显示"-"

  3"d3:disp_dat = hour[11:8];

  //分个位

  3"d4:disp_dat = hour[15:12];

 //分十位

  3"d5:disp_dat = 4"ha;

 //显示"-"

  3"d6:disp_dat = hour[19:16];

 //时个位

  3"d7:disp_dat = hour[23:20];

 //时十位

 endcase

 case(count[17:15])

 //选择数码管显示位

  3"d0:dig_r = 8"b11111110;

  //选择第一个数码管显示

  3"d1:dig_r = 8"b11111101;

  //选择第二个数码管显示

  3"d2:dig_r = 8"b11111011;

  //选择第三个数码管显示

  3"d3:dig_r = 8"b11110111;

  //选择第四个数码管显示

  3"d4:dig_r = 8"b11101111;

  //选择第五个数码管显示

 3"d5:dig_r = 8"b11011111;

  //选择第六个数码管显示

  3"d6:dig_r = 8"b10111111;

  //选择第七个数码管显示

  3"d7:dig_r = 8"b01111111;

  //选择第八个数码管显示

 endcase

 end

 always (posedge clk) begin

 case(disp_dat)

  4"h0:seg_r = 8"hc0;

  //显示 0

  4"h1:seg_r = 8"hf9;

  //显示 1

  4"h2:seg_r = 8"ha4;

  //显示 2

  4"h3:seg_r = 8"hb0;

  //显示 3

  4"h4:seg_r = 8"h99;

  //显示 4

  4"h5:seg_r = 8"h92;

  //显示 5

  4"h6:seg_r = 8"h82;

  //显示 6

  4"h7:seg_r = 8"hf8;

  //显示 7

  4"h8:seg_r = 8"h80;

  //显示 8

  4"h9:seg_r = 8"h90;

  //显示 9

  4"ha:seg_r = 8"hbf;

  //显示-

  default:seg_r = 8"hff;

 //不显示

 endcase

 if((count[17:15]== 3"d2)&sec)

  seg_r = 8"hff; end

 //计时处理部分 always (negedge sec or negedge key_done[1])//计时处理 begin

 if(!key_done[1])

 //是清零键吗?

 begin

  hour = 24"h0;

 //是,则清零

 end

 else if(!keyen)

 begin

  hour[3:0] = hour[3:0] + 1"b1;

 //秒加 1

  if(hour[3:0] == 4"ha)

  begin

  hour[3:0] = 4"h0;

 hour[7:4] = hour[7:4] + 1"b1; //秒的十位加一

 if(hour[7:4] == 4"h6)

 begin

  hour[7:4] = 4"h0;

  hour[11:8] = hour[11:8] + 1"b1;//分个位加一

  if(hour[11:8] == 4"ha)

  begin

 hour[11:8] = 4"h0;

 hour[15:12] = hour[15:12] + 1"b1;//分十位加一

 if(hour[15:12] == 4"h6)

 begin

  hour[15:12] = 4"h0;

  hour[19:16] = hour[19:16] + 1"b1;//时个位加一

  if(hour[19:16] == 4"ha)

  begin

 hour[19:16] = 4"h0;

 hour[23:20] = hour[23:20] + 1"b1;//时十位加一

  end

  if(hour[23:16] == 8"h24)

 hour[23:16] = 8"h0;

 end

  end

 end

  end

 end end endmodule 六、思考题 1. 自己动手添加校时程序,写出相应程序。

推荐访问:实验 报告 技术

热门排行Top Ranking

弦振动实验报告

弦振动得研究 一、实验目得 1、观察固定均匀弦振动共振干涉形成驻波时得波形,加深驻波得认识。 2、了

宣传委员述职报告12020 幼儿园党支部宣传委员述职报告

下面是小编为大家精心整理的宣传委员述职报告12020幼儿园党支部宣传委员述职报告文章,供大家阅读参考。宣传委员述

党建工作现场述职会上讲话 公安局长在党建工作现场会上的讲话

下面是小编为大家精心整理的党建工作现场述职会上讲话公安局长在党建工作现场会上的讲话文章,供大家阅读参考。党建工作现场

支部宣传委员述职述廉报告范例 幼儿园党支部宣传委员述职报告

下面是小编为大家精心整理的支部宣传委员述职述廉报告范例幼儿园党支部宣传委员述职报告文章,供大家阅读参考。支部宣传

政治生态评估报告5篇

可能会捆绑住经办人员的手脚,不利于业务工作的开展。致使个别中层干部主体责任压力传导出现能量损耗;个别

2021年领导述职报告合集2020 县领导述职报告

下面是小编为大家精心整理的2021年领导述职报告合集2020县领导述职报告文章,供大家阅读参考。2

工商局监察室主任述职述廉报告

工商局监察室主任述职述廉报告 第一篇:工商局监察室主任述职述廉报告 我叫haoword,中共党员,现

党支部书记个人述职报告 对村党支部书记述职报告的点评

下面是小编为大家精心整理的党支部书记个人述职报告对村党支部书记述职报告的点评文章,供大家阅读参考。党支部书记个人

财务分析课程报告4篇

财务分析课程报告4篇财务分析课程报告篇1一年来,在领导和同事们的的支持帮助和指导下,加上自身的不断努

结合乡村振兴战略人才工作述职报告 乡村振兴工作员年度述职

下面是小编为大家精心整理的结合乡村振兴战略人才工作述职报告乡村振兴工作员年度述职文章,供大家阅读参考。结合

个人安全生产履职报告[安全生产述职报告] 党委书记安全生产履职报告

下面是小编为大家精心整理的个人安全生产履职报告[安全生产述职报告]党委书记安全生产履职报告文章,供大家阅读参

企业年度工作总结报告范文13篇

企业年度工作总结报告范文13篇企业年度工作总结报告范文篇1时光飞逝,转眼已经毕业一年了,我顺利地完成