首先调用ip
值得注意的是:zynq支持axi4.0 ,但是创建的ip是属于axi3.0,其区别主要是在数据位宽以及突发长度的区别。
下面附读写控制模块(稍作修改就可使用,数据位宽是64bit 突发长度是256):
assign fifo_wr_data = {8'd0,pixel_rgb};
assign fifo_wr_en = hv;
//fifo 2 clock domain switch
asfifo_wr32x4096_rd64x2048 asfifo_wr32x4096_rd64x2048inst (
.wr_clk(pixel_clk), // input wire wr_clk
.rd_clk(M_AXI_ACLK), // input wire rd_clk
.din(fifo_wr_data), // input wire [31 : 0] din
.wr_en(fifo_wr_en), // input wire wr_en
.rd_en(fifo_rd_en), // input wire rd_en
.dout(fifo_rd_data), // output wire [63 : 0] dout
.full(), // output wire full
.empty(), // output wire empty
.rd_data_count(rd_data_count) // output wire [10 : 0] rd_data_count
);
//dma write channel
assign fifo_rd_en = axi_wvalid & M_AXI_WREADY;
always @(posedge M_AXI_ACLK) begin
if(M_AXI_ARESETN == 1'b0) begin
burst_start <= 1'b0;
end
else if (rd_data_count >='d256 && axi_wvalid == 1'b0 && axi_awvalid == 1'b0) begin
burst_start <= 1'b1;
end
else begin
burst_start <= 1'b0;
end
end
always @(posedge M_AXI_ACLK) begin
if(M_AXI_ARESETN == 1'b0) begin
axi_awvalid <= 1'b0;
end
else if (axi_awvalid == 1'b1 &&M_AXI_AWREADY == 1'b1) begin
axi_awvalid <= 1'b0;
end
else if (burst_start == 1'b1 && axi_awvalid == 1'b0 && axi_wvalid == 1'b0) begin
axi_awvalid <= 1'b1;
end
end
always @(posedge M_AXI_ACLK) begin
if(M_AXI_ARESETN == 1'b0) begin
axi_awaddr <= 'd0;
end
else if (M_AXI_AWREADY == 1'b1 && axi_awvalid == 1'b1 && axi_awaddr == 'd8292352) begin
axi_awaddr <= 'd0;
end
else if (M_AXI_AWREADY == 1'b1 && axi_awvalid == 1'b1) begin
axi_awaddr <= axi_awaddr + 'd2048;
end
end
always @(posedge M_AXI_ACLK) begin
if(M_AXI_ARESETN == 1'b0) begin
axi_wvalid <= 1'b0;
end
else if (M_AXI_WREADY == 1'b1 && axi_wvalid == 1'b1 && burst_cnt == 'd255) begin //burst end
axi_wvalid <= 1'b0;
end
else if (M_AXI_AWREADY == 1'b1 && axi_awvalid == 1'b1) begin
axi_wvalid <= 1'b1;
end
end
always @(posedge M_AXI_ACLK) begin
if(M_AXI_ARESETN == 1'b0) begin
burst_cnt <='d0;
end
else if (M_AXI_WREADY == 1'b1 && axi_wvalid == 1'b1 && burst_cnt == 'd255) begin
burst_cnt <= 'd0;
end
else if (M_AXI_WREADY == 1'b1 && axi_wvalid == 1'b1) begin
burst_cnt <= burst_cnt + 1'b1;
end
end
always @* begin
if(M_AXI_WREADY == 1'b1 && axi_wvalid == 1'b1 && burst_cnt == 'd255) begin
axi_wlast <= 1'b1;
end
else begin
axi_wlast <= 1'b0;
end
end
always @* begin
axi_wdata = fifo_rd_data;
end
always @(posedge M_AXI_ACLK) begin
if(M_AXI_ARESETN == 1'b0) begin
axi_bready <= 1'b0;
end
else begin
axi_bready <= 1'b1;
end
end
写模块代码(数据位宽是64bit 突发长度是256):
reg [7:0]rx_Cnt;
always @(posedge M_AXI_ACLK) begin
if (M_AXI_ARESETN == 0 ) begin
axi_arvalid<=1'b0;
end
else if(axi_arvalid==1'b1 && M_AXI_ARREADY==1'b1)begin
axi_arvalid<=1'b0;
end
else if(rd_data_count<=1024 && axi_arvalid==1'b0 && axi_rready==1'b0 ) begin
axi_arvalid<=1'b1;
end
end
always @(posedge M_AXI_ACLK) begin
if (M_AXI_ARESETN == 0 ) begin
axi_araddr<='d0;
end
else if(axi_arvalid==1'b1 && M_AXI_ARREADY==1'b1 && axi_araddr=='d8292352)begin
axi_araddr<='d0;
end
else if(axi_arvalid==1'b1 && M_AXI_ARREADY==1'b1) begin
axi_araddr<=axi_araddr+'d2048;
end
end
always @(posedge M_AXI_ACLK) begin
if (M_AXI_ARESETN == 0 ) begin
axi_rready<=1'b0;
end
else if(M_AXI_RVALID==1'b1 && M_AXI_RREADY==1'b1 && rx_Cnt=='d255)begin
axi_rready<=1'b0;
end
else if(axi_arvalid==1'b1 && M_AXI_ARREADY==1'b1) begin
axi_rready<=1'b1;
end
end
always @(posedge M_AXI_ACLK) begin
if (M_AXI_ARESETN == 0 ) begin
rx_Cnt <= 'd0;
end
else if(M_AXI_RVALID==1'b1 && M_AXI_RREADY==1'b1 && rx_Cnt=='d255)begin
rx_Cnt <='d0;
end
else if(M_AXI_RVALID==1'b1 && M_AXI_RREADY==1'b1) begin
rx_Cnt<=rx_Cnt+1'b1;
end
end
// Add user logic here
fifo_generator_0 fifo_generator_0inst (
.wr_clk(M_AXI_ACLK), // input wire wr_clk
.rd_clk(hdmi_clk), // input wire rd_clk
.din(M_AXI_RDATA), // input wire [63 : 0] din
.wr_en(M_AXI_RVALID==1'b1 && M_AXI_RREADY==1'b1), // input wire wr_en
.rd_en(rd_fifo_en), // input wire rd_en
.dout(pixel_rgb), // output wire [31 : 0] dout
.full(), // output wire full
.empty(), // output wire empty
.rd_data_count(rd_data_count) // output wire [10 : 0] rd_data_count
);