精华内容
下载资源
问答
  • zynqDDR设计参考

    2018-10-07 09:50:37
    zynqDDR设计参考,已经在项目上实施,需要更改FSBL才可以。资料里包括微博的内容以及官方原版英文的资料。
  • 如题:详细链接:https://blog.csdn.net/LOTOOHE/article/details/78692798
  • ZYNQ基本用法------DDR(1)

    千次阅读 2021-05-10 18:36:48
    PS端对DDR进行读写DDR原理硬件部分1、建立工程2、点击“Create Block Design”,创建一个 Block 设计,也就是图形化设计3、点击“Add IP”快捷图标,搜索ZYNQ,然后双击。4、双击 Block 图中的“processing_system7_...

    PS端对DDR进行读写(一)

    0 DDR原理

    DDR3的地址
    // Canonical definitions for DDR MEMORY
    #define XPAR_DDR_MEM_BASEADDR 0x00000000U
    #define XPAR_DDR_MEM_HIGHADDR 0x3FFFFFFFU
    等会我们要使用这个地址,对DDR3进行读写操作

    读写操作函数
    //从某个地址读数据
    u8 Xil_In8(INTPTR Addr);
    u16 Xil_In16(INTPTR Addr);
    u32 Xil_In32(INTPTR Addr);

    //向某个地址写数据。
    void Xil_Out8(INTPTR Addr, u8 Value);
    void Xil_Out16(INTPTR Addr, u16 Value);
    void Xil_Out32(INTPTR Addr, u32 Value);

    1 硬件部分

    1.1、建立工程

    create Project----------Next------工程命名为p_led,并选择文件保存路径
    -----------Next
    在这里插入图片描述
    -----------Next-----------Next--------器件选择(按照直接的开发板信号进行选择)

    -----------Next-----------finish

    1.2、点击“Create Block Design”,创建一个 Block 设计,也就是图形化设计

    在这里插入图片描述
    “Design name”这里不做修改,保持默认“design_1”,这里可以根据需要修改,不过名字
    要尽量简短,否则在 Windows 下编译会有问题。

    1.3、点击“Add IP”快捷图标,搜索ZYNQ,然后双击。

    在这里插入图片描述

    1.4、双击 Block 图中的“processing_system7_0”,配置相关参数

    1.4.1、首先出现的界面是 ZYNQ 硬核的架构图,可以很清楚看到它的结构,可以参考 ug585 文档,里面有对 ZYNQ 的详细介绍。图中绿色部分是可配置模块,可以点击进入相应的编辑界面,当然也可以在左侧的窗口进入编辑。下面对各个窗口的功能一一介绍。

    在这里插入图片描述

    1.4.2、PS 端外设配置

    (1)从原理图中我们可以找到串口连接在 PS 的 MIO48-MIO49 上,所以在“Peripheral I/O Pins”选项中使能 UART1(MIO48 MIO49),PS 端 MIO 分为两个 Bank,Bank 0 ,也就是原理图中的 BANK500,电压选择“LVCMOS 3.3V”,Bank 1,也就是原理图中的 BANK501,电压选择“LVCOMS 1.8 V”。 如果不配置 Bank1 电平标准,可能导致串口无法接收

    在这里插入图片描述
    (2)配置 QSPI,QSPI 可以作为 ZYNQ 的启动存储设备,ZYNQ 可以通过读取 QSPI 中存储的启动文件加载 ARM 和 FPGA,从原理图得知,我们选择 Quad SPI Flash 为 Single SS 4bit IO
    在这里插入图片描述

    (3)配置以太网,在 PS 端设计有以太网接口,根据原理图选择 Ethernet 0 到 MIO16-MIO27。MDIO 为以太网 PHY 寄存器配置接口,选择 MDIO 并配置到 MIO52-MIO53

    在这里插入图片描述
    在这里插入图片描述
    (4)配置 USB0 到 MIO28-MIO39
    在这里插入图片描述
    (5)除了 QSPI 启动 ZYNQ,还有 SD 卡模式启动 ZYNQ,选择 SD 0,配置到 MIO40-MIO45,选择
    Card Detection MIO47,用于检测 SD 卡的插入。
    在这里插入图片描述
    (6)打开 GPIO MIO,PS 便可以控制剩余未分配的 MIO,用作 GPIO。在 GPIO MIO 中选择 MIO46 作为 USB PHY 的复位。
    在这里插入图片描述
    (7)外设配置结束。

    1.4.3、MIO 配置

    修改 Enet0 的电平标准为 HSTL 1.8V,Speed 为 fast,这些参数非常重要,如果不修改,网
    络可能不通。其他部分保持默认。
    在这里插入图片描述

    1.4.4、时钟配置

    在“Clock Configuration”选项卡中我们可以配置PS时钟输入时钟频率,这里默认是33.333333,和板子上一致,不用修改,CPU 频率默认 666.666666Mhz,这里也不修改。同时 PS 还可以给 PL 端提供 4 路时钟,频率可以配置,这里不需要,所以保持默认即可。还有 PS 端外设的时钟等也可以进行配置,这里保持默认。
    在这里插入图片描述

    1.4.5、DDR3 配置

    在“DDR Configuration”选项卡中可以配置 PS 端 ddr 的参数,AX7010 配置 DDR3 型号为
    “MT41J128M16 HA-125”, 这里 ddr3型号并不是板子上的 ddr3 型号,而是参数最接近的型号 。Effective DRAM Bus Width”,选择“32 Bit”
    在这里插入图片描述
    其他部分保持默认,点击 OK。至此 ZYNQ 核的配置结束。

    1.5、点击“Run Block Automation”,vivado 软件会自动完成一些导出端口的工作.

    1.6、按照默认点击“OK”.

    点击“OK”以后我们可以看到 PS 端导出一些管脚,包括 DDR 还有 FIXED_IO,DDR 是 DDR3的接口信号,FIXED_IO 为 PS 端固定的一些接口,比如输入时钟,PS 端复位信号,MIO 等。

    1.7、连接 FCLK_CLK0 到 M_AXI_GP0_ACLK,按 Ctrl+S 保存设计

    在这里插入图片描述

    1.8、选择 Block 设计,右键“Create HDL Wrapper…”,创建一个 Verilog 或 VHDL 文件,为 block design生成 HDL 顶层文件。

    在这里插入图片描述
    保持默认选项,点击“OK”
    在这里插入图片描述
    展开设计可以看到 PS 被当成一个普通 IP 来使用。

    1.9、选择 block 设计,右键“Generate Output Products”,此步骤会生成 block 的输出文件,包括IP,例化模板,RTL 源文件,XDC 约束,第三方综合源文件等等。供后续操作使用。

    在这里插入图片描述
    点击“Generate”

    1.10、在菜单栏“File -> Export -> Export Hardware…”导出硬件信息,这里就包含了 PS 端的配置信息。

    1.11、在弹出的对话框中点击“OK”,因为实验仅仅是使用了 PS 的串口,不需要 PL 参与,这里就没有使能“Include bitstream”

    2 软件部分

    2.1、点击 Vivado 菜单“File -> Launch SDK”,启动 SDK

    2.2、在 SDK 的菜单“New -> Application Project”,建立一个 APP 工程。“Project name”填写“hello”,其他默认,点击“Next”

    在这里插入图片描述

    2.3、 模板选择“Hello World”,点击“Finish”

    在这里插入图片描述

    2.4、在hello world模板编写代码

    在这里插入图片描述

    //使用PS控制DDR3的读写
    
    
    /*
    
     Canonical definitions for DDR MEMORY
    #define XPAR_DDR_MEM_BASEADDR 0x00000000U
    #define XPAR_DDR_MEM_HIGHADDR 0x3FFFFFFFU
    
    
    //从某个地址读数据
    u8 Xil_In8(INTPTR Addr);
    u16 Xil_In16(INTPTR Addr);
    u32 Xil_In32(INTPTR Addr);
    
    //向某个地址写数据。
    void Xil_Out8(INTPTR Addr, u8 Value);
    void Xil_Out16(INTPTR Addr, u16 Value);
    void Xil_Out32(INTPTR Addr, u32 Value);
    
     */
    
     #include "stdio.h"
     #include "platform.h"
     #include "xparameters.h"
     #include "xparameters_ps.h"
     #include "xil_printf.h"
     #include "xil_io.h"
     #define DDR_BASEARDDR      XPAR_DDR_MEM_BASEADDR + 0x10000000
    
    int main()
    {
        init_platform();
    
        int i;
        int value;
    
    
    
        // 写数据
        for(i=0; i<32; i++)
        {
            //Xil_Out32(DDR_BASEARDDR+i*4,0xFF);//向某个地址写数据。
            Xil_Out32(DDR_BASEARDDR+i*4,i);//向某个地址写数据。
            // 第一个参数:写入数据的地址     第一个参数:待写入的数据
        }
    
        // 读数据
        for(i=0; i<32; i++)
        {
        	value = Xil_In32(DDR_BASEARDDR+i*4);//从某个地址读数据
            // 第一个参数:写入数据的地址
            printf("the address at  %x data is : %x \n\r" ,DDR_BASEARDDR+i*4, value);
        }
    
        printf("finish write and read!\n");
    
        cleanup_platform();
        return 0;
    }
    

    在这里插入图片描述

    2.5、上电。并连接 JTAG 线到开发板、UART 的 USB 线到 PC

    2.6、使用 PuTTY 软件做为串口终端调试工具,PuTTY 是一个免安装的小软件。选择serial—选择串口号----speed

    在这里插入图片描述

    2.7、 选择“hello”,右键,可以看到很多选项,本实验要用到这里的“Run as”,就是把程序运行起来,“Run as”里又有很对选项,选择第一个“Launch on Hardware (System Debuger) ”,使用系统调试,直接运行程序。

    2.8 结果

    在这里插入图片描述

    展开全文
  • ZYNQ裸板:DDR

    2021-02-09 13:51:50
      DDRzynq的内存又可以叫做主存。是CPU能直接寻址的存储空间,没有DDR的话,运行内存只有很小的内部RAM,软件大小受限,也几乎没法跑操作系统。作为下一篇AXIDMA的基础知识提前做个准备,内容很简单这里就简单做...

    前言

      DDR是zynq的内存又可以叫做主存。是CPU能直接寻址的存储空间,没有DDR的话,运行内存只有很小的内部RAM,软件大小受限,也几乎没法跑操作系统。作为下一篇AXIDMA的基础知识提前做个准备,内容很简单这里就简单做一个读写测试,也可以当做验证下DDR是否都可以正常访问
      还是找到我们的老朋友"xparameters_ps.h"可以看到如下代码:
    在这里插入图片描述
      这就是DDR的基址和偏移了也就是说1GB的内存,
    在这里插入图片描述
      关于DDR的详细描述在芯片手册第十章10.6部分有详细的DDR编程介绍,但是呢按照现在的认知来看,大部分情况下是用不到的,只需要会简单的读写就好了)
      而在xil_io.h里又能找到下面这些读写函数(xilinx真香)

    //从某个地址读数据 
    u8 Xil_In8(INTPTR Addr); 
    u16 Xil_In16(INTPTR Addr); 
    u32 Xil_In32(INTPTR Addr);
    //向某个地址写数据。 
    void Xil_Out8(INTPTR Addr, u8 Value); 
    void Xil_Out16(INTPTR Addr, u16 Value); 
    void Xil_Out32(INTPTR Addr, u32 Value); 
    

      有了这些已经完完全全可以对DDR进行读写了

      那下面要做的就很简单了,挑几个地址访问验证一下就好啦!所以我为什么要单独写一篇,真是奇怪

    #include "xparameters_ps.h"
    #include "xil_io.h"
    #include "xil_printf.h"
    
    int main ()
    {
    	int value;
       Xil_Out32(XPAR_DDR_MEM_BASEADDR,0x12);
       value = Xil_In32(XPAR_DDR_MEM_BASEADDR);
       xil_printf("the address 0 is 0x%x\r\n",value);
       Xil_Out32(0x1FFFFFFF,0x34);
       value = Xil_In32(0x1FFFFFFF);
       xil_printf("the address 0x1FFFFFFF is 0x%x\r\n",value);
       Xil_Out8(XPAR_DDR_MEM_HIGHADDR,0x7);
       value = Xil_In8(XPAR_DDR_MEM_HIGHADDR);
       xil_printf("the address 0x3FFFFFFF is 0x%x\r\n",value);
    
    }
    
    

    这下好了已经简陋到没脸请求批评指正了(捂脸)到了最后居然是建议看芯片手册,咳咳咳

    展开全文
  • 另一个好像传错了,这是主要的ip,sdk的代码在博客中已经给出,https://blog.csdn.net/LOTOOHE/article/details/78692798
  • ZYNQ PL操作DDR内存读写测试

    千次阅读 2020-09-13 23:03:55
    填写完成后填写validate,选择NEXT 7,连续单击 NEXT 8,Accept,然后NEXT,单击 Generate 9,右击 Open IP_Example Design 10,修改顶层接口信号,ZYNQ的核心板上是 100MHZ 差分时钟,以及复位信号是通过按钮提供,...

     一,用户FPGA逻辑接口和搭建FPGA工程

    AXI4  从接口块:AXI4 从站接口将 AXI4 事务映射到 UI,以向内存控制器提供行业标准总线协议接口。

    用户界面块:UI 块向用户提供 FPGA 逻辑块。它通过呈现平面地址空间和缓冲读写数据来提供对本机接口的简单替代。
    内存控制器和本机接口:内存控制器(MC)的前端显示 UI 块的本机接口。本地接口允许用户设计提交存储器读写请求,并提供将数据从用户设计移动到外部存储器件的机制,反之亦然。内存控制器的后端连接到物理接口,并处理该模块的所有接口要求。 内存控制器还提供了重新排序选项,重新排序接收的请求以优化数据吞吐量和延迟。

    用户接口:连接到 FPGA 用户设计,以允许访问外部存储设备。

    1,一路NEXT选择芯片型号

    2,设置 MIG 内核时钟频率为 800M(数据:1600MX32bit)、内存型号、内存的数据位宽

    3,设置输入频率为 200M,不使用调试信号

    4,系统和参考时钟时钟选择no buffer,MIG低电平复位,XADC补偿使能

    5,终端阻抗选择 50hms

    6,先选择 Fixed Pin Out,点击NEXT,根据原理图手动填写 PIN 脚定义。填写完成后填写validate,选择NEXT

    7,连续单击 NEXT

    8,Accept,然后NEXT,单击 Generate

    9,右击 Open IP_Example Design

    10,修改顶层接口信号,ZYNQ的核心板上是 100MHZ 差分时钟,以及复位信号是通过按钮提供,所以修改以下接口,并且增加 clk100m_p/clk100m_n 信号以及 rst_key 信号。增加 PLL 时钟管理模块,从 100MHZ 输入,输出 200MHZ 时钟提供给 MIG 系统时钟和系统参考时钟,这个 200MHZ 时钟就是刚才设置的,必须确保一致。

    11,修补并且增加如下代码

    wire sys_rst;

    wire locked;

    wire clk_ref_i;

    wire sys_clk_i;

    wire clk_200;

    assign sys_rst = ~rst_key;//复位信号

    assign clk_ref_i = clk_200;//200M的参考时钟

    assign sys_clk_i = clk_200;//200M的系统时钟

    12,修改 MIG IP CORE 输入信号

    mig_7series_0 u_mig_7series_0

    (

    // Memory interface ports

    .ddr3_addr (ddr3_addr),

    .ddr3_ba (ddr3_ba),

    .ddr3_cas_n (ddr3_cas_n),

    .ddr3_ck_n (ddr3_ck_n),

    .ddr3_ck_p (ddr3_ck_p),

    .ddr3_cke (ddr3_cke),

    .ddr3_ras_n (ddr3_ras_n),

    .ddr3_we_n (ddr3_we_n),

    .ddr3_dq (ddr3_dq),

    .ddr3_dqs_n (ddr3_dqs_n),

    .ddr3_dqs_p (ddr3_dqs_p),

    .ddr3_reset_n (ddr3_reset_n),

    .init_calib_complete (init_calib_complete),

    .ddr3_cs_n (ddr3_cs_n),

    .ddr3_dm (ddr3_dm),

    .ddr3_odt (ddr3_odt),

    // Application interface ports

    .app_addr (app_addr),

    .app_cmd (app_cmd),

    .app_en (app_en),

    .app_wdf_data (app_wdf_data),

    .app_wdf_end (app_wdf_end),

    .app_wdf_wren (app_wdf_wren),

    .app_rd_data (app_rd_data),

    .app_rd_data_end (app_rd_data_end),

    .app_rd_data_valid (app_rd_data_valid),

    .app_rdy (app_rdy),

    .app_wdf_rdy (app_wdf_rdy),

    .app_sr_req (1'b0),

    .app_ref_req (1'b0),

    .app_zq_req (1'b0),

    .app_sr_active (app_sr_active),

    .app_ref_ack (app_ref_ack),

    .app_zq_ack (app_zq_ack),

    .ui_clk (clk),

    .ui_clk_sync_rst (rst),

    .app_wdf_mask (32'd0),

    // System Clock Ports

    .sys_clk_i (sys_clk_i),

    // Reference Clock Ports

    .clk_ref_i (clk_ref_i),

    .device_temp (device_temp),

    .sys_rst (locked)

    );

    13,添加内存测试的读写逻辑控制代码

    //以下是读写测试

    // End of User Design top instance

    parameter [2:0]CMD_WRITE =3'd0;

    parameter [2:0]CMD_READ =3'd1;

    //parameter TEST_DATA_RANGE=24'd16777215;//全地址测试

    parameter TEST_DATA_RANGE=24'd2000;//部分测试

     

    (*mark_debug="true"*) wire init_calib_complete;

    (*mark_debug="true"*) reg [3:0]state=0;

    (*mark_debug="true"*) reg [23:0]Count_64=0;// 128M*2*16/256

    (*mark_debug="true"*) reg [23:0]Count_64_1=0;

    (*mark_debug="true"*) reg ProsessIn=0;//表示读写操作的包络

    (*mark_debug="true"*) reg WriteSign=0;//表示是写操作

    (*mark_debug="true"*) reg ProsessIn1=0;//表示写操作的包络

    reg [ADDR_WIDTH-1:0]app_addr_begin=0;

    reg [29:0]CountWrite_tem=0;

    reg [29:0]CountRead_tem=0;

     

     

    (*mark_debug="true"*) reg [29:0] CountWrite=0;

    (*mark_debug="true"*) reg [29:0] CountRead=0;

    (*mark_debug="true"*) wire error_rddata=0;

     

    assign app_wdf_end =app_wdf_wren;//两个相等即可

    assign app_en =ProsessIn?(WriteSign?app_rdy&&app_wdf_rdy:app_rdy):1'd0;//控制命令使能

    assign app_cmd =WriteSign?CMD_WRITE:CMD_READ;

    assign app_addr =app_addr_begin;

    assign app_wdf_data =Count_64_1;//写入的数据是计数器

    assign app_wdf_wren =ProsessIn1?app_rdy&&app_wdf_rdy:1'd0;

    always@(posedge clk)

    if(rst&!init_calib_complete)//

    begin

    state <=4'd0;

    app_addr_begin <=28'd0;

    WriteSign <=1'd0;

    ProsessIn <=1'd0;

    Count_64 <=24'd0;

    end

    else case(state)

    4'd0: begin

    state <=4'd1;

    app_addr_begin <=28'd0;

    WriteSign <=1'd0;

    ProsessIn <=1'd0;

    Count_64 <=24'd0;

    CountWrite_tem <=30'd0;//??0

    CountRead_tem <=30'd0;

    CountWrite <=CountWrite_tem;//?¨?D?

    CountRead <=CountRead_tem;

    end

    4'd1: begin

    state <=4'd2;

    WriteSign <=1'd1;

    ProsessIn <=1'd1;

    Count_64 <=24'd0;

    app_addr_begin <=28'd0;

    CountWrite_tem <=CountWrite_tem+30'd1;

    end

    4'd2: begin//写整片的DDR3

    state <=(Count_64==TEST_DATA_RANGE)&&app_rdy&&app_wdf_rdy?4'd3:4'd2;//最后一个地址写完之后跳出状态

    WriteSign <=(Count_64==TEST_DATA_RANGE)&&app_rdy&&app_wdf_rdy?1'd0:1'd1;//写数据使能

    ProsessIn <=(Count_64==TEST_DATA_RANGE)&&app_rdy&&app_wdf_rdy?1'd0:1'd1;//写命令使能

    Count_64 <=app_rdy&&app_wdf_rdy?(Count_64+24'd1):Count_64;

    app_addr_begin <=app_rdy&&app_wdf_rdy?(app_addr_begin+28'd8):app_addr_begin;//跳到下一个(8*32=256)bit数据地址

    CountWrite_tem <=CountWrite_tem+30'd1;

    end

    4'd3: begin

    state <=(state1==4'd0)?4'd4:state;

    WriteSign <=1'd0;

    ProsessIn <=(state1==4'd0)?1'd1:1'd0;

    Count_64 <=24'd0;

    app_addr_begin <=28'd0;

    CountWrite_tem <=CountWrite_tem+30'd1;

    end

    4'd4: begin//读整片的DDR3

    state <=(Count_64==TEST_DATA_RANGE)&&app_rdy?4'd0:state;

    WriteSign <=1'd0;

    ProsessIn <=(Count_64==TEST_DATA_RANGE)&&app_rdy?1'd0:1'd1;

    Count_64 <=app_rdy?(Count_64+24'd1):Count_64;

    app_addr_begin <=app_rdy?(app_addr_begin+28'd8):app_addr_begin;

    CountRead_tem <=CountRead_tem+30'd1;

    end

    default:begin

    state <=4'd1;

    app_addr_begin <=28'd0;

    WriteSign <=1'd0;

    ProsessIn <=1'd0;

    Count_64 <=24'd0;

    end

    endcase

    (*mark_debug="true"*) reg [3:0]state1=0;

    always@(posedge clk)//单独将写操作从上面的状态机提出来,当然也可以和上面的状态机合并到一起

    if(rst&!init_calib_complete)//

    begin

    state1 <=4'd0;

    ProsessIn1 <=1'd0;

    end

    else case(state1)

    4'd0: begin

    state1 <=(state==4'd1)?4'd1:4'd0;

    ProsessIn1 <=(state==4'd1)?1'd1:1'd0;

    Count_64_1 <=24'd0;

    end

    4'd1: begin

    state1 <=(Count_64_1==TEST_DATA_RANGE)&&app_rdy&&app_wdf_rdy?4'd0:4'd1;

    ProsessIn1 <=(Count_64_1==TEST_DATA_RANGE)&&app_rdy&&app_wdf_rdy?1'd0:1'd1;

    Count_64_1 <=app_rdy&&app_wdf_rdy?(Count_64_1+24'd1):Count_64_1;

    end

    default:begin

    state1 <=(state==4'd1)?4'd1:4'd0;

    ProsessIn1 <=(state==4'd1)?1'd1:1'd0;

    Count_64_1 <=24'd0;

    end

    endcase

    (*mark_debug="true"*) reg [23:0]app_rd_data_tem=0;

    (*mark_debug="true"*) reg [23:0]cmp_data_r1=0;

    reg [23:0]cmp_data_r=0;

    always@(posedge clk)

    if(rst&!init_calib_complete)begin

    cmp_data_r <= 24'd0;

    end

    else if(cmp_data_r==TEST_DATA_RANGE)begin

    cmp_data_r <= 24'd0;

    end

    else if(app_rd_data_valid) begin

    cmp_data_r<=cmp_data_r+1'b1;

    end

    reg app_rd_data_valid_r=1'b0;

    always@(posedge clk) begin

    app_rd_data_valid_r <= app_rd_data_valid;

    app_rd_data_tem <= app_rd_data;

    cmp_data_r1 <= cmp_data_r;

    end

    assign error_rddata=(app_rd_data_tem!=cmp_data_r1)&app_rd_data_valid_r;

    14,修改仿真代码中的系统时钟,默认是 200MHZ(5ns) 改为 100MHZ(100ns)

    parameter CLKIN_PERIOD = 5000

    15,修改仿真接口,仿真

    二,注意:该信号仅提供到 memc_ui_top 模块级别。 只有当 ECC 被使能时才应使用该信号。

    1,app_addr [ADDR_WIDTH - - 1 1 : 0]
    此输入表示当前正在提交给用户界面的请求的地址。 UI 聚合外部 SDRAM 的所有地址字段,并向您显示一个平面地址空间。
    2,app_cmd[2 : 0]

    此输入指定请求的命令如下表所示

    3,app_en
    此信号在输入请求中使用,用户必须赋值于 app_addr [],app_cmd [2:0]和 app_hi_pri,然后断言 app_en 将该请求提交给 UI。这将通过断言 app_rdy 启动 UI 确认的握手。

    4,app_hi_pri
    该输入表示当前请求是高优先级。
    5,app_wdf_data [APP_DATA_WIDTH - - 1 1 : 0]
    该总线提供当前正在写入外部存储器的数据。
    6,app_wdf_end
    该输入表示当前周期中 app_wdf_data []总线上的数据是当前请求的数据。

    7,app_wdf_mask [APP_MASK_WIDTH - - 1 1 : 0]
    该总线指示 app_wdf_data []的哪些位被写入外部存储器,哪些位保持在当前状态。
    8,app_wdf_wren
    该输入表示 app_wdf_data []总线上的数据有效。

    9,app_rdy
    此输出向用户显示当前正在提交给 UI 的请求是否被接受。如果在 app_en 被断言之后,UI 不
    会声明此信号,则必须重试当前的请求。如果以下情况,则不会声明 app_rdy 输出:
    1)PHY /内存初始化尚未完成
    2)所有的银行机器都被占用(可以看作命令缓冲区已满)
    - 请求读取,读取缓冲区已满
    - 请求写入,并且没有写缓冲区指针可用
    3)正在插入定期读取
    10,app_rd_data [APP_DATA_WIDTH - - 1 1 : 0]
    该输出包含从外部存储器读取的数据

    11,app_rd_data_end
    此输出表示当前周期中 app_rd_data []总线上的数据为当前请求的最后数据。
    12,app_rd_data_valid
    该输出表示 app_rd_data []总线上的数据有效。,

    13,app_wdf_rdy
    该输出表示写入数据 FIFO 准备好接收数据。 接受写入数据当 app_wdf_rdy 和 app_wdf_wren 都被断言时。
    14,app_ref_req
    当被置位时,该高电平有效输入请求存储器控制器向 DRAM 发送刷新命令。 必须对单个周期进,行脉冲以进行请求,然后至少断言,直到 app_ref_ack 信号被断言以确认请求并指示已经发送请求。
    15,app_ref_ack
    当置位时,此高电平有效输入确认刷新请求,并指示命令已从存储控制器发送到 PHY。

    16,app_zq_req
    当置位时,该高电平有效输入请求存储器控制器向 DRAM 发送 ZQ 校准命令。 必须对单个周期进行脉冲以进行请求,然后至少断言,直到 app_zq_ack 信号被断言以确认请求并指示已经发送请求。
    17,app_zq_ack

    当有效时,此高电平有效输入确认 ZQ 校准请求,并指示命令已从存储控制器发送到 PHY。

    18,ui_clk_sync_rst
    这是从与 ui_clk 同步的 UI 重置。
    19,ui_clk
    这是 UI 的输出时钟。 它必须是出口到外部 SDRAM 的时钟频率的一半或四分之一,这取决于,GUI 中选择的 2:1 或 4:1 模式。
    20,init_calib_complete e
    当校准完成时,PHY 会断言 init_calib_complete。 在向内存控制器发送命令之前,应用程序无需等待 init_calib_complete。

    三,MIG内存控制器用户逻辑时序

    1,命令路径

    当用户逻辑 app_en 信号被断言并且 app_rdy 信号从 UI 被断言时,命令被 UI 接受并写入 FIFO。当 app_rdy 被取消置位时,UI 会忽略该命令。用户逻辑需要将 app_en 保持为高电平以及有效的命令和地址值,直到 app_rdy 被断言。

    可以发出非背靠背写入命令,此图描述了 app_wdf_data,app_wdf_wren 和app_wdf_end 信号的三种场景,如下所示:
    (1).写入数据以及相应的写入命令。
    (2).写入数据在相应的写入命令之前。
    (3).写入数据在相应的写命令之后,不应超过两个时钟周期的限制。对于在写入命令后输出的写入数据,最大延迟为两个时钟周期。

    2,写路径

    当 app_wdf_wren 被断言并且 app_wdf_rdy 为高时,写数据被写入写入 FIFO(图 1-4-2-1)。
    如果 app_wdf_rdy 被取消置位,则用户逻辑需要保留 app_wdf_wren 和 app_wdf_end 以及有效的
    app_wdf_data 值,直到 app_wdf_rdy 被断言。app_wdf_mask 信号可用于屏蔽写入外部存储器的字节。

    写入数据和相关联的写入命令之间的单次写入的最大延迟是两个时钟周期。当发出背靠背写入命令时,写入数据和相关的背靠背写命令之间没有最大延迟。必须使用 app_wdf_end 信号来指示存储器写入突发的结束。对于 8 位的内存突发类型,应该在
    第二个写入数据字上断言 app_wdf_end 信号。应用程序接口数据到 DRAM 输出数据的映射可以是以一个例子解释。

    3,读路径

    读取的数据由 UI 以请求的顺序返回,并且在 app_rd_data_valid 被断言时有效。返回的读取数据总是与地址/控制总线上的请求顺序相同。

    4,用户刷新

    对于用户控制的刷新,应通过将 USER_REFRESH 参数设置为“ON”来禁用内存控制器管理的维护。要请求 REF 命令,app_ref_req 会选通一个周期。当存储器控制器将命令发送到 PHY 时,它会将app_ref_ack 选通一个周期,之后可以发送另一个请求。只要遵循上述定义的握手,可以随时执行用户刷新操作。对于其他命令,没有额外的接口要求。但是,待处理的请求会影响操作何时出现。内存控制器在发出刷新命令之前完成所有挂起的数据请求。在确定何时选择 app_ref_req 以避免 tREFI 违规时,必须考虑每个待处理请求的时序参数。为了解决最坏的情况,减去每个银行机器的 tRCD,CL,数据传输时间 tRP,以确保在 tREFI 到期之前所有事务都可以完成。 (tREFI – (tRCD + ((CL + 4) × tCK) + tRP) × nBANK_MACHS)公式 1-1 显示了 REF请求间隔的最大值。公式 1-1 在校准后应立即发出用户 REF,以建立确定何时发送后续请求的时间基准。

     

    展开全文
  • ZYNQ实现无DDR启动实现

    千次阅读 2019-12-03 16:57:23
    在配置中,不使能DDR 生成bit,导入到sdk 2.SDK操作流程 在平台环境中,修改ps7_init.c文件,将ddr相关文件注释掉 生成bsp后,修改xparameters.h,添加ddr参数配置 然后,生成fsbl 在fsbl的main.c中,增加XPAR_PS7...

    1.硬件环境搭建
    使用版本vivado2018.2
    在配置中,不使能DDR
    在这里插入图片描述
    生成bit,导入到sdk
    2.SDK操作流程
    在平台环境中,修改ps7_init.c文件,将ddr相关文件注释掉
    在这里插入图片描述
    生成bsp后,修改xparameters.h,添加ddr参数配置
    在这里插入图片描述
    然后,生成fsbl
    在fsbl的main.c中,增加XPAR_PS7_DDR_0的条件编译,而这个宏没有定义,相当于注释掉
    在这里插入图片描述
    然后修改fsbl.h文件
    在这里插入图片描述最后修改qspi.c文件
    在这里插入图片描述
    重新编译即可
    3.注意
    在其他文章中,提到修改程序运行空间为ram0,这里目前没有修改,是正常的,这里可作为一个参考

    展开全文
  • 而PS端的DDR3起码是512M,甚至有的达到了4G,可以满足大量数据进行交互。 PL与PS进行高速的数据交互要通过AXI协议。zynq 7000 SOC 的 HP 口是 High-Performance Ports 的缩写,如下图所示,一共有 4个 HP 口
  • 第一步: 在Vivado的ZYNQ Block Design时候不配置DDR 第二步: 在Vitis中: 1、 在Vitis中新建Platform,选择xsa文件: 2、 在xparameters.h中添加DDR的地址空间定义,如下: 3、 修改链接文件,修改每个段都到...
  • ZYNQDDR 启动

    2021-08-18 17:41:32
    ZYNQDDR 启动1 fsbl_bsp 相关修改Translation_table.sxil_exception.cfsbl 相关修改main.cfsbl.hfsbl_handoff.Sfsbl_hooks.cfsbl_hooks.himage_mover.cpcap.cqspi.cqspi.hlscript.ld添加宏定义2 application...
  • ZYNQ PS与PL共享DDR

    千次阅读 2019-11-07 20:37:32
    平台: 开发板:ZYNQ-7000系列裸板开发 开发环境:vivado hls、vivado、sdk 参考 https://blog.csdn.net/weixin_36474809/article/details/85111550 ...
  • zynq使用DATAMOVER实现DDR到PL数据搬运的代码,用于学习ZYNQ的逻辑编程
  • ZYNQ 7020 FPGA DDR3

    千次阅读 2021-07-14 13:46:37
    ZYNQ 7020 FPGA DDR3ZYNQ是FPGA+双核ARM的架构 ZYNQ是FPGA+双核ARM的架构 最近我需要用到ZYNQ来做东西,但是网上看见到的开发板在FPGA部分没有没有挂DDR3,只能结合自己以前的经验和现有的资料,摸索一下。本文分为两...
  • ZYNQ基本用法------DDR(1) 2 软件部分 见ZYNQ基本用法------DDR(1) 2.1 源代码 //使用PS控制DDR3的读写 /* C语言中%X的意思是以十六进制数形式输出整数,类似%x的输出格式还有: 1.%c:单个字符 2.%d:十进制...
  • ZYNQ的PL控制PS的DDR

    2021-10-20 14:48:44
    1. 创建一个ZYNQ核 选择高速互联总线,因为DDR速率比较快,所以PS与PL端的交互,我们选择HP,高速AXI连接,位宽选择32,和DDR位宽保持一致即可 2. 勾选Enable DDR,选中DDR的型号,还有Width,我选的是32,可以...
  • ` `Zynq7021有1G的DDR,PS和PL都可以对DDR进行访问。PS端对DDR的读写,在Xil_io.h文件中,使用Xil_Out函数可以向 DDR写入数据,使用Xil_In函数可以从DDR读取数据。但是要注意ARM的二级缓存问题。## 大端存储和小端...
  • Xilinx-ZYNQ7000系列-学习笔记(6):ZYNQDDR使用OCM加载程序 之前由于某项目需求,需要去掉DDR,但是去掉DDR以后会导致程序无法正常启动,因为默认的启动方式会经过DDR这一步。 在查阅了大量的资料和仔细研究了...
  • ZYNQ7000系列 DDR读取正确性

    千次阅读 2020-04-28 13:34:26
    【摘要】使用ZYNQ或者MPSoC的好处是可以通过PL逻辑设计硬件加速器,对功能进行硬件加速。加速器和ARM之间的交互信息一般包含自定义加速指令传递、待计算数据以及计算结果。这三种交互信息 使用ZYNQ或者MPSoC的...
  • zynqDDR使用OCM加载程序运行

    千次阅读 2018-12-28 13:58:44
    一、使能DDR,但程序不用DDR 赛灵思提供的文档,按照文档进行 ... 第八步 改为注释掉FLASH大小选择,均写成128M 就可以成功的OCM加载程序了 ...采用的方法是在zynq block design配置时保留ddr,而在程序编...
  •   个别时候,嵌入式设备的DDR除了常规的遍历读写和压力测试外,会有提供读写带宽的需求,下面介绍一种没有精确要求的测法,参考自http://github.com/raas/mbw   原理主要分三部分:memcpy(内存拷贝),dumb...
  • PYNQ2之ZYNQ的PS读写DDR

    千次阅读 2018-10-29 21:01:51
     和前面的不一样这里需要用到DDR,所以需要在PS中正确配置DDR,这也是看别人zedboard板卡教程自己却一直实行不了的原因。 问题一:串口打印问题  首先是串口驱动问题,网上下载驱动,安装一直提示未正确安装驱动...
  • 判断有肯能是zynq上的ddr存在有问题。型号选择确定是没有问题。 请教了大佬,说是可以从让arm运行在bram中,因为存储有限,只能跑小程序。 操作方法就是打开SDK软件src下的lscript.ld文件,可以看到有四个存储可以...
  • ZYNQ-用PS控制DDR3内存读写

    千次阅读 2018-02-13 14:33:27
    本编文章的目的主要用简明的方法对DDR3进行读写,当然这种方式每次读写都需要CPU干预,效率是比较低的,但是这是学习的过程吧。本系列文章尽可能的让每一个实验都相对独立,过程尽可能保证完整性,保证实验的可重现...
  • Zynq UltraScale+ MPSoC配置DDR4参数

    千次阅读 热门讨论 2019-10-29 20:07:20
    Zynq UltraScale+ MPSoC配置DDR4参数 前言 自己做自己的嵌入式产品一般要选择合适的DDR,而这里开发板给的是4GB的UIMM的DDR4,也就是电脑上用的,所以用不了,只能自己挂载Component,这里说一下配置的过程,如何从...
  • ZYNQ_PL与PS的DDR交互

    2021-01-13 16:29:25
    ZYNQ7000系列中PS端与PL端的通信都是通过AXI总线进行连接的,利用好AXI协议是PS与PL交互的基础,因此设计这个实验来进一步了解两者间的通信。1.实验目的PL端通过AXI协议访问PS端的DDR内存,其中包括往DDR写数据,...
  • ZYNQ-7000 开发之七】PL读写DDR3

    千次阅读 多人点赞 2019-03-24 22:18:03
    0.引言 构建SoC系统,毕竟是需要实现PS和PL间的数据交互,而像上一讲那样PL主机与PL从机之间通过AXI4-Lite总线进行交互有点杀鸡用牛刀了。 如果PS与PL端进行数据交互,可以...对于这样的应用来说,利用DDR3作为PS...
  • 附录1:主机IP核底层模块代码`timescale 1 ns / 1 psmodule AzIP_AXI_Master_3_v1_0_M00_AXI #(// Users to add parameters here// User parameters ends// Do not modify the parameters beyond this line// The ...
  • zynq pl通过axi总线读写ps端ddr,没有使用dma,完整程序压缩包
  • ZYNQ 7020 PL以AXI_DMA访问DDR或OCM

    千次阅读 2018-08-21 11:47:45
    本章主要介绍ZYNQ 7020的PL端在PS的控制下实现对DDR的访问,通过debug的方式抓取DDR S_AXI_HP接口的时序,方便在PL内以verilog的形式直接访问DDR/OCM 本设计中软件版本:VIVADO2018.1,对应SDK也为 2018.1 硬件...
  • 环境:vivado2018.3 芯片: xc7z100ffg900-2 ... 实验目的:将ADC接收的...DDR芯片的管脚是绑定到ZynqDDR接口上的。 而Zynq系统的这个DDR总线接口有是链接在其内部“Memory Interfaces”中的“DDR2/3,LPDDR2 Con..

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,592
精华内容 1,036
关键字:

ddrzynq