跳至正文

Verilog 功能模块–RAM 和 ROM(03)–自编 RAM 与 Vivado RAM IP 功能对比实测

相关文章:

Xilinx IP 解析之 Block Memory Generator v8.4 ——01-手册重点解读(仅Native RAM) – 徐晓康的博客

Xilinx IP 解析之 Block Memory Generator v8.4 ——02-如何配置 IP(仅 Native RAM) – 徐晓康的博客

Verilog功能模块–RAM和ROM(01)–功能说明与关键代码解析 – 徐晓康的博客

Verilog功能模块–RAM和ROM(02)–同步写-写冲突与读-写冲突实测 – 徐晓康的博客

Verilog 功能模块–RAM 和 ROM(03)–自编 RAM 与 Vivado RAM IP 功能对比实测 – 徐晓康的博客

Verilog功能模块--RAM和ROM(01)--功能说明与关键代码解析

前言

前面文章已经说明了自编 RAM 和 Vivado RAM 的冲突特性,本文将进行两者的功能对比。主要包括初始化功能、使能功能、输出寄存器功能、操作模式功能等。

主要进行 TDPRAM 的测试,对于 SDPRAM、SPRAM、DPROM、SROM 仅进行了少量实验。

部分实验在 300MHz 的条件下进行,所以说也验证了本模块的最大运行频率能达到 300MHz。

一、冲突抑制

因为写-写冲突和读-写冲突会可能导致写入和读取的错乱,所以,本章所有测试都在顶层测试模块,避免了冲突的发生,相关冲突抑制的代码如下:

reg ena_tmp;
always @(posedge clka) begin
  ena_tmp <= random_num[14];
  wea     <= random_num[13];
  addra   <= random_num[ADDR_WIDTH-1+8 : 8];
  dina    <= random_num[DATA_WIDTH-1+2 : 2];
end

reg enb_tmp;
always @(posedge clkb) begin
  enb_tmp <= random_num[7];
  web     <= random_num[5];
  addrb   <= random_num[ADDR_WIDTH-1 : 0];
  dinb    <= random_num[DATA_WIDTH-1 : 0];
end

// //* 避免写-写冲突 已被读写冲突覆盖
// always @(*) begin
//   if (addra == addrb && wea && ena && enb)
//     web = 1'b0;
//   else
//     web = web_tmp;
// end

//* 避免A读-B写冲突
always @(*) begin
  if (addra == addrb && web && enb_tmp)
    ena 
1'b0;
  else
    ena = ena_tmp;
end

//* 避免B读-A写冲突
always @(*) begin
  if (addra == addrb && wea && ena_tmp)
    enb 
1'b0;
  else
    enb = enb_tmp;
end

//* 两RAM读数据是否一致?
(* mark_debug *)reg douta_is_not_equal_vivado_douta;
(* mark_debug *)reg doutb_is_not_equal_vivado_doutb;
always @(posedge clka) begin
  douta_is_not_equal_vivado_douta <= douta != vivado_douta;
end
always @(posedge clkb) begin
  doutb_is_not_equal_vivado_doutb <= doutb != vivado_doutb;
end

其中,还包括了判断两 RAM 输出是否一致的代码。

二、TDPRAM 功能对比实验设计

2.1 实验设计

序号 实测实验条件 波形图 通过 ILA 观测,自编 BRAM 和 Vivado BRAM IP 写入/读取是否一致
1 1.TDPRAM
2.同步时钟–100MHz
3.A 端口和 B 端口均 Write First 模式
4.无输出寄存器
5.带使能信号 ena 和 enb
6.使用相同的初始化文件 COE
TDPRAM-ILA-1 完全一致
功能结论:
1.写优先功能正常
2.使能功能正常
3.初始化功能正常
2 1.TDPRAM
2.同步时钟–300MHz
其余不变
TDPRAM-ILA-2 完全一致
功能结论:
1.工作时钟频率可达 300MHz
3 1.TDPRAM
2.同步时钟–300MHz
3.A 端口 Write First 模式,B 端口 Read First 模式
其余不变
TDPRAM-ILA-3 完全一致
功能结论:
Write First 模式和 Read First 模式工作正常
4 1.TDPRAM
2.同步时钟–300MHz
3.A 端口 Write First 模式,B 端口 No Change 模式
其余不变
TDPRAM-ILA-4 完全一致
功能结论:
Write First 模式和 No Change 模式工作正常
5 1.TDPRAM
2.异步时钟,clka(300MHz),clkb(120MHz)
3.A 端口和 B 端口均 Write First 模式
其余不变
TDPRAM-ILA-5 完全一致
功能结论:
异步时钟下工作正常
6 1.TDPRAM
2.异步时钟,clka(300MHz),clkb(120MHz)
3.A 端口和 B 端口均 Write First 模式
4.A 端口添加一个输出寄存器(Primitives Output Register)
5.B 端口均添加两个输出寄存器(Primitives Output Register + Core Output Register)

其余不变
TDPRAM-ILA-6 完全一致
功能结论:
输出寄存器功能工作正常

2.2 实验波形

TDPRAM-ILA-1

两 RAM 输出一致。

TDPRAM-ILA-2

TDPRAM-ILA-3

TDPRAM-ILA-4

TDPRAM-ILA-5

TDPRAM-ILA-6

2.3 实验结论

  1. 自编 TDPRAM 和 Vivado TDPRAM IP 在各个条件下的行为完全一致。
  2. 自编 TDPRAM 支持最大时钟可达 300MHz,更高频率没有经过测试
  3. 自编 TDPRAM 支持同步时钟与异步时钟
  4. 自编 TDPRAM 能支持 WF、RF、NC 三种操作模式
  5. 自编 TDPRAM 使能功能正常
  6. 自编 TDPRAM 初始化功能正常,能正常读取 COE 文件,也能够指定初始值
  7. 如果选择一级寄存器,Vivado TDPRAM IP必须需要选择Primitives Output Register,此寄存器对应一级寄存器,不能只选择 Core Output Register 作为一级寄存器,实测发现,只选择 Core Output Register 作为一级寄存器的行为与自编 TDPRAM 选择一级寄存器行为有小概率不同

三、SDPRAM 功能对比实验设计

3.1 SDPRAM 的三种操作模式

当选择 SDPRAM 时,端口 A 固定为写端口,端口 B 固定为读端口。此时端口 A 的操作模式还是有三种可以选择:WF、RF 和 NC,但是,依据写优先的定义,是当某一端口同时进行读和写时,读数据等于写数据;其它操作模式也都是针对同一端口同时读写的,但 SDPRAM 读写是不同端口,所以,从操作模式的定义来说,无论哪种操作模式对 SDPRAM 应该是无意义的。我不理解的是,为什么Vivado的BRAM IP还保留了SDPRAM的A端口的三种操作模式选择,不同操作模式对SDPRAM究竟有什么不同? 下面进行实测分析。

为了同时比较三种模式的 Vivado SDPRAM IP 输出,将每种模式的 SDPRAM 都实例化,再用 ILA 进行观测,相关代码如下:

blk_mem_gen_0 blk_mem_gen_0_wf (
  .clka  (clka ), // input wire clka
  .ena   (ena  ),
  .wea   (wea  ), // input wire [0  : 0] wea
  .addra (addra), // input wire [3  : 0] addra
  .dina  (dina ), // input wire [15 : 0] dina
  .clkb  (clkb ), // input wire clkb
  .enb   (enb  ),
  .addrb (addrb), // input wire [3  : 0] addrb
  .doutb (vivado_doutb_wf)// output wire [15 : 0] doutb
)
;

blk_mem_gen_1 blk_mem_gen_1_rf (
  .clka  (clka ), // input wire clka
  .ena   (ena  ),
  .wea   (wea  ), // input wire [0  : 0] wea
  .addra (addra), // input wire [3  : 0] addra
  .dina  (dina ), // input wire [15 : 0] dina
  .clkb  (clkb ), // input wire clkb
  .enb   (enb  ),
  .addrb (addrb), // input wire [3  : 0] addrb
  .doutb (vivado_doutb_rf)// output wire [15 : 0] doutb
)
;

blk_mem_gen_2 blk_mem_gen_2_nc (
  .clka  (clka ), // input wire clka
  .ena   (ena  ),
  .wea   (wea  ), // input wire [0  : 0] wea
  .addra (addra), // input wire [3  : 0] addra
  .dina  (dina ), // input wire [15 : 0] dina
  .clkb  (clkb ), // input wire clkb
  .enb   (enb  ),
  .addrb (addrb), // input wire [3  : 0] addrb
  .doutb (vivado_doutb_nc)// output wire [15 : 0] doutb
)
;

再顶层模块修改一下输出一致与否的判断逻辑:

(* mark_debug *)reg doutb_is_not_equal_vivado_doutb;
always @(posedge clkb) begin
  if (doutb != vivado_doutb_wf
      || doutb != vivado_doutb_rf
      || doutb != vivado_doutb_nc
      )

    doutb_is_not_equal_vivado_doutb <
1'b1;
  else
    doutb_is_not_equal_vivado_doutb <= 1'b0;
end

3.2 实验设计

序号 实测实验条件 波形图 通过 ILA 观测,自编 BRAM 和 Vivado BRAM IP 写入/读取是否一致
1 1.SDPRAM
2.同步时钟–300MHz
3.无输出寄存器
5.带使能信号 ena 和 enb
6.使用相同的初始化文件 COE
SDPRAM-ILA-1 完全一致
功能结论:
SDPRAM 同步时钟下
工作频率可到 300MHz
使能信号工作正常
初始化功能正常
三种操作模式的 Vivado BRAM IP 输出一致
2 1.SDPRAM
2.同步时钟–300MHz
3.输出一级寄存器
其余不变
SDPRAM-ILA-2 完全一致
功能结论:
SDPRAM 同步时钟下,
输出一级寄存器工作正常
3 1.SDPRAM
2.同步时钟–300MHz
3.输出二级寄存器
其余不变
SDPRAM-ILA-3 完全一致
功能结论:
SDPRAM 同步时钟下
输出二级寄存器工作正常
4 1.SDPRAM
2.异步时钟,clka(300MHz),clkb(120MHz)
3.输出二级寄存器
其余不变
SDPRAM-ILA-4 完全一致
功能结论:
SDPRAM 异步时钟下
输出二级寄存器工作正常

3.3 实验波形

SDPRAM-ILA-1

显然,三种模式输出没有区别。

同步时钟不变,寄存器设为一级,进行实验,SDPRAM-ILA-2

同步时钟不变,寄存器设为二级,进行实验,SDPRAM-ILA-3

异步时钟,寄存器仍为二级,进行实验,SDPRAM-ILA-4

3.4 实验结论

从各种条件的 ILA 波形看出,三种模式输出没有区别。到这里我们得出结论:Vivado SDPRAM IP的三种操作模式没有意义,每种都一样,所以,自编的 SDPRAM 不设置操作模式选择。

初始化、使能、寄存器等功能均能正常工作。

自编 SDPRAM 的行为与 Vivado SDPRAM IP 完全一致。

这里就有个疑问,如果说 Vivado SDPRAM IP 的三种操作模式之间没有任何区别的话,为什么 Vivado 中会保留模式选择呢,且 PG058 手册中还有 SDPRAM 的不同模式的说明和推荐,这是怎么回事?有懂的同学可以评论区解答一下。

四、SPRAM 功能对比实验设计

4.1 实验设计

序号 实测实验条件 波形图 通过 ILA 观测,自编 BRAM 和 Vivado BRAM IP 写入/读取是否一致
1 1.SPRAM
2.时钟–300MHz
3.A 端口 Write First 模式
4.无输出寄存器
5.带使能信号 ena 和 enb
6.使用相同的初始化文件 COE
SPRAM-ILA-1 完全一致
功能结论:
SPRAM 在 300MHz 时钟下工作正常
WF 模式工作正常
使能信号工作正常
初始化功能正常
2 1.SPRAM
2.时钟–300MHz
3.A 端口 Read First 模式
4.一级输出寄存器
其余不变
SPRAM-ILA-2 完全一致
功能结论:
RF 模式工作正常
SPRAM 一级寄存器功能正常
3 1.SPRAM
2.时钟–300MHz
3.A 端口 No Change 模式
4.二级输出寄存器
其余不变
SPRAM-ILA-3 完全一致
功能结论:
NC 模式工作正常
SPRAM 二级寄存器功能正常

4.2 实验波形

SPRAM-ILA-1

其余波形略。

4.3 实验结论

自编 SPRAM 和 Vivado SPRAM IP 行为完全一致。

五、DPROM 功能对比实验设计

5.1 实验设计

序号 实测实验条件 波形图 通过 ILA 观测,自编 BRAM 和 Vivado BRAM IP 写入/读取是否一致
1 1.DPROM
2.同步时钟–300MHz
3.无输出寄存器
4.带使能信号 ena 和 enb
5.使用相同的初始化文件 COE
DPROM-ILA-1 完全一致
功能结论:
DPROM 同步时钟下工作正常
使能信号工作正常
初始化功能正常
2 1.DPROM
2.同步时钟–300MHz
3.A 端口一级输出寄存器,B 端口二级输出寄存器
其余不变
DPROM-ILA-2 完全一致
功能结论:
DPROM 同步时钟下工作正常
输出寄存器功能正常
3 1.DPROM
2.异步时钟,clka(300MHz),clkb(120MHz)
3.A 端口二级输出寄存器,A 端口一级输出寄存器
其余不变
DPROM-ILA-3 完全一致
功能结论:
DPROM 异步时钟下工作正常

5.2 实验波形

DPROM-ILA-1

DPROM-ILA-2

DPROM-ILA-3

5.3 实验结论

DPROM 功能正常,与 Vivado DPROM IP 行为完全一致。

六、SPROM 功能对比实验设计

6.1 实验设计

序号 实测实验条件 波形图 通过 ILA 观测,自编 BRAM 和 Vivado BRAM IP 写入/读取是否一致
1 1.SPROM
2.时钟–300MHz
3.无输出寄存器
4.带使能信号 ena
5.使用相同的初始化文件 COE
SPROM-ILA-1 完全一致
功能结论:
SROM 工作正常
使能信号正常工作
初始化功能正常
2 1.SPROM
2.时钟–300MHz
3.一级输出寄存器
其它不变
SPROM-ILA-2 完全一致
功能结论:
SROM 工作正常
寄存器功能正常
3 1.SPROM
2.时钟–300MHz
3.二级输出寄存器
其它不变
SPROM-ILA-3 完全一致
功能结论:
SROM 工作正常
寄存器功能正常

6.2 实验波形

SPROM-ILA-1

SPROM-ILA-2

SPROM-ILA-3

6.3 实验结论

SPROM 功能正常,与 Vivado SPROM IP 行为完全一致。

七、总结与分享

本文对自编 RAM/ROM 与 Vivado BRAM/BROM IP 进行了全面的对比,最终结论是:自编 RAM/ROM 模块的行为和 Vivado 相关 IP 是一样的。

本模块开源,两处仓库同步。

Gitee: Verilog 功能模块–RAM 和 ROM https://gitee.com/xuxiaokang/verilog-function-module–RAM_ROM

Github: zhengzhideakang/verilog-function-module–RAM_ROM https://github.com/zhengzhideakang/verilog-function-module–RAM_ROM

仿真和实测的 Vivado 2024.2 工程通过网盘分享(本系列文章所有分享均相同,均需获取一次即可):

欢迎大家关注我的微信公众号:徐晓康的博客,回复以下 6 位数字获取网盘链接。

402368

建议复制过去不会码错字!


如果本文对你有所帮助,欢迎点赞、转发、收藏、评论让更多人看到,赞赏支持就更好了。

如果对文章内容有疑问,请务必清楚描述问题,留言评论或私信告知我,我看到会回复。


徐晓康的博客持续分享高质量硬件、FPGA与嵌入式知识,软件,工具等内容,欢迎大家关注。

0 0 投票数
文章评分
订阅评论
提醒
0 评论
内联反馈
查看所有评论
0
希望看到您的想法,请您发表评论x