//来自微信公众号 "数字晶元实验室"

Memory是晶元设计的重要组成部分。

Memory可以小到形成一个简单的寄存器组。随著晶元面积的增长,晶元中的Memory越来越多。本文讨论综合出设计中Memory的多维数组的含义和选择来自工艺厂商Memory的一些需要考虑的因素。

如何实现多维数组。

Memory可以由综合工具直接根据数组结构综合出来。以下是用于综合出小型存储器的实例 RTL代码。

module my_memory (datai,datao,clk,wr_n,addr) ;
parameter width = 4 ;
parameter log2_depth = 16 ;
input [width-1 : 0] datai ,addr ;
input clk ,wr_n,rd_n ;
output [width-1 :0] datao ;

reg [width-1 :0] memory [log2_depth -1 :0] ;
reg [width -1 : 0 ] datao ;
always@(posedge clk) begin
if(wr_n == 1b0) memory[addr] <= datai ;
else if(rd_n == 1b0) datao <= memory[addr] ; //Synchronous read
end
endmodule //my_module

上述代码会综合出64个根据地址索引的触发器。

Verilog-2001引入了多维存储器。上面的例子可以扩展到三个维度,即x,y和z,如下:

module my_memory(datai , datao , clk ,wr_n ,addr_x , addr_y ,addr_z) begin
parameter width = 4 ;
parameter log2_d = 4 ;
input [width -1 : 0] datai , addr_x ,addr_y , addr_z ;
input clk ,wr_n ,rd_n ;
output [width -1 : 0] datao ;
reg [width-1 :0] memory [log2_d -1 : 0 ] //addr_x
[log2_d -1 : 0 ] //addr_y
[log2_d -1 : 0 ] ; //addr_z
reg [width-1 : 0] datao ;
always@(posedge clk) begin
if(wr_n == 1』b0 ) memory[addr_x][addr_y][addr_z] <= datai ;
else if(rd_n == 1』b0) datao <= memory[addr_x][addr_y][addr_z] ;
end
endmodule

上面的多维数组最终会被合成x * y * z * width_=4 * 4 * 4 * 4= 256个单独的触发器。

使用来自半导体供应商的硬核memory会有更好的时序,面积和功耗,因为??它的逻辑是经过优化的,而不是使用离散逻辑。

但是,例化一个工艺相关的memory将使得该设计在不同工艺下不可重用。所以,我们应该在顶层用一个wrapper实例化设计和memory,而不是在设计中实例化memory。

实例化工艺相关的memory有哪些需要考虑的因素?

根据应用,memory的选择基于在以下性能参数上:

面积:如果该晶元,面积是主要关注点,那么就需要高密度的memory。通常而言,面积还取决于memory的工艺。

频率:如果速度是主要关注点,那么就需要高速的memory。

功耗:这是低电压和低功耗应用的关键问题之一。此外,如果功耗变高,则整个系统的性能变得更低。它还增加了最终的封装成本。

还需要考虑memory的其他设计变数:

memory容量:例如,将memory指定为512Kbits。

电压:某些memory是针对特定电压范围而设计的。

同步或非同步:指定memory是否具有同步读/写或非同步读/写。使用哪一个主要取决于是否存在时钟和匹配设计的时序要求。

单埠或多埠:确定memory是否由单个或多个读/写埠访问。使用多埠memory的一个关键问题是多个埠正在尝试写入相同地址的memory会发生什么问题。

触发器或基于锁存器:确定memory内的基本单元是否是基于触发器或者锁存器。

这种memory的重要考虑因素是可测试性和功耗。基于触发器的设计比基于锁存器更容易测试。随著memory大小的增加,memory的可扫描性是重要的标准。许多供应商都提供了BIST逻辑,使memory可扫描。


推荐阅读:
相关文章