verilog 代码分析与仿真

注意:使用vivado 自带的仿真工具, reg和wire等信号需要赋予初始值

边沿检测

  1. module signal_test(
  2.  
  3. input wire cmos_pclk_i,
  4. input wire cmos_vsync_i
  5.  
  6. );
  7.  
  8. // 上升沿捕获
  9.  
  10. reg [:] vsync_d;
  11. wire vsync_start;
  12. wire vsync_end;
  13. always @(posedge cmos_pclk_i)
  14. begin
  15. vsync_d <= {vsync_d[], cmos_vsync_i};
  16. end
  17.  
  18. assign vsync_start = vsync_d[] && (!vsync_d[]);
  19. assign vsync_end = (!vsync_d[]) && vsync_d[];
  20.  
  21. endmodule
  22.  
  23. /*
  24.  
  25. add_force {/signal_test/cmos_pclk_i} -radix hex {1 0ns} {0 50000ps} -repeat_every 100000ps
  26. add_force {/signal_test/cmos_vsync_i} -radix hex {1 0ns} {0 300ns} {1 700ns}
  27.  
  28. */

仿真结果:

时钟二分频的巧用

  1. //在一定区域内,将时钟cmos_pclk_i 进行二分频
  2. reg byte_flag = ;
  3. always@(posedge cmos_pclk_i)
  4. begin
  5. if(rst)
  6. byte_flag <= ;
  7.  
  8. else if(cmos_href_i) //控制信号,固定区域
  9. byte_flag <= ~byte_flag;
  10.  
  11. else
  12. byte_flag <= ;
  13. end
  14.  
  15. //将byte_flag 延时一拍,从仿真图中才可以看出此处的用意
  16. reg byte_flag_r0 = ;
  17. always@(posedge cmos_pclk_i)
  18. begin
  19. if(rst)
  20. byte_flag_r0 <= ;
  21.  
  22. else
  23. byte_flag_r0 <= byte_flag;
  24. end

仿真结果:

数据采集与数据融合

注意rgb565信号的生成

  1. //接收摄像头的数据,当href为高电平时,采集数据,当为低电平时,用0填充
  2. reg [:] cmos_data_d0 = ;
  3. always@(posedge cmos_pclk_i)
  4. begin
  5. if(rst)
  6. cmos_data_d0 <= 'd0;
  7.  
  8. else if(cmos_href_i)
  9. cmos_data_d0 <= cmos_data_i; //MSB -> LSB
  10.  
  11. else if(~cmos_href_i)
  12. cmos_data_d0 <= 'd0;
  13. end
  14.  
  15. reg [:] rgb565_o = ;
  16. always@(posedge cmos_pclk_i)
  17. begin
  18. if(rst)
  19. rgb565_o <= 'd0;
  20.  
  21. //当href为高电平,byte_flag 为高时候,对rgb565数据进行拼装
  22. else if(cmos_href_i & byte_flag)
  23. rgb565_o <= {cmos_data_d0,cmos_data_i}; //MSB -> LSB
  24.  
  25. else if(~cmos_href_i)
  26. rgb565_o <= 'd0;
  27. end

仿真结果:

成功的将两个数融合在一起,一个是寄存器里面保存的数据,一个是实时的输入数据。

关于像素的输出使能信号的生成

  1. assign vs_o = vsync_d[];
  2. assign hs_o = href_d[];
  3. assign vid_clk_ce = (byte_flag_r0&hs_o)||(!hs_o);

仿真结果:

当hs_o 为高时,摄像头输出有效数据,2个2个一起,每当数据进行更新时,ce信号产生,当输出的是消隐区数据的时候,ce信号一直使能。

  1. module signal_test_1(
  2.  
  3. input wire cmos_pclk_i,
  4. input wire rst,
  5. input wire [:]cmos_data_i,
  6. input wire cmos_href_i,
  7. input wire cmos_vsync_i,
  8. output wire hs_o,
  9. output wire vs_o,
  10. output wire vid_clk_ce
  11.  
  12. );
  13.  
  14. /*parameter[5:0]CMOS_FRAME_WAITCNT = 4'd15;*/
  15.  
  16. // 对行场信号进行边沿检测处理
  17. reg[:]vsync_d = 'b11;
  18. reg[:]href_d = 'b00;
  19. wire vsync_start;
  20. wire vsync_end;
  21. //vs signal deal with.
  22. always@(posedge cmos_pclk_i)
  23. begin
  24. vsync_d <= {vsync_d[],cmos_vsync_i};
  25. href_d <= {href_d[],cmos_href_i};
  26. end
  27. assign vsync_start = vsync_d[]&(!vsync_d[]); //捕捉vsync信号的下降沿
  28. assign vsync_end = (!vsync_d[])&vsync_d[]; //捕捉vsync信号的上升沿
  29.  
  30. /*reg[6:0]cmos_fps = 0;
  31. //frame count.
  32. always@(posedge cmos_pclk_i)
  33. begin
  34. if(rst)
  35. begin
  36. cmos_fps <= 7'd0;
  37. end
  38.  
  39. else if(vsync_start) //每当一场开始的时候,计数器加一,难道是一帧只有一场?
  40. begin
  41. cmos_fps <= cmos_fps + 7'd1;
  42. end
  43.  
  44. //计数到了CMOS_FRAME_WAITCNT时,就保持这个数值不变(15)
  45. else if(cmos_fps >= CMOS_FRAME_WAITCNT)
  46. begin
  47. cmos_fps <= CMOS_FRAME_WAITCNT;
  48. end
  49. end*/
  50.  
  51. //在一定区域内,将时钟cmos_pclk_i 进行二分频
  52. reg byte_flag = ;
  53. always@(posedge cmos_pclk_i)
  54. begin
  55. if(rst)
  56. byte_flag <= ;
  57.  
  58. else if(cmos_href_i) //控制信号,固定区域
  59. byte_flag <= ~byte_flag;
  60.  
  61. else
  62. byte_flag <= ;
  63. end
  64.  
  65. //将byte_flag 延时一拍,从仿真图中才可以看出此处的用意
  66. reg byte_flag_r0 = ;
  67. always@(posedge cmos_pclk_i)
  68. begin
  69. if(rst)
  70. byte_flag_r0 <= ;
  71.  
  72. else
  73. byte_flag_r0 <= byte_flag;
  74. end
  75.  
  76. //接收摄像头的数据,当href为高电平时,采集数据,当为低电平时,用0填充
  77. reg [:] cmos_data_d0 = ;
  78. always@(posedge cmos_pclk_i)
  79. begin
  80. if(rst)
  81. cmos_data_d0 <= 'd0;
  82.  
  83. else if(cmos_href_i)
  84. cmos_data_d0 <= cmos_data_i; //MSB -> LSB
  85.  
  86. else if(~cmos_href_i)
  87. cmos_data_d0 <= 'd0;
  88. end
  89.  
  90. reg [:] rgb565_o = ;
  91. always@(posedge cmos_pclk_i)
  92. begin
  93. if(rst)
  94. rgb565_o <= 'd0;
  95.  
  96. //当href为高电平,byte_flag 为高时候,对rgb565数据进行拼装
  97. else if(cmos_href_i & byte_flag)
  98. rgb565_o <= {cmos_data_d0,cmos_data_i}; //MSB -> LSB
  99.  
  100. else if(~cmos_href_i)
  101. rgb565_o <= 'd0;
  102. end
  103.  
  104. assign vs_o = vsync_d[];
  105. assign hs_o = href_d[];
  106. assign vid_clk_ce = (byte_flag_r0&hs_o)||(!hs_o);
  107.  
  108. /*
  109.  
  110. add_force {/signal_test_1/cmos_pclk_i} -radix hex {1 0ns} {0 50000ps} -repeat_every 100000ps
  111. add_force {/signal_test_1/rst} -radix hex {1 0ns} {0 100ns}
  112. add_force {/signal_test_1/cmos_href_i} -radix hex {0 0ns} {1 500ns} {0 1500ns}
  113. add_force {/signal_test_1/cmos_data_i} -radix hex {0 0ns} {1 500ns} {2 600ns} {3 700ns} {4 800ns} {5 900ns} {6 1000ns}\
  114. {7 1100ns} {8 1200ns} {9 1300ns} {10 1400ns} {0 1500ns}
  115. add_force {/signal_test_1/cmos_vsync_i} -radix hex {1 0ns} {0 300ns} {1 1800ns}
  116.  
  117. */
  118.  
  119. endmodule

源程序与注释:

  1. `timescale 1ns / 1ps
  2. //////////////////////////////////////////////////////////////////////////////////
  3. // Company:
  4. // Engineer:
  5. //
  6. // Create Date: 2018/05/17 13:22:09
  7. // Design Name:
  8. // Module Name: cmos_decode
  9. // Project Name:
  10. // Target Devices:
  11. // Tool Versions:
  12. // Description:
  13. //
  14. // Dependencies:
  15. //
  16. // Revision:
  17. // Revision 0.01 - File Created
  18. // Additional Comments:
  19. //
  20. //////////////////////////////////////////////////////////////////////////////////
  21.  
  22. module cmos_decode(
  23. //system signal.
  24. input cmos_clk_i, //cmos senseor clock.
  25. input rst_n_i, //system reset.active low.
  26. //cmos sensor hardware interface.
  27. input cmos_pclk_i, //input pixel clock.
  28. input cmos_href_i, //input pixel hs signal.
  29. input cmos_vsync_i, //input pixel vs signal.
  30. input[:]cmos_data_i, //data.
  31. output cmos_xclk_o, //output clock to cmos sensor.
  32. //user interface.
  33. output hs_o, //hs signal.
  34. output vs_o, //vs signal.
  35. output reg [:] rgb565_o, //data output
  36. output vid_clk_ce
  37. );
  38.  
  39. parameter[:]CMOS_FRAME_WAITCNT = 'd15;
  40.  
  41. //复位信号延时5个时钟周期
  42. reg[:] rst_n_reg = 'd0;
  43. //reset signal deal with.
  44. always@(posedge cmos_clk_i)
  45. begin
  46. rst_n_reg <= {rst_n_reg[:],rst_n_i};
  47. end
  48.  
  49. // 对行场信号进行边沿检测处理
  50. reg[:]vsync_d;
  51. reg[:]href_d;
  52. wire vsync_start;
  53. wire vsync_end;
  54. //vs signal deal with.
  55. always@(posedge cmos_pclk_i)
  56. begin
  57. vsync_d <= {vsync_d[],cmos_vsync_i};
  58. href_d <= {href_d[],cmos_href_i};
  59. end
  60. assign vsync_start = vsync_d[]&(!vsync_d[]); //捕捉vsync信号的下降沿
  61. assign vsync_end = (!vsync_d[])&vsync_d[]; //捕捉vsync信号的上升沿
  62.  
  63. reg[:]cmos_fps;
  64. //frame count.
  65. always@(posedge cmos_pclk_i)
  66. begin
  67. if(!rst_n_reg[])
  68. begin
  69. cmos_fps <= 'd0;
  70. end
  71.  
  72. else if(vsync_start) //每当一场开始的时候,计数器加一,难道是一帧只有一场?
  73. begin
  74. cmos_fps <= cmos_fps + 'd1;
  75. end
  76.  
  77. //计数到了CMOS_FRAME_WAITCNT时,就保持这个数值不变(15)
  78. else if(cmos_fps >= CMOS_FRAME_WAITCNT)
  79. begin
  80. cmos_fps <= CMOS_FRAME_WAITCNT;
  81. end
  82. end
  83.  
  84. //wait frames and output enable.
  85. reg out_en;
  86. always@(posedge cmos_pclk_i)
  87. begin
  88. if(!rst_n_reg[])
  89. begin
  90. out_en <= 'b0;
  91. end
  92.  
  93. //当计数器达到CMOS_FRAME_WAITCNT(15)时,产生一个使能信号
  94. else if(cmos_fps >= CMOS_FRAME_WAITCNT)
  95. begin
  96. out_en <= 'b1;
  97. end
  98.  
  99. //没有达到条件时候,保持原信号不变
  100. else
  101. begin
  102. out_en <= out_en;
  103. end
  104. end
  105.  
  106. //output data 8bit changed into 16bit in rgb565.
  107. reg [:] cmos_data_d0;
  108. reg [:]cmos_rgb565_d0;
  109. reg byte_flag;
  110. always@(posedge cmos_pclk_i)
  111. begin
  112. if(!rst_n_reg[])
  113. byte_flag <= ;
  114.  
  115. //产生一个标志位,每当href为高 电平时,产生跳变
  116. else if(cmos_href_i)
  117. byte_flag <= ~byte_flag;
  118. else
  119. byte_flag <= ;
  120. end
  121.  
  122. //为什么在这里打一拍
  123. reg byte_flag_r0;
  124. always@(posedge cmos_pclk_i)
  125. begin
  126. if(!rst_n_reg[])
  127. byte_flag_r0 <= ;
  128. else
  129. byte_flag_r0 <= byte_flag;
  130. end
  131.  
  132. //接收摄像头的数据,当href为高电平时,采集数据,当为低电平时,用0填充
  133. always@(posedge cmos_pclk_i)
  134. begin
  135. if(!rst_n_reg[])
  136. cmos_data_d0 <= 'd0;
  137.  
  138. else if(cmos_href_i)
  139. cmos_data_d0 <= cmos_data_i; //MSB -> LSB
  140.  
  141. else if(~cmos_href_i)
  142. cmos_data_d0 <= 'd0;
  143. end
  144.  
  145. //重要的来了
  146. always@(posedge cmos_pclk_i)
  147. begin
  148. if(!rst_n_reg[])
  149. rgb565_o <= 'd0;
  150.  
  151. //当href为高电平,byte_flag 为高时候,对rgb565数据进行拼装
  152. else if(cmos_href_i & byte_flag)
  153. rgb565_o <= {cmos_data_d0,cmos_data_i}; //MSB -> LSB
  154.  
  155. else if(~cmos_href_i)
  156. rgb565_o <= 'd0;
  157. end
  158.  
  159. assign vid_clk_ce = out_en ? (byte_flag_r0&hs_o)||(!hs_o) : 'b0;
  160. assign vs_o = out_en ? vsync_d[] : 'b0;
  161. assign hs_o = out_en ? href_d[] : 'b0;
  162. assign cmos_xclk_o = cmos_clk_i;
  163.  
  164. endmodule

verilog 代码分析与仿真的更多相关文章

  1. 串口接收端verilog代码分析

    串口接收端verilog代码分析 `timescale 1ns / 1ps ////////////////////////////////////////////////////////////// ...

  2. 串口发送端verilog代码分析

    串口发送端verilog代码分析 `timescale 1ns / 1ps ////////////////////////////////////////////////////////////// ...

  3. VGA设计(原理说明。Verilog代码实现,仿真结果)

    各类显示屏的显示原理大部分是利用人眼的视觉暂留效应.比如之前的数码管显示就是设计每个周期内各个小段按顺序显示,来达到显示一个数字的效果. VGA同理,显示屏在显示时是一个像素一个像素地显示,在人眼看来 ...

  4. 学会使用Hdlbits网页版Verilog代码仿真验证平台

    给大家推荐一款网页版的 Verilog代码编辑仿真验证平台,这个平台是国外的一家开源FPGA学习网站,通过“https://hdlbits.01xz.net/wiki/Main_Page” 地址链接进 ...

  5. Verilog代码规范I

    Verilog代码规范I "规范"这问题 "规范"这个富含专业气息的词汇(个人感觉),其实规范这种东西,就是大家都约定熟成的东西,一旦你不遵守这个东西,专业人士 ...

  6. Xilinx Vivado的使用详细介绍(1):创建工程、编写代码、行为仿真

    Xilinx Vivado的使用详细介绍(1):创建工程.编写代码.行为仿真 Author:zhangxianhe 新建工程 打开Vivado软件,直接在欢迎界面点击Create New Projec ...

  7. STM32F103片外运行代码分析

    STM32F103片外运行代码分析 STM32F103有三种启动方式: 1.从片内Flash启动: 2.从片内RAM启动: 3.从片内系统存储器启动,内嵌的自举程序,用于串口IAP. 无法直接在片外N ...

  8. Verilog代码和FPGA硬件的映射关系(一)

    代码和硬件之间的映射关系是一个很奇妙的过程,也展现出人类的智慧.单片机内部的硬件结构都是固定的,无法改变,我们通过代码操作着寄存器的读写,来执行各种复杂的任务.FPGA的硬件结构并不像单片机一样是固定 ...

  9. Verilog代码和FPGA硬件的映射关系(二)

    大家可能会有这样的疑问,我们编写的Verilog代码最终会在FPGA上以怎样的映射关系来实现功能呢?我们以一个最简单的组合逻辑与门为例来向大家说明.RTL代码如下所示: //------------- ...

随机推荐

  1. 无头浏览器phantomJS

    selenium: 有头浏览器的代表(selenium+python也可实现静默运行 引入python的一个包,包叫:虚拟屏幕pyvirtualdisplay) PhantomJS : 无头浏览器的代 ...

  2. 【分布式搜索引擎】Elasticsearch如何部署以及优化查询性能

    一.Elasticsearch生产集群如何部署 (1)es生产集群部署5台机器,若每台机器是6核64G的,那么集群总内存是320G (2)假如我们es集群的日增量数据大概是2000万条,每天日增量数据 ...

  3. Web版记账本开发记录(六)

    经过今天的学习和实践,终于把这个web版的记账系统给做出来了, 虽然是很简单的一个系统,但是自己花费的时间也着实不少. 今天将大部分功能都实现了,接下来就是完善和美化, 接下来会对不足的地方进行改善, ...

  4. 小程序 input 组件内容显示不全(显示的长度不满 input 宽度)问题

    问题:小程序的input组件经常用到,但在使用input组件的时候会出现一种现象:明明设置了input的宽度,但是输入的内容显示的长度范围却怎么都不到一整个input组件的宽度,而且后面没显示的地方无 ...

  5. 漏洞复现——Apache SSI远程命令执行

    漏洞原理:当目标服务器开启了SSI与CGI支持,我们就可以上传shtml文件,利用<!--#exec cmd="id" -->语法执行命令. SSI:SSI(服务器端包 ...

  6. 选择器:first-child与:last-child失效的解决方法

    作为还在努力练习的代码小白来说,有时类名或者ID名太多很容易就会搞混,为此,在练习中会想着借用多样的选择器来设置而不是每一个标签都设一个类名(Id名),在此次练习中使用选择器:first-child与 ...

  7. CloudStack学习-1

    环境准备 实验使用的虚拟机配置 Vmware Workstation 虚拟机系统2个 系统版本:centos6.6 x86_64 内存:4GB 网络:两台机器都是nat 磁盘:装完系统后额外添加个50 ...

  8. Excel中针对IP地址的排序方法

    新建一个辅助排序列,用辅助列来扩展,辅助列公式如下: =TRIM(TEXT(LEFT(SUBSTITUTE(A1,".",REPT(" ",99)),100), ...

  9. 跟随我在oracle学习php(3)

    这次讲一下html中的列表和比较重要的表格 列表分为有序和无序,有序列表与无序列表都是块状元素 <ul>(父标签) 定义无序列表.复合标签(由父标签和子标签组成),不单独出现,用<l ...

  10. 为Linux技术学习推荐看的书籍—《Linux就该这么学》

    成长,是一种经历:经历,是一种人生的体验.人生的意义不在于我们拥有了什么,而在于从中我们体悟了什么.在这短短的三年,却在我的人生中弥足珍贵,在脑海中记忆犹新,在这大学三年里,我从一个莽撞少年成长为一名 ...