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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM