【Quartus FPGA】EMIF DDR3 读写带宽测试

在通信原理中,通信系统的有效性用带宽来衡量,带宽定义为每秒传输的比特数,单位 b/s,或 bps。在 DDR3 接口的产品设计中,DDR3 读/写带宽是设计者必须考虑的指标。本文主要介绍了 Quartus FPGA 平台 EMIF 参数配置,以及测试 DDR3 读写带宽的过程,FPGA 器件型号是 Cyclone 10 GX 10CX220YF780E6G,DDR3 颗粒型号是 Winbond W631GG6KB。

目录

1 EMIF IP 配置

2 AMM 接口

3 读写带宽测试


1 EMIF IP 配置

        在进行 EMIF DDR3 读写带宽测试之前,先确保 EMIF DDR3 IP 时钟与时序参数配置正确。

         General -> Clocks 选项卡,填写内存时钟频率 Memory clock frequency ,这里填了 933M,PLL 参考时钟频率为 116.625MHz.

        Memory -> Latency and Burst 选项卡,根据 DDR3 内存颗粒用户手册,设置 Memory CAS latency 和 Memory write CAS latency 值。

        这里所使用的 DDR3 内存型号为 Winbond W631GG6KB,933M 对应的 tCK 为 1.07ns,根据手册得知,CL = 13,CWL = 9.

 Memory Timing 参数如下:

 

2 AMM 接口

        Quartus EMIF IP 提供了 AMM(Avalon Memory-Mapped) 接口,用于 DDR3 数据的传输,AMM 接口定义如下。

        amm_ready 扮演 waitrequest_n 的角色,当控制器处于 busy 状态时,该信号将会拉低;amm_burstcount 表示读/写 burst 传输的周期数;DDR3 颗粒数据接口位宽是 16bit,8n-prefetch,所以 amm_writedata 与 amm_readdata 的位宽是 16bit × 8 = 128bit。

AMM 接口读写时序图与其他细节,可以参考 Intel 官网 Avalon® 接口规范简介。

3 读写带宽测试

        在本设计中,DDR3 读写采用固定地址突发的方式,amm_burstcount 大小固定为 64,每次先写入 64 个数据,再读出 64 个数据。

        同时定义两个计数器 wr_data_cnt 与 rd_data_cnt,用于一段时间读写数据的计数,需要注意计数器位宽,避免溢出的情况。这里计数器位宽定义 32bit,时间间隔取 200ms。

VHDL 设计代码如下,

process(sys_rst,sys_clk) 
begin
   if sys_rst = '1' then
      pstate <= st_init;
      buf_test_wr_req <= '0';
      buf_test_rd_req <= '0';
      test_wr_q <= (others => '0');
      test_wr_mask <= (others => '0');
      wr_cnt_scope <= (others => '0');
      rd_cnt_scope <= (others => '0');
      rd_err_cnt_scope <= (others => '0');
   elsif rising_edge(sys_clk) then
      if timeout_event = '1' then
         wr_cnt_scope <= (others => '0');
         rd_cnt_scope <= (others => '0');
         rd_err_cnt_scope <= (others => '0');
      end if;
   
      case(pstate) is
         when st_init => 
            -- power on delay and initialization
            if ddr_init_done = '1' then
               pstate <= st_idle;
            else
               pstate <= st_init;
            end if;
            
         when st_idle => 
            -- idle state
            pstate <= st_test_write;
            
         when st_test_write => 
            -- pull up req and wait fot ack
            if buf_test_wr_req = '1' and test_wr_ack = '1' then
               pstate <= st_test_write_end;
               buf_test_wr_req <= '0';
            else
               pstate <= st_test_write;
               buf_test_wr_req <= '1';
            end if;
         
         when st_test_write_end => 
            -- wait write ending
            if test_wr_end = '1' then
               pstate <= st_test_read;
            else
               pstate <= st_test_write_end;
            end if;
            
            test_wr_q(4*128-1 downto 3*128) <= DDR_DATA_PATTERN;
            test_wr_q(3*128-1 downto 2*128) <= DDR_DATA_PATTERN;
            test_wr_q(2*128-1 downto 1*128) <= DDR_DATA_PATTERN;
            test_wr_q(1*128-1 downto 0*128) <= DDR_DATA_PATTERN;
            test_wr_mask <= (others => '0');
            if test_wr_rden = '1' then
               wr_cnt_scope <= wr_cnt_scope + 1;
            end if;
            
         when st_test_read => 
            -- pull up req and wait for ack
            if buf_test_rd_req = '1' and test_rd_ack = '1' then
               pstate <= st_test_read_end;
               buf_test_rd_req <= '0';
            else
               pstate <= st_test_read;
               buf_test_rd_req <= '1';
            end if;
         
         when st_test_read_end => 
            -- wait read ending
            if test_rd_end = '1' then
               pstate <= st_idle;
            else
               pstate <= st_test_read_end;
               if test_rd_rdvld = '1' then
                  rd_cnt_scope <= rd_cnt_scope + 1;
                  if test_rd_rdata(4*128-1 downto 3*128) /= DDR_DATA_PATTERN then
                     rd_err_cnt_scope <= rd_err_cnt_scope + 1;
                  elsif test_rd_rdata(3*128-1 downto 2*128) /= DDR_DATA_PATTERN then
                     rd_err_cnt_scope <= rd_err_cnt_scope + 1;
                  elsif test_rd_rdata(2*128-1 downto 1*128) /= DDR_DATA_PATTERN then
                     rd_err_cnt_scope <= rd_err_cnt_scope + 1;
                  elsif test_rd_rdata(1*128-1 downto 0*128) /= DDR_DATA_PATTERN then
                     rd_err_cnt_scope <= rd_err_cnt_scope + 1;
                  end if;
               end if;
            end if;
         
         when others => NULL;
            
      end case;
   end if;
end process;

SignalTap 调试波形如下:

读带宽:

7533666 × 128bit × 1s/200ms = 4.822Gbps

写带宽:

7653248 × 128bit × 1s/200ms = 4.898Gbps

可以进一步计算,在突发传输为 64 时,DDR3 的读写效率约 32.56%.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/55815.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Tomcat 创建https

打开CMD,按下列输入 keytool -genkeypair -alias www.bo.org -keyalg RSA -keystore d:\ambition.keystore -storetype pkcs12 输入密钥库口令:123456 再次输入新口令:123456 您的名字与姓氏是什么? [Unknown]: www.ambition.com 您的组织单位名称是什么? [Unknown…

cc2652在使用过程中的一些注意事项

可能不只是cc2652有这些坑&#xff0c;估计cc26xx系列都存在。 CCS的预编译宏配置位置 时钟获取 时钟获取__STATIC_INLINE uint32_t SysCtrlClockGet( void )在sys_ctrl.h中&#xff0c;sys_ctrl.h没有在工程路径下面&#xff0c;在其sdk中 节拍时间获取 ICall_getTicks(); …

IPv6 over IPv4隧道配置举例

配置IPv6 over IPv4手动隧道示例 组网需求 如图1所示&#xff0c;两台IPv6主机分别通过SwitchA和SwitchC与IPv4骨干网络连接&#xff0c;客户希望两台IPv6主机能通过IPv4骨干网互通。 图1 配置IPv6 over IPv4手动隧道组网图 配置思路 配置IPv6 over IPv4手动隧道的思路如下&…

roop 视频换脸

roop: one click face swap. 只用一张人脸图片&#xff0c;就能完成视频换脸。 项目地址&#xff1a; https://github.com/s0md3v/roopColab 部署&#xff1a; https://github.com/dream80/roop_colab 本文是本地部署的实践记录。 环境基础 OS: Ubuntu 22.04.2 LTSKernel: 5…

Redis实战(4)——Redisson分布式锁

1 基于互斥命令实现分布式锁的弊端 根据上篇文章基于redis互斥命令实现的分布式锁任然存在一定的弊端 1无法重入: 同一个线程无法重新获得同一把锁2超时删除 &#xff1a;会因为超时、任务阻塞而自动释放锁&#xff0c;出现其他线程抢占锁出现并行导致线程不安全的问题3 不可…

unity行为决策树实战详解

一、行为决策树的概念 行为决策树是一种用于游戏AI的决策模型&#xff0c;它将游戏AI的行为分解为一系列的决策节点&#xff0c;并通过节点之间的连接关系来描述游戏AI的行为逻辑。在行为决策树中&#xff0c;每个节点都代表一个行为或决策&#xff0c;例如移动、攻击、逃跑等…

LInux的安装(VMware,网卡设置,SSH连接工具)

Linux的安装 1、安装方式介绍 1.安装方式: 物理机安装:直接将操作系统安装到服务器硬件上 虚拟机安装:通过虚拟机软件安装 **虚拟机( Virtual Machine&#xff09;**指通过软件模拟的具有完整硬件系统功能、运行在完全隔离环境中的完整计算机系统。 2、安装Linux 在官网将…

20款奔驰S350升级原厂HUD抬头显示系统,提升您的行车安全

HUD是平视显示器的简称&#xff0c;它原先是运用在航空器上的飞行辅助仪器。指飞行员不需要低头&#xff0c;就能够看到他需要的重要资讯。由于HUD的方便性以及能够提高飞行安全&#xff0c;这项技术后来也发展到汽车行业。汽车搭载的HUD抬头数字显示功能&#xff0c;是利用光学…

Toolformer :让AI学会使用工具

paper: 《Toolformer: Language Models Can Teach Themselves to Use Tools 》 核心思想&#xff0c; 1. Sampling API Calls &#xff1a;设计设计prompt,让模型生成含API调用的文本&#xff08;如图3&#xff09;&#xff0c;只保留K个概率最高的API调用 2. Executing API …

MySql006——基本的SELECT查询语句

在《MySql003——结构化查询语言SQL基础知识》中&#xff0c;我们学习了有关SQL的基础知识&#xff0c;也知道SQL中查询语句SELECT使用最为频繁 接下来我们将学习一些基本的SELECT查询语句 一、SELECT语句的通用语法 在MySQL数据库中&#xff0c;使用SELECT语句可以查询数据…

Android Studio多渠道打包

使用环境&#xff1a; Android studio 多渠道打包 使用方法&#xff1a; 1 APP下build.gradle文件 flavorDimensions "default"productFlavors {huawei {dimension "default"manifestPlaceholders [ channel:"huawei" ]}xiaomi {dimension &…

Nginx学习教程(基础篇)

目录 一、Nginx安装 二、Nginx基本使用 2.1、目录结构 conf html logs sbin 2.2、基本运行原理 2.3、nginx.conf最小配置解析 worker_processes worker_connections include mime.types default_type application/octet-stream sendfile on keepalive_timeout…

Python实现GA遗传算法优化循环神经网络分类模型(LSTM分类算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 遗传算法&#xff08;Genetic Algorithm&#xff0c;GA&#xff09;最早是由美国的 John holland于20世…

lc1074.元素和为目标值的子矩阵数量

创建二维前缀和数组 两个for循环&#xff0c;外循环表示子矩阵的左上角&#xff08;x1,y1&#xff09;&#xff0c;内循环表示子矩阵的右下角&#xff08;x2,y2&#xff09; 两个for循环遍历&#xff0c;计算子矩阵的元素总和 四个变量&#xff0c;暴力破解的时间复杂度为O(…

驱动开发(中断)

头文件&#xff1a; #ifndef __LED_H__ #define __LED_H__#define PHY_LED1_MODER 0X50006000 #define PHY_LED1_ODR 0X50006014 #define PHY_LED1_RCC 0X50000A28#define PHY_LED2_MODER 0X50007000 #define PHY_LED2_ODR 0X50007014 #define PHY_LED2_RCC 0X50000A28#def…

【安装Tomcat,web站点部署】

Tomcat部署 第一种安装 yum install tomcat.noarch -y yum install tomcat-webapps.noarch -y #启动脚本 [rootlocalhost ~]# systemctl start tomcat这时可以通过IP地址端口访问 第二种安装 点击此处找到apache-tomcat-8.5.70.tar.gz 官网下载JDK #先安装JDK [rootlocalh…

小程序云开发快速入门(1/4)

前言 从上次完成了码仔备忘录本地版本后&#xff0c;码仔就养成了每天记录备忘录的好习惯&#xff0c;每周早上会记录下自己要做的任务&#xff0c;然后晚上在复盘一下今天的计划是否完成。 有一天&#xff0c;码仔看到它最喜欢的码妞在一旁愁眉苦脸。 码仔&#xff1a;“怎么…

思腾云计算

以AI赋能&#xff0c;致敬不凡 原创 Sitonholy 思腾合力 2023-04-28 07:00 发表于北京 收录于合集#品牌介绍156个 致敬不凡 以AI赋能 思 腾 合 力 人工智能的发展和应用与五一劳动节的意义和价值是相通的。人工智能的快速发展将会对劳动力市场和生产方式产生深远的影响&…

【Ansible】Ansible自动化运维工具之playbook剧本

playbook 一、playbook 的概述1. playbook 的概念2. playbook 的构成 二、playbook 的应用1. 安装 httpd 并启动2. 定义、引用变量3. 指定远程主机 sudo 切换用户4. when条件判断5. 迭代6. Templates 模块6.1 添加模板文件6.2 修改主机清单文件6.3 编写 playbook 7. tags 模块 …

谈一谈缓存穿透,击穿,雪崩

缓存穿透 缓存穿透是指在使用缓存系统时&#xff0c;频繁查询一个不存在于缓存中的数据&#xff0c;导致这个查询每次都要通过缓存层去查询数据源&#xff0c;无法从缓存中获得结果。这种情况下&#xff0c;大量的请求会直接穿透缓存层&#xff0c;直接访问数据源&#xff0c;…