日本黄色一级经典视频|伊人久久精品视频|亚洲黄色色周成人视频九九九|av免费网址黄色小短片|黄色Av无码亚洲成年人|亚洲1区2区3区无码|真人黄片免费观看|无码一级小说欧美日免费三级|日韩中文字幕91在线看|精品久久久无码中文字幕边打电话

當(dāng)前位置:首頁 > > ZYNQ

1. 讀寫DDR底層結(jié)構(gòu)

zynq 7000 SOCHP口是High-Performance Ports的縮寫,如下圖所示,一共有4HP接口,HP接口是AXI Slave設(shè)備,我們可以通過這4HP接口實現(xiàn)高帶寬的數(shù)據(jù)交互。實現(xiàn)PL讀寫PS端掛載的DDR需要使用HP接口。

如下圖所示,選擇HP0 interface。

使用的時鐘是150Mhz,HP的帶寬是150Mhz * 64bit,對于視頻處理,ADC數(shù)據(jù)采集等應(yīng)用都有足夠的帶寬。如下圖所示,配置完HP端口以后,zynq會多出一個AXI Slave端口,名稱為S_AXI_HP0,不過這些端口都是AXI3標(biāo)準(zhǔn)的,我們常用的是AXI4協(xié)議,這里添加1AXI Interconnect IP,用于協(xié)議轉(zhuǎn)換(AXI3AXI4)。設(shè)置S00_AXI端口為AXI4協(xié)議。

2. PLAXI   MASTER的機制

AXI4所采用的是一種READY,VALID握手通信機制,即主從模塊進(jìn)行數(shù)據(jù)通信前,先根據(jù)操作對各所用到的數(shù)據(jù)、地址通道進(jìn)行握手。主要操作包括傳輸發(fā)送者A等到傳輸接受者BREADY信號后,A將數(shù)據(jù)與VALID信號同時發(fā)送給B,這是一種典型的握手機制。


AXI總線分為五個通道:

?讀地址通道,包含ARVALID, ARADDR, ARREADY信號;

?寫地址通道,包含AWVALID,AWADDR, AWREADY信號;

?讀數(shù)據(jù)通道,包含RVALID, RDATA, RREADY, RRESP信號;

?寫數(shù)據(jù)通道,包含WVALID, WDATA,WSTRB, WREADY信號;

?寫應(yīng)答通道,包含BVALID, BRESP, BREADY信號;

?系統(tǒng)通道,包含:ACLK,ARESETN信號;


其中ACLKaxi總線時鐘,ARESETNaxi總線復(fù)位信號,低電平有效;讀寫數(shù)據(jù)與讀寫地址類信號寬度都為32bitREADYVALID是對應(yīng)的通道握手信號;WSTRB信號為1bit對應(yīng)WDATA有效數(shù)據(jù)字節(jié),WSTRB寬度是32bit/8=4bit;BRESPRRESP分別為寫回應(yīng)信號,讀回應(yīng)信號,寬度都為2bit,‘h0代表成功,其他為錯誤。

讀操作順序為主與從進(jìn)行讀地址通道握手并傳輸?shù)刂穬?nèi)容,然后在讀數(shù)據(jù)通道握手并傳輸所讀內(nèi)容以及讀取操作的回應(yīng),時鐘上升沿有效。如圖所示:

寫操作順序為主與從進(jìn)行寫地址通道握手并傳輸?shù)刂穬?nèi)容,然后在寫數(shù)據(jù)通道握手并傳輸所讀內(nèi)容,最后再寫回應(yīng)通道握手,并傳輸寫回應(yīng)數(shù)據(jù),時鐘上升沿有效。如圖所示:



附錄代碼清單:

moduleaq_axi_master( // Reset, Clock input ARESETN, input ACLK,  // Master 寫地址通道 output [0:0] M_AXI_AWID, output [31:0] M_AXI_AWADDR, output [7:0] M_AXI_AWLEN,    // Burst Length:0-255 output [2:0] M_AXI_AWSIZE,   // Burst Size:Fixed 2'b011 output [1:0] M_AXI_AWBURST,  // Burst Type:Fixed 2'b01(Incremental Burst) output M_AXI_AWLOCK,   // Lock: Fixed2'b00 output [3:0] M_AXI_AWCACHE,  // Cache: Fiex2'b0011 output [2:0] M_AXI_AWPROT,   // Protect: Fixed2'b000 output [3:0] M_AXI_AWQOS,    // QoS: Fixed2'b0000 output [0:0] M_AXI_AWUSER,   // User: Fixed32'd0 output M_AXI_AWVALID, input M_AXI_AWREADY,  // Master 寫數(shù)據(jù)通道 output [63:0] M_AXI_WDATA, output [7:0] M_AXI_WSTRB, output M_AXI_WLAST, output [0:0] M_AXI_WUSER, output M_AXI_WVALID, input M_AXI_WREADY,  // Master 寫響應(yīng)通道 input [0:0]  M_AXI_BID, input [1:0]  M_AXI_BRESP, input [0:0]  M_AXI_BUSER, input M_AXI_BVALID, output M_AXI_BREADY,  // Master 讀地址通道 output [0:0] M_AXI_ARID, output [31:0] M_AXI_ARADDR, output [7:0] M_AXI_ARLEN, output [2:0] M_AXI_ARSIZE, output [1:0] M_AXI_ARBURST, output [1:0] M_AXI_ARLOCK, output [3:0] M_AXI_ARCACHE, output [2:0] M_AXI_ARPROT, output [3:0] M_AXI_ARQOS, output [0:0] M_AXI_ARUSER, output M_AXI_ARVALID, input M_AXI_ARREADY,  // Master 讀數(shù)據(jù)通道 input [0:0]  M_AXI_RID, input [63:0] M_AXI_RDATA, input [1:0]  M_AXI_RRESP, input M_AXI_RLAST, input [0:0]  M_AXI_RUSER, input M_AXI_RVALID, output M_AXI_RREADY,  // Local Bus input MASTER_RST,  input WR_START, input [31:0] WR_ADRS, input [31:0] WR_LEN, output WR_READY, output WR_FIFO_RE, input WR_FIFO_EMPTY, input WR_FIFO_AEMPTY, input [63:0] WR_FIFO_DATA, output WR_DONE,  input RD_START, input [31:0] RD_ADRS, input [31:0] RD_LEN, output RD_READY, output RD_FIFO_WE, input RD_FIFO_FULL, input RD_FIFO_AFULL, output [63:0] RD_FIFO_DATA, output RD_DONE,  output [31:0] DEBUG);  localparam S_WR_IDLE  = 3'd0; localparam S_WA_WAIT  = 3'd1; localparam S_WA_START = 3'd2; localparam S_WD_WAIT  = 3'd3; localparam S_WD_PROC  = 3'd4; localparam S_WR_WAIT  = 3'd5; localparam S_WR_DONE  = 3'd6;  reg [2:0]  wr_state; reg [31:0] reg_wr_adrs; reg [31:0] reg_wr_len; reg reg_awvalid, reg_wvalid, reg_w_last; reg [7:0]  reg_w_len; reg [7:0]  reg_w_stb; reg [1:0]  reg_wr_status; reg [3:0]  reg_w_count, reg_r_count;  reg [7:0]  rd_chkdata, wr_chkdata; reg [1:0]  resp; reg rd_first_data; reg rd_fifo_enable; reg[31:0] rd_fifo_cnt;assign WR_DONE =(wr_state == S_WR_DONE);   assignWR_FIFO_RE = rd_first_data |(reg_wvalid & ~WR_FIFO_EMPTY & M_AXI_WREADY & rd_fifo_enable);always @(posedgeACLK or negedge ARESETN)begin if(!ARESETN) rd_fifo_cnt <= 32'd0; else if(WR_FIFO_RE) rd_fifo_cnt <= rd_fifo_cnt +32'd1; else if(wr_state == S_WR_IDLE) rd_fifo_cnt <= 32'd0;end always @(posedgeACLK or negedge ARESETN)begin if(!ARESETN) rd_fifo_enable <= 1'b0; else if(wr_state == S_WR_IDLE &&WR_START) rd_fifo_enable <= 1'b1; else if(WR_FIFO_RE && (rd_fifo_cnt== RD_LEN[31:3] - 32'd1) ) rd_fifo_enable <= 1'b0; end // Write State always @(posedge ACLK or negedge ARESETN)begin if(!ARESETN) begin wr_state <= S_WR_IDLE; reg_wr_adrs[31:0]   <= 32'd0; reg_wr_len[31:0]    <= 32'd0; reg_awvalid <= 1'b0; reg_wvalid <= 1'b0; reg_w_last <= 1'b0; reg_w_len[7:0]      <= 8'd0; reg_w_stb[7:0]      <= 8'd0; reg_wr_status[1:0]  <= 2'd0; reg_w_count[3:0]    <= 4'd0; reg_r_count[3:0]  <= 4'd0; wr_chkdata <= 8'd0; rd_chkdata <= 8'd0; resp <= 2'd0; rd_first_data <= 1'b0; end else begin if(MASTER_RST) begin wr_state <= S_WR_IDLE; end else begin case(wr_state) S_WR_IDLE: begin if(WR_START) begin              //外部開始寫地址 wr_state <= S_WA_WAIT; reg_wr_adrs[31:0] <=WR_ADRS[31:0];//寫地址 reg_wr_len[31:0]  <= WR_LEN[31:0] -32'd1;//寫長度 rd_first_data <= 1'b1; end reg_awvalid <= 1'b0; reg_wvalid <= 1'b0; reg_w_last <= 1'b0; reg_w_len[7:0]      <= 8'd0; reg_w_stb[7:0]      <= 8'd0; reg_wr_status[1:0]  <= 2'd0; end //寫地址等待 S_WA_WAIT: begin //外部FIFO不空或者長度為0則開始寫地址 if(!WR_FIFO_AEMPTY |(reg_wr_len[31:11] == 21'd0)) begin wr_state <= S_WA_START; end rd_first_data <= 1'b0; end //寫地址開始 S_WA_START: begin wr_state <= S_WD_WAIT;//寫數(shù)據(jù)等待 reg_awvalid <= 1'b1; //寫長度減一 reg_wr_len[31:11]    <= reg_wr_len[31:11] - 21'd1; if(reg_wr_len[31:11] != 21'd0) begin reg_w_len[7:0]  <= 8'hFF;//每次寫256個數(shù)據(jù) reg_w_last <= 1'b0; reg_w_stb[7:0]  <= 8'hFF; end else begin//最后不足256個的數(shù)據(jù)寫入 reg_w_len[7:0]  <= reg_wr_len[10:3]; reg_w_last <= 1'b1; reg_w_stb[7:0]  <= 8'hFF; end end S_WD_WAIT: begin //等待寫總線READY,進(jìn)入寫數(shù)據(jù)狀態(tài) if(M_AXI_AWREADY) begin wr_state <= S_WD_PROC; reg_awvalid <= 1'b0; //開始寫數(shù)據(jù) reg_wvalid <= 1'b1; end end //寫數(shù)據(jù) S_WD_PROC: begin if(M_AXI_WREADY & ~WR_FIFO_EMPTY)begin //一次突發(fā)寫完成 if(reg_w_len[7:0] == 8'd0) begin wr_state <= S_WR_WAIT; reg_wvalid <= 1'b0; reg_w_stb[7:0]  <= 8'h00; end else begin reg_w_len[7:0]  <= reg_w_len[7:0] -8'd1; end end end //寫等待 S_WR_WAIT: begin //寫響應(yīng)完成 if(M_AXI_BVALID) begin reg_wr_status[1:0]  <= reg_wr_status[1:0] | M_AXI_BRESP[1:0]; if(reg_w_last) begin//寫完成 wr_state <= S_WR_DONE; end else begin//寫未完成 wr_state <= S_WA_WAIT; //地址每次遞增 reg_wr_adrs[31:0] <=reg_wr_adrs[31:0] + 32'd2048; end end end S_WR_DONE: begin wr_state <= S_WR_IDLE; end  default: begin wr_state <= S_WR_IDLE; end endcase end end end  assign M_AXI_AWID         = 1'b0; assign M_AXI_AWADDR[31:0] =reg_wr_adrs[31:0]; assign M_AXI_AWLEN[7:0]   = reg_w_len[7:0]; assign M_AXI_AWSIZE[2:0]  = 2'b011; assign M_AXI_AWBURST[1:0] = 2'b01; assign M_AXI_AWLOCK       = 1'b0; assign M_AXI_AWCACHE[3:0] = 4'b0011; assign M_AXI_AWPROT[2:0]  = 3'b000; assign M_AXI_AWQOS[3:0]   = 4'b0000; assign M_AXI_AWUSER[0]    = 1'b1; assign M_AXI_AWVALID      = reg_awvalid;  assign M_AXI_WDATA[63:0]  = WR_FIFO_DATA[63:0]; assign M_AXI_WSTRB[7:0]   = (reg_wvalid & ~WR_FIFO_EMPTY)?8'hFF:8'h00; assign M_AXI_WLAST        = (reg_w_len[7:0] == 8'd0)?1'b1:1'b0; assign M_AXI_WUSER        = 1; assign M_AXI_WVALID       = reg_wvalid & ~WR_FIFO_EMPTY; assign M_AXI_BREADY       = M_AXI_BVALID; assign WR_READY           = (wr_state == S_WR_IDLE)?1'b1:1'b0;  localparam S_RD_IDLE  = 3'd0; localparam S_RA_WAIT  = 3'd1; localparam S_RA_START = 3'd2; localparam S_RD_WAIT  = 3'd3; localparam S_RD_PROC  = 3'd4; localparam S_RD_DONE  = 3'd5;  reg [2:0]  rd_state; reg[31:0]  reg_rd_adrs; reg [31:0] reg_rd_len; reg reg_arvalid, reg_r_last; reg [7:0]  reg_r_len; assign RD_DONE = (rd_state == S_RD_DONE) ; // Read State always @(posedge ACLK or negedge ARESETN)begin if(!ARESETN) begin rd_state <= S_RD_IDLE; reg_rd_adrs[31:0] <= 32'd0; reg_rd_len[31:0]  <= 32'd0; reg_arvalid <= 1'b0; reg_r_len[7:0]    <= 8'd0; end else begin case(rd_state) S_RD_IDLE: begin //讀開始 if(RD_START) begin rd_state <= S_RA_WAIT; reg_rd_adrs[31:0] <=RD_ADRS[31:0]; reg_rd_len[31:0]  <= RD_LEN[31:0] -32'd1; end reg_arvalid <= 1'b0; reg_r_len[7:0]  <= 8'd0; end //讀通道等待 S_RA_WAIT: begin if(~RD_FIFO_AFULL) begin rd_state <= S_RA_START; end end //讀地址開始 S_RA_START: begin rd_state <= S_RD_WAIT; reg_arvalid <= 1'b1; reg_rd_len[31:11] <=reg_rd_len[31:11] -21'd1; if(reg_rd_len[31:11] != 21'd0) begin reg_r_last <= 1'b0; reg_r_len[7:0]  <= 8'd255; end else begin reg_r_last <= 1'b1; reg_r_len[7:0]  <= reg_rd_len[10:3]; end end //讀數(shù)據(jù)等待 S_RD_WAIT: begin if(M_AXI_ARREADY) begin rd_state <= S_RD_PROC; reg_arvalid <= 1'b0; end end //讀數(shù)據(jù)開始 S_RD_PROC: begin if(M_AXI_RVALID) begin if(M_AXI_RLAST) begin if(reg_r_last) begin rd_state <= S_RD_DONE; end else begin rd_state <= S_RA_WAIT; reg_rd_adrs[31:0] <=reg_rd_adrs[31:0] + 32'd2048; end end else begin reg_r_len[7:0] <=reg_r_len[7:0] -8'd1; end end end S_RD_DONE:begin rd_state <= S_RD_IDLE; end  endcase end end  // Master Read Address assign M_AXI_ARID         = 1'b0; assign M_AXI_ARADDR[31:0] =reg_rd_adrs[31:0]; assign M_AXI_ARLEN[7:0]   = reg_r_len[7:0]; assign M_AXI_ARSIZE[2:0]  = 3'b011; assign M_AXI_ARBURST[1:0] = 2'b01; assign M_AXI_ARLOCK       = 1'b0; assign M_AXI_ARCACHE[3:0] = 4'b0011; assign M_AXI_ARPROT[2:0]  = 3'b000; assign M_AXI_ARQOS[3:0]   = 4'b0000; assign M_AXI_ARUSER[0]    = 1'b1; assignM_AXI_ARVALID = reg_arvalid;  assign M_AXI_RREADY       = M_AXI_RVALID & ~RD_FIFO_FULL;  assign RD_READY           = (rd_state == S_RD_IDLE)?1'b1:1'b0; assign RD_FIFO_WE         = M_AXI_RVALID; assign RD_FIFO_DATA[63:0] = M_AXI_RDATA[63:0];  assign DEBUG[31:0] = {reg_wr_len[31:8], 1'd0, wr_state[2:0],1'd0, rd_state[2:0]}; endmodule
本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
關(guān)閉