首页 > 其他分享 >手撕MIPI详细版

手撕MIPI详细版

时间:2024-03-12 15:14:13浏览次数:24  
标签:Mipi wire MIPI 详细 Byte Data Alignment Vaild

 

平台: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

 

标签:Mipi,wire,MIPI,详细,Byte,Data,Alignment,Vaild
From: https://www.cnblogs.com/VerweileDoch/p/18068343

相关文章

  • 面试中超详细的HTTP状态码
    一状态码定义 二遵守的规范 200一定是正确。所有异常都不使用200返回码业务逻辑上的错误,有特别的错误码尽量使用4xx,否则使用400。服务器端内部错误,无特别错误码使用500。业务异常时,返回内容使用JSON格式定义error信息。......
  • H265 NALU类型详细解析
    1.H265NALU类型解析F:禁止位,必须为0,表示有效;为1的话表示无效。Type:6-bitsNALType确定NAL的类型,其中VCLNAL和non-VCLNAL各有32类。0-31是vclnal单元;32-63,是非vclnal单元。VCL是指携带编码数据的数据流,而non-VCL则是控制数据流。vclnal单元的类型(0-31)如下表: no......
  • 详细解读Gitlab Runner中SSH到远程服务器的细节
    生成特有的密钥对用windows的命令行生成即可$ssh-keygen-trsa-C"[email protected]"执行如下图:上述命令行中,密钥保存在C:\Users\d211.ssh目录下:把上述公钥拷贝到目标服务器的对应用户目录下比方我们要在目标服务器,用上述私钥,以用户runner的身份登入。那么我们在目标......
  • ModbusTCP协议报文详细分析
    ModbusTCP与ModbusUDP的报文格式是一样的,它们之间的区别其实就是TCP与UDP的区别,因此下面就针对ModbusTCP的协议进行分析,ModbusTCP与ModbusRtu(ModbusASCII)之间的区别如下图:从上图可以看出,ModbusTCP在Modbus串行通信的基础上,去除了校验(由于TCP本身就带有校验和)和设备地址(M......
  • C/C++结构体最详细的讲解
    转载自知乎:https://zhuanlan.zhihu.com/p/6117720311.定义结构体法一(推荐,写法简单)structStudent{stringm_Name;intm_Age;Student()=default;Student(stringname,intage):m_Name(name),age(m_Age){}};一般定义结构体和类时,如果不写关于构造函数的任何东西,结构......
  • CentOS7安装python3详细教程
    1.检查CentOS7自带python环境centos一般自带Python2,先使用python-V来查看python版本建议大家在保留python2的基础上安装一个python3,因为python2和python3还是有一些区别的,同时安装python2和python3的环境,以便不时之需或者对比学习。如果想要删除原有的python环境,可以通过下面......
  • 速存,详细罗列香橙派AIpro外设接口样例大全(附源码)
    本文分享自华为云社区《香橙派AIpro外设接口样例大全(附源码)》,作者:昇腾CANN。OrangePiAIPro开发板是香橙派联合华为精心打造的高性能AI开发板,其搭载了昇腾AI处理器,可提供8TOPSINT8的计算能力,内存提供了8GB和16GB两种版本。可以实现图像、视频等多种数据分析与推理计......
  • HTML开发工具和环境介绍,内附超详细的VS code安装教程!
    工欲善其事必先利其器,一款好的开发工具可以让我们事半功倍。前面我们对HTML的相关概念和基本结构已经有了基本的了解,下面我们就来安装在前端开发中的需要使用的开发工具及环境。在众多HTML编辑器中,选择一个适合自己的工具至关重要。今天我们就来认识一下前端开发工作中使用的最广......
  • Linux `chown` 命令的详细使用说明文档概要
    chown命令在Linux中用于更改文件或目录的所有者和/或所属组。以下是chown命令的详细使用说明文档:chown命令简介chown命令允许系统管理员或文件的所有者更改文件或目录的所有者和/或所属组。这是一个强大的命令,需要谨慎使用,因为不正确的使用可能导致系统安全性或文件访问......
  • 技术干货 | 英码嵌入式IVP92x开发主板上电启动及各模块测试详细教程(附工具)
    IVP92x是一款基于英码嵌入式低照度全彩视频处理模组SOM928设计的开发主板,IVP92x主板具备多路智能视觉分析(目标识别/运动跟踪/周界防范等)能力,支持[email protected]/H.264多码流编解码,同时支持智能降噪、全景拼接以及双目深度处理;除此之外,还设计了丰富的外围接口,满足无人机、智能摄......