以太网学习之TCP/IP:PC上位机通过Socket连接下发视频至FPGA的若干总结

笔记:

TCP/IP LWIP FPGA 笔记-CSDN博客

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

参考:

第一个很精炼简单有效,但我是PC发FPGA而不是FPGA发PC,所以也不是那么有用;

Xilinx ZYNQ+TCP通信+Python上位机 实现实时视频传输系统 - 知乎 (zhihu.com)

千兆以太网视频传输 - LeiWang1999 (leiblog.wang)

【开源、应用】QT—TCP网络上位机的设计_qt上位机-CSDN博客

TCP实时视频传输学习记录【附代码】【含视频】_tcp协议传输视频流-CSDN博客

前期搭建使用的Matlab测试代码:

clc;
clear all; 
close all; 
warning off;

% ConfigPacket Frame Packet
ConfigPacket_Length = 14;% 配置包单帧长
ConfigPacket_Content = zeros(1,ConfigPacket_Length,"uint8");% 配置包单帧内容初始化

image_w = 640;
image_h = 512;

Set_ConfigPacket_Content = [8,image_w,image_h,0];% 配置包内容数组
Set_ConfigPacket_Length = length(Set_ConfigPacket_Content);% 配置包总帧长

Readback_ConfigPacket = zeros(Set_ConfigPacket_Length, ConfigPacket_Length, "uint8");

% Data Frame Packet
framehead = uint8([170,170,170,170,170,170,170,170]);% 配置包单帧内容初始化
Data_Line_Buf = zeros(1, image_w * 2,"uint8");


% Set Connection 
Client_1 = tcpclient("192.168.1.10",10000,"Timeout",20,"ConnectTimeout",30);

for j = 1:Set_ConfigPacket_Length 
    for i = 1:ConfigPacket_Length 
        if i <= 8
            ConfigPacket_Content (i) = 85;% Frame Header
        elseif i == 9
            ConfigPacket_Content (i) = j - 1;% addr
        elseif i == 10
            ConfigPacket_Content (i) = 0;% R/W
        elseif i == 11
            ConfigPacket_Content (i) = uint8(bitand((bitshift(Set_ConfigPacket_Content(j),-24)),255));
        elseif i == 12
            ConfigPacket_Content (i) = uint8(bitand((bitshift(Set_ConfigPacket_Content(j),-16)),255));
        elseif i == 13
            ConfigPacket_Content (i) = uint8(bitand((bitshift(Set_ConfigPacket_Content(j),-8)),255));
        elseif i == 14
            ConfigPacket_Content (i) = uint8(bitand((bitshift(Set_ConfigPacket_Content(j),0)),255));
        end
    end  
    % s is a tcp/ip object
    write(Client_1,ConfigPacket_Content)
    pause(0.0001)
    Readback_ConfigPacket(j, 1:end) = read(Client_1, ConfigPacket_Length, "uint8");
end



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");

clear Client_1;
View Code

整体描述:完成了PC下发图像和读取方式等信息完成配置,通过FPGA收取图像完成处理并HDMI显示;

一.Matlab发送配置包和Ps接收

第一部分:通过上位机软件发送配置包到FPGA PS端,Arm通过解析配置包完成对PL端DMA和HDMI模块的配置,主要配置:图像的高度、宽度、选通模式:

image_w = 640;
image_h = 512;

Set_ConfigPacket_Content = [0,image_w,image_h,0];% 配置包内容数组
Set_ConfigPacket_Length = length(Set_ConfigPacket_Content);% 配置包总帧长
View Code

1.1.配置包要自定义合适的包头,并且根据包头解析;

1.2 此过程中,TCP/IP上位机由于发送过快,难以完成相关任务,而本人暂时没有学好QT,打算之后再进行拓展;

1.3 为了完成下文中的三帧缓存,每发完一帧需要Arm端接收并且通信FPGA完成读取地址的切换;

1.4 为了保障读取数据的准确。要使用DCACHE相关函数完成及时的数据刷新;

二.Pl读取配置和DMA设置

第二部分:PS端将配置包存入指定的寄存器地址,通过GP口读出,Pl端接收这部分配置,输入到DMA和HDMI模块;

2.1 DMA配置

这部分配置决定了DMA读取一帧的大小,便于设立缓冲区,同时吩咐HDMI模块完成开窗;

2.1.1 通过乘法器完成缓冲区的大小计算:

需要使用一个乘法器,通过乘好长宽高来完成缓冲区的设置;

部分代码:

//========================================= 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 =========================================//
 
View Code
    always @(posedge M_AXI_ACLK) begin
        r1_I_D_Size <= I_D_Size   ;
        r2_I_D_Size <= r1_I_D_Size;   
    end
    // D_Size_Enable Mode
    // 1 Pixel = 16bit = 2 byte
    assign  D_Total_Frame_Offset = {r2_I_D_Size,1'b0};
    // brust length = 256 = 2^8 data width = 64 
    // 256x64/8 = 256x8 = 1024x2 = 2048
    // D_Total_Frame_Offset / 2048 = I_D_Size / 1024
    assign  D_rd_burst_times = r2_I_D_Size[23:10];
View Code
    always@(posedge M_AXI_ACLK)begin
        if(M_AXI_ARESETN == 1'b0) begin
            rd_vcnt <= 'd0;
        end else if((D_Size_Enable[0] == 1'b0)&&(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((D_Size_Enable[0] == 1'b1)&&(M_AXI_RVALID == 1'b1)&&(axi_rready == 1'b1)&&(rd_hcnt == C_M_AXI_BURST_LEN - 1)&&(rd_vcnt == D_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
View Code
    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(D_Size_Enable[0] == 1'b0 && sys_Nege_pre_vs == 1'b1) begin
            wr_base_addr <= wr_base_addr + Total_Frame_Offset;
        end else if(D_Size_Enable[0] == 1'b1 && sys_Nege_pre_vs == 1'b1) begin
            wr_base_addr <= wr_base_addr + D_Total_Frame_Offset;
        end else begin
            wr_base_addr <= wr_base_addr;
        end
View Code

完整代码:

  1 `timescale 1 ns / 1 ps
  2 
  3     module DMA_Loop_top #
  4     (
  5         parameter         WR_Base_addr                  = 32'h2000000,
  6         parameter         RD_Base_addr                  = 32'h2000000,
  7         parameter integer C_M_AXI_BURST_LEN             = 256  ,
  8         parameter integer C_M_AXI_ID_WIDTH              = 1    ,
  9         parameter integer C_M_AXI_ADDR_WIDTH            = 32   ,
 10         parameter integer C_M_AXI_DATA_WIDTH            = 64   ,
 11         parameter integer C_M_AXI_AWUSER_WIDTH          = 0    ,
 12         parameter integer C_M_AXI_ARUSER_WIDTH          = 0    ,
 13         parameter integer C_M_AXI_WUSER_WIDTH           = 0    ,
 14         parameter integer C_M_AXI_RUSER_WIDTH           = 0    ,
 15         parameter integer C_M_AXI_BUSER_WIDTH           = 0    ,
 16         parameter         I_image_w                     = 1920 ,
 17         parameter         I_image_h                     = 1080 ,
 18         parameter         Pixel_byte_num                = 4    ,
 19         parameter         AXI_Buff_NUM                  = 3    ,
 20         parameter         Input_Data_width              = 24   ,
 21         parameter         WR_CH_EN                      = 1    ,
 22         parameter         RD_CH_EN                      = 1    ,
 23         parameter         D_Size_Enable                 = 1
 24     )
 25     (
 26         input    wire                              M_AXI_ACLK    ,
 27         input    wire                              M_AXI_ARESETN ,
 28         output   wire [C_M_AXI_ID_WIDTH-1 : 0]     M_AXI_AWID    ,
 29         output   wire [C_M_AXI_ADDR_WIDTH-1 : 0]   M_AXI_AWADDR  ,
 30         output   wire [7 : 0]                      M_AXI_AWLEN   ,
 31         output   wire [2 : 0]                      M_AXI_AWSIZE  ,
 32         output   wire [1 : 0]                      M_AXI_AWBURST ,
 33         output   wire                              M_AXI_AWLOCK  ,
 34         output   wire [3 : 0]                      M_AXI_AWCACHE ,
 35         output   wire [2 : 0]                      M_AXI_AWPROT  ,
 36         output   wire [3 : 0]                      M_AXI_AWQOS   ,
 37         output   wire [C_M_AXI_AWUSER_WIDTH-1 : 0] M_AXI_AWUSER  ,
 38         output   wire                              M_AXI_AWVALID ,
 39         input    wire                              M_AXI_AWREADY ,
 40 
 41         output   wire [C_M_AXI_DATA_WIDTH-1 : 0]   M_AXI_WDATA   ,
 42         output   wire [C_M_AXI_DATA_WIDTH/8-1 : 0] M_AXI_WSTRB   ,
 43         output   wire                              M_AXI_WLAST   ,
 44         output   wire [C_M_AXI_WUSER_WIDTH-1 : 0]  M_AXI_WUSER   ,
 45         output   wire                              M_AXI_WVALID  ,
 46         input    wire                              M_AXI_WREADY  ,
 47 
 48         input    wire [C_M_AXI_ID_WIDTH-1 : 0]     M_AXI_BID,
 49         input    wire [1 : 0]                      M_AXI_BRESP   ,
 50         input    wire [C_M_AXI_BUSER_WIDTH-1 : 0]  M_AXI_BUSER   ,
 51         input    wire                              M_AXI_BVALID  ,
 52         output   wire                              M_AXI_BREADY  ,
 53 
 54         output   wire [C_M_AXI_ID_WIDTH-1 : 0]     M_AXI_ARID    ,
 55         output   wire [C_M_AXI_ADDR_WIDTH-1 : 0]   M_AXI_ARADDR  ,
 56         output   wire [7 : 0]                      M_AXI_ARLEN   ,
 57         output   wire [2 : 0]                      M_AXI_ARSIZE  ,
 58         output   wire [1 : 0]                      M_AXI_ARBURST ,
 59         output   wire                              M_AXI_ARLOCK  ,
 60         output   wire [3 : 0]                      M_AXI_ARCACHE ,
 61         output   wire [2 : 0]                      M_AXI_ARPROT  ,
 62         output   wire [3 : 0]                      M_AXI_ARQOS   ,
 63         output   wire [C_M_AXI_ARUSER_WIDTH-1 : 0] M_AXI_ARUSER  ,
 64         output   wire                              M_AXI_ARVALID ,
 65         input    wire                              M_AXI_ARREADY ,
 66 
 67         input    wire [C_M_AXI_ID_WIDTH-1 : 0]     M_AXI_RID     ,
 68         input    wire [C_M_AXI_DATA_WIDTH-1 : 0]   M_AXI_RDATA   ,
 69         input    wire [1 : 0]                      M_AXI_RRESP   ,
 70         input    wire                              M_AXI_RLAST   ,
 71         input    wire [C_M_AXI_RUSER_WIDTH-1 : 0]  M_AXI_RUSER   ,
 72         input    wire                              M_AXI_RVALID  ,
 73         output   wire                              M_AXI_RREADY  ,
 74 
 75         //Custom
 76         input    wire  [7:0]                       I_wr_index        ,// 仅读通道下接受所读取帧的位置;
 77         input    wire                              I_rd_start        ,
 78         input    wire  [23:0]                      I_D_Size          ,
 79         //Aribe-----------------------------------------------------//
 80         output   wire                              O_wr_req          ,
 81         input    wire                              I_Aribe_wr_enable ,
 82         output   wire                              O_wr_brust_now    ,
 83         output   wire                              O_wr_brust_end    ,             
 84 
 85         output   wire                              O_rd_req          ,
 86         input    wire                              I_Aribe_rd_enable ,
 87         output   wire                              O_rd_brust_now    ,
 88         output   wire                              O_rd_brust_end    ,
 89         //Aribe-----------------------------------------------------//
 90         input    wire                              I_Pre_clk     ,
 91         input    wire                              I_Pre_vs      ,
 92         input    wire  [Input_Data_width-1:0]      I_Pre_data    ,
 93         input    wire                              I_Pre_de      ,        
 94 
 95         input    wire                              I_Post_clk   ,
 96         output   wire                              O_Post_Start ,//Reset Post Module
 97         output   wire  [16-1:0]                    O_Post_data  ,
 98         input    wire                              I_Post_de    ,
 99         input    wire                              I_Post_vs           
100     );
101                      
102     function integer clogb2 (input integer bit_depth);              
103       begin                                                           
104         for(clogb2=0; bit_depth>0; clogb2=clogb2+1)                   
105           bit_depth = bit_depth >> 1;                                 
106         end                                                           
107     endfunction                                                     
108     
109 //========================================= Define Ports =========================================//
110     localparam integer C_TRANSACTIONS_NUM   = clogb2(C_M_AXI_BURST_LEN-1)                   ;
111 
112     localparam         Awaddr_Brust_Offset  = (C_M_AXI_DATA_WIDTH)*(C_M_AXI_BURST_LEN)/8    ;
113     localparam         Araddr_Brust_Offset  = (C_M_AXI_DATA_WIDTH)*(C_M_AXI_BURST_LEN)/8    ;
114     localparam         Total_Frame_Offset   = I_image_w*I_image_h*Pixel_byte_num            ;
115     localparam         RAM_1_start_addr     = 0                                             ;
116     localparam         RAM_2_start_addr     = Total_Frame_Offset                            ;
117     localparam         RAM_3_start_addr     = Total_Frame_Offset*2                          ;
118 
119     localparam         wr_burst_times       = I_image_w*I_image_h*Pixel_byte_num /Awaddr_Brust_Offset        ;    
120     localparam         rd_burst_times       = I_image_w*I_image_h*Pixel_byte_num /Araddr_Brust_Offset        ;
121 
122 //========================================= Define Ports =========================================//
123  
124     // AXI4LITE signals
125     //AXI4 internal temp signals
126     reg  [C_M_AXI_ADDR_WIDTH-1 : 0]  axi_awaddr      ;
127     reg                              axi_awvalid     ;
128   
129     reg                              axi_wlast       ;
130     reg                              axi_wvalid      ;
131     reg  [C_TRANSACTIONS_NUM-1:0]    wr_burst_cnt    ;
132 
133     reg                              axi_bready      ;
134   
135     reg  [C_M_AXI_ADDR_WIDTH-1 : 0]  axi_araddr      ;
136     reg                              axi_arvalid     ;
137     reg                              axi_rready      ;
138 
139       //W_FIFO
140     wire                              wr_fifo_wr_en    ;
141     wire [C_M_AXI_DATA_WIDTH-1 : 0]   wr_fifo_wr_data  ;
142     wire                              wr_fifo_rd_en    ; 
143     wire [C_M_AXI_DATA_WIDTH-1 : 0]   wr_fifo_rd_data  ;
144     wire                              full_w           ;
145     wire                              empty_w          ;
146     wire [15 : 0]                     w_rd_data_count  ;
147     wire [15 : 0]                     w_wr_data_count  ;
148     
149       //r_FIFO
150     wire                              rd_fifo_wr_en    ;
151     wire [C_M_AXI_DATA_WIDTH-1 : 0]   rd_fifo_wr_data  ;
152 
153     wire                              rd_fifo_rd_en    ; 
154     wire [15 : 0]                     rd_fifo_rd_data  ;
155 
156     wire [15 : 0]                     r_rd_data_count  ;
157     wire [15 : 0]                     r_wr_data_count  ;
158     wire                              full_r           ;
159     wire                              empty_r          ;
160 
161     reg  [15:0]                       rd_hcnt          ;
162     reg  [15:0]                       rd_vcnt          ;
163 
164     //  D_Size parameter
165     reg  [23:0]                       r1_I_D_Size         ;
166     reg  [23:0]                       r2_I_D_Size         ;
167     wire [24:0]                       D_Total_Frame_Offset;
168     wire [24:0]                       D_rd_burst_times    ;
169 
170     always @(posedge M_AXI_ACLK) begin
171         r1_I_D_Size <= I_D_Size   ;
172         r2_I_D_Size <= r1_I_D_Size;   
173     end
174     // D_Size_Enable Mode
175     // 1 Pixel = 16bit = 2 byte
176     assign  D_Total_Frame_Offset = {r2_I_D_Size,1'b0};
177     // brust length = 256 = 2^8 data width = 64 
178     // 256x64/8 = 256x8 = 1024x2 = 2048
179     // D_Total_Frame_Offset / 2048 = I_D_Size / 1024
180     assign  D_rd_burst_times = r2_I_D_Size[23:10];
181 
182     //I/O Connections. Write Address (AW)
183     assign M_AXI_AWID       = 'b0;
184     assign M_AXI_AWADDR     = WR_Base_addr + axi_awaddr;
185     assign M_AXI_AWLEN      = C_M_AXI_BURST_LEN - 1;
186     assign M_AXI_AWSIZE     = clogb2((C_M_AXI_DATA_WIDTH/8)-1);
187     assign M_AXI_AWBURST    = 2'b01;
188     assign M_AXI_AWLOCK     = 1'b0;
189     assign M_AXI_AWCACHE    = 4'b0010;
190     assign M_AXI_AWPROT     = 3'h0;
191     assign M_AXI_AWQOS      = 4'h0;
192     assign M_AXI_AWUSER     = 'b1;
193     assign M_AXI_AWVALID    = axi_awvalid;
194     //Write Data(W)
195     assign wr_fifo_rd_en    = (axi_wvalid == 1'b1)&&(M_AXI_WREADY == 1'b1);
196     assign M_AXI_WDATA      = wr_fifo_rd_data;
197     //All bursts are complete and aligned in this example
198     assign M_AXI_WSTRB      = {(C_M_AXI_DATA_WIDTH/8){1'b1}};
199     assign M_AXI_WLAST      = axi_wlast;
200     assign M_AXI_WUSER      = 'b0;
201     assign M_AXI_WVALID     = axi_wvalid;
202     //Write Response (B)
203     assign M_AXI_BREADY     = axi_bready;
204     //Read Address (AR)
205     assign M_AXI_ARID       = 'b0;
206     assign M_AXI_ARADDR     = RD_Base_addr + axi_araddr;
207     assign M_AXI_ARLEN      = C_M_AXI_BURST_LEN - 1;
208     assign M_AXI_ARSIZE     = clogb2((C_M_AXI_DATA_WIDTH/8)-1);
209     assign M_AXI_ARBURST    = 2'b01;
210     assign M_AXI_ARLOCK     = 1'b0;
211     assign M_AXI_ARCACHE    = 4'b0010;
212     assign M_AXI_ARPROT     = 3'h0;
213     assign M_AXI_ARQOS      = 4'h0;
214     assign M_AXI_ARUSER     = 'b1;
215     assign M_AXI_ARVALID    = axi_arvalid;
216     //Read and Read Response (R)
217     assign M_AXI_RREADY     = axi_rready;
218 
219 // Wr_Sync------------------------------------------------------------------------------------------//
220 
221     //W Sync Port
222     //wrclk
223     reg                               r1_pre_vs        ;
224     wire                              Pose_pre_vs      ;
225     wire                              Nege_pre_vs      ;
226     wire                              Ext_Pose_pre_vs  ;
227     //sysclk
228     reg                               sys_pre_vs       ;
229     reg                               r1_sys_pre_vs    ;
230     reg                               sys_Pose_pre_vs  ;
231     reg                               sys_Nege_pre_vs  ;
232     reg                               r_sys_Nege_pre_vs;
233     reg  [1:0]                        wr_index         ;
234     reg   [C_M_AXI_ADDR_WIDTH-1 : 0]  wr_base_addr     ;
235     
236     always @(posedge I_Pre_clk) begin
237         r1_pre_vs <= I_Pre_vs;
238     end
239 
240     assign  Pose_pre_vs = (I_Pre_vs == 1'b1)&&(r1_pre_vs == 1'b0);
241     assign  Nege_pre_vs = (I_Pre_vs == 1'b0)&&(r1_pre_vs == 1'b1);
242 
243     always@(posedge M_AXI_ACLK) begin
244         sys_pre_vs        <= I_Pre_vs  ;
245         r1_sys_pre_vs     <= sys_pre_vs;
246         r_sys_Nege_pre_vs <= sys_Nege_pre_vs;
247     end
248 
249     always @(posedge M_AXI_ACLK) begin
250         if(M_AXI_ARESETN == 1'b0) begin
251             sys_Pose_pre_vs <= 1'b0;
252             sys_Nege_pre_vs <= 1'b0;
253         end else if(sys_pre_vs==1'b1&&r1_sys_pre_vs==1'b0) begin
254             sys_Pose_pre_vs <= 1'b1;
255             sys_Nege_pre_vs <= 1'b0; 
256         end else if(sys_pre_vs==1'b0&&r1_sys_pre_vs==1'b1) begin
257             sys_Pose_pre_vs <= 1'b0;
258             sys_Nege_pre_vs <= 1'b1; 
259         end else begin
260             sys_Pose_pre_vs <= 1'b0;
261             sys_Nege_pre_vs <= 1'b0;
262         end
263     end
264 
265 
266     Data_sync_ext Data_sync_ext_Inst0(
267         .clka           ( I_Pre_clk          ),
268         .rst_n          ( M_AXI_ARESETN      ),    
269         .pulse_a        ( Pose_pre_vs        ),
270         .ext_pulse_a    ( Ext_Pose_pre_vs    )
271     );
272 
273     always@(posedge M_AXI_ACLK)
274         if(M_AXI_ARESETN == 1'b0) begin
275             wr_index <= 'd1;
276         end else if(sys_Nege_pre_vs == 1'b1&&wr_index == AXI_Buff_NUM) begin
277             wr_index <= 'd1;
278         end else if(sys_Nege_pre_vs==1'b1) begin
279             wr_index <= wr_index + 1'b1;
280         end else begin
281             wr_index <= wr_index;
282         end
283             
284     always@(posedge M_AXI_ACLK)
285         if(M_AXI_ARESETN == 1'b0) begin
286             wr_base_addr <= 0;
287         end else if(sys_Nege_pre_vs == 1'b1&&wr_index == AXI_Buff_NUM) begin
288             wr_base_addr <= 0;
289         end else if(D_Size_Enable[0] == 1'b0 && sys_Nege_pre_vs == 1'b1) begin
290             wr_base_addr <= wr_base_addr + Total_Frame_Offset;
291         end else if(D_Size_Enable[0] == 1'b1 && sys_Nege_pre_vs == 1'b1) begin
292             wr_base_addr <= wr_base_addr + D_Total_Frame_Offset;
293         end else begin
294             wr_base_addr <= wr_base_addr;
295         end
296 
297 // Wr_Sync------------------------------------------------------------------------------------------//
298 
299     assign  wr_fifo_wr_en = I_Pre_de;
300     assign  wr_fifo_wr_data = {8'h0,I_Pre_data};
301 
302 generate
303   if (WR_CH_EN[0]==1) begin: WR_EN
304     wdata_w64x1024_r64x1024 wdata_w32x4096_r64x2048 (
305     .rst        ( (!M_AXI_ARESETN)|(Ext_Pose_pre_vs)),  // input wire rst
306     .wr_clk     ( I_Pre_clk                         ),  // input wire wr_clk
307     .rd_clk     ( M_AXI_ACLK                        ),  // input wire rd_clk
308     .din        ( wr_fifo_wr_data                   ),  // input wire [63 : 0] din
309     .wr_en      ( wr_fifo_wr_en                     ),  // input wire wr_en
310     .rd_en      ( wr_fifo_rd_en                     ),  // input wire rd_en
311     .dout       ( wr_fifo_rd_data                   ),  // output wire [63 : 0] dout
312     .full       ( full_w                            ),  // output wire full
313     .empty      ( empty_w                           ),  // output wire empty
314     .rd_data_count(w_rd_data_count ),            // output wire [10 : 0] rd_data_count
315     .wr_data_count(w_wr_data_count ),            // output wire [10 : 0] wr_data_count
316     .wr_rst_busy(),                // output wire wr_rst_busy
317     .rd_rst_busy()                 // output wire rd_rst_busy
318     );
319   end
320 endgenerate
321 
322 // w_start_control----------------------------------------------------------------------------------//
323 
324     //Control
325     reg                              wr_brust_start  ;
326     wire                             wr_brust_Req    ;            
327     wire                             wr_brust_end    ;
328     reg                              wr_brust_now    ;
329 
330     assign    wr_brust_Req   = (w_rd_data_count>=C_M_AXI_BURST_LEN);
331     assign    wr_brust_end   = (axi_wvalid==1'b1&&M_AXI_WREADY==1'b1&&wr_burst_cnt==C_M_AXI_BURST_LEN-1);
332     assign    O_wr_req       = wr_brust_Req;
333     assign    O_wr_brust_now = wr_brust_now;
334     assign    O_wr_brust_end = wr_brust_end;
335 
336     //多路输入的时候,wr_brust_Req输出到仲裁器中,使用仲裁器输出的aribe_req请求完成此处wr_brust_Req的工作
337     always@(*)
338         if(WR_CH_EN[0] == 1'b1 && wr_brust_Req == 1'b1 && I_Aribe_wr_enable == 1'b1) begin
339             wr_brust_start <= 1'b1;
340         end else begin
341             wr_brust_start <= 1'b0; 
342         end
343     
344     always@(posedge M_AXI_ACLK)
345         if(M_AXI_ARESETN == 1'b0) begin
346             wr_brust_now <= 1'b0;
347         end else if(wr_brust_end == 1'b1 && wr_brust_now == 1'b1) begin
348             wr_brust_now <= 1'b0; 
349         end else if(wr_brust_start == 1'b1 && wr_brust_now == 1'b0) begin
350             wr_brust_now <= 1'b1;
351         end else begin
352             wr_brust_now <= wr_brust_now; 
353         end
354 
355 // w_start_control----------------------------------------------------------------------------------//
356 
357 // Aw------ --------------------------------------------------------------------------------------//
358 
359  //axi_awvalid
360     always@(posedge M_AXI_ACLK)
361         if(M_AXI_ARESETN == 1'b0) begin
362             axi_awvalid <= 1'b0;
363         end else if(axi_awvalid == 1'b1 && M_AXI_AWREADY == 1'b1) begin
364             axi_awvalid <= 1'b0;
365         end else if(wr_brust_start == 1'b1 && wr_brust_now == 1'b0) begin
366             axi_awvalid <= 1'b1; 
367         end else begin
368             axi_awvalid <= axi_awvalid;
369         end
370 
371  //axi_awaddr
372     always@(posedge M_AXI_ACLK)
373         if(M_AXI_ARESETN == 1'b0) begin
374             axi_awaddr <= 'd0;
375         end else if(r_sys_Nege_pre_vs == 1'b1) begin
376             axi_awaddr <= wr_base_addr;
377         // end else if(r_sys_Nege_pre_vs == 1'b1) begin
378         //     axi_awaddr <= 0;
379         end else if(axi_awvalid==1'b1 && M_AXI_AWREADY==1'b1) begin
380             axi_awaddr <= axi_awaddr + Awaddr_Brust_Offset ;  
381         end else begin
382             axi_awaddr <= axi_awaddr;
383         end
384 
385 // Aw---------------------------------------------------------------------------------------------//
386 
387 // W----------------------------------------------------------------------------------------------//
388  //axi_wvalid
389     always@(posedge M_AXI_ACLK)
390         if(M_AXI_ARESETN == 1'b0) begin
391             axi_wvalid <= 1'b0;
392         end else if(axi_wvalid==1'b1&&M_AXI_WREADY==1'b1&&wr_burst_cnt==C_M_AXI_BURST_LEN-1) begin
393             axi_wvalid <= 1'b0;
394         end else if(axi_awvalid==1'b1&&M_AXI_AWREADY==1'b1) begin
395             axi_wvalid <= 1'b1;
396         end else begin
397             axi_wvalid <= axi_wvalid;
398         end 
399 
400  //wr_burst_cnt
401     always@(posedge M_AXI_ACLK) begin
402         if(M_AXI_ARESETN == 1'b0) begin
403             wr_burst_cnt <= 'd0;
404         end else if(axi_wvalid==1'b1&&M_AXI_WREADY==1'b1&&wr_burst_cnt==C_M_AXI_BURST_LEN-1) begin
405             wr_burst_cnt <= 'd0;
406         end else if(axi_wvalid==1'b1&&M_AXI_WREADY==1'b1) begin
407             wr_burst_cnt <= wr_burst_cnt + 1'b1;
408         end else begin
409             wr_burst_cnt <= wr_burst_cnt;
410         end
411     end
412 
413  //axi_wlast
414     always@(posedge M_AXI_ACLK) begin
415         if(M_AXI_ARESETN == 1'b0) begin
416             axi_wlast <= 1'b0;
417         end else if(axi_wvalid==1'b1&&M_AXI_WREADY==1'b1&&wr_burst_cnt==C_M_AXI_BURST_LEN-1'b1) begin
418             axi_wlast <= 1'b0;
419         end else if(axi_wvalid==1'b1&&M_AXI_WREADY==1'b1&&wr_burst_cnt==C_M_AXI_BURST_LEN-2'd2) begin
420             axi_wlast <= 1'b1;
421         end else begin
422             axi_wlast <= axi_wlast;
423         end
424     end
425 
426 // W----------------------------------------------------------------------------------------------//
427 
428 // b----------------------------------------------------------------------------------------------//
429 
430     always @(posedge M_AXI_ACLK) begin
431         if(M_AXI_ARESETN == 0) begin
432             axi_bready <= 'd0;
433         end else begin
434             axi_bready <= 1'b1;
435         end
436     end
437 
438 // b----------------------------------------------------------------------------------------------//
439 
440 // r_start_control----------------------------------------------------------------------------------//
441 
442     //Control
443     reg [7:0]                        rd_index         ;
444     reg [7:0]                        rd_index_ptr     ;
445     reg [C_M_AXI_ADDR_WIDTH-1 : 0]   rd_base_addr     ;
446 
447     reg                              rd_start_cycle   ;
448     reg [2:0]                        rd_start_cnt     ;
449     reg                              rd_brust_start   ;
450     reg                              rd_brust_Req     ;            
451     reg                              rd_brust_end     ;
452     reg                              rd_brust_now     ;
453     reg                              Post_Start       ;
454 
455     always@(posedge M_AXI_ACLK) begin
456         if(M_AXI_ARESETN == 0) begin
457             rd_index <= 0;
458         end else case (WR_CH_EN[0])
459             1'b0:begin
460                 if(I_wr_index > 1) begin
461                     rd_index <= I_wr_index - 1'b1;
462                 end else begin
463                     rd_index <= AXI_Buff_NUM;
464                 end
465             end 
466             1'b1:begin
467                 if(wr_index > 1) begin
468                     rd_index <= wr_index - 1'b1;
469                 end else begin
470                     rd_index <= AXI_Buff_NUM;
471                 end
472             end
473             default: begin
474                 rd_index <= rd_index;
475             end
476         endcase
477     end
478 
479     always@(posedge M_AXI_ACLK) begin
480         if(M_AXI_ARESETN == 0) begin
481             rd_index_ptr <= 'd0;
482         end else begin
483             rd_index_ptr <= rd_index - 1'b1; 
484         end
485     end
486 
487     always@(posedge M_AXI_ACLK) begin
488         if(M_AXI_ARESETN == 0) begin
489             rd_base_addr <= 'd0;
490         end else if(D_Size_Enable[0] == 1'b0) begin
491             rd_base_addr <= rd_index_ptr*Total_Frame_Offset; 
492         end else if(D_Size_Enable[0] == 1'b1) begin
493             case (rd_index_ptr)
494                 8'd0:begin
495                     rd_base_addr <= 'd0;
496                 end 
497                 8'd1:begin
498                     rd_base_addr <= D_Total_Frame_Offset;
499                 end 
500                 8'd2:begin
501                     rd_base_addr <= {D_Total_Frame_Offset,1'b0};
502                 end 
503                 default:begin
504                     rd_base_addr <= 'd0;
505                 end 
506             endcase
507         end
508     end
509 
510     always@(posedge M_AXI_ACLK) begin
511         if(M_AXI_ARESETN == 0) begin
512             rd_start_cnt <= 'd0;
513         end else if(sys_Nege_pre_vs == 1'b1 && rd_start_cnt[2] != 1'b1 && WR_CH_EN[0] == 1'b1) begin
514             rd_start_cnt <= rd_start_cnt + 1'b1;
515         end else if(I_rd_start == 1'b1 && WR_CH_EN[0] == 1'b0) begin
516             rd_start_cnt <= rd_start_cnt + 1'b1;
517         end else begin
518             rd_start_cnt <= rd_start_cnt;
519         end
520     end
521 
522     always@(posedge M_AXI_ACLK) begin
523         if(M_AXI_ARESETN == 0) begin
524             rd_start_cycle <= 1'b0;
525         end else if(rd_start_cnt[2] == 1'b1 && full_r == 1'b0) begin
526             rd_start_cycle <= 1'b1;
527         end else begin
528             rd_start_cycle <= rd_start_cycle;
529         end
530     end
531 
532     always@(posedge I_Post_clk)
533         if(M_AXI_ARESETN == 0) begin
534             Post_Start <= 1'b0;
535         end else if(rd_start_cycle == 1'b1 && r_rd_data_count >= C_M_AXI_BURST_LEN) begin
536             Post_Start <= 1'b1;
537         end  else begin
538             Post_Start <= Post_Start;
539         end
540 
541     assign  O_Post_Start   =  Post_Start  ;
542     assign  O_rd_req       =  rd_brust_Req;
543     assign  O_rd_brust_now =  rd_brust_now;
544     assign  O_rd_brust_end =  rd_brust_end;
545 
546 
547     always @(*) begin
548         if((RD_CH_EN[0] == 1'b1) && (rd_start_cycle == 1'b1) && (r_wr_data_count < C_M_AXI_BURST_LEN*4)) begin
549             rd_brust_Req <= 1'b1;
550         end else begin
551             rd_brust_Req <= 1'b0;
552         end
553     end
554 
555     always@(*) begin
556         if((M_AXI_RVALID == 1'b1)&&(axi_rready == 1'b1)&&(M_AXI_RLAST == 1'b1)) begin
557             rd_brust_end <= 1'b1;
558         end else begin
559             rd_brust_end <= 1'b0;
560         end
561     end
562 
563     //No aribe
564     always@(*) begin
565         if(rd_brust_Req == 1'b1 && I_Aribe_rd_enable == 1'b1) begin
566             rd_brust_start <= 1'b1;
567         end else begin
568             rd_brust_start <= 1'b0;
569         end
570     end
571 
572     always@(posedge M_AXI_ACLK)
573         if(M_AXI_ARESETN == 1'b0) begin
574             rd_brust_now <= 1'b0;
575         end else if(rd_brust_end == 1'b1 && rd_brust_now == 1'b1) begin
576             rd_brust_now <= 1'b0; 
577         end else if(rd_brust_start == 1'b1 && rd_brust_now == 1'b0) begin
578             rd_brust_now <= 1'b1;
579         end else begin
580             rd_brust_now <= rd_brust_now; 
581         end
582 
583 // r_start_control----------------------------------------------------------------------------------//
584 
585 // ar---------------------------------------------------------------------------------------------//
586 
587     always@(posedge M_AXI_ACLK) begin
588         if(M_AXI_ARESETN == 1'b0) begin
589             axi_arvalid <= 1'b0;
590         end else if(axi_arvalid==1'b1&&M_AXI_ARREADY==1'b1) begin
591             axi_arvalid <= 1'b0;
592         end else if(rd_brust_start == 1'b1 && rd_brust_now == 1'b0) begin
593             axi_arvalid <= 1'b1;
594         end else begin
595             axi_arvalid <= axi_arvalid;
596         end
597     end
598     always@(posedge M_AXI_ACLK) begin
599         if(M_AXI_ARESETN == 1'b0) begin
600             axi_araddr <= 'd0;
601         end else if((D_Size_Enable[0] == 1'b0)&&(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
602             axi_araddr <= rd_base_addr;
603         end else if((D_Size_Enable[0] == 1'b1)&&(M_AXI_RVALID == 1'b1)&&(axi_rready == 1'b1)&&(rd_hcnt == C_M_AXI_BURST_LEN - 1)&&(rd_vcnt == D_rd_burst_times - 1'b1)) begin
604             axi_araddr <= rd_base_addr;
605         end else if(axi_arvalid==1'b1&&M_AXI_ARREADY==1'b1) begin
606             axi_araddr <= axi_araddr + Araddr_Brust_Offset;    
607         end else begin
608             axi_araddr <= axi_araddr;
609         end
610     end
611 // ar---------------------------------------------------------------------------------------------//
612 
613 // r----------------------------------------------------------------------------------------------//
614 
615     always@(posedge M_AXI_ACLK) begin
616         if(M_AXI_ARESETN == 1'b0) begin
617             axi_rready <= 1'b0;
618         end else if((M_AXI_RVALID == 1'b1)&&(axi_rready == 1'b1)&&(M_AXI_RLAST == 1'b1)) begin
619             axi_rready <= 1'b0;
620         end else if(axi_arvalid==1'b1&&M_AXI_ARREADY==1'b1) begin
621             axi_rready <= 1'b1;
622         end else begin
623             axi_rready <= axi_rready;
624         end
625     end
626     
627 // r----------------------------------------------------------------------------------------------//
628 
629 
630 // r_Sync-----------------------------------------------------------------------------------------//
631 
632 
633     assign  rd_fifo_wr_en = (M_AXI_RVALID == 1'b1)&&(axi_rready == 1'b1);
634     // assign  rd_fifo_wr_data = M_AXI_RDATA;
635     assign  rd_fifo_wr_data = {M_AXI_RDATA[15:0],M_AXI_RDATA[31:16],M_AXI_RDATA[47:32],M_AXI_RDATA[63:48]};
636 
637     assign  rd_fifo_rd_en = I_Post_de && Post_Start;
638     assign  O_Post_data = rd_fifo_rd_data;
639 
640 generate
641   if (RD_CH_EN[0]==1) begin: RD_EN
642     as_rdata_w64x2048_r16x8192 as_rdata_w64x2048_r16x8192 (
643     .rst    ( (!M_AXI_ARESETN)&&(!rd_start_cnt[2])),  // input wire rst
644     .wr_clk ( M_AXI_ACLK            ),  // input wire wr_clk
645     .rd_clk ( I_Post_clk            ),  // input wire rd_clk
646     .din    ( rd_fifo_wr_data       ),  // input wire [63 : 0] din
647     .wr_en  ( rd_fifo_wr_en         ),  // input wire wr_en
648     .rd_en  ( rd_fifo_rd_en         ),  // input wire rd_en
649     .dout   ( rd_fifo_rd_data       ),  // output wire [15 : 0] dout
650     .full   ( full_r                ),  // output wire full
651     .empty  ( empty_r               ),  // output wire empty
652     .rd_data_count( r_rd_data_count ),  // output wire [13 : 0] rd_data_count
653     .wr_data_count( r_wr_data_count ),  // output wire [11 : 0] wr_data_count
654     .wr_rst_busy(),                     // output wire wr_rst_busy
655     .rd_rst_busy()                      // output wire rd_rst_busy
656     );
657   end
658 endgenerate
659 
660 //hcnt
661     always@(posedge M_AXI_ACLK)begin
662         if(M_AXI_ARESETN == 1'b0) begin
663             rd_hcnt <= 'd0;
664         end else if((M_AXI_RVALID == 1'b1)&&(axi_rready == 1'b1)&&(rd_hcnt == C_M_AXI_BURST_LEN - 1)) begin
665             rd_hcnt <= 'd0;
666         end else if((M_AXI_RVALID == 1'b1)&&(axi_rready == 1'b1)) begin
667             rd_hcnt <= rd_hcnt + 1'b1;
668         end else begin
669             rd_hcnt <= rd_hcnt;
670         end
671     end
672 //vcnt
673     always@(posedge M_AXI_ACLK)begin
674         if(M_AXI_ARESETN == 1'b0) begin
675             rd_vcnt <= 'd0;
676         end else if((D_Size_Enable[0] == 1'b0)&&(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
677             rd_vcnt <= 'd0;
678         end else if((D_Size_Enable[0] == 1'b1)&&(M_AXI_RVALID == 1'b1)&&(axi_rready == 1'b1)&&(rd_hcnt == C_M_AXI_BURST_LEN - 1)&&(rd_vcnt == D_rd_burst_times - 1'b1)) begin
679             rd_vcnt <= 'd0;
680         end else if((M_AXI_RVALID == 1'b1)&&(axi_rready == 1'b1)&&(rd_hcnt == C_M_AXI_BURST_LEN - 1)) begin
681             rd_vcnt <= rd_vcnt + 1'b1;
682         end else begin
683             rd_vcnt <= rd_vcnt;
684         end
685     end
686 
687 // r_Sync-----------------------------------------------------------------------------------------//
688 
689 //Test
690     reg [11:0] Post_hcnt;
691     reg        r_I_Post_de;
692     reg [11:0] Post_vcnt;
693 
694     always @(posedge I_Post_clk) begin
695         r_I_Post_de <= I_Post_de;
696     end
697 
698     always@(posedge I_Post_clk)begin
699         if(M_AXI_ARESETN == 1'b0) begin
700             Post_hcnt <= 'd0;
701         end else if(I_Post_vs == 1'b1) begin
702             Post_hcnt <= 'd0;
703         end else if(r_I_Post_de == 1'b1 && I_Post_de == 1'b0) begin
704             Post_hcnt <= 'd0;
705         end else if(I_Post_de == 1'b1) begin
706             Post_hcnt <= Post_hcnt + 1'b1;
707         end else begin
708             Post_hcnt <= Post_hcnt;
709         end
710     end
711 
712     always@(posedge I_Post_clk)begin
713         if(M_AXI_ARESETN == 1'b0) begin
714             Post_vcnt <= 'd0;
715         end else if(I_Post_vs == 1'b1) begin
716             Post_vcnt <= 'd0;
717         end else if(r_I_Post_de == 1'b0 && I_Post_de == 1'b1) begin
718             Post_vcnt <= Post_vcnt + 1'b1;
719         end else begin
720             Post_vcnt <= Post_vcnt;
721         end
722     end
723 
724     AXI_ILA AXI_ILA (
725     .clk(M_AXI_ACLK), // input wire clk
726     
727     .probe0( axi_arvalid ), //1
728     .probe1( axi_araddr  ), //32
729     .probe2( axi_rready  )  //1
730 );
731 
732     endmodule
View Code

2.1.2 HDMI

通过接收配置包的数据对HDMI的视频像素有效区域进行设置;

//Cut Video
            reg             r_O_Pixel_Active    ;
            reg     [11:0]  Cut_hcnt            ;
            reg     [11:0]  Cut_vcnt            ;

            wire    [11:0]  hbegin              ;
            wire    [11:0]  hend                ;
            wire    [11:0]  vbegin              ;
            wire    [11:0]  vend                ;
            reg             Cut_hact            ;
            reg             Cut_vact            ;

            reg     [11:0]  r1_Cut_Width        ;
            reg     [11:0]  r1_Cut_High         ;
            reg     [3:0]   r1_sel_bit          ; 
            reg     [11:0]  r2_Cut_Width        ;
            reg     [11:0]  r2_Cut_High         ;
            reg     [3:0]   r2_sel_bit          ; 
// Video Cut -------------------------------------------------------------------------------- //

    always @(posedge Pixl_CLK) begin
        r1_Cut_Width <= Cut_Width   ;
        r1_Cut_High  <= Cut_High    ;
        r1_sel_bit   <= sel_bit     ;
        r2_Cut_Width <= r1_Cut_Width;
        r2_Cut_High  <= r1_Cut_High ;
        r2_sel_bit   <= r1_sel_bit  ;
    end 

    always @(posedge Pixl_CLK) begin
        if(Rst_Posedge == 1'b1) begin
            Cut_hcnt <= 'd0;
        end else if(Pre_V_Sync == 1'b1) begin
            Cut_hcnt <= 'd0;
        end else if(Pre_VGA_De == 1'b1) begin
            if(Cut_hcnt == H_ActiveSize - 1'b1) begin
                Cut_hcnt <= 'd0;
            end else begin
                Cut_hcnt <= Cut_hcnt + 1'b1;
            end
        end else begin
            Cut_hcnt <= Cut_hcnt;
        end
    end
    always @(posedge Pixl_CLK) begin
        if(Rst_Posedge == 1'b1) begin
            Cut_vcnt <= 'd0;
        end else if(Pre_V_Sync == 1'b1) begin
            Cut_vcnt <= 'd0;
        end else if((Pre_VGA_De == 1'b1) && (Cut_hcnt == H_ActiveSize - 1'b1)) begin
            if(Cut_vcnt == V_ActiveSize - 1'b1) begin
                Cut_vcnt <= 'd0;
            end else begin
                Cut_vcnt <= Cut_vcnt + 1'b1;
            end
        end else begin
            Cut_vcnt <= Cut_vcnt;
        end
    end

    assign  hbegin = (H_ActiveSize - r2_Cut_Width) >> 1;
    assign  hend   = (H_ActiveSize >> 1) + (r2_Cut_Width >> 1);
    always @(*) begin
        if(H_ActiveSize > r2_Cut_Width) begin
            if ((Cut_hcnt > (hbegin - 1'b1)) && (Cut_hcnt < (hend)) && (Pre_VGA_De)) begin
                Cut_hact <= 1'b1;
            end else begin
                Cut_hact <= 1'b0;
            end
        end else if(H_ActiveSize <= r2_Cut_Width) begin
            if(Pre_VGA_De == 1'b1) begin
                Cut_hact <= 1'b1;
            end else begin
                Cut_hact <= 1'b0;
            end
        end else begin
            Cut_hact <= 1'b0;
        end
    end

    assign  vbegin = (V_ActiveSize - r2_Cut_High) >> 1;
    assign  vend   = (V_ActiveSize >> 1) + (r2_Cut_High >> 1);
    always @(*) begin
        if(V_ActiveSize > r2_Cut_High) begin
            if((Cut_vcnt > (vbegin - 1'b1)) && (Cut_vcnt < (vend)) && (Pre_VGA_De)) begin
                Cut_vact <= 1'b1;
            end else begin
                Cut_vact <= 1'b0;
            end
        end else if(V_ActiveSize <= r2_Cut_High)begin
            if(Pre_VGA_De == 1'b1) begin
                Cut_vact <= 1'b1;
            end else begin
                Cut_vact <= 1'b0;
            end
        end else begin
            Cut_vact <= 1'b0;
        end
    end

    assign  O_Pixel_Active   = (Cut_hact)&&(Cut_vact) ;
    assign  Encode_CLK_10Bit = 10'b11111_00000  ;
    assign  Rst_Negedge      = (!Rst_Posedge)   ;
    assign  O_VGA_Sync       = Pre_V_Sync       ;
View Code

 

 

三.PS端:数据同步操作

第三部分:

1.PS端每接收完一帧图像发送一次写同步信号,使得缓冲地址及时调整;

2.每接收到数据包就刷新指定长度的cache以完成数据更新;

Xil_DCacheFlushRange(recv_buf, read_bytes);
        if (recv_buf[0] == 0x55 &&
            recv_buf[1] == 0x55 &&
            recv_buf[2] == 0x55 &&
            recv_buf[3] == 0x55 &&
            recv_buf[4] == 0x55 &&
            recv_buf[5] == 0x55 &&
            recv_buf[6] == 0x55 &&
            recv_buf[7] == 0x55 ) {
                u32 RegAddr;
                u32 Direct_RW_Flag;
                u32 RegData = 0;
                RegAddr = recv_buf[8];
                Direct_RW_Flag = recv_buf[9];

            /* 将解析的配置数据写入指定好的PL端寄存器地址 */
            if(Direct_RW_Flag == 0){
                RegData  = recv_buf[10]<<24;
                RegData |= recv_buf[11]<<16;
                RegData |= recv_buf[12]<<8;
                RegData |= recv_buf[13]<<0;
                if(RegAddr == 1){
                    ImageWeigh = RegData;
                    xil_printf("ConfigSet ImageWeigh!\r\n");
                }
                if(RegAddr == 2){
                    ImageHeigh = RegData;
                    xil_printf("ConfigSet ImageHeigh!\r\n");
                }
                if(RegAddr == 3){
                    ReadBack_Flag = RegData;
                    xil_printf("ConfigSet ReadBack_Flag!\r\n");
                }

                AxiLite_W_Single(AXI_ConFig_list_BaseAddr, RegAddr, RegData);
                RegData = AxiLite_R_Single(AXI_ConFig_list_BaseAddr, RegAddr);
                recv_buf[10] = (RegData>>24) & 0xff;
                recv_buf[11] = (RegData>>16) & 0xff;
                recv_buf[12] = (RegData>>8 ) & 0xff;
                recv_buf[13] = (RegData>>0 ) & 0xff;
                if((lwip_send(sock, recv_buf, read_bytes, 0))<0){
                    xil_printf("%s : Send Error!\r\n",sock);
                    break;
                }
            }
        }

        /* Vaild_Data_Header */
        if (recv_buf[0] == 0xAA &&
            recv_buf[1] == 0xAA &&
            recv_buf[2] == 0xAA &&
            recv_buf[3] == 0xAA &&
            recv_buf[4] == 0xAA &&
            recv_buf[5] == 0xAA &&
            recv_buf[6] == 0xAA &&
            recv_buf[7] == 0xAA ){
                FrameHeader_Flag = 1;
            }

        if(Image_Begin_Flag == 1){
            recv_buf  += read_bytes;
            Pixel_Cnt += read_bytes;
            Frame_Cnt += read_bytes;
            if((Pixel_Cnt == ImageWeigh * ImageHeigh * 2)&&(Begin_Flag == 0)){
                Begin_Flag = 1;
                FrameHeader_Flag = 0;
                Image_Begin_Flag = 0;
                Frame_Cnt = 0;
                Buff_Num += 1;

                HDMI_Rd_Start(0x01);
                xil_printf("Begin HDMI!\r\n");
                u8 Req_ReadNext[8] = {0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb};
                lwip_send(sock, Req_ReadNext, sizeof(Req_ReadNext), 0);
            }
            else if((Frame_Cnt == ImageWeigh * ImageHeigh * 2)&&(Pixel_Cnt != ImageWeigh * ImageHeigh * 2 * Max_BuffNum)&&(Begin_Flag == 1)){
                FrameHeader_Flag = 0;
                Image_Begin_Flag = 0;
                Frame_Cnt = 0;
                Buff_Num += 1;

                xil_printf("Frame:%d!\r\n",Buff_Num);
                u8 Req_ReadNext[8] = {0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb};
                lwip_send(sock, Req_ReadNext, sizeof(Req_ReadNext), 0);
            }
            else if(Pixel_Cnt == ImageWeigh * ImageHeigh * 2 * Max_BuffNum){
                FrameHeader_Flag = 0;
                Image_Begin_Flag = 0;
                Frame_Cnt = 0;
                Buff_Num  = 0;
                recv_buf  = 0x05000000;
                Pixel_Cnt = 0;
                u8 Req_ReadNext[8] = {0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb, 0xbb};
                lwip_send(sock, Req_ReadNext, sizeof(Req_ReadNext), 0);
            }
        }

        if(FrameHeader_Flag == 1){
            Image_Begin_Flag = 1;
        }
View Code

代码仓库:

关于拓展:

上位机在发文件的时候出现了粘包的现象,即头尾文件相连;

为了缓解这个问题,重新写一个上位机是好的选择;

所以我会在近期学习QT进行编写;

而之后可能不会采用TCP完成相关操作,而是通过UDP,这是因为我发现:【正点原子FPGA连载】第四十六章以太网传输视频实验-摘自【正点原子】开拓者 FPGA 开发指南 - 知乎 (zhihu.com)

这个链接中讲述了UDP传视频的若干好处,我决定投敌,TCP的上位机假若以后我有时间,有能力再写吧。

视频效果展示:

 

PC通过TCP传视频到FPGA-CSDN直播

NoNounknow/FPGA_TCP_Server: PC_Client send video to FPGA _Server (github.com)

 

 

posted @ 2024-02-21 21:45  NoNounknow  阅读(572)  评论(0)    收藏  举报