XPM_MEMORY_SDPRAM的使用说明

19 篇文章 6 订阅

        此篇是我在学习中做的归纳与总结,其中如果存在版权或知识错误请直接联系我,欢迎留言。
        PS:本着知识共享的原则,此篇博客可以转载,但请标明出处!

引言:        

        存储单元在FPGA设计中几乎是不可或缺的。无论是单端口(SP)、简单双端口(SDP)或真双端口(TDP),也无论是采用BlockRAM或分布式RAM(Distributed RAM)实现,都可以采用如下几种方式:

        1)、RTL代码

                具有较强的可控性和可测性,但未必能获得最优的综合结果;

        2)、IP Core

                比较快速且灵活,能根据性能或资源需求获得期望的综合结果,但如果需要

        更换Memory的实现方式或IP版本升级,就需要重新调用IP生成

        3)、XPM_MEMORY

                相比之下,XPM_MEMORY就很好地继承了这些方式的优点。

关键参数说明:

详情可参照Xilinx  UG974文档

参数名称默认值说明

ADDR_WIDTH_A

32

指定端口 A 地址端口 addra 的宽度,以位为单位。必须足够大才能从端口 A 访问整个内存,即 >= $clog2(MEMORY_SIZE / WRITE_DATA_WIDTH_A)。

AUTO_SLEEP_TIME

0

自动睡眠的 clk[a|b] 周期数,如果功能在架构中可用

• 0 - 禁用自动睡眠功能

• 3 - 15 - 自动睡眠延迟周期数 不要更改模板中提供的值实例化

BYTE_WRITE_WIDTH_A

32

在端口 A 上启用字节宽写入,请指定字节宽度,以位为单位

• 8 - 8 - 位字节宽写入,当 WRITE_DATA_WIDTH_A 是 8 的整数倍时合法

• 9 - 9 - 位字节宽写入,在以下情况下合法WRITE_DATA_WIDTH_A 是 9 的整数倍 或者要在端口 A 上启用字宽写入,请指定与 WRITE_DATA_WIDTH_A 相同的值。

CLOCKING_MODE

"common_clock"

• "common_clock" - 通用时钟;使用 clka 为端口 A 和端口 B 提供时钟

• “independent_clock” - 独立时钟;带有 clka 的时钟端口 A 和带有 clkb 的端口 B

ECC_MODE

"no_ecc"

MEMORY_OPTIMIZATION

"true"

“true”以启用优化未使用的内存或内存结构中的位。

“false”以禁用优化未使用的内存或内存结构中的位

MEMORY _PRIMITIVE

"auto"

指定要使用的内存原语(资源类型)

• "auto" - 允许 Vivado Synthesis 选择

• "distributed" - 分布式内存

• "block" - 块内存

• "ultra" - 超 RAM 内存

MEMORY_SIZE

2048

以位为单位指定总内存阵列大小。例如,对于 2kx32RAM,输入 65536。

• 当启用 ECC 并设置为“encode_only”时,内存大小必须是READ_DATA_WIDTH_B 的倍数 • 当启用 ECC 并设置为“decode_only”时,内存大小必须是WRITE_DATA_WIDTH_A的倍数

READ_DATA_WIDTH_B

32

指定端口 B 读取数据输出端口 doutb 的宽度,以位为单位。

• 当启用 ECC 并设置为“encode_only”时,READ_DATA_WIDTH_B 必须是 72 位的倍数

• 当启用 ECC 并设置为“decode_only”或“both_encode_and_decode”时,READ_DATA_WIDTH_B 必须是 64 位的倍数

READ_LATENCY_B

2

指定端口 B 读取数据管道中的寄存器级数。读取输出到端口 doutb 的数据需要此数量的 clkb 周期(当 CLOCKING_MODE 为“common_clock”时为 clka)。要定位块内存,需要 1 或更大的值 - 1 导致仅使用内存锁存器; 2 导致使用输出寄存器。要定位分布式内存,需要 0 或更大的值 - 0 表示组合输出。大于 2 的值会合成额外的触发器,这些触发器不会重新定时到内存基元中。

USE_EMBEDDED_CONSTRAINT

0

1:启用分布式 RAM 的 clka 和 clkb 上的 doutb_reg 之间的 set_false_path 约束添加

USE_MEM_INIT

1

WAKEUP_TIME

"disable_sleep"

指定“disable_sleep”禁用动态节能选项,指定“use_sleep_pin”启用动态节能选项

WRITE_DATA_WIDTH_A

32

64 位的倍数 当启用 ECC 并设置为“decode_only”时,WRITE_DATA_WIDTH_A 必须是 72 位的倍数

WRITE_MODE_B

"no_change"

"no _change",

"read _first",

"write _first"

使用说明:

为了方便说明,首先举例IP核的设置:

如下图,我们要使用异步双口BRAM,

        写位宽  512  深度  2 ^ 8

        读位宽  32 

 例化如下:

Wr512x256Rd32x4096BRAM u_RdBram(
    .clka   ( InDdrClk      ) , //: IN STD_LOGIC;
    .ena    ( 'b1           ) , //: IN STD_LOGIC;
    .wea    ( InRdBufEn     ) , //: IN STD_LOGIC_VECTOR(0 DOWNTO 0);
    .addra  ( InRdBufAddr   ) , //: IN STD_LOGIC_VECTOR(7 DOWNTO 0);
    .dina   ( InRdBufData   ) , //: IN STD_LOGIC_VECTOR(511 DOWNTO 0);
    .clkb   ( InRdBramClk   ) , //: IN STD_LOGIC;
    .enb    ( 'b1           ) , //: IN STD_LOGIC;
    .addrb  ( RdBramAddr    ) , //: IN STD_LOGIC_VECTOR(11 DOWNTO 0);
    .doutb  ( OutRdBramData )   //: OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
  );

XPM_MEMORY参考代码:

        其中:

ADDR_WIDTH_A可参照IP Core的IN STD_LOGIC_VECTOR(7 DOWNTO 0);设置为8;

ADDR_WIDTH_B可参照IP Core的IN STD_LOGIC_VECTOR(11 DOWNTO 0);设置为12;

CLOCKING_MODE 设置为异步时钟 "independent_clock"

BYTE_WRITE_WIDTH_A和WRITE_DATA_WIDTH_A设置为 DDR_MIG_DW = 512

BYTE_WRITE_WIDTH_B设置为 32

MEMORY_SIZE  设置为:DDR_MIG_DW * 2 ^ 8

xpm_memory_sdpram #(
    .ADDR_WIDTH_A           ( 8                ) , // DECIMAL
    .ADDR_WIDTH_B           ( 12                        ) , // DECIMAL
    .AUTO_SLEEP_TIME        ( 0                         ) , // DECIMAL
    .BYTE_WRITE_WIDTH_A     ( DDR_MIG_DW                ) , // DECIMAL
    .CLOCKING_MODE          ( "independent_clock"       ) , // String
    .ECC_MODE               ( "no_ecc"                  ) , // String
    .MEMORY_INIT_FILE       ( "none"                    ) , // String
    .MEMORY_INIT_PARAM      ( "0"                       ) , // String
    .MEMORY_OPTIMIZATION    ( "true"                    ) , // String
    .MEMORY_PRIMITIVE       ( "block"                   ) , // String
    .MEMORY_SIZE            ( DDR_MIG_DW * 256          ) , // DECIMAL DDR_MIG_DW * 2^8
    .MESSAGE_CONTROL        ( 0                         ) , // DECIMAL
    .READ_DATA_WIDTH_B      ( 32                        ) , // DECIMAL
    .READ_LATENCY_B         ( 2                         ) , // DECIMAL
    .READ_RESET_VALUE_B     ( "0"                       ) , // String
    .USE_EMBEDDED_CONSTRAINT( 0                         ) , // DECIMAL
    .USE_MEM_INIT           ( 1                         ) , // DECIMAL
    .WAKEUP_TIME            ( "disable_sleep"           ) , // String
    .WRITE_DATA_WIDTH_A     ( DDR_MIG_DW                ) , // DECIMAL
    .WRITE_MODE_B           ( "no_change"               )   // String
) Wr512x256Rd32x4096(
    .dbiterrb               (                           ) , // 1-bit output
    .doutb                  ( OutRdBramData             ) , // READ_DATA_WIDTH_B-bit output
    .sbiterrb               (                           ) , // 1-bit output
    .addra                  ( InRdBufAddr               ) , // ADDR_WIDTH_A-bit input
    .addrb                  ( RdBramAddr                ) , // ADDR_WIDTH_B-bit input
    .clka                   ( InDdrClk                  ) , // 1-bit input
    .clkb                   ( InRdBramClk               ) , // 1-bit input
    .dina                   ( InRdBufData               ) , // WRITE_DATA_WIDTH_A-bit input
    .ena                    ( InRdBufEn                 ) , // 1-bit input
    .enb                    ( 1'b1                      ) , // 1-bit input
    .injectdbiterra         ( 1'b0                      ) , // 1-bit input
    .injectsbiterra         ( 1'b0                      ) , // 1-bit input
    .regceb                 ( 1'b1                      ) , // 1-bit input
    .rstb                   ( InDdrRst                  ) , // 1-bit input
    .sleep                  ( 1'b0                      ) , // 1-bit input
    .wea                    ( InRdBufEn                 ) // WRITE_DATA_WIDTH_A-bit input
);

        注意:建议enb常置一,否则读数据最后一位会出错!

仿真结果如下图所示:

  • 9
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
这个错误是由于文件路径中包含空格而导致的。为了解决这个错误,你需要在文件路径中的包含空格的地方添加双引号。例如,将 "C:/Program Files/Xilinx/verilog/src/glbl.v" 改为 "C:/Program Files/Xilinx/verilog/src/glbl.v"。\[1\] 另外,你提到了一个关于使用ModelSim进行仿真时出现的错误。这个错误是由于在do文件中指定的设计单元文件路径中包含了空格,导致无法以读取模式打开文件。为了解决这个问题,你需要在文件路径中的包含空格的地方添加双引号。例如,将 "D:/diamond" 改为 "D:/diamond projects/cpu_if/src/cpu_if.v"。\[3\] 至于你提到的另一个错误,"Error: (vlog-7) Failed to open design unit file "C:/Xilinx/Vivado/2018.3/data/ip/xpm/xpm_memory/hdl/xpm_memory.sv" in read mode.",这个错误是由于无法以读取模式打开指定的设计单元文件。可能的原因是文件路径不正确或文件不存在。请确保文件路径正确,并检查文件是否存在。如果文件存在并且路径正确,那么可能是文件权限或其他问题导致无法打开文件。你可以尝试更改文件权限或使用其他方法来打开文件。 #### 引用[.reference_title] - *1* [Failed to open design unit file "%XILINX%/verilog/src/glbl.v](https://blog.csdn.net/alan5555/article/details/9378009)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [modelsim10.4仿真错误Error: (vlog-7) Failed to open design unit file "XXXXX" in read mode解决办法](https://blog.csdn.net/llf021421/article/details/79181118)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

虚怀若水

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值