Memory的例化使用与FPGA中ram的替换解决方案

Memory的例化使用与FPGA中ram的替换解决方案

1. 使用寄存器组(Memoeies)的目的

Memoeies,此处指由reg变量组成的寄存器数组。例化memories的目的是
(1) verilog中的书写的Memories是可以综合,并在FPGA上运行的。为了尽量少的使用IP,同时设置好memories的时序,以便于后期使用的IP的替换。一般按照经验来说,当一个memories的使用小于2kbit时,是可以直接使用寄存器组进行设计的,当使用的Memories大于2kbit,考虑功耗面积等约束,寄存器组要替换为专用的SRAM。
(2)现在的ASIC的验证环境一般由UVM方法学进行搭建,但是UVM验证环境需要专门的验证人员进行搭建。对于小白设计师,也可以用verilog来编写测试激励,观察仿真波形。对于FPGA来说,片上的RAM一般来说2MB已经很大了,当你要存一张大于2MB的图片时,要怎么办呢?这个时候可以在tb文件中例化一个寄存器,并把图片例化到寄存器中。

2. 以寄存器组为核心模拟SRAM(FPGA中RAM)输入输出时序代码如下所示:

以下代码模拟了SRAM的输入输出时序,当需要做综合,需要替换IP时,可以直接进行替换,也可以替换FPGA中的RAM资源,并且可以直接综合生成bit流文件。

module memories(

    clka,
    addra,
    dina,
    pusha,
    clkb,
    addrb,
    popb,
    doutb
        );


input           clka;
input  [63:0]  	addra;
input  [31:0]   dina;
input           pusha;

input           clkb;
input  [63:0]   addrb;
input           popb;
output [31:0]   doutb;

reg [31:0]   memories[63:0];
reg [31:0]   doutb_reg;
assign    doutb = doutb_reg;

always @ (posedge clka) begin
    if (pusha)
        memories[addra] <= #1 dina;
end

always @ (posedge clkb) begin
    if (popb)
        doutb_reg <= #1 memories[addrb];
end
endmodule

3.Tb文件中Memories的例化及初始化可以用如下代码进行:

reg  [31:0]  memories[0:63];
initial begin
   $readmemh("D:/simple_project_ddr/emccd_top/tb1.txt",memories);  
end

使用系统任务函数进行存储:系统任务函数从指定的文本中读取数据并加载到存储器。
$readmemb(加载二进制文件)
$readmemh(加载十六进制文件)
文本数据样式如下所示:
在这里插入图片描述

为了进行测试,我写了一个简单的tb文件如下所示:

`timescale 1ns / 1ps
module read_mem();
reg  	     clk;
reg	[31:0] 	dout;
reg			rst_n;
reg [0:63] 	addr;
reg 		read_en;
reg [9:0]   cnt;

initial begin
	clk = 0;
	forever #5 clk = ~clk;
end
initial begin
	rst_n = 0;
	#100 rst_n = 1;
end

reg  [31:0]  memories[0:63];
initial begin
   $readmemh("D:/simple_project_ddr/emccd_top/tb1.txt",memories);  
end
always@(posedge clk) begin
    if (read_en)
        dout <= #1 memories[addr];
end
always@(posedge clk or negedge rst_n) begin
	if(!rst_n)
		cnt <= 10'b0;
	else 
		cnt <= cnt + 1;
end
always@(posedge clk or negedge rst_n) begin
	if(!rst_n)
		addr  <= 64'b0;
	else if(read_en)
		addr <= addr + 1;
	else 
		addr <= addr;
end
assign read_en = (cnt >= 10'b00_1000_0000) ? 1 : 0;
endmodule
  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值