博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

verilog 代码分析与仿真

Posted on 2018-05-22 18:12  沉默改良者  阅读(4404)  评论(0编辑  收藏  举报

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