后端基础——rom,ram,memory compiler
一,memory基础
1,导览
Memory用来存储和读写的大量的二进制数据。按功能上分类,基本可以分为两大类:只读存储器(ROM)和随机存取存储器(RAM)。ROM只能读,不能写;RAM既能读又能写。RAM具有易失性。断电以后,RAM中保存的数据将全部丢失;而ROM中的数据则可以长久保存。
RAM可以分为常用的SRAM和DRAM。SRAM是静态的存储器,存储单元是一个触发器,有0,1两个稳态;DRAM是动态的存储器,比SRAM要复杂一些,因为它会利用电容器存储电荷来保存0或1,需要在存储数据的过程中需要对于存储的信息不停的刷新。 另一种常用的存储器,我们称为Register File。 它是由多个寄存器堆组成的阵列,内部结构功能上和SRAM完全类似。只是Register File去除了bist电路,容量较小,速度也比较快,经常用于前端仿真,Register file速度快,面积小,容量小。小容量下,我们也应该优先选择Register file。
2,结构
一般由存储阵列,地址译码器和输出控制电路组成。我们把存储阵列以外的电路都称为外围电路(Periphery)。存储阵列是memory的核心区域,它有许多存储单元组成,每个存储单元存放一位二值数据。每次读出一组数据,称为一组字。一个字中所含的位数称为字长(Bit)。为了区别各个不同的字,给每个字赋予一个编号,称为地址,由译码器将地址代码转译。地址单元个数就是字数(Depth),用N表示,数值为2n,n为地址码的位数。
3,ROM,RAM的verilog实现
ROM
`include "../core/defines.v" //包含一些常量和宏定义,如WriteEnable、RstEnable、ZeroWord等 module rom( input wire clk, //时钟 input wire rst, //复位 input wire we_i, // write enable使能信号 input wire[`MemAddrBus] addr_i, // addr地址 input wire[`MemBus] data_i, //数据 output reg[`MemBus] data_o // read data读出的数据 ); reg[`MemBus] _rom[0:`RomNum - 1]; //定义了一个内部的只读存储器_rom,存储的数据位宽为MemBus,ROM的大小为RomNum。直接用reg[]a[]寄存器堆实现 //当为写使能时,将data_i写入_rom中的addr_i[31:2]位置 always @ (posedge clk) begin if (we_i == `WriteEnable) begin _rom[addr_i[31:2]] <= data_i; end end //读使能,当rst为RstEnable时,将data_o的值设为ZeroWord;否则将data_o的值设为_rom中addr_i[31:2]位置的值 always @ (*) begin if (rst == `RstEnable) begin data_o = `ZeroWord; end else begin data_o = _rom[addr_i[31:2]]; end end endmodule
RAM的verilog逻辑与之相同,均例化为寄存器堆。
在进行仿真测试时,利用系统函数$readmemh和$readmemb分别用来读取十六进制文件和二进制文件,将需要写的数据读进rom里,利用display将rom数据读出。
二,Memory macro配置
1,参数指标
一般foundry提供的memory databook上,会有以下参数指标:
WL: Physical Word Lines 字线 假设16
BL:Physical Bit Lines 位线 假设16
WD: Word Depth (WL * MUX)字数 16*16 =256
BIT: I/O Data Width (BL/MUX)字长 16/16 =1
Granularity:步长,WD或者BIT间隔的大小,只能按步长整数倍增加
BANK:分块,在Memory中,如果Bit line很长,会造成它的充放电速度很慢,导致memory的频率很低,这时,我们会将存储阵列分成N个bank来降低Bit line的长度
SEG: 分段,在Memory中,如果Word line很长,会影响它的性能,所以按Word line方向,把存储阵列分成N个segment.
bank和seg如下图所示:
C64,C128,C256: Cell per bit line:每条bit line上挂的存储单元个数,经常有64,128,256等不同数字,该数值越大,表示配置的memory速度越慢,但是面积会越小;数值越小,表示配置的memory速度越快,但是面积会越大。
通常,大家还会看到类型HD,HC,HP等缩写,这些都是表征不同类型Bitcell和外围电路(Periphery)组成的:
HD:High Density Bitcell ,面积较小
HC:High Current Bitcell 高工作电流,access time较小
HP:High Performance Periphery ,速度快
LP:Low-Power Periphery ,功耗较小
ULP:Ultra-Low Power Periphery,超低功耗
ULL:Ultra-Low Leakage Periphery,超低漏电流
2,memory端口
(1)Register file
通常分为单口和双口,可以分为以下三种:
Single port(1RW): 一个端口,只能执行读或者写操作
Two port(1R/1W):2个端口,一个端口读,另一个端口写,可以独立不同的时钟频率
Pseudo two port(1R/1W):2个端口,一个端口读,另一个端口写,只有一个时钟
(2)SRAM包含更多的模块,容量可以做得更大,可以拥有更多的bank,速度较慢,面积更大。大容量需求时,可以优先考虑SRAM。
Single port(1RW): 一个端口,只能执行读或者写操作
Dual port(2RW):2个端口,两个端口可以同时读写,可以独立不同的时钟频率
Pseudo two port(1R/1RW):2个端口,一个端口读,另一个端口可以读可以写,只有一个时钟。
即类型与(1)一致
三,Memory compiler使用
通常使用ARM Artisan Physical IP,能够给SoC提供物理IP,这其中就包括嵌入式的存储器。它包含了从250nm到3nm的每个foundry的IP,而且包含单、双口SRAM、Register File、eMRAM和ROM多种Memory。
参数设定:
- Number of Words:SRAM的深度,有范围限制。
- Number of bits:SRAM数据宽度,有范围限制。
- Multiplexer Width:根据官方PDF内设置即可,这个设定与SRAM的形状,有关,有范围限制
-
Frequency:根据系统工作频率设定,个人认为,不同频率,生成的SRAM硬件单元密度,形状,布线是不同的。
- Word-write Mask:掩码,根据需要开启即可。
- Corners:工艺角,一般跟整个系统需要的工艺角相同即可,一般只勾选一个就可以,否则会生成好多文件。ss为slow,tt为标准,ff为fast;一般SRAM工艺角与标准单元工艺角参数相同。
生成文件:
- .lib文件:lib库文件转为db库,用于DC综合和ICC后端导入的库文件。
- .lef文件:用于生成物理库MW
- .v文件:生成verilog模型,用于前端仿真。在综合时,不要包括进来,否则会提是无法综合的错误。后端也不会用到。
其中lib可能需要转换。
参考文献:
(10条消息) 数字芯片后端设计——Memory Complier使用及库导入_数字后端怎样用lef文件生成mv库_Kimho-emo的博客-CSDN博客
(10条消息) 记忆深处有尘埃——Memory Compiler_Tao_ZT的博客-CSDN博客
使用Memory Compiler生成ASIC Embedded Memory - 知乎 (zhihu.com)