精华内容
下载资源
问答
  • 本文档讲述了DDR控制器的详细设计过程,并使用镁光的DDR model进行 仿真验证
  • ddr控制器随笔

    千次阅读 2017-07-23 19:58:25
    ddr控制器的数据和指令输入来自AXI Bus,AHB Bus等,它们连接的是访存指令的发起方,如CPU, GPU, DMA控制器等。ddr控制器输出的数据和指令通过DFI连接的ddr phy访问外设ddr sdram。下面对Arbiter和Command Queue

    下图是依据使用过的cadence ddr controller IP画出的SOC中常用的ddr controller的结构图。
    ddrc
    ddr控制器的数据和指令输入来自AXI Bus,AHB Bus等,它们连接的是访存指令的发起方,如CPU, GPU, DMA控制器等。ddr控制器输出的数据和指令通过DFI连接的ddr phy访问外设ddr sdram。

    下面对Arbiter和Command Queue with Logic进行简单说明。
    Arbiter
    多端口输入Arbiter,常使用的策略有Round-Robin Arbitration(时间片), Transation Priority(优先级),Port Bandwidth Limitation(带宽限制)等。

    Command Queue with Placement Logic
    常用的影响command queue中指令排序的规则有,
    Address Collision/ Data Coherency Violation 对相同地址的读写命令重新排序可能会引起数据一致性的错误,因此对同一地址的读写指令进入队列忽略优先级
    Priority 指令优先级高,AXI port的优先级
    Bank Spliting 相同bank不同row之间需要插入对其他bank的操作
    write-to-read spliting 在相同CS的写命令和读命令之间可插入新的command
    Read/Write Grouping 读命令和写命令按组排序,减少读写转换的时间overhead

    展开全文
  • 实用DDR控制器

    2013-08-11 08:32:03
    在分析DDR SDRAM 基本操作原理的基础上,提出了一个基于FPGA 的DDR SDRAM 控制器的设计,实现了DDR SDRAM 读写时序控制,并给出实现结果
  • DDR控制器(xilinx)

    2009-05-16 08:26:33
    DDR控制器(xilinx) 安福利详细设计教程
  • ddr和ddr2的使用方法以quartus ii 中的ddr和ddr2控制器的使用手册
  • Altera DDR2控制器使用IP的方式实现,一般很少自己写控制器代码。 ddr22 ddr22_inst ( .aux_full_rate_clk (mem_aux_full_rate_clk), .aux_half_rate_clk (mem_aux_half_rate_clk), .global_reset_n (gl...

    Altera DDR2控制器使用IP的方式实现,一般很少自己写控制器代码。

      ddr22 ddr22_inst
        (
          .aux_full_rate_clk (mem_aux_full_rate_clk),
          .aux_half_rate_clk (mem_aux_half_rate_clk),
          .global_reset_n (global_reset_n),
          .local_address (mem_local_addr),
          .local_be (mem_local_be),
          .local_burstbegin (local_burstbegin_sig),
          .local_init_done (),
          .local_rdata (mem_local_rdata),
          .local_rdata_valid (mem_local_rdata_valid),
          .local_read_req (mem_local_read_req),
          .local_ready (mem_local_ready),
          .local_refresh_ack (),
          .local_size (mem_local_size),
          .local_wdata (mem_local_wdata),
          .local_write_req (mem_local_write_req),
          .mem_addr (mem_addr[12 : 0]),
          .mem_ba (mem_ba),
          .mem_cas_n (mem_cas_n),
          .mem_cke (mem_cke),
          .mem_clk (mem_clk),
          .mem_clk_n (mem_clk_n),
          .mem_cs_n (cs_n),
          .mem_dm (mem_dm[1 : 0]),
          .mem_dq (mem_dq),
          .mem_dqs (mem_dqs[1 : 0]),
          .mem_odt (mem_odt),
          .mem_ras_n (mem_ras_n),
          .mem_we_n (mem_we_n),
          .phy_clk (phy_clk),
          .pll_ref_clk (clock_source),
          .reset_phy_clk_n (reset_phy_clk_n),
          .reset_request_n (),
          .soft_reset_n (tie_high)
        );
    

      以mem开头的一堆信号,是直接导出为顶层引脚,去连接PCB板上的DDR2芯片的。

    以local开头的一堆信号,是ddr2控制器导出给用户的接口信号,用户要向ddr2存储器中写入数据或者从ddr2中读出数据,只需要操作local接口即可。

    local信号,可以分为以下几组:


     

    控制组

    local_init_done:DDR2控制器初始化完成标志信号,DDR2控制器上电需要经过一系列的初始化操作,包括DDR2芯片的初始化和DDR接口的时序校准,整个过程耗时较长。待该信号拉高之后,local接口上才能进行读写操作。

    local_refresh_ack:ddr2控制器对ddr2芯片执行刷新操作后的应答信号,一般用户读写时,不用关心该信号。


     

    用户写接口

    local_address :用户希望将数据写入到的DDR2存储器的地址,该地址为DDR2芯片片选、行地址、bank地址、列地址的组合,{CS、ROW、BA、COL}。
    local_be:写入时候的字节使能,例如对于DDR2是16位硬件接口,则用户数据接口为32位,为4个字节,所以local_be的位宽为4,每一位对应一个字节,如果写入时候用户端32位的数据中有一个字节不希望被写入,则对应的be位设置为0即可。

    local_size:用户接口的突发长度,指定每次用户发起一次写入请求会写入多个数据。该长度最大值在DDR IP的配置界面可以配置,如下图所示。注意该值是控制器的最大突发长度设定值,不等于DDR2芯片支持的最大突发长度,DDR2芯片最大只支持8个长度。
    local_burstbegin:用户接口的突发启动信号,该信号每一个高脉冲会启动一次突发传输,每次传输长度为local_size指定的长度
    local_ready:ddr控制器就绪标志信号,该信号有效则表明当前数据被成功写入了ddr2控制器中,为0则表示ddr控制器无法接受当前操作,用户需要保持当前地址、数据和控制信号不变直到ready信号再次拉高
    local_wdata:用户需要写如到ddr中的数据,位宽为ddr芯片数据线位宽的2倍
    local_write_req::写数据请求信号为1则local_wdata端口上的数据允许被写入ddr控制器,(具体能否成功写入,还得看local_ready的状态)


    local_address:用户希望从DDR2存储器读取数据的地址,该地址为DDR2芯片片选、行地址、bank地址、列地址的组合,{CS、ROW、BA、COL}。
    local_be:读出时候的字节使能,例如对于DDR2是16位硬件接口,则用户数据接口为32位,为4个字节,所以local_be的位宽为4,每一位对应一个字节,如果读出时候用户端32位的数据中有一个字节不希望被读出,则对应的be位设置为0即可。
    local_burstbegin:用户接口的突发启动信号,该信号每一个高脉冲会启动一次突发传输,每次传输长度为local_size指定的长度
    local_rdata:读取到的数据内容,位宽为ddr芯片数据线位宽的2倍
    local_rdata_valid:读取数据有效标志信号,当该信号有效时,表明local_rdata上的数据是读到的有效内容
    local_read_req:读请求信号
    local_size:用户接口的突发长度,指定每次用户发起一次读取请求会读出多少个数据。该长度最大值在DDR IP的配置界面可以配置,如下图所示。注意该值是控制器的最大突发长度设定值,不等于DDR2芯片支持的最大突发长度,DDR2芯片最大只支持8个长度。

     

    转载于:https://www.cnblogs.com/xiaomeige/p/11516610.html

    展开全文
  • 本代码为DDR控制器的xilinx mig用户自定义verilog源代码,自己用状态机写的代码。
  • DDR控制器MIG核的使用

    千次阅读 多人点赞 2020-02-19 15:02:44
    FPGA的片上存储资源bram简单好用,时序清晰,要不是...之前在网上找了好多资料,但发现都没有一个很完整的教程教你怎么使用DDR控制器IP核MIG(Memory Interface Generator),所以写了这篇文章主要希望能帮初学者快...

    FPGA的片上存储资源bram简单好用,时序清晰,要不是总容量往往就几十Mb谁愿意用DDR呀······
    害,言归正传,因为设计需要存储1477x1800x3 双精度浮点复数这样的大号矩阵,所以只能放到DDR上去进行读写。之前在网上找了好多资料,但发现都没有一个很完整的教程教你怎么使用DDR控制器IP核MIG(Memory Interface Generator),所以写了这篇文章主要希望能帮初学者快速上手MIG的使用以实现DDR读写。
    介绍MIG之前,我觉得有必要先对DDR做一个介绍,DDR SDRAM(Double Data Rate Synchronous Dynamic Random Access Memory,实际上还分为DDR SDRAM,DDR2 SDRAM,DDR3 SDRAM,DDR4 SDRAM,主要是数据预取prefetch和工作频率的不同,感兴趣的大家可以自己查),搭眼一看,这玩意本质上不就是数字集成电路里学的DRAM嘛(电容存储,会漏电,时不时需要刷新blablabla······),而double data rate说的是他在clock的上升沿和下降沿都会进行数据读写,设想如果用户逻辑侧的时钟频率和DDR的工作频率之比为1:4的话,用户侧的一个clk, 那么DDR实际上进行了4*2(上下沿)=8次读写操作。
    在这里插入图片描述
    DDR3的内部是如上图的存储阵列组成,数据存储在单元格中,在检索你想要的数据时,先指定一个行(Row),再指定一个列(Column),我们就可以准确地找到所需要的单元格,这就是内存芯片寻址的基本原理。对于内存,这个单元格可称为存储单元,常见存储单元位宽有4bit,8bit,16bit,那么这个表格(存储阵列)就是逻辑 Bank(Logical Bank),而一颗DDR芯片上有若干个bank,一般内存芯片厂家在芯片上是标明容量的,我们可以看芯片上的标识知道,这个芯片有几个逻辑BANK,每个逻辑bank的位宽是多少,每个逻辑BANK内有多少单元格(CELL),eg.比如64MB和128MB内存条常用的**64Mbit的芯片(注意不是Mb,1byte=8bit,所以除以8才是Mb)**就有如下三种结构形式:
    ①16 M x 4 (4 M x 4 x 4 banks) [16M X 4]
    ②8 M x 8 (2 M x 8 x 4 banks) [8M X 8]
    ③4 M x 16 (1 M x 16 x 4 banks) [4M X 16]
    即一颗DDR芯片的单元格数(逻辑bank数 X 每个逻辑bank的单元格数)X 每个单元格的位宽(bit)。
    16bit位宽的芯片意味着你给内存一个地址,内存会给你一个16bit的数据到数据线上,但实际中我们的数据往往不止16bit,例如双精度浮点数(64bit),那么就需要用4块DDR芯片拼接成一个64位宽的DDR,只是这4块DDR共用一个地址线,每个取出的16bit数据再拼成一个64bit的数据,那么就相当于每个地址可以存一个64位宽的数据,而这样一个64位宽的数据集合就是一个物理bank,也经常叫Rank。大家可以参考这篇文章说的很详细:

    64bit数据存储形式
    接下来说说MIG核是干什么的,放一张DDR工作的状态图:
    在这里插入图片描述
    DDR上电后需要控制其初始化,ZQ校准,激活bank,而后读写等一系列过程,这其中还要配置模式寄存器,控制DDR refresh、precharge,考虑怎么样将8/16bit位宽的DDR芯片拼接成更大位宽等等问题。这对于用户侧是十分不友好的。所以就需要DDR控制器提供一个用户友好的接口,而MIG核做的就是这件事情
    在这里插入图片描述
    左边是用户侧读写逻辑,经由MIG核生成DDR需要的信号控制读写。所以,我们只需要把关注点放在MIG核的用户侧接口信号,从官方文档里可以找到接口说明。
    在这里插入图片描述
    在这里插入图片描述
    需要重点关注的信号用红框标注出来了,根据英文也能猜出大概是干嘛的,接下来就可以生成IP核了,这里不得不说一下大家FPGA最好选用Xilinx的亲儿子,之前用的一款adm-pcie 7v3,参考资料少,问题多,而且DDR的管脚还要自己去配,属实折腾人······这次用的是ultrascale+系列的亲儿子kcu116,简直不要太舒服哈哈。在这里插入图片描述
    在这里插入图片描述
    这里说一下系统时钟,因为我的板子时钟源有一个300MHz的差分时钟,所以就刚好用它作为MIG的输入时钟,实际上MIG会利用分频倍频将这个差分时钟变成我们想要的DDR工作频率,第二张图里的memory interface speed指的就是DDR的工作频率,而frequency ratio指的就是DDR工作频率:用户逻辑频率,再加上上下沿传输,意味着用户侧一个clk可以给DDR读写8个数据。reference input就是刚才所说的外接时钟源。底下的data_width指的是我们要存的数据位宽,例如双精度浮点数64,这时候我们可以发现无论是app_rd_data还是app_wdf_data都变成了512位,,刚好和64是8:1的关系,也就是我们所说的用户侧一个clk可以读写8个数据,所以我们在写自己的读写逻辑时,如果是连续地址读写,那么每次的地址数据应该+8。CAS latency指的是DDR在读取时,列地址选中后数据传输放大到I/O口这个过程本身就有的一个延时,相当于我们给了读地址后到得到读数据的延时,这涉及到DDR的工作原理这里不作深究我们可以随便设个值。
    在这里插入图片描述
    在这里插入图片描述
    这里说一下memory address map,大家注意到有row-bank-colum,row-colum-bank,bank-row-column几种数据地址映射机制,就是我们在进行存储时,是按照先填写column,第一行的column写满后跳到下一个bank的第一行去存储,8个bank的第一行都填满后,再跳转到下一行存储,其它几种同理。进一步深究MIG核的代码发现一个有趣的事情,例如row-column-bank的地址映射机制,在这里插入图片描述 这里的addr并不是单纯的row-column-bank的排列顺序,不由得想到一个问题,我们在设计自己的逻辑时,一个app_rd_data或者一个app_wdf_data要占用8个地址所以每次地址都是+8,即+4’b1000,相当于刚好给bank+1从而实现了bank 的跳转,因此Xilinx官方已经帮我们考虑了这些问题我们可以只管给addr+4’b1000其他的不用操心。
    处理完这些就可以点击完成生成IP核。等IP核综合完成,这个时候推荐大家直接右键生成example design,因为你只是生成例化了控制器,但还没有和DDR芯片连接,生成example design便可以直接开始设计自己的读写逻辑。打开example design之后可以看到代码结构,只需要在u_example_tb.v里修改即可。在这里插入图片描述

    接下来就是读写时序的设计了。

    写命令与写地址
    在这里插入图片描述
    如上图所示①,②,③情况,只有在③时刻app_en和app_rdy同时为高电平app_cmd(命令)和(app_addr)地址才有效,所以当需要app_cmd,app_addr有效时app_en必须保持到app_rdy为高电平才有效。
    写时序
    在这里插入图片描述
    如上图所示①,②,③种情况,写命令和写数据直接存在三种逻辑关系。
    1、①表示写命令(app_cmd),写当前地址(app_addr)和写数据(app_wdf_data)以及写控制信号(app_en,app_rdy,app_wdf_rdy,app_wdf_wren,app_wdf_end)同时有效。
    2、②表示写数据(app_wdf_data)和写控制信号(app_wdf_wren,app_wdf_end)先于写命令(app_cmd)和写当前地址(app_addr)以及其他写控制信号(app_en,app_rdy,app_wdf_rdy)一个用户时钟(ui_clk)。
    3、③表示写数据(app_wdf_data)和写控制信号(app_wdf_wren,app_wdf_end)迟于写命令(app_cmd)和写当前地址(app_addr)以及其他写控制信号(app_en,app_rdy,app_wdf_rdy)。最多两个用户时钟(ui_clk)。
    读时序
    在这里插入图片描述
    如上图所示,当读命令(app_cmd)和当前读地址(app_addr)以及读控制信号(app_en,app_rdy)同时有效时,等待读数据有效信号(app_rd_data_valid)有效时读数据(app_rd_data)有效。
    重点说一下app_rdy,因为它的作用是指示你当前给MIG的指令是否被接受。只有它拉高时才会接受指令,否则即使让app_en拉高app_rdy为0也必须重新发出当前请求命令(实际上我们可以设置一个FIFO,将app_rdy作为FIFO的使能信号即可)。而导致app_rdy信号为0的原因可能有:

    1. PHY /内存初始化尚未完成;
    2. 所有bank都被占用;
    3. 请求读取并且读取缓冲区已满;
    4. 请求写入,没有可用的写缓冲区指针(也就是地址信号不可用);
    5. 正在插入定期读取;

    这里给大家提供一段简单的读写代码,为了方便是直接在example design的u_example_tb基础上改的,所以比较粗糙可读性差点,大家可以把波形跑出来重点看时序,连续地址写入50个512bit数据再把它读出来,然后反复这个操作,主要是希望帮助大家熟悉读写时序,然后再根据你们自己的需要去设计自己的读写逻辑。注意app_rdy信号拉高后才可以正常读写操作所以应该用app_rdy信号作为指令继续进行的先决条件,还有就是大家会发现读数据时,第一个数据需要隔很长一段时间才能读出来,但是后续的数据会连续读出,所以在进行自己的设计时,最好一次性读出来一部分数据做处理(这时就体现FIFO的重要性了),不要读一个写一个否则效率太低。还有就是如果你的读写地址是随机的不连续的往往也会导致效率低下(app_rdy信号时常拉低),这是由DDR的工作机制决定的,因为从DDR读数据时,它会先充电激活一个row,如果下一个地址不在这一row,则需要关闭当前操作行(row)再打开新的行,这一过程叫precharge,具体细节感兴趣的同学可以去深究DDR工作机制。因为我的水平也一般般所以欢迎大家给我指出文章中的漏洞,也欢迎讨论~

    module example_tb #(
      parameter SIMULATION       = "FALSE",   // This parameter must be
                                              // TRUE for simulations and 
                                              // FALSE for implementation.
                                              //
      parameter APP_DATA_WIDTH   = 512,        // Application side data bus width.
                                              // It is 8 times the DQ_WIDTH.
                                              //
      parameter APP_ADDR_WIDTH   = 29,        // Application side Address bus width.
                                              // It is sum of COL, ROW and BANK address
                                              // for DDR3. It is sum of COL, ROW, 
                                              // Bank Group and BANK address for DDR4.
                                              //
      parameter nCK_PER_CLK      = 4,         // Fabric to PHY ratio
                                              //
      parameter MEM_ADDR_ORDER   = "ROW_COLUMN_BANK" // Application address order.
                                                     // "ROW_COLUMN_BANK" is the default
                                                     // address order. Refer to product guide
                                                     // for other address order options.
     )
    
    (
      // ********* ALL SIGNALS AT THIS INTERFACE ARE ACTIVE HIGH SIGNALS ********/
      input clk,                 // MC UI clock.
                                 //
      input rst,                 // MC UI reset signal.
                                 //
      input init_calib_complete, // MC calibration done signal coming from MC UI.
                                 //
      input app_rdy,             // cmd fifo ready signal coming from MC UI.
                                 //
      input app_wdf_rdy,         // write data fifo ready signal coming from MC UI.
                                 //
      input app_rd_data_valid,   // read data valid signal coming from MC UI
                                 //
      input [APP_DATA_WIDTH-1 : 0]  app_rd_data, // read data bus coming from MC UI
                                                 //
      output [2 : 0]                app_cmd,     // command bus to the MC UI
                                                 //
      output [APP_ADDR_WIDTH-1 : 0] app_addr,    // address bus to the MC UI
                                                 //
      output                        app_en,      // command enable signal to MC UI.
                                                 //
      output [(APP_DATA_WIDTH/8)-1 : 0] app_wdf_mask, // write data mask signal which
                                                      // is tied to 0 in this example
                                                      // 
      output [APP_DATA_WIDTH-1: 0]  app_wdf_data, // write data bus to MC UI.
                                                  //
      output                        app_wdf_end,  // write burst end signal to MC UI
                                                  //
      output                        app_wdf_wren // write enable signal to MC UI
                                       
                                                  
      );
    
    localparam BEGIN_ADDRESS = 32'h00000000 ; // This is the starting address from
                                         // which the transaction are addressed to
    localparam NUM_TRANSACT  = 100 ; // Total number of transactions
    localparam NUM_WRITES = 50 ;// Total Number of WRITE transactions
    localparam NUM_READS  = 50 ;// Total Number of READ transactions
    localparam TCQ  = 100; // To model the clock to out delay
    localparam RD_INSTR = 3'b001; // Read command
    localparam WR_INSTR = 3'b000; // Write command
    
    reg  [2 :0]                     cmd;               // Command instruction 
    reg  [APP_ADDR_WIDTH-1:0]       cmd_addr;          // Command address
    reg  [9 :0]                     cmd_cnt ;          // Command count
    reg                             cmd_en;            // Command enable 
    reg                             init_calib_complete_r; // Registered version of init_calib_complete 
    reg  [APP_DATA_WIDTH-1: 0]      wr_data;       // Write data internal signal
    reg                             wr_en;         // Write enable signal
    
    always @ (posedge clk)  
      init_calib_complete_r <= #TCQ init_calib_complete;
    assign app_en    = cmd_en & (app_rdy) ;
    assign app_cmd       = cmd;
    assign app_addr  = cmd_addr;
    
    always @(posedge clk)
    begin
      if(rst)
        cmd_addr <= #TCQ BEGIN_ADDRESS;
      else if (cmd_en & app_rdy)
        if (cmd_addr < ((NUM_WRITES-1)*8))
          cmd_addr <= #TCQ cmd_addr + 4'b1000;
        else if (cmd_cnt == (NUM_WRITES-1) || cmd_cnt == NUM_TRANSACT-1)
          cmd_addr <= #TCQ BEGIN_ADDRESS;
        else begin
          cmd_addr <= cmd_addr;
        end
    end
    
    assign app_wdf_wren     = wr_en ;
    assign app_wdf_end    = wr_en ;
    assign app_wdf_data   = {483'b0,cmd_addr};
    assign app_wdf_mask   = 64'b0 ;
    
    always @(posedge clk)
    begin
      if(rst | ~init_calib_complete_r) begin
        cmd_en <= 1'b0;
        cmd <= #TCQ WR_INSTR;
      end
      else if( cmd_cnt == NUM_TRANSACT-1) begin
    //    cmd_en           <= #TCQ 1'b0;
        cmd              <= #TCQ WR_INSTR;
      // Generate 100 write commands till the cmd_cnt reaches a value of 99
      end else if (cmd_cnt < (NUM_WRITES-1)) begin
        cmd             <= #TCQ WR_INSTR;
        cmd_en          <= #TCQ app_rdy;
      // Generate 100 read commands after cmd_cnt reaches 99
      end else if (cmd_cnt == (NUM_WRITES-1) & cmd_en & app_rdy) begin
        cmd             <= #TCQ RD_INSTR;
        cmd_en          <= #TCQ app_rdy;
      end else if (cmd_cnt == (NUM_TRANSACT-1) & cmd_en & app_rdy) begin
        cmd_en          <= #TCQ app_rdy;
      end
    end
    
    always @(posedge clk)
    begin
      if(rst | ~init_calib_complete_r) begin
        wr_en            <= #TCQ 1'b0;
      // Generate 100 write commands till the cmd_cnt reaches a value of 99
      end else if (cmd_cnt < (NUM_WRITES-1)) begin
        wr_en           <= #TCQ app_wdf_rdy;
      end else if (cmd_cnt == (NUM_WRITES-1) & app_wdf_rdy) begin
        wr_en           <= #TCQ 1'b0;
      end else if (cmd_cnt == (NUM_TRANSACT-1) & app_wdf_rdy) begin
        wr_en           <= #TCQ 1'b1;
      end
    end
    
    always @(posedge clk )
    begin
      if(rst)
        cmd_cnt <= #TCQ 'b0;
      else if (cmd_en && app_rdy && cmd_cnt < NUM_TRANSACT-1) begin
          cmd_cnt <= #TCQ cmd_cnt + 'b1;
      end
      else if(cmd_cnt == NUM_TRANSACT-1) begin
          cmd_cnt <= #TCQ 10'b0;
      end
      else begin
          cmd_cnt <= cmd_cnt;
      end
    end
    
    endmodule
    
    展开全文
  • ddr控制器 FPGA

    2009-05-11 23:18:07
    关于DDR控制器,有需要的下,还不错的资料
  • AXI总线之DDR控制器的实现

    千次阅读 2019-05-08 11:31:13
    由于FPGA的内部RAM资源实在有限,同时又不得不面临大数据量缓存的问题,因此,将DDR进行共享成了...这是一个典型的PL端的DDR控制器实现,采用M-AXI总线,因为瞬间数据率可能在1Gbps左右,因此数据位宽设计成(64/32...

    由于FPGA的内部RAM资源实在有限,同时又不得不面临大数据量缓存的问题,因此,将DDR进行共享成了最为直接有效的解决方案。

    设计目标:

    PL端有多个需要大量数据缓存的通道,让每个通道都将DDR作为外部缓存(FIFO)。注意,总的突发在1Gbps左右。

    设计过程:

    这是一个典型的PL端的DDR控制器实现,采用M-AXI总线,因为瞬间数据率可能在1Gbps左右,因此数据位宽设计成(64/32)位,突发传输长度(16~256)。

    总体结构图:

    to ddr----->[FIFO:ddr]---->from ddr

    to ddr----->[FIFO:ddr]---->from ddr
    实现结构图:

    --->infifo--->|waddr,raddr,usednum,data|                  [ddr]                        |---outfifo--->

                                                                  |----[mux]---[m-axi4]---[demux]---|

    --->infifo--->|waddr,raddr,usednum,data|                                                  |---outfifo--->

    其中,m-axi4与ddr进行数据交换。

    后记:

    画图工具不熟练,先做示意图。代码较多,整理好了会上传。

    展开全文
  • 2,SDRAM控制器设计 (1)上电初始化; (2) 预充电; (3) 读写 操作命令如下, 初始化配置行参数说明如下: 上电初始化顺序: 预充电: SDRAM为电容模式,如果不进行预充电,随着时间,他内部...
  • 介绍了 DDR SDRAM 控制器的系统命令和结构 ,设计了一种基于状态机的 DDR SDRAM 控制器 。利 用状态机对读写操作进行控制可提高系统性能 ,给出了基于 FPGA 的控制器的仿真结果 。
  • 文档可以非常方便地用于FPGA的MIG控制器和ZYNQ上并实现对ZYNQ PS 或者PL的DDR进行读写控制。和官方 的DMA以及VDMA相比, FDMA具备无需驱动程序,只要会FPGA就能读写DDR的简单方便性
  •  i.MX 6ULL系列芯片的MMDC是一个多模式DDR控制器,支持DDR3/DDR3Lx16和LPDDR2x16的存储类型,MMDC是可配置,高性能,优化的内存控制器。  注:DDR3/DDR3Lx16、LPDDR2x16 ,此处的x16表示芯片位宽,每个传输周期...
  • ddr控制器参数对照表

    千次阅读 2019-06-04 11:31:43
    men_a是指men接口的地址总线,并非内存内部的地址(行/列/bank等构成=AFI_addr)。 一般men_a*2=AFI_addr,因为双沿采集。
  • 4端口DDR控制器的设计与实现

    千次阅读 2017-08-14 19:23:16
    在视频图像显示界面中,需要用到DDR作为视频缓存的存储器,在一路视频输入的过程中,我们采用DDR的两个BANK的乒乓操作来实现视频的缓存,实现了数据的无损耗缓存和显示,这种方法已经得到了广泛的应用,但是,当我们...
  • FPGA外存储器之DDR2控制器1

    千次阅读 2014-06-09 07:57:41
  • FPGA片外存储器之DDR2控制器2

    千次阅读 2014-06-10 23:41:34
     这次的主要内容是仿真。...写控制器,看看仿真,理解好,看明白。就开始写吧。     我能力有限,但是我努力分享我所知道的。希望一点点知识,能帮到各位 。          
  • FPGA的片内存储器可以根据需求定义存储器的大小、位宽、种类、及特殊的片内存储器特性,如DDR模式等。 片内存储器在基于FPGA的嵌入式系统的存储器中具有最高吞吐量和最低反应延时。它的反应延时通常仅为一个时钟...
  • xilinx 7serise DDR3控制器

    2016-01-09 11:13:36
    xilinx 7serise DDR3控制器
  • DDR3基础控制器

    2015-05-16 11:56:57
    DDR3的控制器的配置以及使用介绍,DDR Memory controller fundamentals review,QorIQ processors。
  • DDR SDRAM控制器verilog代码
  • xilinx ultrascale ddr3控制器 开发手册
  • 介绍了DDR3 SDRAM的技术特点、工作原理,以及控制器的构成。利用Xilinx公司的MIG软件工具在Virtex-6系列FPGA芯片上,实现了控制器的设计方法,并给出了ISim仿真验证结果,验证了该设计方案的可行性。
  • DDR SDRAM控制器的FPGA实现 DDR SDRAM 高容量和快速度的优点使它获得了广泛的应用,但是其接口与目前广泛 应用的微处理器不兼容。介绍了一种通用的DDR SDRAM控制器的设计,从而使得DDR SDRAM 能 应用到微处理器中去
  • DDR内存控制器

    2018-12-07 15:56:05
    DDR=Double Data Rate双倍速率同步动态随机存储器。严格的说DDR应该叫DDR SDRAM,人们习惯称为DDR,其中,SDRAM 是Synchronous Dynamic Random Access Memory的缩写,即同步动态随机存取存储器。而DDR SDRAM是...
  • DDR SDRAM控制器参考设计VHDL代码
  • DDR SDRAM控制器verilog代码.7z
  • DDR_SDRAM控制器的VHDL

    2016-08-24 16:48:52
    DDR_SDRAM控制器的VHDL代码已经测试

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 17,569
精华内容 7,027
关键字:

ddr控制器