VIVADO仿真的使用之呼吸灯(含工程源码)

(基于 ZYNQ MINI开发板)

本文档实现对设计代码进行仿真,使用VIVADO自身的工具进行仿真,通过本教程学习如何使用VIVADO软件自带仿真功能。 工程新建方法请参考文档《开发软件安装和介绍/VIVADO简介及 软件下新建ZYNQ工程教程》。

一、ZYNQ 工程建立

起始页(或file->Project->New)创建新工程(CreateNew Project)
向导起始页面点击 Next- >
ProjectName(工程名)工程名:fpga_02_breath_led工程路径: (自己选择,不要有中文路径)勾选Create ProjectSubdirectory,点击Next- >
AddSource(添加设计源文件)点击 Next- >
AddExsixtingIP(添加已有的 IP)点击 Next- >
AddConstraints(添加已有约束文件)点击 Next- >
DefaultPart(默认配置,芯片选型)Family->Zynq-7000 Package- >clg400Speed->7010选-1,7020选-27010版本选择目标器件:xc7z010clg400-1  7020版本选择目标器件:xc7z020clg400-2点击 Next- >
NewProjectSummary(新建工程概况)确认工程信息,选型等,点击 Finish 完成

二、呼吸灯的实现

新建verilog文档方法请参考《01fpga开发之最简单的led流水灯》。这里不再重新进行详细说明, 我们新建的文档名:breath_led.v,模块名为breath_led,模块实现4个led的轮流呼吸灯效果。

breath_led.v代码如下(代码不要从这里拷贝,请从对应的demo拷贝,pdf文档拷贝出来格式会发生变化):

  1. module breath_led #
  2. (
  3. parameter CLOCK_FRQ=50000000,//输入时钟频率50M
  4. parameter PWM_FRQ=1000,//PWM频率1K
  5. parameter BREATH_ERIOD=2,//呼吸周期 2S
  6. parameter SET_COMPARE_FRQ=1000,//比较输出频率 1K
  7. parameter PWM_COUNTER_MAX=CLOCK_FRQ/PWM_FRQ,//PWM发生计数最大值
  8. parameter BREATH_COUNTER_MAX=CLOCK_FRQ*BREATH_ERIOD,//呼吸计数最大值
  9. parameter SET_COMPARE_COUNTER_MAX=CLOCK_FRQ/SET_COMPARE_FRQ,//设置的比较计数最大值
  10. parameter COMPARE_VALUE_STEP=PWM_COUNTER_MAX/SET_COMPARE_FRQ//比较值的步长
  11. )
  12. (
  13. input wire clk,
  14. input wire rstn,
  15. output wire [3:0]led
  16. );
  17. reg [31:0]counter_pwm;
  18. reg [31:0]counter_breath;
  19. reg [31:0]counter_compare;
  20. reg [31:0]compare_value;
  21. regpwm_period_clk_view;
  22. reg breath_period_clk_view;
  23. reg compare_period_clk_view;
  24. reg [3:0]led_number;
  25. reg led_breath_view;
  26. reg breath_dir;
  27. reg [3:0]led_reg;
  28. assign led=led_reg;
  29. //led的值输出
  30. always @(posedgeclk)
  31. begin
  32. if(rstn==0)led_reg<=0;
  33. case (led_number)
  34. 8'b000: led_reg[0]<=led_breath_view;
  35. 8'b001: led_reg[1]<=led_breath_view;
  36. 8'b010: led_reg[2]<=led_breath_view;
  37. 8'b011: led_reg[3]<=led_breath_view;
  38. default: led_reg[0]<=led_breath_view;
  39. endcase
  40. end
  41. //pwm
  42. always @(posedgeclk or negedge rstn)
  43. begin
  44. if(rstn==0)
  45. begin
  46. counter_pwm<=0;
  47. pwm_period_clk_view<=0;
  48. end
  49. else
  50. begin
  51. counter_pwm<=counter_pwm+1;
  52. if(counter_pwm<compare_value)led_breath_view<=1;
  53. else led_breath_view<=0;
  54. if(counter_pwm>PWM_COUNTER_MAX-1)
  55. begin
  56. counter_pwm<=0;
  57. pwm_period_clk_view<=~pwm_period_clk_view;
  58. end
  59. end
  60. end
  61. //led输出逻辑
  62. reg [3:0]led_number_state;
  63. always @(posedgeclk or negedge rstn)
  64. begin
  65. if(rstn==0)
  66. begin
  67. led_number=0;
  68. counter_breath<=0;
  69. breath_period_clk_view<=0;
  70. breath_dir<=0;
  71. led_number_state<=0;
  72. end
  73. else
  74. begin
  75. counter_breath<=counter_breath+1;
  76. if(counter_breath>BREATH_COUNTER_MAX-1)
  77. begin
  78. counter_breath<=0;
  79. breath_period_clk_view<=~breath_period_clk_view;
  80. breath_dir<=~breath_dir;
  81. if(breath_dir==1)
  82. begin
  83. case (led_number_state)
  84. 0: begin led_number_state=1;led_number=0; end
  85. 1: begin led_number_state=2;led_number=1; end
  86. 2: begin led_number_state=3;led_number=2; end
  87. 3: begin led_number_state=4;led_number=3; end
  88. 4: begin led_number_state=5;led_number=2; end
  89. 5: begin led_number_state=6;led_number=1; end
  90. 6: begin led_number_state=0;led_number=0; end
  91. default: begin led_number_state=0; led_number=0;end
  92. endcase
  93. end
  94. end
  95. end
  96. end
  97. //呼吸逻辑和向上向下计数逻辑
  98. always @(posedgeclk or negedge rstn)
  99. begin
  100. if(rstn==0)
  101. begin
  102. counter_compare<=0;
  103. compare_period_clk_view<=0;
  104. compare_value<=0;
  105. end
  106. else
  107. begin
  108. counter_compare<=counter_compare+1;
  109. if(counter_compare>SET_COMPARE_COUNTER_MAX-1)
  110. begin
  111. counter_compare<=0;
  112. if(breath_dir==0)
  113. begin
  114. if(compare_value<PWM_COUNTER_MAX)compare_value<=compare_value+COMPARE_VALUE_STEP;
  115. end
  116. else if(breath_dir==1)
  117. begin
  118. if(compare_value>0)compare_value<=compare_value-COMPARE_VALUE_STEP;
  119. end
  120. compare_period_clk_view<=~compare_period_clk_view;
  121. end
  122. end
  123. end
  124. endmodule

代码中,首先顶层参数列表定义了一些参数,比如周期, PWM计数相关参数。然后代 码中,有呼吸周期 产生的代码,有PWM计数代码,有LED切换代码。我们本教程主要是给大 家演示如何使用VIVADO自身仿真工具来进行设计的仿真,代码逻辑不做讲解。接着我们讲解 如何仿真。

三、新建verilog 的testbench文件

我们可以看到,新建了verilog文件breath_led.v之后,Sources文件栏下的simulation sources->sim_1下也出现了breath_led.v文件。新建的设计文件也会被同步到仿 真文件目录。

VIVADO仿真的使用之呼吸灯(含工程源码) - 第1张

我们在simulation soruces右键Add Sources,弹出添加源文件界面,默认勾选Add or Create simulation sources然后点击next- >:

VIVADO仿真的使用之呼吸灯(含工程源码) - 第2张

然后点击Create File弹出新建文件窗口,我们这里默认File Type和File location不变,然后File name填入breath_led_tb,然后点击OK:

VIVADO仿真的使用之呼吸灯(含工程源码) - 第3张

然后点击Finish完成testbench文件添加。最后弹出定义testbench顶层模块名窗口, 这里我们默认不修改,然后点击OK:

VIVADO仿真的使用之呼吸灯(含工程源码) - 第4张

弹出的对话框点击YES:

VIVADO仿真的使用之呼吸灯(含工程源码) - 第5张

最后我们看到sim_1下面我们新建的breath_led_tb.v新建好了。

VIVADO仿真的使用之呼吸灯(含工程源码) - 第6张

我们双击breath_led_tb.v进行编辑。我们先将要进行测试的breath_led模块例化进来,然后编写一系列的信号初始化, 和时钟驱动代码。最终,breath_led_tb.v文件代码如下:

  1. `timescale 1ns / 1ns
  2. module breath_led_tb();
  3. reg clk_reg;
  4. reg rstn_reg;
  5. wire [3:0]led;
  6. wire clk;
  7. wire rstn;
  8. initial begin
  9. clk_reg=0;
  10. rstn_reg=0;
  11. #10
  12. rstn_reg=1;
  13. end
  14. always #1 clk_reg=~clk_reg;
  15. assign rstn=rstn_reg;
  16. assign clk=clk_reg;
  17. breath_led #
  18. (
  19. .CLOCK_FRQ(1000000)
  20. )
  21. breath_led_inst
  22. (
  23. .clk(clk),
  24. .rst_n(rstn),
  25. .led(led)
  26. );
  27. endmodule

我们为了提高仿真验证速度,将时钟信号参数改为100000HZ,通过参数传递的形式修改。如上代码标红的地 方。这种技巧可以在仿真的时候使用,提高开发效率,大大节约时间。

我们设置仿真。首先,我们在工程管理栏的Settings,点击进去。在弹出的设置里面可以进行很多设置,有工程设置, 型号设置,仿真设置等。

VIVADO仿真的使用之呼吸灯(含工程源码) - 第7张

我们点击simulation进去,默认选择Vivado Simulator。然后点击OK退出。

VIVADO仿真的使用之呼吸灯(含工程源码) - 第8张

回到主界面之后,工程管理栏的SIMULATION下面的Run Simulation右键,选择第 一个Run Behavioral Simulation:

VIVADO仿真的使用之呼吸灯(含工程源码) - 第9张

最后,仿真启动。通过上面的控制仿真启停按钮可以开始仿真。点击中间那个右三 角符号启动仿真。

VIVADO仿真的使用之呼吸灯(含工程源码) - 第10张

可以通过拖拽的方式适当重新布局。我们调整窗口,等待运行一段时间。可以看到, 我们的LED信号输出随着时间,流动进行呼吸灯波形输出。

VIVADO仿真的使用之呼吸灯(含工程源码) - 第11张

细心的小伙伴拉动X轴会发现, LED高电平的周期宽度在变化。

VIVADO仿真的使用之呼吸灯(含工程源码) - 第12张

四、综合布局布线生成比特流下载验证效果

绑定管脚和综合布局布线生成比特文件请参考《fpga开发之最简单的led流水灯》文档,这里不再 详细说明。我们绑定管脚如下:

VIVADO仿真的使用之呼吸灯(含工程源码) - 第13张

最后布局布线生成比特文件,下载到开发板,大家可以看到,我们呼吸灯的渐变亮度效果。

本节教程到此结束。如果需要用到第三方modelsim仿真,可以在设置里面更改使用的仿真软件选 项,然后安装modelsim进行仿真。第三方仿真软件使用比VIVADO更加方便,性能更高。第三方的仿 真软件需自己研究,本教程不做讨论。

相关文件下载地址
*该资源需回复评论后下载,马上去发表评论?
©下载资源版权归作者所有;本站所有资源均来源于网络,仅供学习使用,请支持正版!
本文原创,作者:FPGA小白,其版权均为FPGA线上课程平台|最全栈的FPGA学习平台|FPGA工程师认证培训所有。
如需转载,请注明出处:https://z.shaonianxue.cn/9221.html

"愿我的文字能带给您一丝美好"

还没有人赞赏,支持一下

评论

A 为本文作者,G 为游客总数:0
加载中…

提交评论

游客,您好,欢迎参与讨论。

我的购物车

购物车为空

优惠券

没有优惠券