【多通道视频写】+【多通道视频读】+【图像处理】:FPGA实现

包含:图像处理代码、通道输入代码(摄像头,以太网,hdmi)、通道输出代码(以太网,hdmi,可能的pcie)、缓存管理代码

多通道读写总线管理:

多通道的AXI仲裁方法【第三版】:互联状态机 - NoNounknow - 博客园 (cnblogs.com)

多通道的AXI仲裁方法【第二版】:简易仲裁和DMA拓展优化 - NoNounknow - 博客园 (cnblogs.com)

图像处理方法:

  ①:伽马校正:

    伽马校正:FPGA-CSDN博客

    目的:改变图像在人眼中的亮度;

    原理:O_Pixel = (I_Pixel)^(1/Gamma_value)

    实现方法:查找表

    伽马2.2代码:变暗

    
//Curve of Gamma = 2.2
module Curve_Gamma_2P2
(
   input        [7:0]    Pre_Data,
   output    reg    [7:0]    Post_Data
);

always@(*)
begin
    case(Pre_Data)
    8'h00 : Post_Data = 8'h00; 
    8'h01 : Post_Data = 8'h00; 
    8'h02 : Post_Data = 8'h00; 
    8'h03 : Post_Data = 8'h00; 
    8'h04 : Post_Data = 8'h00; 
    8'h05 : Post_Data = 8'h00; 
    8'h06 : Post_Data = 8'h00; 
    8'h07 : Post_Data = 8'h00; 
    8'h08 : Post_Data = 8'h00; 
    8'h09 : Post_Data = 8'h00; 
    8'h0A : Post_Data = 8'h00; 
    8'h0B : Post_Data = 8'h00; 
    8'h0C : Post_Data = 8'h00; 
    8'h0D : Post_Data = 8'h00; 
    8'h0E : Post_Data = 8'h00; 
    8'h0F : Post_Data = 8'h01; 
    8'h10 : Post_Data = 8'h01; 
    8'h11 : Post_Data = 8'h01; 
    8'h12 : Post_Data = 8'h01; 
    8'h13 : Post_Data = 8'h01; 
    8'h14 : Post_Data = 8'h01; 
    8'h15 : Post_Data = 8'h01; 
    8'h16 : Post_Data = 8'h01; 
    8'h17 : Post_Data = 8'h01; 
    8'h18 : Post_Data = 8'h01; 
    8'h19 : Post_Data = 8'h02; 
    8'h1A : Post_Data = 8'h02; 
    8'h1B : Post_Data = 8'h02; 
    8'h1C : Post_Data = 8'h02; 
    8'h1D : Post_Data = 8'h02; 
    8'h1E : Post_Data = 8'h02; 
    8'h1F : Post_Data = 8'h02; 
    8'h20 : Post_Data = 8'h03; 
    8'h21 : Post_Data = 8'h03; 
    8'h22 : Post_Data = 8'h03; 
    8'h23 : Post_Data = 8'h03; 
    8'h24 : Post_Data = 8'h03; 
    8'h25 : Post_Data = 8'h04; 
    8'h26 : Post_Data = 8'h04; 
    8'h27 : Post_Data = 8'h04; 
    8'h28 : Post_Data = 8'h04; 
    8'h29 : Post_Data = 8'h05; 
    8'h2A : Post_Data = 8'h05; 
    8'h2B : Post_Data = 8'h05; 
    8'h2C : Post_Data = 8'h05; 
    8'h2D : Post_Data = 8'h06; 
    8'h2E : Post_Data = 8'h06; 
    8'h2F : Post_Data = 8'h06; 
    8'h30 : Post_Data = 8'h06; 
    8'h31 : Post_Data = 8'h07; 
    8'h32 : Post_Data = 8'h07; 
    8'h33 : Post_Data = 8'h07; 
    8'h34 : Post_Data = 8'h08; 
    8'h35 : Post_Data = 8'h08; 
    8'h36 : Post_Data = 8'h08; 
    8'h37 : Post_Data = 8'h09; 
    8'h38 : Post_Data = 8'h09; 
    8'h39 : Post_Data = 8'h09; 
    8'h3A : Post_Data = 8'h0A; 
    8'h3B : Post_Data = 8'h0A; 
    8'h3C : Post_Data = 8'h0B; 
    8'h3D : Post_Data = 8'h0B; 
    8'h3E : Post_Data = 8'h0B; 
    8'h3F : Post_Data = 8'h0C; 
    8'h40 : Post_Data = 8'h0C; 
    8'h41 : Post_Data = 8'h0D; 
    8'h42 : Post_Data = 8'h0D; 
    8'h43 : Post_Data = 8'h0D; 
    8'h44 : Post_Data = 8'h0E; 
    8'h45 : Post_Data = 8'h0E; 
    8'h46 : Post_Data = 8'h0F; 
    8'h47 : Post_Data = 8'h0F; 
    8'h48 : Post_Data = 8'h10; 
    8'h49 : Post_Data = 8'h10; 
    8'h4A : Post_Data = 8'h11; 
    8'h4B : Post_Data = 8'h11; 
    8'h4C : Post_Data = 8'h12; 
    8'h4D : Post_Data = 8'h12; 
    8'h4E : Post_Data = 8'h13; 
    8'h4F : Post_Data = 8'h13; 
    8'h50 : Post_Data = 8'h14; 
    8'h51 : Post_Data = 8'h14; 
    8'h52 : Post_Data = 8'h15; 
    8'h53 : Post_Data = 8'h16; 
    8'h54 : Post_Data = 8'h16; 
    8'h55 : Post_Data = 8'h17; 
    8'h56 : Post_Data = 8'h17; 
    8'h57 : Post_Data = 8'h18; 
    8'h58 : Post_Data = 8'h19; 
    8'h59 : Post_Data = 8'h19; 
    8'h5A : Post_Data = 8'h1A; 
    8'h5B : Post_Data = 8'h1A; 
    8'h5C : Post_Data = 8'h1B; 
    8'h5D : Post_Data = 8'h1C; 
    8'h5E : Post_Data = 8'h1C; 
    8'h5F : Post_Data = 8'h1D; 
    8'h60 : Post_Data = 8'h1E; 
    8'h61 : Post_Data = 8'h1E; 
    8'h62 : Post_Data = 8'h1F; 
    8'h63 : Post_Data = 8'h20; 
    8'h64 : Post_Data = 8'h21; 
    8'h65 : Post_Data = 8'h21; 
    8'h66 : Post_Data = 8'h22; 
    8'h67 : Post_Data = 8'h23; 
    8'h68 : Post_Data = 8'h23; 
    8'h69 : Post_Data = 8'h24; 
    8'h6A : Post_Data = 8'h25; 
    8'h6B : Post_Data = 8'h26; 
    8'h6C : Post_Data = 8'h27; 
    8'h6D : Post_Data = 8'h27; 
    8'h6E : Post_Data = 8'h28; 
    8'h6F : Post_Data = 8'h29; 
    8'h70 : Post_Data = 8'h2A; 
    8'h71 : Post_Data = 8'h2B; 
    8'h72 : Post_Data = 8'h2B; 
    8'h73 : Post_Data = 8'h2C; 
    8'h74 : Post_Data = 8'h2D; 
    8'h75 : Post_Data = 8'h2E; 
    8'h76 : Post_Data = 8'h2F; 
    8'h77 : Post_Data = 8'h30; 
    8'h78 : Post_Data = 8'h31; 
    8'h79 : Post_Data = 8'h31; 
    8'h7A : Post_Data = 8'h32; 
    8'h7B : Post_Data = 8'h33; 
    8'h7C : Post_Data = 8'h34; 
    8'h7D : Post_Data = 8'h35; 
    8'h7E : Post_Data = 8'h36; 
    8'h7F : Post_Data = 8'h37; 
    8'h80 : Post_Data = 8'h38; 
    8'h81 : Post_Data = 8'h39; 
    8'h82 : Post_Data = 8'h3A; 
    8'h83 : Post_Data = 8'h3B; 
    8'h84 : Post_Data = 8'h3C; 
    8'h85 : Post_Data = 8'h3D; 
    8'h86 : Post_Data = 8'h3E; 
    8'h87 : Post_Data = 8'h3F; 
    8'h88 : Post_Data = 8'h40; 
    8'h89 : Post_Data = 8'h41; 
    8'h8A : Post_Data = 8'h42; 
    8'h8B : Post_Data = 8'h43; 
    8'h8C : Post_Data = 8'h44; 
    8'h8D : Post_Data = 8'h45; 
    8'h8E : Post_Data = 8'h46; 
    8'h8F : Post_Data = 8'h47; 
    8'h90 : Post_Data = 8'h49; 
    8'h91 : Post_Data = 8'h4A; 
    8'h92 : Post_Data = 8'h4B; 
    8'h93 : Post_Data = 8'h4C; 
    8'h94 : Post_Data = 8'h4D; 
    8'h95 : Post_Data = 8'h4E; 
    8'h96 : Post_Data = 8'h4F; 
    8'h97 : Post_Data = 8'h51; 
    8'h98 : Post_Data = 8'h52; 
    8'h99 : Post_Data = 8'h53; 
    8'h9A : Post_Data = 8'h54; 
    8'h9B : Post_Data = 8'h55; 
    8'h9C : Post_Data = 8'h57; 
    8'h9D : Post_Data = 8'h58; 
    8'h9E : Post_Data = 8'h59; 
    8'h9F : Post_Data = 8'h5A; 
    8'hA0 : Post_Data = 8'h5B; 
    8'hA1 : Post_Data = 8'h5D; 
    8'hA2 : Post_Data = 8'h5E; 
    8'hA3 : Post_Data = 8'h5F; 
    8'hA4 : Post_Data = 8'h61; 
    8'hA5 : Post_Data = 8'h62; 
    8'hA6 : Post_Data = 8'h63; 
    8'hA7 : Post_Data = 8'h64; 
    8'hA8 : Post_Data = 8'h66; 
    8'hA9 : Post_Data = 8'h67; 
    8'hAA : Post_Data = 8'h69; 
    8'hAB : Post_Data = 8'h6A; 
    8'hAC : Post_Data = 8'h6B; 
    8'hAD : Post_Data = 8'h6D; 
    8'hAE : Post_Data = 8'h6E; 
    8'hAF : Post_Data = 8'h6F; 
    8'hB0 : Post_Data = 8'h71; 
    8'hB1 : Post_Data = 8'h72; 
    8'hB2 : Post_Data = 8'h74; 
    8'hB3 : Post_Data = 8'h75; 
    8'hB4 : Post_Data = 8'h77; 
    8'hB5 : Post_Data = 8'h78; 
    8'hB6 : Post_Data = 8'h79; 
    8'hB7 : Post_Data = 8'h7B; 
    8'hB8 : Post_Data = 8'h7C; 
    8'hB9 : Post_Data = 8'h7E; 
    8'hBA : Post_Data = 8'h7F; 
    8'hBB : Post_Data = 8'h81; 
    8'hBC : Post_Data = 8'h82; 
    8'hBD : Post_Data = 8'h84; 
    8'hBE : Post_Data = 8'h85; 
    8'hBF : Post_Data = 8'h87; 
    8'hC0 : Post_Data = 8'h89; 
    8'hC1 : Post_Data = 8'h8A; 
    8'hC2 : Post_Data = 8'h8C; 
    8'hC3 : Post_Data = 8'h8D; 
    8'hC4 : Post_Data = 8'h8F; 
    8'hC5 : Post_Data = 8'h91; 
    8'hC6 : Post_Data = 8'h92; 
    8'hC7 : Post_Data = 8'h94; 
    8'hC8 : Post_Data = 8'h95; 
    8'hC9 : Post_Data = 8'h97; 
    8'hCA : Post_Data = 8'h99; 
    8'hCB : Post_Data = 8'h9A; 
    8'hCC : Post_Data = 8'h9C; 
    8'hCD : Post_Data = 8'h9E; 
    8'hCE : Post_Data = 8'h9F; 
    8'hCF : Post_Data = 8'hA1; 
    8'hD0 : Post_Data = 8'hA3; 
    8'hD1 : Post_Data = 8'hA5; 
    8'hD2 : Post_Data = 8'hA6; 
    8'hD3 : Post_Data = 8'hA8; 
    8'hD4 : Post_Data = 8'hAA; 
    8'hD5 : Post_Data = 8'hAC; 
    8'hD6 : Post_Data = 8'hAD; 
    8'hD7 : Post_Data = 8'hAF; 
    8'hD8 : Post_Data = 8'hB1; 
    8'hD9 : Post_Data = 8'hB3; 
    8'hDA : Post_Data = 8'hB5; 
    8'hDB : Post_Data = 8'hB6; 
    8'hDC : Post_Data = 8'hB8; 
    8'hDD : Post_Data = 8'hBA; 
    8'hDE : Post_Data = 8'hBC; 
    8'hDF : Post_Data = 8'hBE; 
    8'hE0 : Post_Data = 8'hC0; 
    8'hE1 : Post_Data = 8'hC2; 
    8'hE2 : Post_Data = 8'hC4; 
    8'hE3 : Post_Data = 8'hC5; 
    8'hE4 : Post_Data = 8'hC7; 
    8'hE5 : Post_Data = 8'hC9; 
    8'hE6 : Post_Data = 8'hCB; 
    8'hE7 : Post_Data = 8'hCD; 
    8'hE8 : Post_Data = 8'hCF; 
    8'hE9 : Post_Data = 8'hD1; 
    8'hEA : Post_Data = 8'hD3; 
    8'hEB : Post_Data = 8'hD5; 
    8'hEC : Post_Data = 8'hD7; 
    8'hED : Post_Data = 8'hD9; 
    8'hEE : Post_Data = 8'hDB; 
    8'hEF : Post_Data = 8'hDD; 
    8'hF0 : Post_Data = 8'hDF; 
    8'hF1 : Post_Data = 8'hE1; 
    8'hF2 : Post_Data = 8'hE3; 
    8'hF3 : Post_Data = 8'hE5; 
    8'hF4 : Post_Data = 8'hE7; 
    8'hF5 : Post_Data = 8'hEA; 
    8'hF6 : Post_Data = 8'hEC; 
    8'hF7 : Post_Data = 8'hEE; 
    8'hF8 : Post_Data = 8'hF0; 
    8'hF9 : Post_Data = 8'hF2; 
    8'hFA : Post_Data = 8'hF4; 
    8'hFB : Post_Data = 8'hF6; 
    8'hFC : Post_Data = 8'hF8; 
    8'hFD : Post_Data = 8'hFB; 
    8'hFE : Post_Data = 8'hFD; 
    8'hFF : Post_Data = 8'hFF; 
    endcase
end

endmodule
View Code

    伽马0.6代码:变亮

    
//Curve of Gamma = 0.6
module Gamma_06_Period
(
   input    wire    [7:0]    Pre_Data    ,
   input    wire            Pre_clk     ,
   input    wire            Pre_Rst_n   ,

   input    wire            Pre_DE      ,
   input    wire            Pre_Vsync   ,
   input    wire            Pre_Hsync   ,

   output   reg             Post_DE     ,
   output   reg             Post_Vsync  ,
   output   reg             Post_Hsync  ,

   output    reg        [7:0]    Post_Data
);

always@(posedge Pre_clk) begin
    Post_DE    <= Pre_DE    ;
    Post_Vsync <= Pre_Vsync ;
    Post_Hsync <= Pre_Hsync ;
end

always@(posedge Pre_clk)
    if(Pre_Rst_n == 1'b0) begin
        Post_Data <= 8'h00;
    end else 
        begin
            case(Pre_Data)
            8'h00 : Post_Data = 8'h00; 
            8'h01 : Post_Data = 8'h09; 
            8'h02 : Post_Data = 8'h0E; 
            8'h03 : Post_Data = 8'h12; 
            8'h04 : Post_Data = 8'h15; 
            8'h05 : Post_Data = 8'h18; 
            8'h06 : Post_Data = 8'h1B; 
            8'h07 : Post_Data = 8'h1D; 
            8'h08 : Post_Data = 8'h20; 
            8'h09 : Post_Data = 8'h22; 
            8'h0A : Post_Data = 8'h25; 
            8'h0B : Post_Data = 8'h27; 
            8'h0C : Post_Data = 8'h29; 
            8'h0D : Post_Data = 8'h2B; 
            8'h0E : Post_Data = 8'h2D; 
            8'h0F : Post_Data = 8'h2F; 
            8'h10 : Post_Data = 8'h30; 
            8'h11 : Post_Data = 8'h32; 
            8'h12 : Post_Data = 8'h34; 
            8'h13 : Post_Data = 8'h36; 
            8'h14 : Post_Data = 8'h37; 
            8'h15 : Post_Data = 8'h39; 
            8'h16 : Post_Data = 8'h3B; 
            8'h17 : Post_Data = 8'h3C; 
            8'h18 : Post_Data = 8'h3E; 
            8'h19 : Post_Data = 8'h3F; 
            8'h1A : Post_Data = 8'h41; 
            8'h1B : Post_Data = 8'h42; 
            8'h1C : Post_Data = 8'h44; 
            8'h1D : Post_Data = 8'h45; 
            8'h1E : Post_Data = 8'h47; 
            8'h1F : Post_Data = 8'h48; 
            8'h20 : Post_Data = 8'h49; 
            8'h21 : Post_Data = 8'h4B; 
            8'h22 : Post_Data = 8'h4C; 
            8'h23 : Post_Data = 8'h4D; 
            8'h24 : Post_Data = 8'h4F; 
            8'h25 : Post_Data = 8'h50; 
            8'h26 : Post_Data = 8'h51; 
            8'h27 : Post_Data = 8'h53; 
            8'h28 : Post_Data = 8'h54; 
            8'h29 : Post_Data = 8'h55; 
            8'h2A : Post_Data = 8'h56; 
            8'h2B : Post_Data = 8'h58; 
            8'h2C : Post_Data = 8'h59; 
            8'h2D : Post_Data = 8'h5A; 
            8'h2E : Post_Data = 8'h5B; 
            8'h2F : Post_Data = 8'h5C; 
            8'h30 : Post_Data = 8'h5E; 
            8'h31 : Post_Data = 8'h5F; 
            8'h32 : Post_Data = 8'h60; 
            8'h33 : Post_Data = 8'h61; 
            8'h34 : Post_Data = 8'h62; 
            8'h35 : Post_Data = 8'h63; 
            8'h36 : Post_Data = 8'h64; 
            8'h37 : Post_Data = 8'h66; 
            8'h38 : Post_Data = 8'h67; 
            8'h39 : Post_Data = 8'h68; 
            8'h3A : Post_Data = 8'h69; 
            8'h3B : Post_Data = 8'h6A; 
            8'h3C : Post_Data = 8'h6B; 
            8'h3D : Post_Data = 8'h6C; 
            8'h3E : Post_Data = 8'h6D; 
            8'h3F : Post_Data = 8'h6E; 
            8'h40 : Post_Data = 8'h6F; 
            8'h41 : Post_Data = 8'h70; 
            8'h42 : Post_Data = 8'h71; 
            8'h43 : Post_Data = 8'h72; 
            8'h44 : Post_Data = 8'h73; 
            8'h45 : Post_Data = 8'h74; 
            8'h46 : Post_Data = 8'h75; 
            8'h47 : Post_Data = 8'h76; 
            8'h48 : Post_Data = 8'h77; 
            8'h49 : Post_Data = 8'h78; 
            8'h4A : Post_Data = 8'h79; 
            8'h4B : Post_Data = 8'h7A; 
            8'h4C : Post_Data = 8'h7B; 
            8'h4D : Post_Data = 8'h7C; 
            8'h4E : Post_Data = 8'h7D; 
            8'h4F : Post_Data = 8'h7E; 
            8'h50 : Post_Data = 8'h7F; 
            8'h51 : Post_Data = 8'h80; 
            8'h52 : Post_Data = 8'h81; 
            8'h53 : Post_Data = 8'h82; 
            8'h54 : Post_Data = 8'h83; 
            8'h55 : Post_Data = 8'h84; 
            8'h56 : Post_Data = 8'h85; 
            8'h57 : Post_Data = 8'h86; 
            8'h58 : Post_Data = 8'h87; 
            8'h59 : Post_Data = 8'h88; 
            8'h5A : Post_Data = 8'h89; 
            8'h5B : Post_Data = 8'h89; 
            8'h5C : Post_Data = 8'h8A; 
            8'h5D : Post_Data = 8'h8B; 
            8'h5E : Post_Data = 8'h8C; 
            8'h5F : Post_Data = 8'h8D; 
            8'h60 : Post_Data = 8'h8E; 
            8'h61 : Post_Data = 8'h8F; 
            8'h62 : Post_Data = 8'h90; 
            8'h63 : Post_Data = 8'h91; 
            8'h64 : Post_Data = 8'h91; 
            8'h65 : Post_Data = 8'h92; 
            8'h66 : Post_Data = 8'h93; 
            8'h67 : Post_Data = 8'h94; 
            8'h68 : Post_Data = 8'h95; 
            8'h69 : Post_Data = 8'h96; 
            8'h6A : Post_Data = 8'h97; 
            8'h6B : Post_Data = 8'h97; 
            8'h6C : Post_Data = 8'h98; 
            8'h6D : Post_Data = 8'h99; 
            8'h6E : Post_Data = 8'h9A; 
            8'h6F : Post_Data = 8'h9B; 
            8'h70 : Post_Data = 8'h9C; 
            8'h71 : Post_Data = 8'h9C; 
            8'h72 : Post_Data = 8'h9D; 
            8'h73 : Post_Data = 8'h9E; 
            8'h74 : Post_Data = 8'h9F; 
            8'h75 : Post_Data = 8'hA0; 
            8'h76 : Post_Data = 8'hA1; 
            8'h77 : Post_Data = 8'hA1; 
            8'h78 : Post_Data = 8'hA2; 
            8'h79 : Post_Data = 8'hA3; 
            8'h7A : Post_Data = 8'hA4; 
            8'h7B : Post_Data = 8'hA5; 
            8'h7C : Post_Data = 8'hA5; 
            8'h7D : Post_Data = 8'hA6; 
            8'h7E : Post_Data = 8'hA7; 
            8'h7F : Post_Data = 8'hA8; 
            8'h80 : Post_Data = 8'hA9; 
            8'h81 : Post_Data = 8'hA9; 
            8'h82 : Post_Data = 8'hAA; 
            8'h83 : Post_Data = 8'hAB; 
            8'h84 : Post_Data = 8'hAC; 
            8'h85 : Post_Data = 8'hAD; 
            8'h86 : Post_Data = 8'hAD; 
            8'h87 : Post_Data = 8'hAE; 
            8'h88 : Post_Data = 8'hAF; 
            8'h89 : Post_Data = 8'hB0; 
            8'h8A : Post_Data = 8'hB0; 
            8'h8B : Post_Data = 8'hB1; 
            8'h8C : Post_Data = 8'hB2; 
            8'h8D : Post_Data = 8'hB3; 
            8'h8E : Post_Data = 8'hB3; 
            8'h8F : Post_Data = 8'hB4; 
            8'h90 : Post_Data = 8'hB5; 
            8'h91 : Post_Data = 8'hB6; 
            8'h92 : Post_Data = 8'hB6; 
            8'h93 : Post_Data = 8'hB7; 
            8'h94 : Post_Data = 8'hB8; 
            8'h95 : Post_Data = 8'hB9; 
            8'h96 : Post_Data = 8'hB9; 
            8'h97 : Post_Data = 8'hBA; 
            8'h98 : Post_Data = 8'hBB; 
            8'h99 : Post_Data = 8'hBC; 
            8'h9A : Post_Data = 8'hBC; 
            8'h9B : Post_Data = 8'hBD; 
            8'h9C : Post_Data = 8'hBE; 
            8'h9D : Post_Data = 8'hBF; 
            8'h9E : Post_Data = 8'hBF; 
            8'h9F : Post_Data = 8'hC0; 
            8'hA0 : Post_Data = 8'hC1; 
            8'hA1 : Post_Data = 8'hC2; 
            8'hA2 : Post_Data = 8'hC2; 
            8'hA3 : Post_Data = 8'hC3; 
            8'hA4 : Post_Data = 8'hC4; 
            8'hA5 : Post_Data = 8'hC4; 
            8'hA6 : Post_Data = 8'hC5; 
            8'hA7 : Post_Data = 8'hC6; 
            8'hA8 : Post_Data = 8'hC7; 
            8'hA9 : Post_Data = 8'hC7; 
            8'hAA : Post_Data = 8'hC8; 
            8'hAB : Post_Data = 8'hC9; 
            8'hAC : Post_Data = 8'hC9; 
            8'hAD : Post_Data = 8'hCA; 
            8'hAE : Post_Data = 8'hCB; 
            8'hAF : Post_Data = 8'hCB; 
            8'hB0 : Post_Data = 8'hCC; 
            8'hB1 : Post_Data = 8'hCD; 
            8'hB2 : Post_Data = 8'hCE; 
            8'hB3 : Post_Data = 8'hCE; 
            8'hB4 : Post_Data = 8'hCF; 
            8'hB5 : Post_Data = 8'hD0; 
            8'hB6 : Post_Data = 8'hD0; 
            8'hB7 : Post_Data = 8'hD1; 
            8'hB8 : Post_Data = 8'hD2; 
            8'hB9 : Post_Data = 8'hD2; 
            8'hBA : Post_Data = 8'hD3; 
            8'hBB : Post_Data = 8'hD4; 
            8'hBC : Post_Data = 8'hD4; 
            8'hBD : Post_Data = 8'hD5; 
            8'hBE : Post_Data = 8'hD6; 
            8'hBF : Post_Data = 8'hD6; 
            8'hC0 : Post_Data = 8'hD7; 
            8'hC1 : Post_Data = 8'hD8; 
            8'hC2 : Post_Data = 8'hD8; 
            8'hC3 : Post_Data = 8'hD9; 
            8'hC4 : Post_Data = 8'hDA; 
            8'hC5 : Post_Data = 8'hDA; 
            8'hC6 : Post_Data = 8'hDB; 
            8'hC7 : Post_Data = 8'hDC; 
            8'hC8 : Post_Data = 8'hDC; 
            8'hC9 : Post_Data = 8'hDD; 
            8'hCA : Post_Data = 8'hDE; 
            8'hCB : Post_Data = 8'hDE; 
            8'hCC : Post_Data = 8'hDF; 
            8'hCD : Post_Data = 8'hE0; 
            8'hCE : Post_Data = 8'hE0; 
            8'hCF : Post_Data = 8'hE1; 
            8'hD0 : Post_Data = 8'hE2; 
            8'hD1 : Post_Data = 8'hE2; 
            8'hD2 : Post_Data = 8'hE3; 
            8'hD3 : Post_Data = 8'hE4; 
            8'hD4 : Post_Data = 8'hE4; 
            8'hD5 : Post_Data = 8'hE5; 
            8'hD6 : Post_Data = 8'hE6; 
            8'hD7 : Post_Data = 8'hE6; 
            8'hD8 : Post_Data = 8'hE7; 
            8'hD9 : Post_Data = 8'hE7; 
            8'hDA : Post_Data = 8'hE8; 
            8'hDB : Post_Data = 8'hE9; 
            8'hDC : Post_Data = 8'hE9; 
            8'hDD : Post_Data = 8'hEA; 
            8'hDE : Post_Data = 8'hEB; 
            8'hDF : Post_Data = 8'hEB; 
            8'hE0 : Post_Data = 8'hEC; 
            8'hE1 : Post_Data = 8'hED; 
            8'hE2 : Post_Data = 8'hED; 
            8'hE3 : Post_Data = 8'hEE; 
            8'hE4 : Post_Data = 8'hEE; 
            8'hE5 : Post_Data = 8'hEF; 
            8'hE6 : Post_Data = 8'hF0; 
            8'hE7 : Post_Data = 8'hF0; 
            8'hE8 : Post_Data = 8'hF1; 
            8'hE9 : Post_Data = 8'hF2; 
            8'hEA : Post_Data = 8'hF2; 
            8'hEB : Post_Data = 8'hF3; 
            8'hEC : Post_Data = 8'hF3; 
            8'hED : Post_Data = 8'hF4; 
            8'hEE : Post_Data = 8'hF5; 
            8'hEF : Post_Data = 8'hF5; 
            8'hF0 : Post_Data = 8'hF6; 
            8'hF1 : Post_Data = 8'hF7; 
            8'hF2 : Post_Data = 8'hF7; 
            8'hF3 : Post_Data = 8'hF8; 
            8'hF4 : Post_Data = 8'hF8; 
            8'hF5 : Post_Data = 8'hF9; 
            8'hF6 : Post_Data = 8'hFA; 
            8'hF7 : Post_Data = 8'hFA; 
            8'hF8 : Post_Data = 8'hFB; 
            8'hF9 : Post_Data = 8'hFB; 
            8'hFA : Post_Data = 8'hFC; 
            8'hFB : Post_Data = 8'hFD; 
            8'hFC : Post_Data = 8'hFD; 
            8'hFD : Post_Data = 8'hFE; 
            8'hFE : Post_Data = 8'hFE; 
            8'hFF : Post_Data = 8'hFF; 
            endcase
        end
endmodule
View Code

  ②:白平衡:

   原理:图像处理算法:白平衡、除法器、乘法器~笔记-CSDN博客

   具体原理:

   (1): Ksum = Rsum + Gsum + Bsum

      (2): Kaver = Ksum/[(Image_Size)*(Channel_Num)]

       Raver = Rsum/Image_Size

       Gaver = Gsum/Image_Size

       Baver = Bsum/Image_Size

   (3): Rgain = Kaver / Raver

       Ggain = Kaver / Gaver

     Bgain = Kaver / Baver

     (4):

    O_Rchannel_Pixel = I_Rchannel_Pixel  * Rgain 

    O_Gchannel_Pixel = I_Gchannel_Pixel * Ggain 

    O_Bchannel_Pixel = I_Bchannel_Pixel * Bgain 

   代码:

      
module White_Balance #(
    parameter   I_w = 1920,
    parameter   I_h = 1080,
    parameter   Channel_Num = 3
)(
    input   wire            Pre_CLK     ,
    input   wire            Pre_Rst     ,
    input   wire            Pre_Vsync   ,
    input   wire            Pre_de      ,
    input   wire  [7:0]     Pre_Pixel_R ,
    input   wire  [7:0]     Pre_Pixel_G ,
    input   wire  [7:0]     Pre_Pixel_B ,

    output  wire            Post_Vsync   ,
    output  wire            Post_de      ,
    output  wire  [7:0]     Post_Pixel_R ,
    output  wire  [7:0]     Post_Pixel_G ,
    output  wire  [7:0]     Post_Pixel_B ,
    output  wire  [23:0]    Post_Pixel_Total
);

//========================================= Define Ports =========================================//

    localparam  Shift_Num     = 21;
    localparam  Kaver_Divisor = I_w*I_h*Channel_Num;

            reg  [2:0]      Delay_Pre_de        ;
            wire            Pose_Pre_de         ;
            wire            Nege_Pre_de         ;

            reg             r_Pre_Vsync        ;
            wire            Pose_Pre_Vsync      ;
            wire            Nege_Pre_Vsync      ;

            reg  [31:0]     Red_Sum             ;
            reg  [31:0]     Green_Sum           ;
            reg  [31:0]     Blue_Sum            ;
            reg  [32:0]     K_Sum               ;

            reg  [10:0]     Aver_R              ;
            reg  [10:0]     Aver_G              ;
            reg  [10:0]     Aver_B              ;
            reg  [32:0]     Aver_K              ;

            reg             Calcu_Kaver         ;

            wire [63 : 0]   Kaver_Result        ;
            wire            Kaver_vaild         ;

        //Pixel*Kaver
            wire [18 : 0]   Multi_RxKaver       ;
            wire [18 : 0]   Multi_GxKaver       ;
            wire [18 : 0]   Multi_BxKaver       ;

        //Pixel*Kaver/Pixel_aver
            wire [39 : 0]   Div_RxKaver_D_Raver ;
            wire            Div_RxKaver_vaild   ;

            wire [39 : 0]   Div_GxKaver_D_Gaver ;
            wire            Div_GxKaver_vaild   ;

            wire [39 : 0]   Div_BxKaver_D_Baver ;
            wire            Div_BxKaver_vaild   ;

            wire [18:0]     Quo_R_Pixel         ;      
            wire [18:0]     Quo_G_Pixel         ;  
            wire [18:0]     Quo_B_Pixel         ;  

            reg             r_Post_de           ;
            reg  [7:0]      r_Post_Pixel_R      ;
            reg  [7:0]      r_Post_Pixel_G      ;
            reg  [7:0]      r_Post_Pixel_B      ;
            
    
//========================================= Define Ports =========================================//

    always @(posedge Pre_CLK) begin
        Delay_Pre_de <= {Delay_Pre_de[1:0],Pre_de};
        r_Pre_Vsync <= Pre_Vsync;
    end


    assign  Pose_Pre_Vsync = (Pre_Vsync == 1'b1)&&(r_Pre_Vsync == 1'b0);
    assign  Nege_Pre_Vsync = (Pre_Vsync == 1'b0)&&(r_Pre_Vsync == 1'b1); 

    //Calcu_Kaver
    always @(posedge Pre_CLK) begin
        if(Pre_Rst   == 1'b1) begin
            Calcu_Kaver <= 1'b0;
        end else if(Nege_Pre_Vsync == 1'b1) begin
            Calcu_Kaver <= 1'b1;
        end else begin
            Calcu_Kaver <= 1'b0;
        end
    end

    //Pixel Sum
    always @(posedge Pre_CLK) begin
        if(Pre_Rst   == 1'b1) begin
            Red_Sum   <= 'd0;
            Green_Sum <= 'd0;
            Blue_Sum  <= 'd0;
            K_Sum     <= 'd0;
        end else if(Calcu_Kaver == 1'b1) begin
            Red_Sum   <= 'd0;
            Green_Sum <= 'd0;
            Blue_Sum  <= 'd0;
            K_Sum     <= 'd0;
        end else if(Pre_de == 1'b1) begin
            Red_Sum   <= Red_Sum   + Pre_Pixel_R;
            Green_Sum <= Green_Sum + Pre_Pixel_G;
            Blue_Sum  <= Blue_Sum  + Pre_Pixel_B;
            K_Sum     <= K_Sum + Pre_Pixel_R + Pre_Pixel_G + Pre_Pixel_B;
        end else begin
            Red_Sum   <= Red_Sum  ;
            Green_Sum <= Green_Sum;
            Blue_Sum  <= Blue_Sum ;
            K_Sum     <= K_Sum    ; 
        end
    end

    //Div Pipeline = 16
    Div_Kaver Kaver_Comput_33D23 (
    .aclk                  ( Pre_CLK               ), // input wire aclk
    .aresetn               ( !Pre_Rst              ), // input wire aresetn
    .s_axis_divisor_tvalid ( Calcu_Kaver           ), // input wire s_axis_divisor_tvalid
    .s_axis_divisor_tdata  ( Kaver_Divisor         ), // input wire [23 : 0] s_axis_divisor_tdata
    .s_axis_dividend_tvalid( Calcu_Kaver           ), // input wire s_axis_dividend_tvalid
    .s_axis_dividend_tdata ( K_Sum                 ), // input wire [39 : 0] s_axis_dividend_tdata
    .m_axis_dout_tvalid    ( Kaver_vaild           ), // output wire m_axis_dout_tvalid
    .m_axis_dout_tdata     ( Kaver_Result          )  // output wire [63 : 0] m_axis_dout_tdata [56:24]
    );                      

    //aver 
    always @(posedge Pre_CLK) begin
        if(Pre_Rst   == 1'b1) begin
            Aver_R <= 'd0;
            Aver_G <= 'd0;
            Aver_B <= 'd0;
        end else if(Calcu_Kaver == 1'b1) begin
            Aver_R <= Red_Sum[21+:11]  ;   
            Aver_G <= Green_Sum[21+:11];   
            Aver_B <= Blue_Sum[21+:11] ;    
        end else begin
            Aver_R <= Aver_R;
            Aver_G <= Aver_G;
            Aver_B <= Aver_B;
        end
    end

    always @(posedge Pre_CLK) begin
        if(Pre_Rst   == 1'b1) begin
            Aver_K <= 'd0;
        end else if(Kaver_vaild == 1'b1) begin
            Aver_K <= Kaver_Result[56:24];
        end else begin
            Aver_K <= Aver_K;
        end
    end

    //Multi Pipeline = 3
    //Red
    Pixel_Multi_Kaver Pixel_Multi_Kaver_Red_8x11 (
    .CLK  ( Pre_CLK       ),  // input  wire CLK
    .A    ( Pre_Pixel_R   ),  // input  wire [7 : 0]  
    .B    ( Aver_K[10:0]  ),  // input  wire [10 : 0] 
    .P    ( Multi_RxKaver )   // output wire [18 : 0] 
    );

    //Div Pipeline = 16
    Div_GenGain Div_GenGain_Red (
    .aclk                   ( Pre_CLK               ),  // input wire aclk
    .aresetn                ( !Pre_Rst              ),  // input wire aresetn
    .s_axis_divisor_tvalid  ( Delay_Pre_de[2]       ),  // input wire s_axis_divisor_tvalid
    .s_axis_divisor_tdata   ( Aver_R                ),  // input wire [15 : 0] s_axis_divisor_tdata
    .s_axis_dividend_tvalid ( Delay_Pre_de[2]       ),  // input wire s_axis_dividend_tvalid
    .s_axis_dividend_tdata  ( Multi_RxKaver         ),  // input wire [23 : 0] s_axis_dividend_tdata
    .m_axis_dout_tvalid     ( Div_RxKaver_vaild     ),  // output wire m_axis_dout_tvalid
    .m_axis_dout_tdata      ( Div_RxKaver_D_Raver   )   // output wire [39 : 0] m_axis_dout_tdata [34:16]
    );

    //Gre
    Pixel_Multi_Kaver Pixel_Multi_Kaver_Gre_8x11 (
    .CLK  ( Pre_CLK       ),  // input  wire CLK
    .A    ( Pre_Pixel_G   ),  // input  wire [7 : 0]  
    .B    ( Aver_K[10:0]  ),  // input  wire [10 : 0] 
    .P    ( Multi_GxKaver )   // output wire [18 : 0] 
    );
    
    Div_GenGain Div_GenGain_Gre (
    .aclk                   ( Pre_CLK               ),  // input wire aclk
    .aresetn                ( !Pre_Rst              ),  // input wire aresetn
    .s_axis_divisor_tvalid  ( Delay_Pre_de[2]       ),  // input wire s_axis_divisor_tvalid
    .s_axis_divisor_tdata   ( Aver_G                ),  // input wire [15 : 0] s_axis_divisor_tdata
    .s_axis_dividend_tvalid ( Delay_Pre_de[2]       ),  // input wire s_axis_dividend_tvalid
    .s_axis_dividend_tdata  ( Multi_GxKaver         ),  // input wire [23 : 0] s_axis_dividend_tdata
    .m_axis_dout_tvalid     ( Div_GxKaver_vaild     ),  // output wire m_axis_dout_tvalid
    .m_axis_dout_tdata      ( Div_GxKaver_D_Gaver   )   // output wire [39 : 0] m_axis_dout_tdata
    );

    //Blue
    Pixel_Multi_Kaver Pixel_Multi_Kaver_Blu_8x11 (
    .CLK  ( Pre_CLK       ),  // input  wire CLK
    .A    ( Pre_Pixel_B   ),  // input  wire [7 : 0]  
    .B    ( Aver_K[10:0]  ),  // input  wire [10 : 0] 
    .P    ( Multi_BxKaver )   // output wire [18 : 0] 
    );

    Div_GenGain Div_GenGain_Blu (
    .aclk                   ( Pre_CLK               ),  // input wire aclk
    .aresetn                ( !Pre_Rst              ),  // input wire aresetn
    .s_axis_divisor_tvalid  ( Delay_Pre_de[2]       ),  // input wire s_axis_divisor_tvalid
    .s_axis_divisor_tdata   ( Aver_B                ),  // input wire [15 : 0] s_axis_divisor_tdata
    .s_axis_dividend_tvalid ( Delay_Pre_de[2]       ),  // input wire s_axis_dividend_tvalid
    .s_axis_dividend_tdata  ( Multi_BxKaver         ),  // input wire [23 : 0] s_axis_dividend_tdata
    .m_axis_dout_tvalid     ( Div_BxKaver_vaild     ),  // output wire m_axis_dout_tvalid
    .m_axis_dout_tdata      ( Div_BxKaver_D_Baver   )   // output wire [39 : 0] m_axis_dout_tdata
    );

    assign  Quo_R_Pixel = Div_RxKaver_D_Raver[34:16];
    assign  Quo_G_Pixel = Div_GxKaver_D_Gaver[34:16];
    assign  Quo_B_Pixel = Div_BxKaver_D_Baver[34:16];

    always @(posedge Pre_CLK) begin
        if(Pre_Rst   == 1'b1) begin
            r_Post_Pixel_R <= 'd0; 
        end else if(Div_RxKaver_vaild == 1'b1) begin
            if(Quo_R_Pixel > 8'd255) begin
                r_Post_Pixel_R <= 8'd255;
            end else begin
                r_Post_Pixel_R <= Quo_R_Pixel[7:0];
            end
        end else begin
            r_Post_Pixel_R <= r_Post_Pixel_R;
        end
    end

    always @(posedge Pre_CLK) begin
        if(Pre_Rst   == 1'b1) begin
            r_Post_Pixel_G <= 'd0;
        end else if(Div_GxKaver_vaild == 1'b1) begin
            if(Quo_G_Pixel > 8'd255) begin
                r_Post_Pixel_G <= 8'd255;
            end else begin
                r_Post_Pixel_G <= Quo_G_Pixel[7:0];
            end
        end else begin
            r_Post_Pixel_G <= r_Post_Pixel_G;
        end
    end

    always @(posedge Pre_CLK) begin
        if(Pre_Rst   == 1'b1) begin
            r_Post_Pixel_B <= 'd0;
        end else if(Div_BxKaver_vaild == 1'b1) begin
            if(Quo_B_Pixel > 8'd255) begin
                r_Post_Pixel_B <= 8'd255;
            end else begin
                r_Post_Pixel_B <= Quo_B_Pixel[7:0];
            end
        end else begin
            r_Post_Pixel_B <= r_Post_Pixel_B;
        end
    end

    always @(posedge Pre_CLK) begin
        if(Pre_Rst   == 1'b1) begin
            r_Post_de <= 1'b0;
        end else if(Div_BxKaver_vaild == 1'b1) begin
            r_Post_de <= 1'b1;
        end else begin
            r_Post_de <= 1'b0;
        end
    end

    assign  Post_Vsync = r_Pre_Vsync ;
    assign  Post_de = r_Post_de;
    assign  Post_Pixel_R = r_Post_Pixel_R;
    assign  Post_Pixel_G = r_Post_Pixel_G;
    assign  Post_Pixel_B = r_Post_Pixel_B;
    assign  Post_Pixel_Total = {r_Post_Pixel_R,r_Post_Pixel_G,r_Post_Pixel_B};

    // ila_0 White_ILA (
    // .clk(Pre_CLK), 
    // .probe0(  Pre_de               ),//1
    // .probe1(  Pre_Vsync               ),//1
    // .probe2(  Calcu_Kaver           ),//1
    // .probe3(  Pre_Pixel_R           ),//8
    // .probe4(  Pre_Pixel_G           ),//8
    // .probe5(  Pre_Pixel_B           ),//8
    // .probe6(  Kaver_vaild           ),//1
    // .probe7(  Aver_R                ),//11
    // .probe8(  Aver_G                ),//11
    // .probe9(  Aver_B                ),//11
    // .probe10(  K_Sum                ),//33
    // .probe11(  Aver_K                ),//33
    // .probe12(  Multi_RxKaver        ),//19
    // .probe13(  Multi_GxKaver        ),//19
    // .probe14(  Multi_BxKaver        ),//19
    // .probe15(  Delay_Pre_de         ),//3
    // .probe16(  Post_Pixel_R         ),//8
    // .probe17(  Post_Pixel_G         ),//8
    // .probe18(  Post_Pixel_B         ),//8
    // .probe19(  Post_de              ),//1
    // .probe20(  Div_BxKaver_vaild    ) //1
    // );
endmodule
View Code

输入通道管理:

(1)相机输入通道

1.相机配置操作和输入时钟处理:

相机配置:Sony IMX222相机的配置和解析-CSDN博客

MIPI配置的OV5640的使用_mc5640 mipi-CSDN博客

输入时钟:为输入时钟接PLL,偏移45°以后再接入模块,保证准确采集数据。

2.输入信号的数据解析:

解析情况1:

串行:DVP格式

原理心得:

相机解析驱动小记-CSDN博客

并行LVDS:MIPI格式

1.原理:

手写MIPI(一):MIPI-CSI-2 RAW10笔记_mipi csi协议-CSDN博客

2.代码:整体思路:

(1):dphy:

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

  1 `timescale 1ns / 1ps
  2  module Mipi_dphy_rx #(
  3     Mipi_Lane_Num = 2
  4 )(
  5     input   wire            Rst_n                 ,
  6     //Mipi
  7     input   wire            I_Mipi_phy_clk_p    ,
  8     input   wire            I_Mipi_phy_clk_n    ,
  9     input   wire    [1:0]   I_Mipi_phy_lane_p   ,
 10     input   wire    [1:0]   I_Mipi_phy_lane_n   ,
 11 
 12     output  wire            O_Mipi_CSI_Byte_CLK        ,//Slow Clk
 13     output  wire    [7:0]   O_Mipi_CSI_Byte_Lane0_Data ,
 14     output  wire    [7:0]   O_Mipi_CSI_Byte_Lane1_Data   
 15     );
 16             wire            Bufd_CLK             ;
 17             wire            Bufd_Slow_Clk        ;   
 18             wire            Buff_Clk             ;
 19             wire            Buff_Clk_inv         ;
 20             wire            clock_enable         ;
 21 //clk
 22     //diff to single:clk     
 23     IBUFDS
 24      #(.IOSTANDARD ("LVDS_25"))
 25      ibufds_clk_inst
 26      (.I          ( I_Mipi_phy_clk_p ),
 27       .IB         ( I_Mipi_phy_clk_n ),
 28       .O          ( Bufd_CLK         ));
 29 
 30     // High Speed BUFIO clock buffer
 31     BUFIO bufio_inst
 32      (.O ( Buff_Clk ),
 33       .I ( Bufd_CLK ));
 34 
 35     // BUFR generates the slow clock
 36     BUFR
 37      #(.SIM_DEVICE ("7SERIES"),
 38        .BUFR_DIVIDE("4"))
 39      clkout_buf_inst
 40       (.O    ( Bufd_Slow_Clk    ),
 41        .CE   ( 1'b1             ),
 42        .CLR  ( !Rst_n           ),
 43        .I    ( Bufd_CLK         ));
 44 
 45     assign  O_Mipi_CSI_Byte_CLK = Bufd_Slow_Clk ;//Output Slow Clk
 46     assign  Buff_Clk_inv        = ~ Buff_Clk    ;
 47     assign  clock_enable = 1'b1;
 48 //data
 49     wire     [1:0]  Mipi_IBUFD_Data       ;//Diff data to Single data  
 50     wire     [1:0]  Mipi_IBUFD_Data_delay ;
 51     wire     [7:0]  iserdes_q [1:0]       ;
 52     wire     [1:0]  Bitslip               ;
 53     assign   Bitslip = 2'b00;
 54     //lane0
 55     //diff to single:data
 56     IBUFDS
 57       #(.DIFF_TERM  ("FALSE"),             // Differential termination
 58         .IOSTANDARD ("LVDS_25"))
 59      ibufds_inst_0
 60        (.I          ( I_Mipi_phy_lane_p[0]  ),
 61         .IB         ( I_Mipi_phy_lane_n[0]  ),
 62         .O          ( Mipi_IBUFD_Data[0]    ));
 63 
 64     assign   Mipi_IBUFD_Data_delay = Mipi_IBUFD_Data;
 65 
 66      ISERDESE2
 67        # (
 68          .DATA_RATE         ("DDR"),
 69          .DATA_WIDTH        (8),
 70          .INTERFACE_TYPE    ("NETWORKING"), 
 71          .DYN_CLKDIV_INV_EN ("FALSE"),
 72          .DYN_CLK_INV_EN    ("FALSE"),
 73          .NUM_CE            (2),
 74          .OFB_USED          ("FALSE"),
 75          .IOBDELAY          ("NONE"),                               // Use input at D to output the data on Q
 76          .SERDES_MODE       ("MASTER"))
 77        iserdese2_master_lane0 (
 78          .Q1                ( iserdes_q [0][7] ),
 79          .Q2                ( iserdes_q [0][6] ),
 80          .Q3                ( iserdes_q [0][5] ),
 81          .Q4                ( iserdes_q [0][4] ),
 82          .Q5                ( iserdes_q [0][3] ),
 83          .Q6                ( iserdes_q [0][2] ),
 84          .Q7                ( iserdes_q [0][1] ),
 85          .Q8                ( iserdes_q [0][0] ),
 86          .SHIFTOUT1         ( ),
 87          .SHIFTOUT2         ( ),
 88          .BITSLIP           ( Bitslip[0]),                  // 1-bit Invoke Bitslip. This can be used with any DATA_WIDTH, cascaded or not.
 89                                                             // The amount of BITSLIP is fixed by the DATA_WIDTH selection.
 90          .CE1               ( clock_enable   ),             // 1-bit Clock enable input
 91          .CE2               ( clock_enable   ),             // 1-bit Clock enable input
 92          .CLK               ( Buff_Clk       ),             // Fast source synchronous clock driven by BUFIO
 93          .CLKB              ( Buff_Clk_inv   ),             // Locally inverted fast 
 94          .CLKDIV            ( Bufd_Slow_Clk  ),             // Slow clock from BUFR.
 95          .CLKDIVP           ( 1'b0    ),
 96          .D                 ( Mipi_IBUFD_Data_delay[0]),    // 1-bit Input signal from IOB 
 97          .DDLY              ( 1'b0   ),                     // 1-bit Input from Input Delay component 
 98          .RST               ( !Rst_n ),                     // 1-bit Asynchronous reset only.
 99          .SHIFTIN1          ( 1'b0   ),
100          .SHIFTIN2          ( 1'b0   ),
101     // unused connections 
102          .DYNCLKDIVSEL      ( 1'b0 ),
103          .DYNCLKSEL         ( 1'b0 ),
104          .OFB               ( 1'b0 ),
105          .OCLK              ( 1'b0 ),
106          .OCLKB             ( 1'b0 ),
107          .O                 ( ));                                   // unregistered output of ISERDESE1
108    
109     //lane1 
110     IBUFDS
111       #(.DIFF_TERM  ("FALSE"),             // Differential termination
112         .IOSTANDARD ("LVDS_25"))
113      ibufds_inst_1
114        (.I          ( I_Mipi_phy_lane_p[1] ),
115         .IB         ( I_Mipi_phy_lane_n[1] ),
116         .O          ( Mipi_IBUFD_Data[1]   ));
117 
118      ISERDESE2
119        # (
120          .DATA_RATE         ("DDR"),
121          .DATA_WIDTH        (8),
122          .INTERFACE_TYPE    ("NETWORKING"), 
123          .DYN_CLKDIV_INV_EN ("FALSE"),
124          .DYN_CLK_INV_EN    ("FALSE"),
125          .NUM_CE            (2),
126          .OFB_USED          ("FALSE"),
127          .IOBDELAY          ("NONE"),                               // Use input at D to output the data on Q
128          .SERDES_MODE       ("MASTER"))
129        iserdese2_master_lane1 (
130          .Q1                ( iserdes_q [1][7] ),
131          .Q2                ( iserdes_q [1][6] ),
132          .Q3                ( iserdes_q [1][5] ),
133          .Q4                ( iserdes_q [1][4] ),
134          .Q5                ( iserdes_q [1][3] ),
135          .Q6                ( iserdes_q [1][2] ),
136          .Q7                ( iserdes_q [1][1] ),
137          .Q8                ( iserdes_q [1][0] ),
138          .SHIFTOUT1         ( ),
139          .SHIFTOUT2         ( ),
140          .BITSLIP           ( Bitslip[1]),                  // 1-bit Invoke Bitslip. This can be used with any DATA_WIDTH, cascaded or not.
141                                                             // The amount of BITSLIP is fixed by the DATA_WIDTH selection.
142          .CE1               ( clock_enable   ),             // 1-bit Clock enable input
143          .CE2               ( clock_enable   ),             // 1-bit Clock enable input
144          .CLK               ( Buff_Clk       ),             // Fast source synchronous clock driven by BUFIO
145          .CLKB              ( Buff_Clk_inv   ),             // Locally inverted fast 
146          .CLKDIV            ( Bufd_Slow_Clk  ),             // Slow clock from BUFR.
147          .CLKDIVP           ( 1'b0    ),
148          .D                 ( Mipi_IBUFD_Data_delay[1]),    // 1-bit Input signal from IOB 
149          .DDLY              ( 1'b0   ),                      // 1-bit Input from Input Delay component 
150          .RST               ( !Rst_n ),                      // 1-bit Asynchronous reset only.
151          .SHIFTIN1          ( 1'b0   ),
152          .SHIFTIN2          ( 1'b0   ),
153     // unused connections 
154          .DYNCLKDIVSEL      ( 1'b0 ),
155          .DYNCLKSEL         ( 1'b0 ),
156          .OFB               ( 1'b0 ),
157          .OCLK              ( 1'b0 ),
158          .OCLKB             ( 1'b0 ),
159          .O                 ( ));                                   // unregistered output of ISERDESE1
160     
161     assign   O_Mipi_CSI_Byte_Lane0_Data = iserdes_q[0];
162     assign   O_Mipi_CSI_Byte_Lane1_Data = iserdes_q[1];
163 endmodule
View Code
(2):Byte_Align:

通过寻找SoT完成解析字的对齐;                      

    always @(*) begin
        r_O_Mipi_Byte_Alignment_Data <= Concat_Byte_data_delay[Byte_Offset+:8];
    end
View Code
(3):Lane_Align:

完成不同Lane之间的对齐:细节:不同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的情况:

4LANE的情况改改也是可以用的,只是那种时候发送速率会更快,拼接的情况会更多一些,此后的RAW10转RGB并不属于MIPI解析内容,放在下面的模块; 

    //Frame_Begin
    always @(posedge I_CLK or negedge I_Rst_n) begin
        if(I_Rst_n == 1'b0) begin
            Frame_Begin <= 1'b0;
        end else if(I_Mipi_Sync == 1'b1) begin
            Frame_Begin <= 1'b1;
        end
    end

    //Pixl_Cnt
    always @(posedge I_CLK or negedge I_Rst_n) begin
        if(I_Rst_n == 1'b0) begin
            Pixl_Cnt <= 3'd0;
        end else if((Frame_Begin == 1'b1) && (I_Mipi_Unpacket_Vaild == 1'b1)) begin
            if(Pixl_Cnt == 3'd4) begin 
                Pixl_Cnt <= 3'd0;
            end else begin
                Pixl_Cnt <= Pixl_Cnt + 1'b1;
            end
        end 
    end

    //r_Unpacket_Data
    always @(posedge I_CLK) begin
        rr_Unpacket_Data <= {I_Mipi_Unpacket_Data,rr_Unpacket_Data[16+:16]};
    end

    //r_O_Mipi_raw10_depacker_Vaild
    always @(posedge I_CLK or negedge I_Rst_n) begin
        if(I_Rst_n == 1'b0) begin
            r_O_Mipi_raw10_depacker_Vaild <= 1'b0;
        end else if(Frame_Begin == 1'b1 && I_Mipi_Unpacket_Vaild == 1'b1 &&((Pixl_Cnt == 3'd2)|(Pixl_Cnt == 3'd4))) begin
            r_O_Mipi_raw10_depacker_Vaild <= 1'b1;
        end else begin
            r_O_Mipi_raw10_depacker_Vaild <= 1'b0;
        end
    end

    assign  O_Mipi_raw10_depacker_Data  = {SIGN_A,
                                           SIGN_B,
                                           SIGN_C,
                                           SIGN_D};
    assign  O_Mipi_raw10_depacker_Vaild = r_O_Mipi_raw10_depacker_Vaild   ;    

    always @(posedge I_CLK or negedge I_Rst_n) begin
        if(I_Rst_n == 1'b0) begin
            SIGN_A  <= 10'd0;
            SIGN_B  <= 10'd0;
            SIGN_C  <= 10'd0;
            SIGN_D  <= 10'd0;
        end else if(Frame_Begin == 1'b1) begin
            if((Pixl_Cnt == 3'd2) && (I_Mipi_Unpacket_Vaild == 1'b1)) begin
                SIGN_A <= {rr_Unpacket_Data[00+:8],I_Mipi_Unpacket_Data[0+:2]};
                SIGN_B <= {rr_Unpacket_Data[08+:8],I_Mipi_Unpacket_Data[2+:2]};
                SIGN_C <= {rr_Unpacket_Data[16+:8],I_Mipi_Unpacket_Data[4+:2]};
                SIGN_D <= {rr_Unpacket_Data[24+:8],I_Mipi_Unpacket_Data[6+:2]};
            end else if((Pixl_Cnt == 3'd4) && (I_Mipi_Unpacket_Vaild == 1'b1)) begin
                SIGN_A <= {rr_Unpacket_Data[08+:8],I_Mipi_Unpacket_Data[8+:2]};
                SIGN_B <= {rr_Unpacket_Data[16+:8],I_Mipi_Unpacket_Data[10+:2]};
                SIGN_C <= {rr_Unpacket_Data[24+:8],I_Mipi_Unpacket_Data[12+:2]};
                SIGN_D <= {I_Mipi_Unpacket_Data[00+:8],I_Mipi_Unpacket_Data[14+:2]};
            end
        end 
    end
View Code          

解析原理一览:

  

 

3.解析信号的处理:bayer2rgb

①应用于卷积的手写FIFO:

参考:手写同步FIFO:用于3X3卷积 - NoNounknow - 博客园 (cnblogs.com)

实际代码实现:(和上文中不是同一个,是项目中实际使用的)

module Line_Shift_RAM
#(
    parameter DATA_WIDTH = 8    ,
    parameter ADDR_WIDTH = 14   ,
    parameter DATA_DEPTH = 2048 
)(
    input  wire                     I_CLK     ,
    input  wire                     I_Rst_n   ,
    input  wire                     I_Wr_en   ,
    input  wire                     I_Rd_en   ,
    input  wire [DATA_WIDTH-1:0]    I_din     ,   
    output wire [DATA_WIDTH-1:0]    O_dout    ,
    output wire                     full      ,
    output wire                     empty     
);
//----------------------------------------------------------------------
localparam ADDR_MSB   = 2 ** ADDR_WIDTH - 1; 
//----------------------------------------------------------------------
reg             [ADDR_WIDTH-1:0]    bram_waddr;
reg             [ADDR_WIDTH-1:0]    bram_raddr;
reg             [DATA_WIDTH-1:0]     r_ram[ADDR_MSB:0]; 
wire            [DATA_WIDTH-1:0]    bram_wdata;
reg             [DATA_WIDTH-1:0]    bram_rdata;
//WR--------------------------------------------------------------------
assign  bram_wdata = I_din;
always @(posedge I_CLK or negedge I_Rst_n) begin
    if(I_Rst_n == 1'b0) begin
        bram_waddr <= 'd0;
    end else if(I_Wr_en == 1'b1) begin
        if(bram_waddr == DATA_DEPTH - 1'b1) begin
            bram_waddr <= 'd0; 
        end else begin
            bram_waddr <= bram_waddr + 1'b1;
        end
    end else begin
        bram_waddr <= bram_waddr;
    end
end

always @(posedge I_CLK) begin:RAM_Define
    if(I_Wr_en) begin
        r_ram[bram_waddr] <= bram_wdata; 
    end else begin
    end
end
//WR--------------------------------------------------------------------

//RD--------------------------------------------------------------------
always @(posedge I_CLK or negedge I_Rst_n) begin
    if(I_Rst_n == 1'b0) begin
        bram_raddr <= 0;
    end else if(I_Rd_en == 1'b1) begin
        if(bram_raddr == DATA_DEPTH - 1'b1) begin
            bram_raddr <= 'd0;
        end else begin
            bram_raddr <= bram_raddr + 1'b1;
        end
    end else begin
        bram_raddr <= bram_raddr;
    end
end
always @(*) begin
    bram_rdata <= r_ram[bram_raddr]; 
end
assign O_dout = bram_rdata;
//RD--------------------------------------------------------------------

//Check-----------------------------------------------------------------
    reg    [ADDR_WIDTH-1:0]    Check_Cnt ;

    always @(posedge I_CLK or negedge I_Rst_n) begin
        if(I_Rst_n == 1'b0) begin
            Check_Cnt <= 'd0;
        end else if(I_Wr_en|I_Rd_en) begin
            if(I_Wr_en == 1'b1 && I_Rd_en == 1'b1)begin
                Check_Cnt <= Check_Cnt;
            end else if(I_Wr_en == 1'b1 && Check_Cnt != DATA_DEPTH-1 && I_Rd_en == 1'b0) begin
                Check_Cnt <= Check_Cnt + 1'b1;
            end else if(I_Rd_en == 1'b1 && Check_Cnt != 'd0 && I_Wr_en == 1'b0) begin
                Check_Cnt <= Check_Cnt - 1'b1;
            end else begin
                Check_Cnt <= Check_Cnt;
            end
        end else begin
            Check_Cnt <= Check_Cnt;
        end
    end
    assign  empty = (Check_Cnt == 'd0         )?1'b1:1'b0;
    assign  full  = (Check_Cnt == DATA_DEPTH-1)?1'b1:1'b0 ;
//Check-----------------------------------------------------------------

endmodule
View Code

②bayer2rgb:3X3卷积:RG/GB格式

module  bayer2rgb_3x3 #(
    parameter   DATA_WIDTH = 8   ,
    parameter   I_W        = 1922,
    parameter   I_H        = 1082
)(
    input   wire    I_Clk   ,
    input   wire    I_Rst   ,


//    input   wire                    I_H_Sync        ,
    input   wire [DATA_WIDTH-1:0]   I_Raw_Data      ,
    input   wire                    I_Raw_Vaild     ,
    input   wire                    I_V_Sync        ,
    //
    output  wire                    O_V_Sync        ,
//    output  wire                    O_H_Sync        ,
    output  wire                    O_RGB_Vaild     ,
    output  wire [DATA_WIDTH-1:0]   O_RGB_Data_r    ,  
    output  wire [DATA_WIDTH-1:0]   O_RGB_Data_g    ,  
    output  wire [DATA_WIDTH-1:0]   O_RGB_Data_b    ,
    output  wire [23:0]             O_RGB_Concat     
);

//--------------------------Define Port---------------------------//
    localparam  H_cnt_w = $clog2(I_W - 1'b1);
    localparam  V_cnt_w = $clog2(I_H - 1'b1);

            reg                     r1_V_Sync       ;
            wire                    Pose_V_Sync     ;

            reg                     r1_Raw_Vaild    ;
            wire                    Nege_Raw_Vaild  ;

            reg  [H_cnt_w-1:0]      H_cnt           ;
            reg  [V_cnt_w-1:0]      V_cnt           ;

            reg  [DATA_WIDTH-1:0]   r1_Raw_Data     ;
            reg  [DATA_WIDTH-1:0]   r2_Raw_Data     ;

            wire [DATA_WIDTH-1:0]   Rd0_Data        ;
            reg  [DATA_WIDTH-1:0]   r1_Rd0_Data     ;
            reg  [DATA_WIDTH-1:0]   r2_Rd0_Data     ;

            wire [DATA_WIDTH-1:0]   Rd1_Data        ;
            reg  [DATA_WIDTH-1:0]   r1_Rd1_Data     ;
            reg  [DATA_WIDTH-1:0]   r2_Rd1_Data     ;

            reg                     wr_en_0         ;
            reg  [DATA_WIDTH-1:0]   wr_data_0       ;
            reg                     rd_en_0         ;

            reg                     wr_en_1         ;
            reg  [DATA_WIDTH-1:0]   wr_data_1       ;
            reg                     rd_en_1         ;  

            reg [DATA_WIDTH+2:0]    RGB_Data_r      ;
            reg [DATA_WIDTH+2:0]    RGB_Data_g      ;
            reg [DATA_WIDTH+2:0]    RGB_Data_b      ;
            reg                     RGB_vaild       ;
            reg                     r1_RGB_vaild    ;

            reg  [H_cnt_w-1:0]      H_Addr          ;
            reg  [V_cnt_w-1:0]      V_Addr          ;                

//--------------------------Define Port---------------------------//

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

always @(posedge I_Clk) begin
    H_Addr <= (H_cnt >1)?(H_cnt - 2):0;
    V_Addr <= (V_cnt >1)?(V_cnt - 2):0;
end


always @(posedge I_Clk) begin
    r1_V_Sync    <= I_V_Sync    ;
    r1_Raw_Vaild <= I_Raw_Vaild ;
    {r1_Raw_Data, r2_Raw_Data} <= { I_Raw_Data, r1_Raw_Data };
    {r1_Rd0_Data, r2_Rd0_Data} <= { Rd0_Data  , r1_Rd0_Data };
    {r1_Rd1_Data, r2_Rd1_Data} <= { Rd1_Data  , r1_Rd1_Data };
    r1_RGB_vaild <= RGB_vaild;
end

    assign  Pose_V_Sync    = (I_V_Sync == 1'b1)&&(r1_V_Sync == 1'b0);
    assign  Nege_Raw_Vaild = (I_Raw_Vaild == 1'b0)&&(r1_Raw_Vaild==1'b1); 

//H_cnt
    always @(posedge I_Clk or posedge I_Rst) begin
        if(I_Rst == 1'b1) begin
            H_cnt <= 'd0;
        end else if(Pose_V_Sync == 1'b1|Nege_Raw_Vaild) begin
            H_cnt <= 'd0;
        end else if(I_Raw_Vaild == 1'b1) begin
            if(H_cnt == I_W - 1'b1) begin
                H_cnt <= 'd0;
            end else begin
                H_cnt <= H_cnt + 1'b1;
            end
        end
    end

    always @(posedge I_Clk or posedge I_Rst) begin
        if(I_Rst == 1'b1) begin
            V_cnt <= 'd0;
        end else if(Pose_V_Sync == 1'b1) begin
            V_cnt <= 'd0;
        end else if(Nege_Raw_Vaild == 1'b1) begin
            if(V_cnt == I_H - 1'b1) begin
                V_cnt <= 'd0;
            end else begin
                V_cnt <= V_cnt + 1'b1;
            end
        end else begin
            V_cnt <= V_cnt;
        end
    end

//wr
    //delay_0 
    always @(*) begin
        if(V_cnt == 0) begin
            wr_en_0 <= I_Raw_Vaild;
        end else if(V_cnt >= 2 && V_cnt < I_H - 1'b1) begin
            wr_en_0 <= I_Raw_Vaild;
        end else begin
            wr_en_0 <= 1'b0;
        end
    end

    always @(*) begin
        if(V_cnt == 0) begin
            wr_data_0 <= I_Raw_Data;
        end else if(V_cnt != 0)begin
            wr_data_0 <= Rd1_Data ;
        end
    end


    //delay_1
    always @(*) begin
        if(V_cnt >= 1 && V_cnt < I_H - 1'b1) begin
            wr_en_1 <= I_Raw_Vaild;
        end else begin
            wr_en_1 <= 1'b0;
        end
    end

    always @(*) begin
        if(V_cnt >= 1) begin
            wr_data_1 <= I_Raw_Data;
        end else begin
            wr_data_1 <= 'd0;
        end
    end

//rd
    //delay_0 
    always @(*) begin
        if(V_cnt >= 2 && V_cnt <= I_H - 1'b1) begin
            rd_en_0 <= I_Raw_Vaild;
        end else begin
            rd_en_0 <= 0;
        end
    end

    //delay_1
    always @(*) begin
        if(V_cnt >= 2 && V_cnt <= I_H - 1'b1) begin
            rd_en_1 <= I_Raw_Vaild;
        end else begin
            rd_en_1 <= 0;
        end
    end

// RGB_vaild
    assign  O_RGB_Vaild = r1_RGB_vaild;
    assign  O_V_Sync    = I_V_Sync    ;
//    assign  O_H_Sync    = I_H_Sync    ;

    always @(posedge I_Clk or posedge I_Rst) begin
        if(I_Rst == 1'b1) begin
            RGB_vaild <= 1'b0;
        end else if(V_cnt >= 2 
                 && H_cnt >= 1 
                 && V_cnt <= I_H - 1'b1 
                 && H_cnt <  I_W - 1'b1) begin
            RGB_vaild <= I_Raw_Vaild;
        end else begin
            RGB_vaild <= 1'b0;
        end
    end

    //RGB
    assign O_RGB_Concat = {O_RGB_Data_r,O_RGB_Data_g,O_RGB_Data_b};
    assign O_RGB_Data_r = (O_RGB_Vaild)?(RGB_Data_r[DATA_WIDTH-1:0]):8'd0;
    assign O_RGB_Data_g = (O_RGB_Vaild)?(RGB_Data_g[DATA_WIDTH-1:0]):8'd0;
    assign O_RGB_Data_b = (O_RGB_Vaild)?(RGB_Data_b[DATA_WIDTH-1:0]):8'd0;

    always @(posedge I_Clk or posedge I_Rst) begin
        if(I_Rst == 1'b1) begin
            RGB_Data_r <= 'd0;
            RGB_Data_g <= 'd0;
            RGB_Data_b <= 'd0;
        end else if(RGB_vaild == 1'b1) begin
            case({V_cnt[0],H_cnt[0]})
                2'b00:begin
                    RGB_Data_r <= (I_Raw_Data + r2_Raw_Data + Rd0_Data + r2_Rd0_Data)>>2;
                    RGB_Data_g <= (r1_Raw_Data + Rd1_Data + r2_Rd1_Data + r1_Rd0_Data)>>2;
                    RGB_Data_b <= r1_Rd1_Data;
                end
                2'b01:begin
                    RGB_Data_r <= (r1_Raw_Data + r1_Rd0_Data)>>1;
                    RGB_Data_g <= (((I_Raw_Data + r2_Raw_Data + Rd0_Data + r2_Rd0_Data)>>2) + r1_Rd1_Data)>>1;
                    RGB_Data_b <= (Rd1_Data + r2_Rd1_Data)>>1;
                end
                2'b10:begin
                    RGB_Data_r <= (Rd1_Data + r2_Rd1_Data)>>1;
                    RGB_Data_g <= ((I_Raw_Data + r2_Raw_Data + Rd0_Data + r2_Rd0_Data)>>2 + r1_Rd1_Data)>>1;
                    RGB_Data_b <= (r1_Raw_Data + r1_Rd0_Data)>>1;
                end
                2'b11:begin
                    RGB_Data_r <= r1_Rd1_Data;
                    RGB_Data_g <= (r1_Raw_Data + Rd1_Data + r2_Rd1_Data + r1_Rd0_Data)>>2;
                    RGB_Data_b <= (I_Raw_Data + r2_Raw_Data + Rd0_Data + r2_Rd0_Data)>>2;
                end
            endcase
        end else begin
            RGB_Data_r <= 'd0;
            RGB_Data_g <= 'd0;
            RGB_Data_b <= 'd0;
        end
    end

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

    wire    full_0  ;
    wire    empty_0 ;
    wire    full_1  ;
    wire    empty_1 ;

    Line_Shift_RAM #(
    .DATA_WIDTH ( 8  ),
    .ADDR_WIDTH ( 11 ),
    .DATA_DEPTH ( 2048 ))
    u0_Line_Shift_RAM (
        .I_CLK                   ( I_Clk       ),
        .I_Rst_n                 ( !Pose_V_Sync & !I_Rst),
        .I_Wr_en                 ( wr_en_0     ),
        .I_Rd_en                 ( rd_en_0     ),
        .I_din                   ( wr_data_0   ),

        .O_dout                  ( Rd0_Data    ),
        .full                    ( full_0      ),
        .empty                   ( empty_0     )
    );
    
    Line_Shift_RAM #(
    .DATA_WIDTH ( 8  ),
    .ADDR_WIDTH ( 11 ),
    .DATA_DEPTH ( 2048 ))
    u1_Line_Shift_RAM (
        .I_CLK                   ( I_Clk       ),
        .I_Rst_n                 ( !Pose_V_Sync & !I_Rst ),
        .I_Wr_en                 ( wr_en_1     ),
        .I_Rd_en                 ( rd_en_1     ),
        .I_din                   ( wr_data_1   ),

        .O_dout                  ( Rd1_Data    ),
        .full                    ( full_1      ),
        .empty                   ( empty_1     )
    );
    ila_0 ila_1 (
    .clk(I_Clk), // input wire clk


    .probe0 (   I_V_Sync       ), // input wire [0:0]  probe0  
    .probe1 (   I_Raw_Vaild    ), // input wire [0:0]  probe1 
    .probe2 (   I_Raw_Data     ), // input wire [7:0]  probe2 
    .probe3 (   r1_Raw_Data    ), // input wire [7:0]  probe3 
    .probe4 (   r2_Raw_Data    ), // input wire [7:0]  probe4 
    .probe5 (   Rd0_Data       ), // input wire [7:0]  probe5 
    .probe6 (   r1_Rd0_Data    ), // input wire [7:0]  probe6 
    .probe7 (   r2_Rd0_Data    ), // input wire [7:0]  probe7 
    .probe8 (   Rd1_Data       ), // input wire [7:0]  probe8 
    .probe9 (   r1_Rd1_Data    ), // input wire [7:0]  probe9 
    .probe10(   r2_Rd1_Data    ), // input wire [7:0]  probe10 
    .probe11(   H_cnt          ), // input wire [11:0]  probe11 
    .probe12(   V_cnt          ), // input wire [11:0]  probe12 
    .probe13(   wr_en_0        ), // input wire [0:0]  probe13 
    .probe14(   rd_en_0        ), // input wire [0:0]  probe14 
    .probe15(   wr_en_1        ), // input wire [0:0]  probe15 
    .probe16(   rd_en_1        ), // input wire [0:0]  probe16 
    .probe17(   O_RGB_Vaild    ), // input wire [0:0]  probe17 
    .probe18(   H_Addr         ), // input wire [11:0]  probe18 
    .probe19(   V_Addr         ), // input wire [11:0]  probe19
    .probe20(   RGB_Data_r     ), // input wire [0:0]  probe17 
    .probe21(   RGB_Data_g     ), // input wire [11:0]  probe18 
    .probe22(   RGB_Data_b     ), // input wire [11:0]  probe19
    .probe23(   I_Rst          )  // input wire [11:0]  probe19
);
endmodule
View Code

③bayer2rgb:2X2卷积:BG/GR格式

module  Post_Raw2Rgb (
    input   wire    I_Clk   ,
    input   wire    I_Rsy_n ,

    input   wire         I_V_Sync        ,
    input   wire         I_H_Sync        ,
    input   wire         I_Raw_Vaild     ,
    input   wire [7:0]   I_Raw_Data      ,
    //
    output  wire         O_V_Sync        ,
    output  wire         O_H_Sync        ,
    output  wire         O_RGB_Vaild     ,
    output  wire [7:0]   O_RGB_Data_r    ,  
    output  wire [7:0]   O_RGB_Data_g    ,  
    output  wire [7:0]   O_RGB_Data_b         
);
        reg  [15:0] Row_Cnt      ;
        reg  [15:0] Col_Cnt      ;
        //FIFO
        wire        FIFO_Wr_en   ;
        wire [7:0]  FIFO_Wr_Data ;
        wire        FIFO_Rd_en   ;
        wire [7:0]  FIFO_Rd_data ;

        reg         r1_FIFO_Wr_en   ;
        reg  [7:0]  r1_FIFO_Wr_Data ;
        reg         r1_FIFO_Rd_en   ;
        reg  [7:0]  r1_FIFO_Rd_data ;

        wire        full            ;
        wire        empty           ;
        wire        wr_rst_busy     ;
        wire        rd_rst_busy     ;
        //Pose
        reg         r1_I_V_Sync     ;
        wire        Pose_I_V_Sync   ;
        wire        Ext_Pose_V_Sync ;
        reg         r1_I_H_Sync     ;
        wire        Pose_I_H_Sync   ;

        //Pixel
        reg [8:0]   RGB_Data_r;
        reg [8:0]   RGB_Data_g;
        reg [8:0]   RGB_Data_b;

    //FIFO
    assign  FIFO_Wr_en   = I_Raw_Vaild;
    assign  FIFO_Wr_Data = I_Raw_Data ;
    assign  FIFO_Rd_en   = (Row_Cnt >= 1)?(FIFO_Wr_en):(1'b0);

    always @(posedge I_Clk) begin
        r1_I_V_Sync     <= I_V_Sync    ;
        r1_I_H_Sync     <= I_H_Sync    ;

        r1_FIFO_Wr_en   <= FIFO_Wr_en  ;
        r1_FIFO_Wr_Data <= FIFO_Wr_Data;
        
        r1_FIFO_Rd_en   <= FIFO_Rd_en  ;
        r1_FIFO_Rd_data <= FIFO_Rd_data;
    end
    assign  Pose_I_V_Sync = (I_V_Sync == 1'b1)&&(r1_I_V_Sync == 1'b0);
    assign  Pose_I_H_Sync = (I_H_Sync == 1'b1)&&(r1_I_H_Sync == 1'b0);

    //Col_Cnt
    always @(posedge I_Clk or negedge I_Rsy_n) begin
        if(I_Rsy_n == 1'b0) begin
            Col_Cnt <= 'd0;
        end else if(FIFO_Wr_en == 1'b1) begin
            Col_Cnt <= Col_Cnt + 1'b1;
        end else begin
            Col_Cnt <= 'd0;
        end
    end
    //Row_Cnt
    always @(posedge I_Clk or negedge I_Rsy_n) begin
        if(I_Rsy_n == 1'b0) begin
            Row_Cnt <= 'd0;
        end else if(Pose_I_V_Sync) begin
            Row_Cnt <= 'd0;
        end else if(Pose_I_H_Sync == 1'b1) begin
            Row_Cnt <= Row_Cnt + 1'b1;
        end else begin
            Row_Cnt <= Row_Cnt;
        end
    end

    assign O_RGB_Vaild   = r1_FIFO_Wr_en   ;
    assign O_RGB_Data_r  = RGB_Data_r[7:0] ;  
    assign O_RGB_Data_g  = RGB_Data_g[7:0] ;  
    assign O_RGB_Data_b  = RGB_Data_b[7:0] ;  
    assign O_V_Sync      = r1_I_V_Sync     ;
    assign O_H_Sync      = r1_I_H_Sync     ;    

    //BGBG
    //GRGR
    always @(posedge I_Clk or negedge I_Rsy_n) begin
        if(I_Rsy_n == 1'b0) begin
            RGB_Data_r <= 'd0;
            RGB_Data_g <= 'd0;
            RGB_Data_b <= 'd0;
        end else if(FIFO_Wr_en == 1'b1) begin
            case({Row_Cnt[0],Col_Cnt[0]})
            2'b00:begin 
                RGB_Data_r <= r1_FIFO_Rd_data;
                RGB_Data_g <=(FIFO_Rd_data + r1_FIFO_Wr_Data)>>1'b1;
                RGB_Data_b <= FIFO_Wr_Data;
            end
            2'b10:begin
                RGB_Data_r <= r1_FIFO_Wr_Data;
                RGB_Data_g <=(FIFO_Wr_Data + r1_FIFO_Rd_data)>>1'b1;
                RGB_Data_b <= FIFO_Rd_data;
            end
            2'b01:begin
                RGB_Data_r <= FIFO_Rd_data;
                RGB_Data_g <=(FIFO_Wr_Data + r1_FIFO_Rd_data)>>1'b1;
                RGB_Data_b <= r1_FIFO_Wr_Data;
            end
            2'b11:begin
                RGB_Data_r <= FIFO_Wr_Data; 
                RGB_Data_g <=(FIFO_Rd_data + r1_FIFO_Wr_Data)>>1'b1;
                RGB_Data_b <= r1_FIFO_Wr_Data;
            end
            endcase
        end else begin
            RGB_Data_r <= 'd0;
            RGB_Data_g <= 'd0;
            RGB_Data_b <= 'd0;
        end
    end

    data_sync_ext Post_Raw2Rgb_FIFO_Rst(
        .clka            (I_Clk                  ),
        .rst_n            (I_Rsy_n                  ),    
        .pulse_a        (Pose_I_V_Sync          ),
        .ext_pulse_a    (Ext_Pose_V_Sync        )
    );

    S_fifo_w16x2048_r16x2048 S_fifo_w16x2048_r16x2048 (
    .rst    ( Ext_Pose_V_Sync ), // input wire rst
    .wr_clk ( I_Clk           ), // input wire wr_clk
    .rd_clk ( I_Clk           ), // input wire rd_clk
    .din    ( FIFO_Wr_Data    ), // input wire [15 : 0] din
    .wr_en  ( FIFO_Wr_en      ), // input wire wr_en
    .rd_en  ( FIFO_Rd_en      ), // input wire rd_en
    .dout   ( FIFO_Rd_data    ), // output wire [15 : 0] dout
    .full       ( full        ), // output wire full
    .empty      ( empty       ), // output wire empty
    .wr_rst_busy( wr_rst_busy ), // output wire wr_rst_busy
    .rd_rst_busy( rd_rst_busy )  // output wire rd_rst_busy
    );
endmodule
View Code     

4.处理后信号的存储:

①:写入FIFO;

②:写入DDR的请求:

循环优先级仲裁~位屏蔽仲裁算法-CSDN博客

(此处如果不考虑平台移植可以使用Axi interconnect ip)

③:帧同步和撕裂防止:

帧同步:利用输入信号的同步信号同步写入地址和清空写入FIFO,输出信号的同步信号同步读出地址和清空读出FIFO;

帧同步的思想与异步FIFO复位_异步fifo怎么复位-CSDN博客

撕裂防止措施:

【1】:乒乓操作;

【2】:帧缓存架构:永远读刚读取完的那一帧;

魔改自: 02基于FDMA三缓存构架_哔哩哔哩_bilibili

代码来自:NoNounknow/DMA: DMA仓库,主要包含了各种操作场景下用的DMA,细节在博客园。 (github.com)

其中之一:

`timescale 1 ns / 1 ps

    module DMA_Custom #
    (
        parameter         C_M_TARGET_SLAVE_BASE_ADDR    = 32'h2000000,
        parameter integer C_M_AXI_BURST_LEN             = 256  ,
        parameter integer C_M_AXI_ID_WIDTH              = 1    ,
        parameter integer C_M_AXI_ADDR_WIDTH            = 32   ,
        parameter integer C_M_AXI_DATA_WIDTH            = 64   ,
        parameter integer C_M_AXI_AWUSER_WIDTH          = 0    ,
        parameter integer C_M_AXI_ARUSER_WIDTH          = 0    ,
        parameter integer C_M_AXI_WUSER_WIDTH           = 0    ,
        parameter integer C_M_AXI_RUSER_WIDTH           = 0    ,
        parameter integer C_M_AXI_BUSER_WIDTH           = 0    ,
        parameter         I_image_w                     = 1920 ,
        parameter         I_image_h                     = 1080 ,
        parameter         Pixel_byte_num                = 4    ,
        parameter         AXI_Buff_NUM                  = 3    ,
        parameter         Input_Data_width              = 24
    )
    (
        input    wire                              M_AXI_ACLK    ,
        input    wire                              M_AXI_ARESETN ,
        output   wire [C_M_AXI_ID_WIDTH-1 : 0]     M_AXI_AWID    ,
        output   wire [C_M_AXI_ADDR_WIDTH-1 : 0]   M_AXI_AWADDR  ,
        output   wire [7 : 0]                      M_AXI_AWLEN   ,
        output   wire [2 : 0]                      M_AXI_AWSIZE  ,
        output   wire [1 : 0]                      M_AXI_AWBURST ,
        output   wire                              M_AXI_AWLOCK  ,
        output   wire [3 : 0]                      M_AXI_AWCACHE ,
        output   wire [2 : 0]                      M_AXI_AWPROT  ,
        output   wire [3 : 0]                      M_AXI_AWQOS   ,
        output   wire [C_M_AXI_AWUSER_WIDTH-1 : 0] M_AXI_AWUSER  ,
        output   wire                              M_AXI_AWVALID ,
        input    wire                              M_AXI_AWREADY ,

        output   wire [C_M_AXI_DATA_WIDTH-1 : 0]   M_AXI_WDATA   ,
        output   wire [C_M_AXI_DATA_WIDTH/8-1 : 0] M_AXI_WSTRB   ,
        output   wire                              M_AXI_WLAST   ,
        output   wire [C_M_AXI_WUSER_WIDTH-1 : 0]  M_AXI_WUSER   ,
        output   wire                              M_AXI_WVALID  ,
        input    wire                              M_AXI_WREADY  ,

        input    wire [C_M_AXI_ID_WIDTH-1 : 0]     M_AXI_BID,
        input    wire [1 : 0]                      M_AXI_BRESP   ,
        input    wire [C_M_AXI_BUSER_WIDTH-1 : 0]  M_AXI_BUSER   ,
        input    wire                              M_AXI_BVALID  ,
        output   wire                              M_AXI_BREADY  ,

        output   wire [C_M_AXI_ID_WIDTH-1 : 0]     M_AXI_ARID    ,
        output   wire [C_M_AXI_ADDR_WIDTH-1 : 0]   M_AXI_ARADDR  ,
        output   wire [7 : 0]                      M_AXI_ARLEN   ,
        output   wire [2 : 0]                      M_AXI_ARSIZE  ,
        output   wire [1 : 0]                      M_AXI_ARBURST ,
        output   wire                              M_AXI_ARLOCK  ,
        output   wire [3 : 0]                      M_AXI_ARCACHE ,
        output   wire [2 : 0]                      M_AXI_ARPROT  ,
        output   wire [3 : 0]                      M_AXI_ARQOS   ,
        output   wire [C_M_AXI_ARUSER_WIDTH-1 : 0] M_AXI_ARUSER  ,
        output   wire                              M_AXI_ARVALID ,
        input    wire                              M_AXI_ARREADY ,

        input    wire [C_M_AXI_ID_WIDTH-1 : 0]     M_AXI_RID     ,
        input    wire [C_M_AXI_DATA_WIDTH-1 : 0]   M_AXI_RDATA   ,
        input    wire [1 : 0]                      M_AXI_RRESP   ,
        input    wire                              M_AXI_RLAST   ,
        input    wire [C_M_AXI_RUSER_WIDTH-1 : 0]  M_AXI_RUSER   ,
        input    wire                              M_AXI_RVALID  ,
        output   wire                              M_AXI_RREADY  ,

        //Custom

        input    wire                              I_Pre_clk     ,
        input    wire                              I_Pre_vs      ,
        input    wire  [Input_Data_width-1:0]      I_Pre_data    ,
        input    wire                              I_Pre_de      ,        

        input    wire                              I_Post_clk   ,
        output  wire                               O_Post_Start ,
        output    wire  [Input_Data_width-1:0]     O_Post_data  ,
        input    wire                              I_Post_de    ,
        input   wire                               I_Post_vs           
    );
                     
    function integer clogb2 (input integer bit_depth);              
      begin                                                           
        for(clogb2=0; bit_depth>0; clogb2=clogb2+1)                   
          bit_depth = bit_depth >> 1;                                 
        end                                                           
    endfunction                                                     
    
//========================================= Define Ports =========================================//
    localparam integer C_TRANSACTIONS_NUM   = clogb2(C_M_AXI_BURST_LEN-1)                   ;

    localparam         Awaddr_Brust_Offset  = (C_M_AXI_DATA_WIDTH)*(C_M_AXI_BURST_LEN)/8    ;
    localparam         Araddr_Brust_Offset  = (C_M_AXI_DATA_WIDTH)*(C_M_AXI_BURST_LEN)/8    ;
    localparam         Total_Frame_Offset   = I_image_w*I_image_h*Pixel_byte_num            ;
    localparam         RAM_1_start_addr     = 0                                             ;
    localparam         RAM_2_start_addr     = Total_Frame_Offset                            ;
    localparam         RAM_3_start_addr     = Total_Frame_Offset*2                          ;

    localparam         wr_burst_times       = I_image_w*I_image_h*Pixel_byte_num /Awaddr_Brust_Offset        ;    
    localparam         rd_burst_times       = I_image_w*I_image_h*Pixel_byte_num /Araddr_Brust_Offset        ;

//========================================= Define Ports =========================================//
 
    // AXI4LITE signals
    //AXI4 internal temp signals
    reg  [C_M_AXI_ADDR_WIDTH-1 : 0]  axi_awaddr      ;
    reg                              axi_awvalid     ;
  
    reg                              axi_wlast       ;
    reg                              axi_wvalid      ;
    reg  [C_TRANSACTIONS_NUM-1:0]    wr_burst_cnt    ;

    reg                              axi_bready      ;
  
    reg  [C_M_AXI_ADDR_WIDTH-1 : 0]  axi_araddr      ;
    reg                              axi_arvalid     ;
    reg                              axi_rready      ;

      //W_FIFO
    wire                              wr_fifo_wr_en    ;
    wire [C_M_AXI_DATA_WIDTH-1 : 0]   wr_fifo_wr_data  ;
    wire                              wr_fifo_rd_en    ; 
    wire [C_M_AXI_DATA_WIDTH-1 : 0]   wr_fifo_rd_data  ;
    wire                              full_w           ;
    wire                              empty_w          ;
    wire [15 : 0]                     w_rd_data_count  ;
    wire [15 : 0]                     w_wr_data_count  ;
    
      //r_FIFO
    wire                              rd_fifo_wr_en    ;
    wire [C_M_AXI_DATA_WIDTH-1 : 0]   rd_fifo_wr_data  ;

    wire                              rd_fifo_rd_en    ; 
    wire [31 : 0]                     rd_fifo_rd_data  ;

    wire [12 : 0]                     r_rd_data_count  ;
    wire [11 : 0]                     r_wr_data_count  ;
    wire                              full_r           ;
    wire                              empty_r          ;

    reg  [15:0]                       rd_hcnt          ;
    reg  [15:0]                       rd_vcnt          ;

    //I/O Connections. Write Address (AW)
    assign M_AXI_AWID       = 'b0;
    assign M_AXI_AWADDR     = C_M_TARGET_SLAVE_BASE_ADDR + axi_awaddr;
    assign M_AXI_AWLEN      = C_M_AXI_BURST_LEN - 1;
    assign M_AXI_AWSIZE     = clogb2((C_M_AXI_DATA_WIDTH/8)-1);
    assign M_AXI_AWBURST    = 2'b01;
    assign M_AXI_AWLOCK     = 1'b0;
    assign M_AXI_AWCACHE    = 4'b0010;
    assign M_AXI_AWPROT     = 3'h0;
    assign M_AXI_AWQOS      = 4'h0;
    assign M_AXI_AWUSER     = 'b1;
    assign M_AXI_AWVALID    = axi_awvalid;
    //Write Data(W)
    assign wr_fifo_rd_en    = (axi_wvalid == 1'b1)&&(M_AXI_WREADY == 1'b1);
    assign M_AXI_WDATA      = wr_fifo_rd_data;
    //All bursts are complete and aligned in this example
    assign M_AXI_WSTRB      = {(C_M_AXI_DATA_WIDTH/8){1'b1}};
    assign M_AXI_WLAST      = axi_wlast;
    assign M_AXI_WUSER      = 'b0;
    assign M_AXI_WVALID     = axi_wvalid;
    //Write Response (B)
    assign M_AXI_BREADY     = axi_bready;
    //Read Address (AR)
    assign M_AXI_ARID       = 'b0;
    assign M_AXI_ARADDR     = C_M_TARGET_SLAVE_BASE_ADDR + axi_araddr;
    assign M_AXI_ARLEN      = C_M_AXI_BURST_LEN - 1;
    assign M_AXI_ARSIZE     = clogb2((C_M_AXI_DATA_WIDTH/8)-1);
    assign M_AXI_ARBURST    = 2'b01;
    assign M_AXI_ARLOCK     = 1'b0;
    assign M_AXI_ARCACHE    = 4'b0010;
    assign M_AXI_ARPROT     = 3'h0;
    assign M_AXI_ARQOS      = 4'h0;
    assign M_AXI_ARUSER     = 'b1;
    assign M_AXI_ARVALID    = axi_arvalid;
    //Read and Read Response (R)
    assign M_AXI_RREADY     = axi_rready;

// Wr_Sync------------------------------------------------------------------------------------------//

    //W Sync Port
    //wrclk
    reg                               r1_pre_vs        ;
    wire                              Pose_pre_vs      ;
    wire                              Nege_pre_vs      ;
    wire                              Ext_Pose_pre_vs  ;
    //sysclk
    reg                               sys_pre_vs       ;
    reg                               r1_sys_pre_vs    ;
    reg                               sys_Pose_pre_vs  ;
    reg                               sys_Nege_pre_vs  ;
    reg                               r_sys_Nege_pre_vs;
    reg  [1:0]                        wr_index         ;
    reg   [C_M_AXI_ADDR_WIDTH-1 : 0]  wr_base_addr     ;
    
    always @(posedge I_Pre_clk) begin
        r1_pre_vs <= I_Pre_vs;
    end

    assign  Pose_pre_vs = (I_Pre_vs == 1'b1)&&(r1_pre_vs == 1'b0);
    assign  Nege_pre_vs = (I_Pre_vs == 1'b0)&&(r1_pre_vs == 1'b1);

    always@(posedge M_AXI_ACLK) begin
        sys_pre_vs        <= I_Pre_vs  ;
        r1_sys_pre_vs     <= sys_pre_vs;
        r_sys_Nege_pre_vs <= sys_Nege_pre_vs;
    end

    always @(posedge M_AXI_ACLK) begin
        if(M_AXI_ARESETN == 1'b0) begin
            sys_Pose_pre_vs <= 1'b0;
            sys_Nege_pre_vs <= 1'b0;
        end else if(sys_pre_vs==1'b1&&r1_sys_pre_vs==1'b0) begin
            sys_Pose_pre_vs <= 1'b1;
            sys_Nege_pre_vs <= 1'b0; 
        end else if(sys_pre_vs==1'b0&&r1_sys_pre_vs==1'b1) begin
            sys_Pose_pre_vs <= 1'b0;
            sys_Nege_pre_vs <= 1'b1; 
        end else begin
            sys_Pose_pre_vs <= 1'b0;
            sys_Nege_pre_vs <= 1'b0;
        end
    end


    Data_sync_ext Data_sync_ext_Inst0(
        .clka           ( I_Pre_clk          ),
        .rst_n          ( M_AXI_ARESETN      ),    
        .pulse_a        ( Pose_pre_vs        ),
        .ext_pulse_a    ( Ext_Pose_pre_vs    )
    );

    always@(posedge M_AXI_ACLK)
        if(M_AXI_ARESETN == 1'b0) begin
            wr_index <= 'd1;
        end else if(sys_Nege_pre_vs == 1'b1&&wr_index == AXI_Buff_NUM) begin
            wr_index <= 'd1;
        end else if(sys_Nege_pre_vs==1'b1) begin
            wr_index <= wr_index + 1'b1;
        end else begin
            wr_index <= wr_index;
        end
            
    always@(posedge M_AXI_ACLK)
        if(M_AXI_ARESETN == 1'b0) begin
            wr_base_addr <= 0;
        end    else if(sys_Nege_pre_vs == 1'b1&&wr_index == AXI_Buff_NUM) begin
            wr_base_addr <= 0;
        end else if(sys_Nege_pre_vs == 1'b1) begin
            wr_base_addr <= wr_base_addr + Total_Frame_Offset;
        end else begin
            wr_base_addr <= wr_base_addr;
        end

// Wr_Sync------------------------------------------------------------------------------------------//

    assign  wr_fifo_wr_en = I_Pre_de;
    assign  wr_fifo_wr_data = {8'h0,I_Pre_data};

    wdata_w64x1024_r64x1024 wdata_w32x4096_r64x2048 (
    .rst        ( (!M_AXI_ARESETN)|(Ext_Pose_pre_vs)),  // input wire rst
    .wr_clk     ( I_Pre_clk                         ),  // input wire wr_clk
    .rd_clk     ( M_AXI_ACLK                        ),  // input wire rd_clk
    .din        ( wr_fifo_wr_data                   ),  // input wire [63 : 0] din
    .wr_en      ( wr_fifo_wr_en                     ),  // input wire wr_en
    .rd_en      ( wr_fifo_rd_en                     ),  // input wire rd_en
    .dout       ( wr_fifo_rd_data                   ),  // output wire [63 : 0] dout
    .full       ( full_w                            ),  // output wire full
    .empty      ( empty_w                           ),  // output wire empty
    .rd_data_count(w_rd_data_count ),            // output wire [10 : 0] rd_data_count
    .wr_data_count(w_wr_data_count ),            // output wire [10 : 0] wr_data_count
    .wr_rst_busy(),                // output wire wr_rst_busy
    .rd_rst_busy()                 // output wire rd_rst_busy
    );

// w_start_control----------------------------------------------------------------------------------//

    //Control
    reg                              wr_brust_start  ;
    wire                             wr_brust_Req     ;            
    wire                             wr_brust_end    ;
    reg                              wr_brust_now     ;

    assign    wr_brust_Req = (w_rd_data_count>=C_M_AXI_BURST_LEN);
    assign    wr_brust_end = (axi_wvalid==1'b1&&M_AXI_WREADY==1'b1&&wr_burst_cnt==C_M_AXI_BURST_LEN-1);


    //多路输入的时候,wr_brust_Req输出到仲裁器中,使用仲裁器输出的aribe_req请求完成此处wr_brust_Req的工作
    always@(*)
        if(wr_brust_Req == 1'b1) begin
            wr_brust_start <= 1'b1;
        end else begin
            wr_brust_start <= 1'b0; 
        end
    
    always@(posedge M_AXI_ACLK)
        if(M_AXI_ARESETN == 1'b0) begin
            wr_brust_now <= 1'b0;
        end else if(wr_brust_end == 1'b1 && wr_brust_now == 1'b1) begin
            wr_brust_now <= 1'b0; 
        end else if(wr_brust_start == 1'b1 && wr_brust_now == 1'b0) begin
            wr_brust_now <= 1'b1;
        end else begin
            wr_brust_now <= wr_brust_now; 
        end

// w_start_control----------------------------------------------------------------------------------//

// Aw------ --------------------------------------------------------------------------------------//

 //axi_awvalid
    always@(posedge M_AXI_ACLK)
        if(M_AXI_ARESETN == 1'b0) begin
            axi_awvalid <= 1'b0;
        end else if(axi_awvalid == 1'b1 && M_AXI_AWREADY == 1'b1) begin
            axi_awvalid <= 1'b0;
        end else if(wr_brust_start == 1'b1 && wr_brust_now == 1'b0) begin
            axi_awvalid <= 1'b1; 
        end else begin
            axi_awvalid <= axi_awvalid;
        end

 //axi_awaddr
    always@(posedge M_AXI_ACLK)
        if(M_AXI_ARESETN == 1'b0) begin
            axi_awaddr <= 'd0;
        end else if(r_sys_Nege_pre_vs == 1'b1) begin
            axi_awaddr <= wr_base_addr;
        // end else if(r_sys_Nege_pre_vs == 1'b1) begin
        //     axi_awaddr <= 0;
        end else if(axi_awvalid==1'b1 && M_AXI_AWREADY==1'b1) begin
            axi_awaddr <= axi_awaddr + Awaddr_Brust_Offset ;  
        end else begin
            axi_awaddr <= axi_awaddr;
        end

// Aw---------------------------------------------------------------------------------------------//

// W----------------------------------------------------------------------------------------------//
 //axi_wvalid
    always@(posedge M_AXI_ACLK)
        if(M_AXI_ARESETN == 1'b0) begin
            axi_wvalid <= 1'b0;
        end else if(axi_wvalid==1'b1&&M_AXI_WREADY==1'b1&&wr_burst_cnt==C_M_AXI_BURST_LEN-1) begin
            axi_wvalid <= 1'b0;
        end else if(axi_awvalid==1'b1&&M_AXI_AWREADY==1'b1) begin
            axi_wvalid <= 1'b1;
        end else begin
            axi_wvalid <= axi_wvalid;
        end 

 //wr_burst_cnt
    always@(posedge M_AXI_ACLK) begin
        if(M_AXI_ARESETN == 1'b0) begin
            wr_burst_cnt <= 'd0;
        end else if(axi_wvalid==1'b1&&M_AXI_WREADY==1'b1&&wr_burst_cnt==C_M_AXI_BURST_LEN-1) begin
            wr_burst_cnt <= 'd0;
        end else if(axi_wvalid==1'b1&&M_AXI_WREADY==1'b1) begin
            wr_burst_cnt <= wr_burst_cnt + 1'b1;
        end else begin
            wr_burst_cnt <= wr_burst_cnt;
        end
    end

 //axi_wlast
    always@(posedge M_AXI_ACLK) begin
        if(M_AXI_ARESETN == 1'b0) begin
            axi_wlast <= 1'b0;
        end else if(axi_wvalid==1'b1&&M_AXI_WREADY==1'b1&&wr_burst_cnt==C_M_AXI_BURST_LEN-1'b1) begin
            axi_wlast <= 1'b0;
        end else if(axi_wvalid==1'b1&&M_AXI_WREADY==1'b1&&wr_burst_cnt==C_M_AXI_BURST_LEN-2'd2) begin
            axi_wlast <= 1'b1;
        end else begin
            axi_wlast <= axi_wlast;
        end
    end

// W----------------------------------------------------------------------------------------------//

// b----------------------------------------------------------------------------------------------//

    always @(posedge M_AXI_ACLK) begin
        if(M_AXI_ARESETN == 0) begin
            axi_bready <= 'd0;
        end else begin
            axi_bready <= 1'b1;
        end
    end

// b----------------------------------------------------------------------------------------------//

// r_start_control----------------------------------------------------------------------------------//

    //Control
    reg [7:0]                        rd_index         ;
    reg [7:0]                        rd_index_ptr     ;
    reg [C_M_AXI_ADDR_WIDTH-1 : 0]   rd_base_addr     ;

    reg                              rd_start_cycle   ;
    reg [2:0]                        rd_start_cnt     ;
    reg                              rd_brust_start   ;
    reg                              rd_brust_Req     ;            
    reg                              rd_brust_end     ;
    reg                              rd_brust_now     ;
    reg                              Post_Start       ;

    always@(posedge M_AXI_ACLK) begin
        if(M_AXI_ARESETN == 0) begin
            rd_index <= 0;
        end else if(wr_index > 1) begin
            rd_index <= wr_index - 1'b1;
        end else begin
            rd_index <= AXI_Buff_NUM;
        end
    end

    always@(posedge M_AXI_ACLK) begin
        if(M_AXI_ARESETN == 0) begin
            rd_index_ptr <= 'd0;
        end else begin
            rd_index_ptr <= rd_index - 1'b1; 
        end
    end

    always@(posedge M_AXI_ACLK) begin
        if(M_AXI_ARESETN == 0) begin
            rd_base_addr <= 'd0;
        end else begin
            rd_base_addr <= rd_index_ptr*Total_Frame_Offset; 
        end
    end

    always@(posedge M_AXI_ACLK) begin
        if(M_AXI_ARESETN == 0) begin
            rd_start_cnt <= 'd0;
        end else if(sys_Nege_pre_vs && rd_start_cnt[2] != 1'b1) begin
            rd_start_cnt <= rd_start_cnt + 1'b1;
        end else begin
            rd_start_cnt <= rd_start_cnt;
        end
    end

    always@(posedge M_AXI_ACLK) begin
        if(M_AXI_ARESETN == 0) begin
            rd_start_cycle <= 1'b0;
        end else if(rd_start_cnt[2] == 1'b1 && full_r == 1'b0) begin
            rd_start_cycle <= 1'b1;
        end else begin
            rd_start_cycle <= rd_start_cycle;
        end
    end

    always@(posedge I_Post_clk)
        if(M_AXI_ARESETN == 0) begin
            Post_Start <= 1'b0;
        end else if(rd_start_cycle == 1'b1 && r_rd_data_count >= C_M_AXI_BURST_LEN) begin
            Post_Start <= 1'b1;
        end  else begin
            Post_Start <= Post_Start;
        end

    assign  O_Post_Start   =  Post_Start;

    always @(*) begin
        if((rd_start_cycle == 1'b1) && (r_wr_data_count < C_M_AXI_BURST_LEN*4)) begin
            rd_brust_Req <= 1'b1;
        end else begin
            rd_brust_Req <= 1'b0;
        end
    end

    always@(*) begin
        if((M_AXI_RVALID == 1'b1)&&(axi_rready == 1'b1)&&(M_AXI_RLAST == 1'b1)) begin
            rd_brust_end <= 1'b1;
        end else begin
            rd_brust_end <= 1'b0;
        end
    end

    //No aribe
    always@(*) begin
        if(rd_brust_Req == 1'b1) begin
            rd_brust_start <= 1'b1;
        end else begin
            rd_brust_start <= 1'b0;
        end
    end

    always@(posedge M_AXI_ACLK)
        if(M_AXI_ARESETN == 1'b0) begin
            rd_brust_now <= 1'b0;
        end else if(rd_brust_end == 1'b1 && rd_brust_now == 1'b1) begin
            rd_brust_now <= 1'b0; 
        end else if(rd_brust_start == 1'b1 && rd_brust_now == 1'b0) begin
            rd_brust_now <= 1'b1;
        end else begin
            rd_brust_now <= rd_brust_now; 
        end

// r_start_control----------------------------------------------------------------------------------//

// ar---------------------------------------------------------------------------------------------//

    always@(posedge M_AXI_ACLK) begin
        if(M_AXI_ARESETN == 1'b0) begin
            axi_arvalid <= 1'b0;
        end else if(axi_arvalid==1'b1&&M_AXI_ARREADY==1'b1) begin
            axi_arvalid <= 1'b0;
        end else if(rd_brust_start == 1'b1 && rd_brust_now == 1'b0) begin
            axi_arvalid <= 1'b1;
        end else begin
            axi_arvalid <= axi_arvalid;
        end
    end
    always@(posedge M_AXI_ACLK) begin
        if(M_AXI_ARESETN == 1'b0) begin
            axi_araddr <= 'd0;
        end else if((M_AXI_RVALID == 1'b1)&&(axi_rready == 1'b1)&&(rd_hcnt == C_M_AXI_BURST_LEN - 1)&&(rd_vcnt == rd_burst_times - 1'b1)) begin
            axi_araddr <= rd_base_addr;
        // end else if((M_AXI_RVALID == 1'b1)&&(axi_rready == 1'b1)&&(rd_hcnt == C_M_AXI_BURST_LEN - 1)&&(rd_vcnt == rd_burst_times - 1'b1)) begin
        //     axi_araddr <= 0;
        end else if(axi_arvalid==1'b1&&M_AXI_ARREADY==1'b1) begin
            axi_araddr <= axi_araddr + Araddr_Brust_Offset;    
        end else begin
            axi_araddr <= axi_araddr;
        end
    end
// ar---------------------------------------------------------------------------------------------//

// r----------------------------------------------------------------------------------------------//

    always@(posedge M_AXI_ACLK) begin
        if(M_AXI_ARESETN == 1'b0) begin
            axi_rready <= 1'b0;
        end else if((M_AXI_RVALID == 1'b1)&&(axi_rready == 1'b1)&&(M_AXI_RLAST == 1'b1)) begin
            axi_rready <= 1'b0;
        end else if(axi_arvalid==1'b1&&M_AXI_ARREADY==1'b1) begin
            axi_rready <= 1'b1;
        end else begin
            axi_rready <= axi_rready;
        end
    end
    
// r----------------------------------------------------------------------------------------------//


// r_Sync-----------------------------------------------------------------------------------------//


    assign  rd_fifo_wr_en = (M_AXI_RVALID == 1'b1)&&(axi_rready == 1'b1);
    assign  rd_fifo_wr_data = M_AXI_RDATA;

    assign  rd_fifo_rd_en = I_Post_de && Post_Start;
    assign  O_Post_data = rd_fifo_rd_data[23:0];

    rdata_w64x2048_r32x4096 rdata_w64x2048_r32x4096 (
    .rst    ( (!M_AXI_ARESETN)&&(!rd_start_cnt[2])),  // input wire rst
    .wr_clk ( M_AXI_ACLK            ),  // input wire wr_clk
    .rd_clk ( I_Post_clk            ),  // input wire rd_clk
    .din    ( rd_fifo_wr_data       ),  // input wire [63 : 0] din
    .wr_en  ( rd_fifo_wr_en         ),  // input wire wr_en
    .rd_en  ( rd_fifo_rd_en         ),  // input wire rd_en
    .dout   ( rd_fifo_rd_data       ),  // output wire [31 : 0] dout
    .full   ( full_r                ),  // output wire full
    .empty  ( empty_r               ),  // output wire empty
    .rd_data_count( r_rd_data_count ),  // output wire [12 : 0] rd_data_count
    .wr_data_count( r_wr_data_count ),  // output wire [11 : 0] wr_data_count
    .wr_rst_busy(),                     // output wire wr_rst_busy
    .rd_rst_busy()                      // output wire rd_rst_busy
    );

//hcnt
    always@(posedge M_AXI_ACLK)begin
        if(M_AXI_ARESETN == 1'b0) begin
            rd_hcnt <= 'd0;
        end else if((M_AXI_RVALID == 1'b1)&&(axi_rready == 1'b1)&&(rd_hcnt == C_M_AXI_BURST_LEN - 1)) begin
            rd_hcnt <= 'd0;
        end else if((M_AXI_RVALID == 1'b1)&&(axi_rready == 1'b1)) begin
            rd_hcnt <= rd_hcnt + 1'b1;
        end else begin
            rd_hcnt <= rd_hcnt;
        end
    end
//vcnt
    always@(posedge M_AXI_ACLK)begin
        if(M_AXI_ARESETN == 1'b0) begin
            rd_vcnt <= 'd0;
        end else if((M_AXI_RVALID == 1'b1)&&(axi_rready == 1'b1)&&(rd_hcnt == C_M_AXI_BURST_LEN - 1)&&(rd_vcnt == rd_burst_times - 1'b1)) begin
            rd_vcnt <= 'd0;
        end else if((M_AXI_RVALID == 1'b1)&&(axi_rready == 1'b1)&&(rd_hcnt == C_M_AXI_BURST_LEN - 1)) begin
            rd_vcnt <= rd_vcnt + 1'b1;
        end else begin
            rd_vcnt <= rd_vcnt;
        end
    end

// r_Sync-----------------------------------------------------------------------------------------//

//Test
    reg [15:0]  Test_wr_hcnt;
    reg [15:0]  Test_wr_vcnt;
    reg         r_I_Pre_de;

    always @(posedge I_Pre_clk) begin
        r_I_Pre_de <= I_Pre_de;
    end
    always @(posedge I_Pre_clk) begin
        if(M_AXI_ARESETN == 1'b0) begin
            Test_wr_hcnt <= 'd0;
        end else if(I_Pre_de == 1'b1 && Test_wr_hcnt == 1920-1) begin
            Test_wr_hcnt <= 'd0;
        end else if(I_Pre_de == 1'b1) begin
            Test_wr_hcnt <= Test_wr_hcnt + 1'b1;
        end else begin
            Test_wr_hcnt <= Test_wr_hcnt;
        end
    end

    always @(posedge I_Pre_clk) begin
        if(M_AXI_ARESETN == 1'b0) begin
            Test_wr_vcnt <= 'd0;
        end else if(Nege_pre_vs == 1'b1) begin
            Test_wr_vcnt <= 'd0;
        end else if(I_Pre_de == 1'b0&&r_I_Pre_de == 1'b1) begin
            Test_wr_vcnt <= Test_wr_vcnt + 1'b1;
        end else begin
            Test_wr_vcnt <= Test_wr_vcnt;
        end
    end


    reg [15:0]  Test_rd_hcnt;
    reg [15:0]  Test_rd_vcnt;
    reg         r_I_Post_de ;

    always @(posedge I_Post_clk) begin
        r_I_Post_de <= I_Post_de;
    end
    always @(posedge I_Post_clk) begin
        if(M_AXI_ARESETN == 1'b0) begin
            Test_rd_hcnt <= 'd0;
        end else if(I_Post_vs == 1'b1) begin
            Test_rd_hcnt <= 'd0;
        end else if(I_Post_de == 1'b1 && Test_rd_hcnt == 1920-1) begin
            Test_rd_hcnt <= 'd0;
        end else if(I_Post_de == 1'b1) begin
            Test_rd_hcnt <= Test_rd_hcnt + 1'b1;
        end else begin
            Test_rd_hcnt <= Test_rd_hcnt;
        end
    end

    always @(posedge I_Post_clk) begin
        if(M_AXI_ARESETN == 1'b0) begin
            Test_rd_vcnt <= 'd0;
        end else if(I_Post_vs == 1'b1) begin
            Test_rd_vcnt <= 'd0;
        end else if(I_Post_de == 1'b1&&r_I_Post_de == 1'b0) begin
            Test_rd_vcnt <= Test_rd_vcnt + 1'b1;
        end else begin
            Test_rd_vcnt <= Test_rd_vcnt;
        end
    end

    AXI_ILA AXI_ILA (
    .clk(M_AXI_ACLK), // input wire clk


    .probe0(  I_Pre_de             ), //1
    .probe1(  wr_index             ), //2
    .probe2(  wr_base_addr         ), //32
    .probe3(  w_rd_data_count      ), //12
    .probe4(  full_w               ), //1
    .probe5(  empty_w              ), //1
    .probe6(  wr_brust_Req         ), //1
    .probe7(  wr_brust_end         ), //1
    .probe8(  wr_brust_now         ), //1
    .probe9(  axi_awvalid          ), //1
    .probe10( axi_awaddr           ), //32 
    .probe11( axi_wvalid           ), //1 
    .probe12( wr_burst_cnt         ), //8 
    .probe13( axi_wlast            ), //1 
    .probe14( I_Post_de            ), //1
    .probe15( I_Post_vs            ), //1
    .probe16( I_Pre_vs             ), //1
    .probe17( O_Post_data          ), //24
    .probe18( rd_index_ptr         ), //8
    .probe19( rd_base_addr         ), //32
    .probe20( rd_start_cnt         ), //2
    .probe21( rd_brust_Req         ), //1
    .probe22( r_wr_data_count      ), //12
    .probe23( axi_arvalid          ), //1
    .probe24( axi_araddr           ), //32
    .probe25( axi_rready           ), //1
    .probe26( rd_fifo_wr_en        ),//1 
    .probe27( rd_hcnt              ), //16
    .probe28( rd_vcnt              ), //16
    .probe29( Test_wr_hcnt         ), //16 
    .probe30( Test_wr_vcnt         ), //16 
    .probe31( Test_rd_hcnt         ), //16 
    .probe32( Test_rd_vcnt         ), //16 
    .probe33( full_r               ), //16 
    .probe34( empty_r              )  //16 
);

    endmodule
View Code

【3】:Three-two-pull-down:与帧缓存架构类似;

3:2 pulldown_3:2 pull down-CSDN博客

(2)HDMI输入通道

(3)以太网输入通道:Ps以太网输入:TCP/IP

1.实现方法:

 lwip实现TCP/IP格式的上位机视频收发。

以太网学习之TCP/IP:PC上位机通过Socket连接下发视频至FPGA的若干总结 - NoNounknow - 博客园 (cnblogs.com)

2.实现原理:

TCP/IP LWIP FPGA 笔记-CSDN博客

3.测试手段:自建matlab上位机

上位机建立TCP/IP连接:Matlab实现-CSDN博客

其中一部分比较重要的

pause(0.0001);
write(Client_1,framehead);
pause(0.0001);
for n = 1:image_h
    for m = 1:image_w
        Data_Line_Buf(2 * m -1) = 0;
        if n < image_h/4
            Data_Line_Buf(2 * m) = 64;
        elseif n < image_h/2
            Data_Line_Buf(2 * m) = 128;
        elseif n < image_h/2 + image_h/4
            Data_Line_Buf(2 * m) = 192;
        else
            Data_Line_Buf(2 * m) = 255;
        end
    end
    write(Client_1,Data_Line_Buf)
    pause(0.000001);
end
readreq = read(Client_1, 8, "uint8");
View Code

4.代码:

使用了NoNounknow/DMA: DMA仓库,主要包含了各种操作场景下用的DMA,细节在博客园。 (github.com)的DMA模块;

使用了HDMI等模块;

C代码用的是官方例程稍作修改后的,通过把接受区的地址直接设置为指定的DMA读取地址,可以实现低延迟访问;

一定记得DCACHE刷新数据!

(3)以太网输入通道:PL以太网输入:UDP

解帧:

以太网:UDP包结构 - NoNounknow - 博客园 (cnblogs.com)

CRC:

【CRC校验方法】+【FPGA实现(接收端)】 - NoNounknow - 博客园 (cnblogs.com)

上位机:

Matlab构建上位机:UDP测试 - NoNounknow - 博客园 (cnblogs.com)

防丢包:

UDP接收PC发送数据的丢包处理:同步头 - NoNounknow - 博客园 (cnblogs.com)     

      

posted @ 2024-01-06 12:12  NoNounknow  阅读(41)  评论(0编辑  收藏  举报