以太网学习之TCP/IP:PC上位机通过Socket连接下发视频至FPGA的若干总结
笔记:
参考:
第一个很精炼简单有效,但我是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;
整体描述:完成了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);% 配置包总帧长
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 =========================================//
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];
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
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
完整代码:
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

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 ;

三.PS端:数据同步操作
第三部分:
1.PS端每接收完一帧图像发送一次写同步信号,使得缓冲地址及时调整;
2.每接收到数据包就刷新指定长度的cache以完成数据更新;
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; }
代码仓库:
关于拓展:
上位机在发文件的时候出现了粘包的现象,即头尾文件相连;
为了缓解这个问题,重新写一个上位机是好的选择;
所以我会在近期学习QT进行编写;
而之后可能不会采用TCP完成相关操作,而是通过UDP,这是因为我发现:【正点原子FPGA连载】第四十六章以太网传输视频实验-摘自【正点原子】开拓者 FPGA 开发指南 - 知乎 (zhihu.com)
这个链接中讲述了UDP传视频的若干好处,我决定投敌,TCP的上位机假若以后我有时间,有能力再写吧。
视频效果展示:

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

浙公网安备 33010602011771号