平台:xilinx A7 75t+ov5640

完整地址:

NoNounknow/OV5640_MIPI_DDR3_HDMI: MIPI格式5640;1080P@30配置;输入无IP手写解析; (github.com)


`timescale 1ns / 1ps
module Mipi_camera_top #(
    Mipi_Lane_Num = 2
)(
    input   wire                          I_Top_Rst_n           ,  
//Mipi CSI            
    input   wire                          I_Mipi_phy_clk_p    ,
    input   wire                          I_Mipi_phy_clk_n    ,
    input   wire    [Mipi_Lane_Num-1:0]   I_Mipi_phy_lane_p   ,
    input   wire    [Mipi_Lane_Num-1:0]   I_Mipi_phy_lane_n   ,
    output  wire    [40-1:0]              O_Mipi_raw10_depacker_Data ,
    output  wire                          O_Mipi_raw10_depacker_Vaild,
    output  wire                          O_Mipi_CSI_Byte_CLK        ,
    output  wire                          O_Mipi_Unpacket_V_sync     
    );

//--------------------------------Port Defination----------------------------------//

    //u_Mipi_dphy_rx
            wire            Mipi_CSI_Byte_CLK          ;
            wire    [7:0]   Mipi_CSI_Byte_Lane0_Data   ;
            wire    [7:0]   Mipi_CSI_Byte_Lane1_Data   ;
    //Mipi_Byte_Alignment
            wire            ReSearch_Offset            ;
        //LANE0
            wire    [7:0]   Mipi_Byte_Alignment_Data_0 ;
            wire            Mipi_Byte_Alignment_Vaild_0;
        //LANE1
            wire    [7:0]   Mipi_Byte_Alignment_Data_1 ;
            wire            Mipi_Byte_Alignment_Vaild_1;
    //Mipi_Lane_Alignment
            wire            ReSearch_Offset_Lane       ;
            wire    [15:0]  Mipi_Lane_Alignment_Data   ;
            wire            Mipi_Lane_Alignment_Vaild  ;
    //Mipi_Unpacket
            wire    [15:0]  Mipi_Unpacket_Data         ;
            wire            Mipi_Unpacket_Vaild        ;
            wire            Mipi_Unpacket_done         ;
            wire            Mipi_Unpacket_V_sync       ;
    //Mipi_raw10_depacker
            wire [40-1:0]   Mipi_raw10_depacker_Data   ;
            wire            Mipi_raw10_depacker_Vaild  ;
    //
            wire            Frame_Begin                ;

//--------------------------------Port Defination----------------------------------//

//--------------------------------Main Code----------------------------------------//

    assign  O_Mipi_raw10_depacker_Data  =  Mipi_raw10_depacker_Data ;
    assign  O_Mipi_raw10_depacker_Vaild =  Mipi_raw10_depacker_Vaild;
    assign  O_Mipi_CSI_Byte_CLK         =  Mipi_CSI_Byte_CLK        ;
    assign  O_Mipi_Unpacket_V_sync      =  Mipi_Unpacket_V_sync     ;
//--------------------------------Main Code----------------------------------------//

//--------------------------------Instance-----------------------------------------//
    Mipi_dphy_rx  Mipi_dphy_rx_Inst0 (
        .Rst_n                       ( I_Top_Rst_n                ),
        .I_Mipi_phy_clk_p            ( I_Mipi_phy_clk_p           ),
        .I_Mipi_phy_clk_n            ( I_Mipi_phy_clk_n           ),
        .I_Mipi_phy_lane_p           ( I_Mipi_phy_lane_p          ),
        .I_Mipi_phy_lane_n           ( I_Mipi_phy_lane_n          ),

        .O_Mipi_CSI_Byte_CLK         ( Mipi_CSI_Byte_CLK          ),
        .O_Mipi_CSI_Byte_Lane0_Data  ( Mipi_CSI_Byte_Lane0_Data   ),
        .O_Mipi_CSI_Byte_Lane1_Data  ( Mipi_CSI_Byte_Lane1_Data   )
    );
    Mipi_Byte_Alignment  Mipi_Byte_Alignment_Inst_0 (
        .I_CLK                        ( Mipi_CSI_Byte_CLK          ),
        .I_Rst_n                      ( I_Top_Rst_n                ),
        .I_Mipi_CSI_Byte_Data         ( Mipi_CSI_Byte_Lane0_Data   ),
        .I_ReSearch_Offset            ( ReSearch_Offset_Lane | Mipi_Unpacket_done ),

        .O_Mipi_Byte_Alignment_Data   ( Mipi_Byte_Alignment_Data_0 ),
        .O_Mipi_Byte_Alignment_Vaild  ( Mipi_Byte_Alignment_Vaild_0)
    );
    Mipi_Byte_Alignment  Mipi_Byte_Alignment_Inst_1 (
        .I_CLK                        ( Mipi_CSI_Byte_CLK          ),
        .I_Rst_n                      ( I_Top_Rst_n                ),
        .I_Mipi_CSI_Byte_Data         ( Mipi_CSI_Byte_Lane1_Data   ),
        .I_ReSearch_Offset            ( ReSearch_Offset_Lane | Mipi_Unpacket_done ),

        .O_Mipi_Byte_Alignment_Data   ( Mipi_Byte_Alignment_Data_1 ),
        .O_Mipi_Byte_Alignment_Vaild  ( Mipi_Byte_Alignment_Vaild_1)
    );
    Mipi_Lane_Alignment  Mipi_Lane_Alignment_Inst0 (
        .I_CLK                          ( Mipi_CSI_Byte_CLK           ),
        .I_Rst_n                        ( I_Top_Rst_n                 ),
        .I_Mipi_Byte_Alignment_Data_0   ( Mipi_Byte_Alignment_Data_0  ),
        .I_Mipi_Byte_Alignment_Vaild_0  ( Mipi_Byte_Alignment_Vaild_0 ),
        .I_Mipi_Byte_Alignment_Data_1   ( Mipi_Byte_Alignment_Data_1  ),
        .I_Mipi_Byte_Alignment_Vaild_1  ( Mipi_Byte_Alignment_Vaild_1 ),
        .I_Mipi_Unpacket_done           ( Mipi_Unpacket_done          ),

        .O_ReSearch_Offset_Lane         ( ReSearch_Offset_Lane        ),
        .O_Mipi_Lane_Alignment_Data     ( Mipi_Lane_Alignment_Data    ),
        .O_Mipi_Lane_Alignment_Vaild    ( Mipi_Lane_Alignment_Vaild   )
    );
    Mipi_Unpacket Mipi_Unpacket_Inst0 (
        .I_CLK                        ( Mipi_CSI_Byte_CLK          ),
        .I_Rst_n                      ( I_Top_Rst_n                ),
        .I_Mipi_Lane_Alignment_Data   ( Mipi_Lane_Alignment_Data   ),
        .I_Mipi_Lane_Alignment_Vaild  ( Mipi_Lane_Alignment_Vaild  ),

        .O_Mipi_Unpacket_done         ( Mipi_Unpacket_done         ),
        .O_Mipi_Unpacket_Data         ( Mipi_Unpacket_Data         ),
        .O_Mipi_Unpacket_Vaild        ( Mipi_Unpacket_Vaild        ),
        .O_Mipi_Unpacket_V_sync       ( Mipi_Unpacket_V_sync       )
    );
    Mipi_raw10_depacker Mipi_raw10_depacker (
        .I_CLK                        ( Mipi_CSI_Byte_CLK          ),
        .I_Rst_n                      ( I_Top_Rst_n                ),
        .I_Mipi_Unpacket_Data         ( Mipi_Unpacket_Data         ),
        .I_Mipi_Unpacket_Vaild        ( Mipi_Unpacket_Vaild        ),
        .I_Mipi_Sync                  ( Mipi_Unpacket_V_sync       ),

        .O_Mipi_raw10_depacker_Data   ( Mipi_raw10_depacker_Data   ),
        .O_Mipi_raw10_depacker_Vaild  ( Mipi_raw10_depacker_Vaild  )
    );
//--------------------------------Instance-----------------------------------------//
endmodule

View Code

(1):dphy:

利用IBUFD实现差分转单端,BUFD实现分频,输入时钟过一次时钟增强,通过ISerdes实现串行转并行,完成dphy;

记得注意Serdes的反转顺序。


`timescale 1ns / 1ps
 module Mipi_dphy_rx #(
    Mipi_Lane_Num = 2
)(
    input   wire            Rst_n                 ,
    //Mipi
    input   wire            I_Mipi_phy_clk_p    ,
    input   wire            I_Mipi_phy_clk_n    ,
    input   wire    [1:0]   I_Mipi_phy_lane_p   ,
    input   wire    [1:0]   I_Mipi_phy_lane_n   ,

    output  wire            O_Mipi_CSI_Byte_CLK        ,//Slow Clk
    output  wire    [7:0]   O_Mipi_CSI_Byte_Lane0_Data ,
    output  wire    [7:0]   O_Mipi_CSI_Byte_Lane1_Data   
    );
            wire            Bufd_CLK             ;
            wire            Bufd_Slow_Clk        ;   
            wire            Buff_Clk             ;
            wire            Buff_Clk_inv         ;
            wire            clock_enable         ;
//clk
    //diff to single:clk     
    IBUFDS
     #(.IOSTANDARD ("LVDS_25"))
     ibufds_clk_inst
     (.I          ( I_Mipi_phy_clk_p ),
      .IB         ( I_Mipi_phy_clk_n ),
      .O          ( Bufd_CLK         ));

    // High Speed BUFIO clock buffer
    BUFIO bufio_inst
     (.O ( Buff_Clk ),
      .I ( Bufd_CLK ));

    // BUFR generates the slow clock
    BUFR
     #(.SIM_DEVICE ("7SERIES"),
       .BUFR_DIVIDE("4"))
     clkout_buf_inst
      (.O    ( Bufd_Slow_Clk    ),
       .CE   ( 1'b1             ),
       .CLR  ( !Rst_n           ),
       .I    ( Bufd_CLK         ));

    assign  O_Mipi_CSI_Byte_CLK = Bufd_Slow_Clk ;//Output Slow Clk
    assign  Buff_Clk_inv        = ~ Buff_Clk    ;
    assign  clock_enable = 1'b1;
//data
    wire     [1:0]  Mipi_IBUFD_Data       ;//Diff data to Single data  
    wire     [1:0]  Mipi_IBUFD_Data_delay ;
    wire     [7:0]  iserdes_q [1:0]       ;
    wire     [1:0]  Bitslip               ;
    assign   Bitslip = 2'b00;
    //lane0
    //diff to single:data
    IBUFDS
      #(.DIFF_TERM  ("FALSE"),             // Differential termination
        .IOSTANDARD ("LVDS_25"))
     ibufds_inst_0
       (.I          ( I_Mipi_phy_lane_p[0]  ),
        .IB         ( I_Mipi_phy_lane_n[0]  ),
        .O          ( Mipi_IBUFD_Data[0]    ));

    assign   Mipi_IBUFD_Data_delay = Mipi_IBUFD_Data;

     ISERDESE2
       # (
         .DATA_RATE         ("DDR"),
         .DATA_WIDTH        (8),
         .INTERFACE_TYPE    ("NETWORKING"), 
         .DYN_CLKDIV_INV_EN ("FALSE"),
         .DYN_CLK_INV_EN    ("FALSE"),
         .NUM_CE            (2),
         .OFB_USED          ("FALSE"),
         .IOBDELAY          ("NONE"),                               // Use input at D to output the data on Q
         .SERDES_MODE       ("MASTER"))
       iserdese2_master_lane0 (
         .Q1                ( iserdes_q [0][7] ),
         .Q2                ( iserdes_q [0][6] ),
         .Q3                ( iserdes_q [0][5] ),
         .Q4                ( iserdes_q [0][4] ),
         .Q5                ( iserdes_q [0][3] ),
         .Q6                ( iserdes_q [0][2] ),
         .Q7                ( iserdes_q [0][1] ),
         .Q8                ( iserdes_q [0][0] ),
         .SHIFTOUT1         ( ),
         .SHIFTOUT2         ( ),
         .BITSLIP           ( Bitslip[0]),                  // 1-bit Invoke Bitslip. This can be used with any DATA_WIDTH, cascaded or not.
                                                            // The amount of BITSLIP is fixed by the DATA_WIDTH selection.
         .CE1               ( clock_enable   ),             // 1-bit Clock enable input
         .CE2               ( clock_enable   ),             // 1-bit Clock enable input
         .CLK               ( Buff_Clk       ),             // Fast source synchronous clock driven by BUFIO
         .CLKB              ( Buff_Clk_inv   ),             // Locally inverted fast 
         .CLKDIV            ( Bufd_Slow_Clk  ),             // Slow clock from BUFR.
         .CLKDIVP           ( 1'b0    ),
         .D                 ( Mipi_IBUFD_Data_delay[0]),    // 1-bit Input signal from IOB 
         .DDLY              ( 1'b0   ),                     // 1-bit Input from Input Delay component 
         .RST               ( !Rst_n ),                     // 1-bit Asynchronous reset only.
         .SHIFTIN1          ( 1'b0   ),
         .SHIFTIN2          ( 1'b0   ),
    // unused connections 
         .DYNCLKDIVSEL      ( 1'b0 ),
         .DYNCLKSEL         ( 1'b0 ),
         .OFB               ( 1'b0 ),
         .OCLK              ( 1'b0 ),
         .OCLKB             ( 1'b0 ),
         .O                 ( ));                                   // unregistered output of ISERDESE1
   
    //lane1 
    IBUFDS
      #(.DIFF_TERM  ("FALSE"),             // Differential termination
        .IOSTANDARD ("LVDS_25"))
     ibufds_inst_1
       (.I          ( I_Mipi_phy_lane_p[1] ),
        .IB         ( I_Mipi_phy_lane_n[1] ),
        .O          ( Mipi_IBUFD_Data[1]   ));

     ISERDESE2
       # (
         .DATA_RATE         ("DDR"),
         .DATA_WIDTH        (8),
         .INTERFACE_TYPE    ("NETWORKING"), 
         .DYN_CLKDIV_INV_EN ("FALSE"),
         .DYN_CLK_INV_EN    ("FALSE"),
         .NUM_CE            (2),
         .OFB_USED          ("FALSE"),
         .IOBDELAY          ("NONE"),                               // Use input at D to output the data on Q
         .SERDES_MODE       ("MASTER"))
       iserdese2_master_lane1 (
         .Q1                ( iserdes_q [1][7] ),
         .Q2                ( iserdes_q [1][6] ),
         .Q3                ( iserdes_q [1][5] ),
         .Q4                ( iserdes_q [1][4] ),
         .Q5                ( iserdes_q [1][3] ),
         .Q6                ( iserdes_q [1][2] ),
         .Q7                ( iserdes_q [1][1] ),
         .Q8                ( iserdes_q [1][0] ),
         .SHIFTOUT1         ( ),
         .SHIFTOUT2         ( ),
         .BITSLIP           ( Bitslip[1]),                  // 1-bit Invoke Bitslip. This can be used with any DATA_WIDTH, cascaded or not.
                                                            // The amount of BITSLIP is fixed by the DATA_WIDTH selection.
         .CE1               ( clock_enable   ),             // 1-bit Clock enable input
         .CE2               ( clock_enable   ),             // 1-bit Clock enable input
         .CLK               ( Buff_Clk       ),             // Fast source synchronous clock driven by BUFIO
         .CLKB              ( Buff_Clk_inv   ),             // Locally inverted fast 
         .CLKDIV            ( Bufd_Slow_Clk  ),             // Slow clock from BUFR.
         .CLKDIVP           ( 1'b0    ),
         .D                 ( Mipi_IBUFD_Data_delay[1]),    // 1-bit Input signal from IOB 
         .DDLY              ( 1'b0   ),                      // 1-bit Input from Input Delay component 
         .RST               ( !Rst_n ),                      // 1-bit Asynchronous reset only.
         .SHIFTIN1          ( 1'b0   ),
         .SHIFTIN2          ( 1'b0   ),
    // unused connections 
         .DYNCLKDIVSEL      ( 1'b0 ),
         .DYNCLKSEL         ( 1'b0 ),
         .OFB               ( 1'b0 ),
         .OCLK              ( 1'b0 ),
         .OCLKB             ( 1'b0 ),
         .O                 ( ));                                   // unregistered output of ISERDESE1
    
    assign   O_Mipi_CSI_Byte_Lane0_Data = iserdes_q[0];
    assign   O_Mipi_CSI_Byte_Lane1_Data = iserdes_q[1];
endmodule

View Code

(2):Byte_Align:通过寻找SoT完成解析字的对齐;

核心部分:

 搜索解析字和偏移量,此处有多种写法;


    //Search_Byte_Offset
    reg [3:0]   i;
    always @(posedge I_CLK or negedge I_Rst_n) begin
        if(I_Rst_n == 1'b0) begin
            Byte_Offset <= 4'b0;
            Search_Locking <= 1'b0;
        end else if(!ReSearch_delay && I_ReSearch_Offset) begin
            Byte_Offset <= 4'b0;
            Search_Locking <= 1'b0;
        end else if(Search_Locking == 1'b0) begin
            for(i=8'h0;i<8;i=i+1) begin
                if(Concat_Byte_data[(i+1'b1)+:8] == SoT) begin
                    Byte_Offset <= i[2:0] + 1'b1;
                    Search_Locking <= 1'b1;
                end
            end
        end
    end

View Code

 完整代码:


module Mipi_Byte_Alignment (
    input   wire    I_CLK   ,
    input   wire    I_Rst_n ,
    //Mipi_dphy_rx
    input   wire    [7:0]   I_Mipi_CSI_Byte_Data       ,
    output  wire    [7:0]   O_Mipi_Byte_Alignment_Data ,
    output  wire            O_Mipi_Byte_Alignment_Vaild,
    input   wire            I_ReSearch_Offset      
);
//-----------Parameter & Port Define----------------------------------------------------------//
    localparam  SoT = 8'hB8;
            reg    [ 7:0]   r_Byte_data_delay_0   ;
            reg    [ 7:0]   r_Byte_data_delay_1   ;
        //Concat
           wire    [15:0]   Concat_Byte_data   ;
        //Offset  
            reg    [ 3:0]   Byte_Offset        ;  
        //Lock
            reg             ReSearch_delay     ;
            reg             Search_Locking     ;
            reg    [ 7:0]   r_O_Mipi_Byte_Alignment_Data ;
//-----------Parameter & Port Define----------------------------------------------------------//
    
    //delay & Concat
    always @(posedge I_CLK) begin
        {r_Byte_data_delay_0, r_Byte_data_delay_1}  <= {I_Mipi_CSI_Byte_Data, r_Byte_data_delay_0};
    end
    assign  Concat_Byte_data = {r_Byte_data_delay_0,r_Byte_data_delay_1};
    always @(posedge I_CLK) begin
        ReSearch_delay <= {ReSearch_delay,I_ReSearch_Offset};
    end
    
    //O_Mipi_Byte_Alignment_Vaild & Byte_Offset
    assign  O_Mipi_Byte_Alignment_Vaild = Search_Locking;

    //Search_Byte_Offset
    reg [3:0]   i;
    always @(posedge I_CLK or negedge I_Rst_n) begin
        if(I_Rst_n == 1'b0) begin
            Byte_Offset <= 4'b0;
            Search_Locking <= 1'b0;
        end else if(!ReSearch_delay && I_ReSearch_Offset) begin
            Byte_Offset <= 4'b0;
            Search_Locking <= 1'b0;
        end else if(Search_Locking == 1'b0) begin
            for(i=8'h0;i<8;i=i+1) begin
                if(Concat_Byte_data[(i+1'b1)+:8] == SoT) begin
                    Byte_Offset <= i[2:0] + 1'b1;
                    Search_Locking <= 1'b1;
                end
            end
        end
    end

    reg [15:0]  Concat_Byte_data_delay;
    always @(posedge I_CLK) begin
        Concat_Byte_data_delay = Concat_Byte_data;
    end

    assign O_Mipi_Byte_Alignment_Data = r_O_Mipi_Byte_Alignment_Data;

    always @(*) begin
        r_O_Mipi_Byte_Alignment_Data <= Concat_Byte_data_delay[Byte_Offset+:8];
    end
endmodule

View Code

 (3):Lane_Align:完成不同Lane之间的对齐:

拓展:如果此处是4LANE的话需要做出调整,但也只是增加更多通道而已,原理是一致的。

细节:不同Lane之前如果做了等长的PCB处理,此处不应该超过1个时钟周期的延迟,所以如果超过了,及时重新字对齐;

原理:在Byte_Align的模块vaild到来的时候,比较不同模块的vaild先后顺序,完成对齐处理;

代码:


module Mipi_Lane_Alignment (
    input   wire    I_CLK   ,
    input   wire    I_Rst_n ,
    //Byte_Alignment_Data
    input   wire    [7:0]   I_Mipi_Byte_Alignment_Data_0 ,
    input   wire            I_Mipi_Byte_Alignment_Vaild_0,
    input   wire    [7:0]   I_Mipi_Byte_Alignment_Data_1 ,
    input   wire            I_Mipi_Byte_Alignment_Vaild_1,
    input   wire            I_Mipi_Unpacket_done         ,
    //Lane_Alignment_Data
    output  wire    [15:0]  O_Mipi_Lane_Alignment_Data   ,
    output  reg             O_ReSearch_Offset_Lane       ,
    output  wire            O_Mipi_Lane_Alignment_Vaild
);
    //--------------------Port Define-----------------------------------------------//
    localparam Lane0_First = 2'b10;
    localparam Lane1_First = 2'b01;
    localparam Both_timing = 2'b11;
            wire            Vaild_Or    ;   
            wire            Vaild_And   ;
            reg             r_Vaild_Or  ;
           wire             Vaild_Or_Posedge  ;  
            reg             r_Vaild_Or_Posedge;
            reg     [15:0]  r_lane0_data;
            reg     [15:0]  r_lane1_data;
            reg     [ 1:0]  Flag        ;
    //--------------------Port Define-----------------------------------------------//

    //Vaild_Or
    assign  Vaild_And = (I_Mipi_Byte_Alignment_Vaild_0) & ( I_Mipi_Byte_Alignment_Vaild_1);
    assign  Vaild_Or  = (I_Mipi_Byte_Alignment_Vaild_0) | (I_Mipi_Byte_Alignment_Vaild_1);
    assign  Vaild_Or_Posedge = (!r_Vaild_Or) && Vaild_Or;

    always @(posedge I_CLK) begin
        r_Vaild_Or                      <= Vaild_Or        ; 
        r_Vaild_Or_Posedge              <= Vaild_Or_Posedge;
    end

    //Data_in delay
    always @(posedge I_CLK) begin
            r_lane0_data <= {r_lane0_data[7:0], I_Mipi_Byte_Alignment_Data_0};
            r_lane1_data <= {r_lane1_data[7:0], I_Mipi_Byte_Alignment_Data_1};
    end

    always @(posedge I_CLK or negedge I_Rst_n) begin
        if(I_Rst_n == 1'b0) begin
            Flag <= 2'd0;
        end else if(Vaild_Or_Posedge == 1'b1) begin
            Flag <= {I_Mipi_Byte_Alignment_Vaild_0,I_Mipi_Byte_Alignment_Vaild_1};
        end else begin
            Flag <= Flag;
        end
    end

    //O_Mipi_Lane_Alignment_Vaild
    reg             r_O_Mipi_Lane_Alignment_Vaild;
    reg  [15:0]     r_O_Mipi_Lane_Alignment_Data ;

    assign  O_Mipi_Lane_Alignment_Vaild = r_O_Mipi_Lane_Alignment_Vaild;
    assign  O_Mipi_Lane_Alignment_Data  = r_O_Mipi_Lane_Alignment_Data ;

    always @(posedge I_CLK or negedge I_Rst_n) begin
        if(I_Rst_n == 1'b0) begin
            r_O_Mipi_Lane_Alignment_Vaild <= 1'd0;
        end else if(I_Mipi_Unpacket_done == 1'b1) begin
             r_O_Mipi_Lane_Alignment_Vaild <= 1'd0;
        end else if(r_Vaild_Or_Posedge == 1'b1 && Vaild_And == 1'b1) begin
            r_O_Mipi_Lane_Alignment_Vaild <= 1'b1;
        end
    end

    //O_Mipi_Lane_Alignment_Data
    always @(*) begin
            case (Flag)
                Lane0_First:begin
                    r_O_Mipi_Lane_Alignment_Data <= {r_lane1_data[7:0], r_lane0_data[15:8]};
                end 
                Lane1_First:begin
                    r_O_Mipi_Lane_Alignment_Data <= {r_lane1_data[15:8], r_lane0_data[7:0]};
                end 
                Both_timing:begin
                    r_O_Mipi_Lane_Alignment_Data <= {r_lane1_data[15:8],  r_lane0_data[15:8]};
                end
                default: begin
                    r_O_Mipi_Lane_Alignment_Data <= {r_lane1_data[7:0], r_lane0_data[7:0]};
                end
            endcase
    end

    always @(posedge I_CLK or negedge I_Rst_n) begin
        if(I_Rst_n == 'd0) begin
            O_ReSearch_Offset_Lane <= 1'b0;
        end else if(Vaild_Or_Posedge == 1'b1) begin
            O_ReSearch_Offset_Lane <= 1'b0;
        end else if(r_Vaild_Or_Posedge == 1'b1 && Vaild_And == 1'b0) begin
            O_ReSearch_Offset_Lane <= 1'b1;
        end
    end 
endmodule

View Code

(4):Unpaket解包模块:通过ECC校验完成对错误的甄别,

同时如果发现错误,重置前两个模块的解析结果;

ECC:


module ECC_Calculate_Haming #(
    parameter  Data_bit_width      = 24,
    parameter  Redundant_bit_width =  8
)(
    input   wire    [Data_bit_width -1:0]        I_Data        ,
    output  wire    [Redundant_bit_width-1:0]    O_ECC         
);
            reg     [Redundant_bit_width-1:0]    r_O_ECC;     
            assign O_ECC = r_O_ECC;
    always@(*) begin
            r_O_ECC[7] <= 1'b0;
            r_O_ECC[6] <= 1'b0;
            r_O_ECC[5] <= ^{I_Data[10], I_Data[11], I_Data[12], I_Data[13], I_Data[14], I_Data[15], 
                          I_Data[16], I_Data[17], I_Data[18], I_Data[19], I_Data[21], I_Data[22], I_Data[23]};
            r_O_ECC[4] <= ^{I_Data[ 4], I_Data[ 5], I_Data[ 6], I_Data[ 7], I_Data[ 8], I_Data[ 9], 
                          I_Data[16], I_Data[17], I_Data[18], I_Data[19], I_Data[20], I_Data[22], I_Data[23]};
            r_O_ECC[3] <= ^{I_Data[ 1], I_Data[ 2], I_Data[ 3], I_Data[ 7], I_Data[ 8], I_Data[ 9], 
                          I_Data[13], I_Data[14], I_Data[15], I_Data[19], I_Data[20], I_Data[21], I_Data[23]};
            r_O_ECC[2] <= ^{I_Data[ 0], I_Data[ 2], I_Data[ 3], I_Data[ 5], I_Data[ 6], I_Data[ 9], 
                          I_Data[11], I_Data[12], I_Data[15], I_Data[18], I_Data[20], I_Data[21], I_Data[22]};
            r_O_ECC[1] <= ^{I_Data[ 0], I_Data[ 1], I_Data[ 3], I_Data[ 4], I_Data[ 6], I_Data[ 8], 
                          I_Data[10], I_Data[12], I_Data[14], I_Data[17], I_Data[20], I_Data[21], I_Data[22], I_Data[23]};
            r_O_ECC[0] <= ^{I_Data[ 0], I_Data[ 1], I_Data[ 2], I_Data[ 4], I_Data[ 5], I_Data[ 7], 
                          I_Data[10], I_Data[11], I_Data[13], I_Data[16], I_Data[20], I_Data[21], I_Data[22], I_Data[23]};
    end
endmodule

View Code

(5):数据还原模块:将打包数据(分多个通道分发的RAW10数据)还原为原始的RAW10格式,此处是2LANE的情况:


`timescale 1ns / 1ps
module Mipi_camera_top #(
    Mipi_Lane_Num = 2
)(
    input   wire                          I_Top_Rst_n           ,  
//Mipi CSI            
    input   wire                          I_Mipi_phy_clk_p    ,
    input   wire                          I_Mipi_phy_clk_n    ,
    input   wire    [Mipi_Lane_Num-1:0]   I_Mipi_phy_lane_p   ,
    input   wire    [Mipi_Lane_Num-1:0]   I_Mipi_phy_lane_n   ,
    output  wire    [40-1:0]              O_Mipi_raw10_depacker_Data ,
    output  wire                          O_Mipi_raw10_depacker_Vaild,
    output  wire                          O_Mipi_CSI_Byte_CLK        ,
    output  wire                          O_Mipi_Unpacket_V_sync     
    );

//--------------------------------Port Defination----------------------------------//

    //u_Mipi_dphy_rx
            wire            Mipi_CSI_Byte_CLK          ;
            wire    [7:0]   Mipi_CSI_Byte_Lane0_Data   ;
            wire    [7:0]   Mipi_CSI_Byte_Lane1_Data   ;
    //Mipi_Byte_Alignment
            wire            ReSearch_Offset            ;
        //LANE0
            wire    [7:0]   Mipi_Byte_Alignment_Data_0 ;
            wire            Mipi_Byte_Alignment_Vaild_0;
        //LANE1
            wire    [7:0]   Mipi_Byte_Alignment_Data_1 ;
            wire            Mipi_Byte_Alignment_Vaild_1;
    //Mipi_Lane_Alignment
            wire            ReSearch_Offset_Lane       ;
            wire    [15:0]  Mipi_Lane_Alignment_Data   ;
            wire            Mipi_Lane_Alignment_Vaild  ;
    //Mipi_Unpacket
            wire    [15:0]  Mipi_Unpacket_Data         ;
            wire            Mipi_Unpacket_Vaild        ;
            wire            Mipi_Unpacket_done         ;
            wire            Mipi_Unpacket_V_sync       ;
    //Mipi_raw10_depacker
            wire [40-1:0]   Mipi_raw10_depacker_Data   ;
            wire            Mipi_raw10_depacker_Vaild  ;
    //
            wire            Frame_Begin                ;

//--------------------------------Port Defination----------------------------------//

//--------------------------------Main Code----------------------------------------//

    assign  O_Mipi_raw10_depacker_Data  =  Mipi_raw10_depacker_Data ;
    assign  O_Mipi_raw10_depacker_Vaild =  Mipi_raw10_depacker_Vaild;
    assign  O_Mipi_CSI_Byte_CLK         =  Mipi_CSI_Byte_CLK        ;
    assign  O_Mipi_Unpacket_V_sync      =  Mipi_Unpacket_V_sync     ;
//--------------------------------Main Code----------------------------------------//

//--------------------------------Instance-----------------------------------------//
    Mipi_dphy_rx  Mipi_dphy_rx_Inst0 (
        .Rst_n                       ( I_Top_Rst_n                ),
        .I_Mipi_phy_clk_p            ( I_Mipi_phy_clk_p           ),
        .I_Mipi_phy_clk_n            ( I_Mipi_phy_clk_n           ),
        .I_Mipi_phy_lane_p           ( I_Mipi_phy_lane_p          ),
        .I_Mipi_phy_lane_n           ( I_Mipi_phy_lane_n          ),

        .O_Mipi_CSI_Byte_CLK         ( Mipi_CSI_Byte_CLK          ),
        .O_Mipi_CSI_Byte_Lane0_Data  ( Mipi_CSI_Byte_Lane0_Data   ),
        .O_Mipi_CSI_Byte_Lane1_Data  ( Mipi_CSI_Byte_Lane1_Data   )
    );
    Mipi_Byte_Alignment  Mipi_Byte_Alignment_Inst_0 (
        .I_CLK                        ( Mipi_CSI_Byte_CLK          ),
        .I_Rst_n                      ( I_Top_Rst_n                ),
        .I_Mipi_CSI_Byte_Data         ( Mipi_CSI_Byte_Lane0_Data   ),
        .I_ReSearch_Offset            ( ReSearch_Offset_Lane | Mipi_Unpacket_done ),

        .O_Mipi_Byte_Alignment_Data   ( Mipi_Byte_Alignment_Data_0 ),
        .O_Mipi_Byte_Alignment_Vaild  ( Mipi_Byte_Alignment_Vaild_0)
    );
    Mipi_Byte_Alignment  Mipi_Byte_Alignment_Inst_1 (
        .I_CLK                        ( Mipi_CSI_Byte_CLK          ),
        .I_Rst_n                      ( I_Top_Rst_n                ),
        .I_Mipi_CSI_Byte_Data         ( Mipi_CSI_Byte_Lane1_Data   ),
        .I_ReSearch_Offset            ( ReSearch_Offset_Lane | Mipi_Unpacket_done ),

        .O_Mipi_Byte_Alignment_Data   ( Mipi_Byte_Alignment_Data_1 ),
        .O_Mipi_Byte_Alignment_Vaild  ( Mipi_Byte_Alignment_Vaild_1)
    );
    Mipi_Lane_Alignment  Mipi_Lane_Alignment_Inst0 (
        .I_CLK                          ( Mipi_CSI_Byte_CLK           ),
        .I_Rst_n                        ( I_Top_Rst_n                 ),
        .I_Mipi_Byte_Alignment_Data_0   ( Mipi_Byte_Alignment_Data_0  ),
        .I_Mipi_Byte_Alignment_Vaild_0  ( Mipi_Byte_Alignment_Vaild_0 ),
        .I_Mipi_Byte_Alignment_Data_1   ( Mipi_Byte_Alignment_Data_1  ),
        .I_Mipi_Byte_Alignment_Vaild_1  ( Mipi_Byte_Alignment_Vaild_1 ),
        .I_Mipi_Unpacket_done           ( Mipi_Unpacket_done          ),

        .O_ReSearch_Offset_Lane         ( ReSearch_Offset_Lane        ),
        .O_Mipi_Lane_Alignment_Data     ( Mipi_Lane_Alignment_Data    ),
        .O_Mipi_Lane_Alignment_Vaild    ( Mipi_Lane_Alignment_Vaild   )
    );
    Mipi_Unpacket Mipi_Unpacket_Inst0 (
        .I_CLK                        ( Mipi_CSI_Byte_CLK          ),
        .I_Rst_n                      ( I_Top_Rst_n                ),
        .I_Mipi_Lane_Alignment_Data   ( Mipi_Lane_Alignment_Data   ),
        .I_Mipi_Lane_Alignment_Vaild  ( Mipi_Lane_Alignment_Vaild  ),

        .O_Mipi_Unpacket_done         ( Mipi_Unpacket_done         ),
        .O_Mipi_Unpacket_Data         ( Mipi_Unpacket_Data         ),
        .O_Mipi_Unpacket_Vaild        ( Mipi_Unpacket_Vaild        ),
        .O_Mipi_Unpacket_V_sync       ( Mipi_Unpacket_V_sync       )
    );
    Mipi_raw10_depacker Mipi_raw10_depacker (
        .I_CLK                        ( Mipi_CSI_Byte_CLK          ),
        .I_Rst_n                      ( I_Top_Rst_n                ),
        .I_Mipi_Unpacket_Data         ( Mipi_Unpacket_Data         ),
        .I_Mipi_Unpacket_Vaild        ( Mipi_Unpacket_Vaild        ),
        .I_Mipi_Sync                  ( Mipi_Unpacket_V_sync       ),

        .O_Mipi_raw10_depacker_Data   ( Mipi_raw10_depacker_Data   ),
        .O_Mipi_raw10_depacker_Vaild  ( Mipi_raw10_depacker_Vaild  )
    );
//--------------------------------Instance-----------------------------------------//
endmodule

View Code

 

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。