打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
像存储器厂商学习写存储模型
userphoto

2016.08.24

关注

分类:验证平台编码

 

存储器?你说的不就是下面这句话吗?

 


 

的确,在大多数的场景下,memory的内存占用并没有成为我们的困扰。这应该归功于EDA厂商不断提升的仿真器性能,以及内存厂商的竞争使内存颗粒的价格保持在可以接受的范围之内。

 

但是,不可否认的是memory依然是内存占用大户。例如,UVM对于“Register”和“Memory”的理解就不一致。



 

memory”不像“register”存在一个镜像空间,因为Memory较大,存在占用较大数据空间(large data space)的可能。

 

面对可能占用大量内存空间的memory,我们需要更多的更灵活的处理方式。下面,我们分情况来讨论memory的定义方式。

 

1memory的总空间较小(memory例化数*单个memory空间)

“较小”是一个相对概念,这个信息会随着EDA软硬件资源的升级,而不断变大。我们的处理方式是:在没有明显感到内存占用成为瓶颈时,可以采用最简单的内存定义方式。

 

为描述方便,本文将以下定义方式命名为“直接定义法”。

 


 

2、当memory的存储空间较大,但是使用比较“稀疏”时。

 


 

如图所示,memory每个数据的宽度为32bitmemory的深度为2^25=33554432。其中,memory的使用量,与用例执行的数据包个数有关,而绝大部分的用例,数据包个数不超过1000个。对于这样的场景,如何处理呢?

 

首先,如果采用“直接定义法”,定义为bit [32-1:0]memory [2**25-1:0]并没有对仿真造成任何困扰的话,这样的设计方式是可以接受的。

 

然后,如果的确造成了一些困扰,我们可以考虑使用稀疏矩阵的定义方式。

 

当提到“稀疏矩阵”时,有时候会让我们想到SystemVerilog的语法——关联数组。关联数组的确可以解决一部分存储器单元定义的问题,且关联数组的内存占用与存入关联数组的数据个数成正比。

 

“关联数组法”(在大内存,且有效数据很少时才推荐)

 


 

但是,关联数组的内存占用,远远大于普通数组。当memory内部的数据个数稍微多一些时,关联数组的效率就会迅速下降,甚至比“直接定义法”的效率还低很多。

 

那么,面对“稀疏”结构,还有没有其它方式呢?

 

这个方式就是我们像存储器厂商学习的,我们命名为“有效索引法”

 

“有效索引法”的源代码,可以在该链接下载:

 

https://www.micron.com/resource-details/3caf8e7e-ace6-4a7c-bf04-e374d9c08564

 


 

“有效索引法”的思路是:

定义一个不是很大的存储空间,能够存储“足够多”的数据信息即可。这个“足够多”的数量,一般会小于(甚至远小于)总的memory空间的大小。

 

“有效索引法”中,memory定义实现步骤是:

  1. 估计用例使用的memory空间大小;

  2. 定义memory空间的大小与memory估计大小相同,使用index索引,存储数据信息;

  3. 定义address空间的大小与memory估计大小相同,使用index索引,存储地址信息;

  4. 定义memory_used,记录目前已经使用了多少个index,主要用于判断定义的空间是否满足用例要求(为可测试性功能)。

 

“有效索引法”的内存占用估算:

  1. memory空间,存储估计的memory数据;

  2. address空间,存储估计的address数据;

  3. memory_indexmemory_used可忽略。

即存储空间为memory*有效估计值+address*有效估计值。若有效估计值远小于memory实际深度,则非常节省内存空间。若有效估计值等于memory实际深度,则“有效索引法”占用的内存空间大于“直接定义法”,若address的位宽与memory的位宽一致,那么“有效索引法”占用的内存空间为“直接定义法”的2倍。

 


 

“有效索引法”的结构如上图所示。我们可以通过memory_readmemory_write操作,来进一步理解“有效索引法”的方案。

 


读操作解析:

  1. 判断是否可获取有效的index:若该地址(addr)存在,那么在address存储单元内,可以找到与addr相等的单元,设置get_index1(指示找到地址),使用memory_index记录相对应addr地址的索引;若该地址(addr)不存在,则在address存储单元内,找不到与addr相等的单元,返回get_index为循环前设置的0(未找到地址);

  2. 根据get_index返回情况,获取数据信息:若get_index返回1,则指示找到地址,按照memory_index索引取memory空间信息,即为data;若get_index返回0,则指示未找到地址,返回data为不定态。

 

写操作解析:


 

  1. 判断是否可获取有效的index:若该地址(addr)存在,那么在address存储单元内,可以找到与addr相等的单元,设置get_index1(指示找到地址),使用memory_index记录相对应addr地址的索引;若该地址(addr)不存在,则在address存储单元内,找不到与addr相等的单元,返回get_index为循环前设置的0(未找到地址);

  2. 根据get_index返回情况,存储数据信息:若get_index返回1,则指示找到地址(该地址之前被写入过),按照memory_index索引取memory空间信息,写入新的数据data;若get_index返回0,则指示未找到地址,也即这个地址没有被写入过,应当将该数据data写入一片新的空间。但是,如果memory_used达到最大值,则说明没有新的空间可以被写入,我们之前估计的memory使用空间不足,需要报错;若没有达到memory_used的最大值,即还有可以使用的新空间,我们只要将memory写入新空间,然后更新memory_used,即使用的memory个数(也是最后一个数据的下一个索引)。

 

3、当memory的存储空间较大,使用也不“稀疏”,比较饱和时。

 

在这种情况下,使用“直接定义法”、“关联数组法”、“有效索引法”都难以解决内存使用较大的问题了。

 

这时候,解决问题的思路,类似于Windows操作系统的“虚拟内存”。使用硬盘解决软件内存不够的方案,“文件存储法”。

 

虽然存储信息较大,但是,我们可以将memory信息存储在文件中,需要读取时,根据地址信息,读取文件相应位置的数据。

 

初始化打开文件:



 

memory_read



memory_write



全文总结:

1、  一般情况下,使用“直接定义法”即可解决memory定义的问题;

2、  稀疏结构下,推荐使用“有效索引法”;

3、  稀疏差异较大,且数据量很小时(1k以下),可以使用“关联数组法”;

4、  存储器容量大,且数据使用饱和时,推荐使用“文件存储法”,类似于虚拟内存。

 



本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
Linux文件系统的inode介绍 | 云上小悟
内存的静态分配和动态分配的区别
图文详解ElasticSearch技术,看这一篇就够了!
数据结构概述
Verilog数组表示及初始化
粗略阅读haribote内存管理程序 memory.c
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服