一,vivado工程配置

1,ZYNQ7 Processing System 中,HP Slave AXI Interface --> S AXI HP0 Interface,勾选 S AXI HP0 Interface 并且在展开的 AXI HP0 DATA WIDTH 后面选择数据位宽是 64(位宽可以配置为 32bit 或者64bit)。

2,按照如图引出来

3,在 Address Editor 中,由于新增加的 AXI_HP0 总线地址还未做映射,所以如图所示,点击左侧的 Auto Assign Address 进行自动地址分配。完成地址映射后,如图所示,AXI_HP0 默认分配了偏移地址(Offset Address)0x0 开始 的 1G 内存空间,这 1G 的地址空间是 AXI_HP0 可访问的地址空间。DDR3 也会默认映射到这一段地址空间中。通过 AXI_HP0 就可以实现 DDR3 的读写了。

二,PL端HP总线设置

上面配置是在PS端进行配置的,PL端也需要verilog HP总线进行数据读写

1,AXI HP总线,PL到PS端进行数据写设置:

`timescale  1 ns/10psmodule axi_hp0_wr(//系统信号input              rst_n,                   //写入DDR3的数据         input              i_clk,input                 i_data_rst_n,           input               i_data_en,input[15:0]           i_data,input[31:0]      i_ddr3_saddr, //AXI总线时钟input                AXI_clk,//AXI写地址通道(*mark_debug = "true"*) output reg[31:0]   AXI_awaddr, output[3:0]         AXI_awlen,output[2:0]       AXI_awsize,output[1:0]      AXI_awburst,output[1:0]         AXI_awlock,output[3:0]      AXI_awcache,output[2:0]         AXI_awprot,output[3:0]      AXI_awqos,(*mark_debug = "true"*) output reg         AXI_awvalid,    (*mark_debug = "true"*) input                AXI_awready,    //AXI写数据通道(*mark_debug = "true"*) output[63:0] AXI_wdata,output[7:0]         AXI_wstrb,  (*mark_debug = "true"*) output reg           AXI_wlast,(*mark_debug = "true"*) output reg         AXI_wvalid, (*mark_debug = "true"*) input                AXI_wready, //AXI写响应通道input[5:0]        AXI_bid,(*mark_debug = "true"*) input[1:0]           AXI_bresp,(*mark_debug = "true"*) input              AXI_bvalid, (*mark_debug = "true"*) output               AXI_bready);
//内部信号申明
reg         fifo_rd_en;
wire[7:0]   fifo_data_count;
reg[7:0]    wrdata_num;
reg[3:0]    cstate,nstate;parameter AXI_BURST_LEN   = 16;
parameter STATE_RST  = 4'h0;
parameter STATE_IDLE = 4'h1;
parameter STATE_WADD = 4'h2;
parameter STATE_WDAT = 4'h3;
parameter WRITE_DONE = 4'h4;    //------------------------------------------------------------------------------------
//将i_data_rst_n在AXI_clk时钟域打一拍
reg w_data_rst_n;always @(posedge AXI_clk)w_data_rst_n <= i_data_rst_n;        //-------------------------------------------------------------------------------
//FIFO缓存写入DDR3数据fifo_generator_0    uut_fifo_generator_0 (.rst(~rst_n || ~w_data_rst_n),  // input wire rst.wr_clk(i_clk),                // input wire wr_clk.rd_clk(AXI_clk),                // input wire rd_clk.din(i_data),                      // input wire [15 : 0] din.wr_en(i_data_en),                  // input wire wr_en.rd_en(fifo_rd_en),                  // input wire rd_en.dout({AXI_wdata[15:0],AXI_wdata[31:16],AXI_wdata[47:32],AXI_wdata[63:48]}),                    // output wire [63 : 0] dout.full(),                    // output wire full.empty(),                  // output wire empty.rd_data_count(fifo_data_count)  // output wire [7 : 0] rd_data_count
);//-------------------------------------------------------------------------------
//AXI写状态机always @(posedge AXI_clk or negedge rst_n)beginif(~rst_n)begincstate <= STATE_RST;endelse begincstate <= nstate;end
end always @( * )begincase(cstate)STATE_RST: beginif(w_data_rst_n) nstate = STATE_IDLE;else nstate = STATE_RST;endSTATE_IDLE: beginif(!w_data_rst_n) nstate = STATE_RST;else if(fifo_data_count >= AXI_BURST_LEN) nstate = STATE_WADD;else nstate = STATE_IDLE;endSTATE_WADD: beginif(AXI_awvalid && AXI_awready) nstate = STATE_WDAT;else nstate = STATE_WADD;end    STATE_WDAT: beginif(wrdata_num >= (AXI_BURST_LEN+1)) nstate = WRITE_DONE;else nstate = STATE_WDAT;endWRITE_DONE: beginif(AXI_bvalid) nstate = STATE_IDLE;else nstate = WRITE_DONE;enddefault: beginnstate = STATE_RST;end
endcase
end//1个burst写入数据的个数计数
always @(posedge AXI_clk) begin                                                                if (!rst_n) wrdata_num <= 'b0;                                                           else if(cstate == STATE_WDAT) begin if(wrdata_num == 8'd0) wrdata_num <= wrdata_num + 1'b1; else if((wrdata_num <= AXI_BURST_LEN) && AXI_wready && AXI_wvalid) wrdata_num <= wrdata_num + 1'b1;              else wrdata_num <= wrdata_num;end                                                              else wrdata_num <= 'b0;
end //-------------------------------------------------------------------------------
//FIFO读取时能信号产生always @(*) begin                                                                if (cstate == STATE_WDAT) beginif(wrdata_num == 8'd0) fifo_rd_en <= 1'b1;else if((wrdata_num >= 8'd1) && (wrdata_num < AXI_BURST_LEN) && AXI_wready && AXI_wvalid) fifo_rd_en <= 1'b1;else fifo_rd_en <= 1'b0;endelse fifo_rd_en <= 1'b0;
end//-------------------------------------------------------------------------------
//AXI总线写数据时序产生//写地址产生
always @(posedge AXI_clk)beginif(!w_data_rst_n) AXI_awaddr <= i_ddr3_saddr; else if(AXI_awvalid && AXI_awready) AXI_awaddr <= AXI_awaddr + AXI_BURST_LEN * 8;
end//写地址有效信号产生
always @(posedge AXI_clk) begin                                                                if (!rst_n) AXI_awvalid <= 1'b0;                                                               else if(cstate == STATE_WADD) beginif(AXI_awvalid && AXI_awready) AXI_awvalid <= 1'b0;                                                        else AXI_awvalid <= 1'b1;endelse AXI_awvalid <= 1'b0;
end    //写数据有效信号产生
always @(posedge AXI_clk) begin                                                                if (!rst_n) AXI_wvalid <= 1'b0;else if((wrdata_num >= 8'd1) && (wrdata_num < AXI_BURST_LEN)) AXI_wvalid <= 1'b1; else if((wrdata_num == AXI_BURST_LEN) && !AXI_wready) AXI_wvalid <= 1'b1;else AXI_wvalid <= 1'b0;
end//写最后一个数据有效信号产生
always @(posedge AXI_clk) begin                                                                if (!rst_n) AXI_wlast <= 1'b0;                                                               else if((wrdata_num == (AXI_BURST_LEN - 1)) && AXI_wready && AXI_wvalid) AXI_wlast <= 1'b1;  else if((wrdata_num == AXI_BURST_LEN) && !AXI_wready) AXI_wlast <= 1'b1;else AXI_wlast <= 1'b0;
endassign AXI_awsize    = 3'b011; //8 Bytes per burst
assign AXI_awburst  = 2'b01;
assign AXI_awlock   = 2'b00;
assign AXI_awcache  = 4'b0010;
assign AXI_awprot   = 3'h0;
assign AXI_awqos    = 4'h0;
assign AXI_wstrb    = 8'hff;
assign AXI_bready   = 1'b1;
assign AXI_awlen    = AXI_BURST_LEN - 1;
endmodule

其中fifo配置:

fifo_generator_0     uut_fifo_generator_0 (
  .rst(~rst_n || ~w_data_rst_n),   // input wire rst
  .wr_clk(i_clk),                // input wire wr_clk
  .rd_clk(AXI_clk),                // input wire rd_clk
  .din(i_data),                      // input wire [15 : 0] din
  .wr_en(i_data_en),                  // input wire wr_en
  .rd_en(fifo_rd_en),                  // input wire rd_en
  .dout({AXI_wdata[15:0],AXI_wdata[31:16],AXI_wdata[47:32],AXI_wdata[63:48]}),
  .full(),                    // output wire full
  .empty(),                  // output wire empty
  .rd_data_count(fifo_data_count)  // output wire [7 : 0] rd_data_count
);

2,AXI HP总线读取数据

`timescale  1 ns/10psmodule axi_hp0_rd(//系统信号input              rst_n,                   //写入DDR3的数据         input              i_clk,input                 o_data_rst_n,input              o_data_en,input[31:0]           o_ddr3_saddr,//AXI总线时钟input             AXI_clk,//AXI读地址通道(*mark_debug = "true"*) output[31:0]AXI_araddr,output[1:0]     AXI_arburst,output[3:0]     AXI_arcache,            output[3:0]     AXI_arlen,output[1:0]       AXI_arlock,output[2:0]      AXI_arprot,output[3:0]      AXI_arqos,(*mark_debug = "true"*) input              AXI_arready,output[2:0]     AXI_arsize,(*mark_debug = "true"*) output                AXI_arvalid,//AXI读数据通道(*mark_debug = "true"*) input[63:0]            AXI_rdata,input[5:0]        AXI_rid,(*mark_debug = "true"*) input                AXI_rlast,(*mark_debug = "true"*) output                 AXI_rready,(*mark_debug = "true"*) input[1:0]            AXI_rresp,(*mark_debug = "true"*) input              AXI_rvalid          );parameter AXI_BURST_LEN   = 16;
assign AXI_araddr = o_ddr3_saddr;
assign AXI_arvalid = o_data_en;
assign AXI_arsize   = 3'b011; //8 Bytes per burst
assign AXI_arburst  = 2'b01;
assign AXI_arlock   = 2'b00;
assign AXI_arcache  = 4'b0010;
assign AXI_arprot   = 3'h0;
assign AXI_arqos    = 4'h0;
assign AXI_rready   = 1'b1;
assign AXI_arlen    = AXI_BURST_LEN - 1;
endmodule

3,数据控制

`timescale  1 ns/10psmodule axi_hp0_source(//系统信号input          rst_n,                     input            clk,//读出DDR3的数据output           o_data_rst_n,output reg     o_data_en,output [31:0]     o_ddr3_saddr,//写入DDR3的数据                output          i_data_rst_n,           output reg      i_data_en,output reg[15:0]    i_data,output[31:0]       i_ddr3_saddr);parameter MAX_CNT_1S = 32'd100_000_000-1;   //1s计数最大值,时钟为100MHz(10ns)
//1s定时
reg[31:0] cnt;
always @(posedge clk or negedge rst_n)if(!rst_n) cnt <= 32'd0;else if(cnt < MAX_CNT_1S) cnt <= cnt+1'b1;else cnt <= 32'd0;wire timer_wr_en = (cnt >= MAX_CNT_1S-1000) & (cnt < MAX_CNT_1S-1000+64);
assign i_data_rst_n = ~((cnt >= MAX_CNT_1S-10_000) & (cnt < MAX_CNT_1S-10_000+64));
wire timer_rd_en = (cnt == MAX_CNT_1S-10);
//------------------------------------------------------------------------------------
//产生定时数据写入always @(posedge clk or negedge rst_n)if(!rst_n) i_data_en <= 1'b0;else i_data_en <= timer_wr_en;always @(posedge clk or negedge rst_n)if(!rst_n) i_data <= 16'd0;else if(!i_data_rst_n) i_data <= 16'h0000;else if(timer_wr_en) i_data <= i_data+1'b1;assign i_ddr3_saddr = 32'h0100_0000;  //------------------------------------------------------------------------------------
//产生定时数据读取always @(posedge clk or negedge rst_n)if(!rst_n) o_data_en <= 1'b0;else o_data_en <= timer_rd_en;assign o_data_rst_n = i_data_rst_n;assign o_ddr3_saddr = 32'h0100_0000; endmodule

三,SDK代码下载触发验证和信号抓取:

ZYNQ 不用DMA的HP总线使用相关推荐

  1. ZYNQ中DMA与AXI4总线-DMA简介

    ZYNQ中DMA与AXI4总线 为什么在ZYNQ中DMA和AXI联系这么密切?通过上面的介绍我们知道ZYNQ中基本是以AXI总线完成相关功能的: 图4‑34 连接 PS 和 PL 的 AXI 互联和接 ...

  2. AXI DMA测试-AXI总线最后一章

    AXI DMA测试 增加一个AXIDMA章节,这部分内容是很多例程的基础,难度不大但是也不小,需要彻底理解整个运行机制. 图4‑61 测试框图 处理器通过M_AXI_GP0接口和AXI_DMA通信,以 ...

  3. linux zynq ps dma,Zynq PS侧DMA驱动

    Linux中,驱动必然会有驱动对应的设备类型.在linux4.4版本中,其设备是以设备树的形式展现的. PS端设备树的devicetree表示如下 324 dmac_s: dmac@f8003000 ...

  4. linux zynq ps dma,Zynq PS DMA控制器应用笔记

    Zynq-7000系列器件PS端的DMA控制器采用ARM的IP核DMA-330(PL-330)实现.有关DMA控制器的硬件细节及相关指令集.编程实例内容参考ARM官方文档: DDI0424D:dma3 ...

  5. Zynq PS DMA控制器应用笔记

    Zynq PS DMA应用笔记 Hello,Panda Zynq-7000系列器件PS端的DMA控制器采用ARM的IP核DMA-330(PL-330)实现.有关DMA控制器的硬件细节及相关指令集.编程 ...

  6. ZYNQ linux dma驱动及其单向读写

    一,DMA相关定义和注意事项 DMA是Direct Memory Access 的缩写,也就是内存到内存,不通过 CPU.DMA 的可以支持内存到外设.外设到内存.内存到内存的数据交互,必要时节省径多 ...

  7. STM32 进阶教程 20 - 串口+DMA实现OneWire总线

    前言 One-wire总线使用一根并联总线完成对于多个设备的访问,通过上拉的OD门实现多设备的读写操作,通过ID区别设备,通过CRC5完成数据校验.常见对于one-wire总线的操作代码主要使用包含基 ...

  8. ZYNQ | AXI DMA数据环路测试

    利用AXI DMA进行批量数据环路的测试 背景 软硬件平台 原理概述 工程搭建 1.新建一个vivado工程 2.创建block design ①zynq ip核的添加与配置 ②AXI DMA ip核 ...

  9. 聊一聊GNU/Linux 与开源文化的那些人和事

    本文只梳理大致的脉络,不做详尽的叙述. 一.计算机的发明 世上本无路,走的人多了,就有了路.世上本无计算机,琢磨的人多了--没有计算机,一切无从谈起. 三个人对计算机的发明功不可没,居功至伟.阿兰·图 ...

最新文章

  1. 用一个按钮做主窗口,可以吗?
  2. python 类成员变量是否存在_python中类变量与成员变量的使用注意点总结
  3. oracle to_char 数值,oracle to_char格式数值
  4. 谷歌浏览器插件入门示例
  5. NAT模式下虚拟机与主机网络关系配置
  6. 《天天数学》连载00:序言
  7. the dhc driver package_DHC智商低?不,它用1k阅读,444个好看证明了自己
  8. iOS仿京东分类菜单之UICollectionView内容
  9. Java工具类之Base64Utils实现base64码转换为文件流等互换
  10. Android Q共享音频输入
  11. CRT设置LOG日志功能
  12. Apache commons digester简介说明
  13. 解决cnzz加载时间长的问题
  14. 写在2019年来临前的倒数0.5小时
  15. 现在写Android,性能优化太重要了!
  16. 饿了么交易系统设计思路
  17. abp viewmodel的写法
  18. VMware 日记一:基础的系统安装和基本配置解析
  19. 教你如何在centos7服务器中屏蔽掉那些高流量ip
  20. Lora Ra-01模块初步调试问题记录

热门文章

  1. TickSeekBar
  2. PerfDog小程序测试
  3. Android 照片涂鸦4-5
  4. Day32-Docker学习教程系列(四)-Docker使用
  5. 华为android 8系统版本,华为Mate8的手机系统是什么?能升级安卓5.0吗?
  6. 华南理工计算机学院硕士研究生导师何生导师,华南理工大学研究生导师简介-何盛烽...
  7. 软件实施-01-服务器
  8. 织梦搜索页是那个php,织梦dedecms仿站之搜索框、搜索页制作
  9. python第二周小测验a答案_大学慕课Python编程基础章节测验答案
  10. 面试笔记之计算机网络(1.3万字)