verilog 代码分析与仿真

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

边沿检测

module signal_test(

    input wire cmos_pclk_i,
input wire cmos_vsync_i ); // 上升沿捕获 reg [:] vsync_d;
wire vsync_start;
wire vsync_end;
always @(posedge cmos_pclk_i)
begin
vsync_d <= {vsync_d[], cmos_vsync_i};
end assign vsync_start = vsync_d[] && (!vsync_d[]);
assign vsync_end = (!vsync_d[]) && vsync_d[]; endmodule /* add_force {/signal_test/cmos_pclk_i} -radix hex {1 0ns} {0 50000ps} -repeat_every 100000ps
add_force {/signal_test/cmos_vsync_i} -radix hex {1 0ns} {0 300ns} {1 700ns} */

仿真结果:

时钟二分频的巧用

//在一定区域内,将时钟cmos_pclk_i 进行二分频
reg byte_flag = ;
always@(posedge cmos_pclk_i)
begin
if(rst)
byte_flag <= ; else if(cmos_href_i) //控制信号,固定区域
byte_flag <= ~byte_flag; else
byte_flag <= ;
end //将byte_flag 延时一拍,从仿真图中才可以看出此处的用意
reg byte_flag_r0 = ;
always@(posedge cmos_pclk_i)
begin
if(rst)
byte_flag_r0 <= ; else
byte_flag_r0 <= byte_flag;
end

仿真结果:

数据采集与数据融合

注意rgb565信号的生成

//接收摄像头的数据,当href为高电平时,采集数据,当为低电平时,用0填充
reg [:] cmos_data_d0 = ;
always@(posedge cmos_pclk_i)
begin
if(rst)
cmos_data_d0 <= 'd0; else if(cmos_href_i)
cmos_data_d0 <= cmos_data_i; //MSB -> LSB else if(~cmos_href_i)
cmos_data_d0 <= 'd0;
end reg [:] rgb565_o = ;
always@(posedge cmos_pclk_i)
begin
if(rst)
rgb565_o <= 'd0; //当href为高电平,byte_flag 为高时候,对rgb565数据进行拼装
else if(cmos_href_i & byte_flag)
rgb565_o <= {cmos_data_d0,cmos_data_i}; //MSB -> LSB else if(~cmos_href_i)
rgb565_o <= 'd0;
end

仿真结果:

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

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

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

仿真结果:

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

 module signal_test_1(

     input  wire cmos_pclk_i,
input wire rst,
input wire [:]cmos_data_i,
input wire cmos_href_i,
input wire cmos_vsync_i,
output wire hs_o,
output wire vs_o,
output wire vid_clk_ce ); /*parameter[5:0]CMOS_FRAME_WAITCNT = 4'd15;*/ // 对行场信号进行边沿检测处理
reg[:]vsync_d = 'b11;
reg[:]href_d = 'b00;
wire vsync_start;
wire vsync_end;
//vs signal deal with.
always@(posedge cmos_pclk_i)
begin
vsync_d <= {vsync_d[],cmos_vsync_i};
href_d <= {href_d[],cmos_href_i};
end
assign vsync_start = vsync_d[]&(!vsync_d[]); //捕捉vsync信号的下降沿
assign vsync_end = (!vsync_d[])&vsync_d[]; //捕捉vsync信号的上升沿 /*reg[6:0]cmos_fps = 0;
//frame count.
always@(posedge cmos_pclk_i)
begin
if(rst)
begin
cmos_fps <= 7'd0;
end else if(vsync_start) //每当一场开始的时候,计数器加一,难道是一帧只有一场?
begin
cmos_fps <= cmos_fps + 7'd1;
end //计数到了CMOS_FRAME_WAITCNT时,就保持这个数值不变(15)
else if(cmos_fps >= CMOS_FRAME_WAITCNT)
begin
cmos_fps <= CMOS_FRAME_WAITCNT;
end
end*/ //在一定区域内,将时钟cmos_pclk_i 进行二分频
reg byte_flag = ;
always@(posedge cmos_pclk_i)
begin
if(rst)
byte_flag <= ; else if(cmos_href_i) //控制信号,固定区域
byte_flag <= ~byte_flag; else
byte_flag <= ;
end //将byte_flag 延时一拍,从仿真图中才可以看出此处的用意
reg byte_flag_r0 = ;
always@(posedge cmos_pclk_i)
begin
if(rst)
byte_flag_r0 <= ; else
byte_flag_r0 <= byte_flag;
end //接收摄像头的数据,当href为高电平时,采集数据,当为低电平时,用0填充
reg [:] cmos_data_d0 = ;
always@(posedge cmos_pclk_i)
begin
if(rst)
cmos_data_d0 <= 'd0; else if(cmos_href_i)
cmos_data_d0 <= cmos_data_i; //MSB -> LSB else if(~cmos_href_i)
cmos_data_d0 <= 'd0;
end reg [:] rgb565_o = ;
always@(posedge cmos_pclk_i)
begin
if(rst)
rgb565_o <= 'd0; //当href为高电平,byte_flag 为高时候,对rgb565数据进行拼装
else if(cmos_href_i & byte_flag)
rgb565_o <= {cmos_data_d0,cmos_data_i}; //MSB -> LSB else if(~cmos_href_i)
rgb565_o <= 'd0;
end assign vs_o = vsync_d[];
assign hs_o = href_d[];
assign vid_clk_ce = (byte_flag_r0&hs_o)||(!hs_o); /* add_force {/signal_test_1/cmos_pclk_i} -radix hex {1 0ns} {0 50000ps} -repeat_every 100000ps
add_force {/signal_test_1/rst} -radix hex {1 0ns} {0 100ns}
add_force {/signal_test_1/cmos_href_i} -radix hex {0 0ns} {1 500ns} {0 1500ns}
add_force {/signal_test_1/cmos_data_i} -radix hex {0 0ns} {1 500ns} {2 600ns} {3 700ns} {4 800ns} {5 900ns} {6 1000ns}\
{7 1100ns} {8 1200ns} {9 1300ns} {10 1400ns} {0 1500ns}
add_force {/signal_test_1/cmos_vsync_i} -radix hex {1 0ns} {0 300ns} {1 1800ns} */ endmodule

源程序与注释:

 `timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2018/05/17 13:22:09
// Design Name:
// Module Name: cmos_decode
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
////////////////////////////////////////////////////////////////////////////////// module cmos_decode(
//system signal.
input cmos_clk_i, //cmos senseor clock.
input rst_n_i, //system reset.active low.
//cmos sensor hardware interface.
input cmos_pclk_i, //input pixel clock.
input cmos_href_i, //input pixel hs signal.
input cmos_vsync_i, //input pixel vs signal.
input[:]cmos_data_i, //data.
output cmos_xclk_o, //output clock to cmos sensor.
//user interface.
output hs_o, //hs signal.
output vs_o, //vs signal.
output reg [:] rgb565_o, //data output
output vid_clk_ce
); parameter[:]CMOS_FRAME_WAITCNT = 'd15; //复位信号延时5个时钟周期
reg[:] rst_n_reg = 'd0;
//reset signal deal with.
always@(posedge cmos_clk_i)
begin
rst_n_reg <= {rst_n_reg[:],rst_n_i};
end // 对行场信号进行边沿检测处理
reg[:]vsync_d;
reg[:]href_d;
wire vsync_start;
wire vsync_end;
//vs signal deal with.
always@(posedge cmos_pclk_i)
begin
vsync_d <= {vsync_d[],cmos_vsync_i};
href_d <= {href_d[],cmos_href_i};
end
assign vsync_start = vsync_d[]&(!vsync_d[]); //捕捉vsync信号的下降沿
assign vsync_end = (!vsync_d[])&vsync_d[]; //捕捉vsync信号的上升沿 reg[:]cmos_fps;
//frame count.
always@(posedge cmos_pclk_i)
begin
if(!rst_n_reg[])
begin
cmos_fps <= 'd0;
end else if(vsync_start) //每当一场开始的时候,计数器加一,难道是一帧只有一场?
begin
cmos_fps <= cmos_fps + 'd1;
end //计数到了CMOS_FRAME_WAITCNT时,就保持这个数值不变(15)
else if(cmos_fps >= CMOS_FRAME_WAITCNT)
begin
cmos_fps <= CMOS_FRAME_WAITCNT;
end
end //wait frames and output enable.
reg out_en;
always@(posedge cmos_pclk_i)
begin
if(!rst_n_reg[])
begin
out_en <= 'b0;
end //当计数器达到CMOS_FRAME_WAITCNT(15)时,产生一个使能信号
else if(cmos_fps >= CMOS_FRAME_WAITCNT)
begin
out_en <= 'b1;
end //没有达到条件时候,保持原信号不变
else
begin
out_en <= out_en;
end
end //output data 8bit changed into 16bit in rgb565.
reg [:] cmos_data_d0;
reg [:]cmos_rgb565_d0;
reg byte_flag;
always@(posedge cmos_pclk_i)
begin
if(!rst_n_reg[])
byte_flag <= ; //产生一个标志位,每当href为高 电平时,产生跳变
else if(cmos_href_i)
byte_flag <= ~byte_flag;
else
byte_flag <= ;
end //为什么在这里打一拍
reg byte_flag_r0;
always@(posedge cmos_pclk_i)
begin
if(!rst_n_reg[])
byte_flag_r0 <= ;
else
byte_flag_r0 <= byte_flag;
end //接收摄像头的数据,当href为高电平时,采集数据,当为低电平时,用0填充
always@(posedge cmos_pclk_i)
begin
if(!rst_n_reg[])
cmos_data_d0 <= 'd0; else if(cmos_href_i)
cmos_data_d0 <= cmos_data_i; //MSB -> LSB else if(~cmos_href_i)
cmos_data_d0 <= 'd0;
end //重要的来了
always@(posedge cmos_pclk_i)
begin
if(!rst_n_reg[])
rgb565_o <= 'd0; //当href为高电平,byte_flag 为高时候,对rgb565数据进行拼装
else if(cmos_href_i & byte_flag)
rgb565_o <= {cmos_data_d0,cmos_data_i}; //MSB -> LSB else if(~cmos_href_i)
rgb565_o <= 'd0;
end assign vid_clk_ce = out_en ? (byte_flag_r0&hs_o)||(!hs_o) : 'b0;
assign vs_o = out_en ? vsync_d[] : 'b0;
assign hs_o = out_en ? href_d[] : 'b0;
assign cmos_xclk_o = cmos_clk_i; 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. node多项目合一打包

    因为公司的需要,需要将多个项目合并为一个项目,具体要求是:多个项目中的公用部分提取出来,单独维护,业务部分则分别在不同的目录中,而我们的项目配置文件则作为公用部分单独维护,在项目打包的时候遇到一个问题 ...

  2. web中静态资源和动态资源的概念及区别

    1.静态资源和动态资源的概念 简单来说: 静态资源:一般客户端发送请求到web服务器,web服务器从内存在取到相应的文件,返回给客户端,客户端解析并渲染显示出来. 动态资源:一般客户端请求的动态资源, ...

  3. SQL SERVER 查看sql语句性能与执行时间

    [方法一] set statistics profile on set statistics io on set statistics time on go --sql语句 go set statis ...

  4. 【阅读笔记】《C程序员 从校园到职场》第七章 指针和结构体

    原文地址:让你提前认识软件开发(13):指针及结构体的使用 CSDN博客 https://blog.csdn.net/zhouzhaoxiong1227/article/details/2387299 ...

  5. Saiku本地编译运行后Debug调试(十二)

    Saiku源码拉下来在本地编译通过,然后想进行单元测试 发现不知道怎么写测试类了... 幸好有同事大佬的帮助,教了一招哈哈哈哈... 1.将本地编译通过的Saiku打包好(mvn clean inst ...

  6. webApp总结

    有关Meta 基本Meta <!-- 设置缩放 --> <meta name="viewport" content="width=device-widt ...

  7. 2. Net、ASP.Net、C#、VisualStudio之间的关系

    .Net一般指的是.NetFramework 是一个开发和运行环境,是框架, 提供了基础的.Net类.这些类可以被任何一种.Net编程语言调用,.NetFramework还提供了CLR,JIT,GC等 ...

  8. Java语法基础学习DayFourteen(IO)

    一.java.io.FIle类 1.特点 (1)凡是与输入.输出相关的类.接口等都定义在java.io包下. (2)File是一个类,使用构造器创建对象,此对象对应一个文件(.txt .avi .do ...

  9. 2017年4月7日16:18:17 java8 常用记录

    List<String> customerUids = customerTagModel.stream().map(CustomerTagModel::getCustomerUid)   ...

  10. 2019-04-16-day033-锁与队列

    内容回顾 几个问题 概念多,练习少 不问问题 概念?代码? Process类 并发并行 并发 是同一时间段内多个任务交替使用同一个cpu 并行 是在同一个时刻多个任务在不同的cpu上同时执行 同步异步 ...