在UltraScale VCU118中使用URAM

使用XPM原语

在这里插入图片描述

构建URAM模块

URAM模块的端口与BRAM完全相似,但是在配置URAM的时候有细微的差别
1.URMA不支持用IP核调用,但可以使用XPM原语
2. 自定义URAM的配置,调节输入和写入端口的地址宽度修改两个参数ADDR_WIDTH_A
ADDR_WIDTH_B,调节输入和写入端口的数据宽度修改两个参数READ_DATA_WIDTH_A
READ_DATA_WIDTH_B,根据以上的数据手动计算出内存大小MEMORY_SIZE= 2^ADDR_WIDTH_A*READ_DATA_WIDTH_A
3.指定B端口的写入模式,写入模式有两种分别是“read_first”和“write_first”,两者的显著区别是当需要在同一个位置中读写数据时,read_first会首先读取内存中旧的数据,write_first 则会用新数据覆盖掉旧数据,读取到最新的数据。在read_first模式下READ_LATENCY_B的延迟为两个周期而在write_first模式下READ_LATENCY_B的延迟为三个周期。为了与带有primitive output registers 的BRAM存储器的读写周期匹配,因此选择read_first模式
4.用MEMORY_INIT_FILE初始化URAM模块时,可以直接从文件中读取,但是文件格式必须是.mem类型的存储文件。保存.mem文件的技巧是,在记事本中另存文件时,将文件名包括扩展名用双引号括起来,例如输入"uram_init.mem"。确保"保存类型"设置为所有文件。特别注意,在Verilog文件中引用文件时,使用正斜杠(/)而不是反斜杠()作为路径分隔符
在这里插入图片描述

// xpm_memory_sdpram: Simple Dual Port RAM
// Using URAM in Xilinx FPGAs with Xilinx Parameterized Macros


module URAM_Module_a_im_0(
 input wire clka,          // A端口的时钟信号
   input wire ena,           // A端口的使能信号。当为高电平时,允许对RAM的访问。
   input wire wea,           // A端口的写使能信号。当为高电平且ena也为高电平时,允许数据写入。
   input wire [17:0] addra,  // A端口的写地址。
   input wire [31:0] dina,   // A端口的写入数据。
   input wire clkb,          // B端口的时钟信号。在此例中,A和B端口共用相同的时钟信号。
   input wire [17:0] addrb,  // B端口的读地址。
   input wire enb,           // B端口的使能信号。当为高电平时,允许从RAM读取数据。
   output wire [31:0] doutb  // B端口的读出数据。
    );
// 参数化的XPM RAM配置
xpm_memory_sdpram #(
   .ADDR_WIDTH_A(18),               // A端口地址宽度
   .ADDR_WIDTH_B(18),               // B端口地址宽度
   .AUTO_SLEEP_TIME(0),            // 自动休眠时间配置,0表示禁用
   .BYTE_WRITE_WIDTH_A(32),        // A端口的字节写入宽度,此处设定为32位全宽写入
   .CASCADE_HEIGHT(0),             // 级联高度,0表示不使用级联
   .CLOCKING_MODE("common_clock"), // 时钟模式配置,此处A和B端口共用时钟
   .ECC_MODE("no_ecc"),            // ECC模式配置,此处不使用ECC
   .MEMORY_INIT_FILE("D:/FFT_Paper_Code/MDC/memory/input_bank1_a_im.mem"),      // 内存初始化文件,此处使用
   .MEMORY_INIT_PARAM("0"),        // 内存初始化参数,此处不使用
   .MEMORY_OPTIMIZATION("true"),   // 启用内存优化
   .MEMORY_PRIMITIVE("ultra"),     // 使用URAM
   .MEMORY_SIZE(8388608),          // 内存大小配置,以位为单位
   .MESSAGE_CONTROL(0),            // 消息控制,此处禁用
   .READ_DATA_WIDTH_B(32),         // B端口的读数据宽度
   .READ_LATENCY_B(2),             // B端口的读延迟
   .READ_RESET_VALUE_B("0"),       // 读复位值
   .RST_MODE_A("SYNC"),            // A端口复位模式,同步复位
   .RST_MODE_B("SYNC"),            // B端口复位模式,同步复位
   .SIM_ASSERT_CHK(0),             // 模拟断言检查,0表示禁用
   .USE_MEM_INIT(1),               // 使用内存初始化
   .WAKEUP_TIME("disable_sleep"),  // 唤醒时间配置,此处禁用睡眠模式
   .WRITE_DATA_WIDTH_A(32),        // A端口的写数据宽度
   .WRITE_MODE_B("read_first")    // B端口的写模式
) xpm_memory_sdpram_inst (
   .dbiterrb(),                    // 双位错误状态,此处未使用
   .doutb(doutb),                  // B端口的读出数据
   .sbiterrb(),                    // 单位错误状态,此处未使用
   .addra(addra),                  // A端口的写地址
   .addrb(addrb),                  // B端口的读地址
   .clka(clka),                    // A端口的时钟信号
   .clkb(clkb),                    // B端口的时钟信号(共用)
   .dina(dina),                    // A端口的写入数据
   .ena(ena),                      // A端口的使能信号
   .enb(enb),                      // B端口的使能信号
   .injectdbiterra(1'b0),          // 双位错误注入信号,此处未使用
   .injectsbiterra(1'b0),          // 单位错误注入信号,此处未使用
   .regceb(1'b1),                  // 输出寄存器的时钟使能,此处始终使能
   .sleep(1'b0),                   // 睡眠模式信号,此处未使用
   .wea(wea)                       // A端口的写使能信号
);

endmodule
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值