• verilog 代码分析与仿真


    verilog 代码分析与仿真

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

    边沿检测

    module signal_test(
    
        input wire cmos_pclk_i,
        input wire cmos_vsync_i
    
        );
    
    
    // 上升沿捕获
    
        reg [1:0] vsync_d;
        wire vsync_start;
        wire vsync_end;
        always @(posedge cmos_pclk_i)
        begin
            vsync_d <= {vsync_d[0], cmos_vsync_i};
        end
    
        assign vsync_start = vsync_d[1] && (!vsync_d[0]);
        assign vsync_end = (!vsync_d[1]) && vsync_d[0];
    
    
    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 = 0;
        always@(posedge cmos_pclk_i)
        begin
            if(rst)
                byte_flag <= 0;
    
            else if(cmos_href_i) //控制信号,固定区域
                byte_flag <= ~byte_flag;
            
            else
                byte_flag <= 0;
        end
    
        //将byte_flag 延时一拍,从仿真图中才可以看出此处的用意
        reg byte_flag_r0 = 0;
        always@(posedge cmos_pclk_i)
        begin
            if(rst)
                byte_flag_r0 <= 0;
    
            else
                byte_flag_r0 <= byte_flag;
        end

    仿真结果:

    数据采集与数据融合

    注意rgb565信号的生成

    //接收摄像头的数据,当href为高电平时,采集数据,当为低电平时,用0填充
        reg [7:0] cmos_data_d0 = 0;
        always@(posedge cmos_pclk_i)
        begin
            if(rst)
                cmos_data_d0 <= 8'd0;
            
            else if(cmos_href_i)
                cmos_data_d0 <= cmos_data_i; //MSB -> LSB
    
            else if(~cmos_href_i)
                cmos_data_d0 <= 8'd0;
        end
    
    
        reg [15:0] rgb565_o = 0;
        always@(posedge cmos_pclk_i)
        begin
            if(rst)
                rgb565_o <= 16'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 <= 8'd0;
        end

    仿真结果:

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

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

    assign vs_o = vsync_d[1];
    assign hs_o = href_d[1];
    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 [7:0]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[1:0]vsync_d = 2'b11;
     18     reg[1:0]href_d = 2'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[0],cmos_vsync_i};
     25         href_d <= {href_d[0],cmos_href_i};
     26     end
     27     assign vsync_start = vsync_d[1]&(!vsync_d[0]);  //捕捉vsync信号的下降沿
     28     assign vsync_end = (!vsync_d[1])&vsync_d[0];    //捕捉vsync信号的上升沿
     29 
     30 
     31     /*reg[6:0]cmos_fps = 0;
     32     //frame count.
     33     always@(posedge cmos_pclk_i)
     34     begin
     35         if(rst)
     36         begin
     37             cmos_fps <= 7'd0;
     38         end
     39 
     40         else if(vsync_start) //每当一场开始的时候,计数器加一,难道是一帧只有一场?
     41         begin
     42             cmos_fps <= cmos_fps + 7'd1;
     43         end
     44         
     45         //计数到了CMOS_FRAME_WAITCNT时,就保持这个数值不变(15)
     46         else if(cmos_fps >= CMOS_FRAME_WAITCNT)
     47         begin
     48             cmos_fps <= CMOS_FRAME_WAITCNT;
     49         end
     50     end*/
     51 
     52 
     53     //在一定区域内,将时钟cmos_pclk_i 进行二分频
     54     reg byte_flag = 0;
     55     always@(posedge cmos_pclk_i)
     56     begin
     57         if(rst)
     58             byte_flag <= 0;
     59 
     60         else if(cmos_href_i) //控制信号,固定区域
     61             byte_flag <= ~byte_flag;
     62         
     63         else
     64             byte_flag <= 0;
     65     end
     66 
     67     //将byte_flag 延时一拍,从仿真图中才可以看出此处的用意
     68     reg byte_flag_r0 = 0;
     69     always@(posedge cmos_pclk_i)
     70     begin
     71         if(rst)
     72             byte_flag_r0 <= 0;
     73 
     74         else
     75             byte_flag_r0 <= byte_flag;
     76     end
     77 
     78     //接收摄像头的数据,当href为高电平时,采集数据,当为低电平时,用0填充
     79     reg [7:0] cmos_data_d0 = 0;
     80     always@(posedge cmos_pclk_i)
     81     begin
     82         if(rst)
     83             cmos_data_d0 <= 8'd0;
     84         
     85         else if(cmos_href_i)
     86             cmos_data_d0 <= cmos_data_i; //MSB -> LSB
     87 
     88         else if(~cmos_href_i)
     89             cmos_data_d0 <= 8'd0;
     90     end
     91 
     92 
     93     reg [15:0] rgb565_o = 0;
     94     always@(posedge cmos_pclk_i)
     95     begin
     96         if(rst)
     97             rgb565_o <= 16'd0;
     98 
     99     //当href为高电平,byte_flag 为高时候,对rgb565数据进行拼装
    100         else if(cmos_href_i & byte_flag)
    101             rgb565_o <= {cmos_data_d0,cmos_data_i};  //MSB -> LSB
    102 
    103         else if(~cmos_href_i)
    104             rgb565_o <= 8'd0;
    105     end
    106 
    107     assign vs_o = vsync_d[1];
    108     assign hs_o = href_d[1];
    109     assign vid_clk_ce = (byte_flag_r0&hs_o)||(!hs_o);
    110 
    111 
    112 
    113 /*
    114 
    115 add_force {/signal_test_1/cmos_pclk_i} -radix hex {1 0ns} {0 50000ps} -repeat_every 100000ps
    116 add_force {/signal_test_1/rst} -radix hex {1 0ns} {0 100ns}
    117 add_force {/signal_test_1/cmos_href_i} -radix hex {0 0ns} {1 500ns} {0 1500ns}
    118 add_force {/signal_test_1/cmos_data_i} -radix hex {0 0ns} {1 500ns} {2 600ns} {3 700ns} {4 800ns} {5 900ns} {6 1000ns}
    119 {7 1100ns} {8 1200ns} {9 1300ns} {10 1400ns} {0 1500ns}
    120 add_force {/signal_test_1/cmos_vsync_i} -radix hex {1 0ns} {0 300ns} {1 1800ns}
    121 
    122 */
    123 
    124 
    125 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 
     23 module cmos_decode(
     24     //system signal.
     25     input cmos_clk_i,                    //cmos senseor clock.
     26     input rst_n_i,                        //system reset.active low.
     27     //cmos sensor hardware interface.
     28     input cmos_pclk_i,                    //input pixel clock.
     29     input cmos_href_i,                    //input pixel hs signal.
     30     input cmos_vsync_i,                    //input pixel vs signal.
     31     input[7:0]cmos_data_i,                //data.
     32     output cmos_xclk_o,                    //output clock to cmos sensor.
     33     //user interface.
     34     output hs_o,                        //hs signal.
     35     output vs_o,                        //vs signal.
     36     output reg [15:0] rgb565_o,            //data output
     37     output vid_clk_ce
     38 );
     39 
     40 
     41     parameter[5:0]CMOS_FRAME_WAITCNT = 4'd15;
     42 
     43     //复位信号延时5个时钟周期
     44     reg[4:0] rst_n_reg = 5'd0;
     45     //reset signal deal with.
     46     always@(posedge cmos_clk_i)
     47     begin
     48         rst_n_reg <= {rst_n_reg[3:0],rst_n_i};
     49     end
     50 
     51 
     52     // 对行场信号进行边沿检测处理
     53     reg[1:0]vsync_d;
     54     reg[1:0]href_d;
     55     wire vsync_start;
     56     wire vsync_end;
     57     //vs signal deal with.
     58     always@(posedge cmos_pclk_i)
     59     begin
     60         vsync_d <= {vsync_d[0],cmos_vsync_i};
     61         href_d <= {href_d[0],cmos_href_i};
     62     end
     63     assign vsync_start = vsync_d[1]&(!vsync_d[0]);  //捕捉vsync信号的下降沿
     64     assign vsync_end = (!vsync_d[1])&vsync_d[0];    //捕捉vsync信号的上升沿
     65 
     66 
     67     reg[6:0]cmos_fps;
     68     //frame count.
     69     always@(posedge cmos_pclk_i)
     70     begin
     71         if(!rst_n_reg[4])
     72         begin
     73             cmos_fps <= 7'd0;
     74         end
     75 
     76         else if(vsync_start) //每当一场开始的时候,计数器加一,难道是一帧只有一场?
     77         begin
     78             cmos_fps <= cmos_fps + 7'd1;
     79         end
     80         
     81         //计数到了CMOS_FRAME_WAITCNT时,就保持这个数值不变(15)
     82         else if(cmos_fps >= CMOS_FRAME_WAITCNT)
     83         begin
     84             cmos_fps <= CMOS_FRAME_WAITCNT;
     85         end
     86     end
     87 
     88 
     89     //wait frames and output enable.
     90     reg out_en;
     91     always@(posedge cmos_pclk_i)
     92     begin
     93         if(!rst_n_reg[4])
     94         begin
     95             out_en <= 1'b0;
     96         end
     97 
     98         //当计数器达到CMOS_FRAME_WAITCNT(15)时,产生一个使能信号
     99         else if(cmos_fps >= CMOS_FRAME_WAITCNT)
    100         begin
    101             out_en <= 1'b1;
    102         end
    103 
    104         //没有达到条件时候,保持原信号不变
    105         else
    106         begin
    107             out_en <= out_en;
    108         end
    109     end
    110 
    111     //output data 8bit changed into 16bit in rgb565.
    112     reg [7:0] cmos_data_d0;
    113     reg [15:0]cmos_rgb565_d0;
    114     reg byte_flag;
    115     always@(posedge cmos_pclk_i)
    116     begin
    117         if(!rst_n_reg[4])
    118             byte_flag <= 0;
    119 
    120         //产生一个标志位,每当href为高    电平时,产生跳变
    121         else if(cmos_href_i)
    122             byte_flag <= ~byte_flag;
    123         else
    124             byte_flag <= 0;
    125     end
    126 
    127     //为什么在这里打一拍
    128     reg byte_flag_r0;
    129     always@(posedge cmos_pclk_i)
    130     begin
    131         if(!rst_n_reg[4])
    132             byte_flag_r0 <= 0;
    133         else
    134             byte_flag_r0 <= byte_flag;
    135     end
    136 
    137     //接收摄像头的数据,当href为高电平时,采集数据,当为低电平时,用0填充
    138     always@(posedge cmos_pclk_i)
    139     begin
    140         if(!rst_n_reg[4])
    141             cmos_data_d0 <= 8'd0;
    142         
    143         else if(cmos_href_i)
    144             cmos_data_d0 <= cmos_data_i; //MSB -> LSB
    145 
    146         else if(~cmos_href_i)
    147             cmos_data_d0 <= 8'd0;
    148     end
    149 
    150     //重要的来了
    151     always@(posedge cmos_pclk_i)
    152     begin
    153         if(!rst_n_reg[4])
    154             rgb565_o <= 16'd0;
    155 
    156     //当href为高电平,byte_flag 为高时候,对rgb565数据进行拼装
    157         else if(cmos_href_i & byte_flag)
    158             rgb565_o <= {cmos_data_d0,cmos_data_i};  //MSB -> LSB
    159 
    160         else if(~cmos_href_i)
    161             rgb565_o <= 8'd0;
    162     end
    163 
    164 
    165     assign vid_clk_ce = out_en ? (byte_flag_r0&hs_o)||(!hs_o) : 1'b0;
    166     assign vs_o = out_en ? vsync_d[1] : 1'b0;
    167     assign hs_o = out_en ? href_d[1] : 1'b0;
    168     assign cmos_xclk_o = cmos_clk_i;
    169 
    170 endmodule
  • 相关阅读:
    redis
    装饰器之functools与before_request
    版本
    git常用命令
    支付宝支付示例
    ContentType
    vue的基础使用
    es6简单介绍
    解析器、路由控制、分页与响应器
    元素水平居中的方法
  • 原文地址:https://www.cnblogs.com/chensimin1990/p/9073395.html
Copyright © 2020-2023  润新知