xpm_memory_tdpram原语的完整使用实例

6 篇文章 1 订阅
6 篇文章 15 订阅

参考UG573和UG974。

一、xpm_memory_tdpram原语介绍

xpm_memory_tdpram #(
      .ADDR_WIDTH_A(16),               // DECIMAL,A口地址[15:0]
      .ADDR_WIDTH_B(16),               // DECIMAL,B口地址[15:0]
      .AUTO_SLEEP_TIME(0),            // DECIMAL
      .BYTE_WRITE_WIDTH_A(72),        // DECIMAL A口写宽度为72,4个像素点
      .BYTE_WRITE_WIDTH_B(72),        // DECIMAL B口写宽度为72,4个像素点
      .CASCADE_HEIGHT(0),             // DECIMAL
      .CLOCKING_MODE("common_clock"), // String

      .ECC_MODE("no_ecc"),            // String
//      .MEMORY_INIT_FILE("none"),      // String
      .MEMORY_INIT_FILE("triangle_192_256.mem"),      // String
      .MEMORY_INIT_PARAM("0"),        // String
      .MEMORY_OPTIMIZATION("true"),   // String
      .MEMORY_PRIMITIVE("ultra"),      // String
      .MEMORY_SIZE(3538944),             // DECIMAL 内存bits数,192*1024*18=192*256*72=3538944,生成192行1024列的图像,18为图像颜色的深度
      .MESSAGE_CONTROL(0),            // DECIMAL 禁能消息报告
      .READ_DATA_WIDTH_A(72),         // DECIMAL A口读数据位宽[71:0],4个像素点
      .READ_DATA_WIDTH_B(72),         // DECIMAL B口读数据位宽[71:0],4个像素点
      .READ_LATENCY_A(1),           // DECIMAL 读延迟1个时钟 内存大于2MB时,延迟必须大于8
      .READ_LATENCY_B(1),           // DECIMAL 读延迟1个时钟 内存大于2MB时,延迟必须大于8
      .READ_RESET_VALUE_A("0"),       // String
      .READ_RESET_VALUE_B("0"),       // String
      .RST_MODE_A("SYNC"),            // String
      .RST_MODE_B("SYNC"),            // String
      .SIM_ASSERT_CHK(0),             // DECIMAL; 0=disable simulation messages, 1=enable simulation messages
      .USE_EMBEDDED_CONSTRAINT(0),    // DECIMAL
      .USE_MEM_INIT(0),               // DECIMAL
      .USE_MEM_INIT_MMI(0),           // DECIMAL
      .WAKEUP_TIME("disable_sleep"),  // String
      .WRITE_DATA_WIDTH_A(72),        // DECIMAL A口读数据位宽[71:0],4个像素点
      .WRITE_DATA_WIDTH_B(72),        // DECIMAL B口读数据位宽[71:0],4个像素点
      .WRITE_MODE_A("no_change"),     // String
      .WRITE_MODE_B("no_change"),     // String
      .WRITE_PROTECT(1)               // DECIMAL,使用写使能信号
   )
ram_inst (
      .dbiterra(),// 1-bit output: 指示A口数据输出有双bits错误发生
      .dbiterrb(),// 1-bit output: 指示B口数据输出有双bits错误发生
      .sbiterra(),// 1-bit output: 指示A口数据输出有单bits错误发生
      .sbiterrb(), // 1-bit output: 指示B口数据输出有单bits错误发生
      .ena(1'b1), //RAM A口使能信号,高电平有效  
      .enb(1'b1), //RAM B口使能信号,高电平有效  
      .injectdbiterra(1'b0),//控制双bits错误注入 
      .injectdbiterrb(1'b0),//控制双bits错误注入 
      .injectsbiterra(1'b0),//控制单bits错误注入 
      .injectsbiterrb(1'b0),//控制单bits错误注入 
      .regcea(1'b1), //输入端口,输出数据路径的上一个寄存器阶段,时钟使能
      .regceb(1'b1), //输入端口,输出数据路径的上一个寄存器阶段,时钟使能
      .rsta(1'b0), //复位信号,高电平有效 
      .rstb(1'b0),//复位信号,高电平有效
      .sleep(1'b0), //高电平使能动态降低功耗功能,此处禁能 
      
      .douta(douta), //READ_DATA_WIDTH_A bits 输出,[71:0],B口读数据
      .doutb(doutb), //READ_DATA_WIDTH_B bits 输出,[71:0],B口读数据
      .addra(addra),//ADDR_WIDTH_A bits输入 [15:0]A口写地址
      .addrb(addrb),//ADDR_WIDTH_B bits输入 [15:0]B口写地址
      .clka(clk_300M), //A口输入时钟
      .clkb(clk_300M), //B口输入时钟
      .dina(dina), // WRITE_DATA_WIDTH_A bits A口数据输入[71:0]
      .dinb(dinb),  // WRITE_DATA_WIDTH_B bits B口数据输入[71:0]

      .wea(wea), //A口写使能信号,宽度为 WRITE_DATA_WIDTH_A / BYTE_WRITE_WIDTH_A  =72/72=1 
      .web(web) //B口写使能信号,宽度为 WRITE_DATA_WIDTH_B / BYTE_WRITE_WIDTH_B  =72/72=1 

   );

         当需要指定RAM内初始化数值时,可以使用原语中的参数MEMORY_INIT_FILE,指向一个尾缀为.mem的文件。该文件内的内容要求必须时十六进制的,与$readmemh函数读取的文件内容格式一致,用空格或者回车将数据隔开即可。

        另外需要注意的是,本着节约使用ultra RAM的想法,一个ultra RAM的数据位宽为72bits,因此72bits拆分为18bits,即ultra RAM的一个地址上,保存着4个18bits的像素数据。

 二、如何生成.mem文件

        借助于matlab,与生成.coe文件类似,matlabl示例程序如下:


M = 192;
N = 1024 ;
y = zeros(M , N) ;%生成192行1024列的矩阵
for i = 1:1:M
    for j = 1:1:N
        if(j <= N/2) %锯齿波,从0到512时,下降斜率直线
            if( i == round(191/512*j)) 
                y(i,j) = 255 ;%出现在斜率线附近的点赋值255
            else
                y(i,j) = 0 ;%不在斜率线附近的点赋值0
            end
        end
        if(j > N/2)%%锯齿波,从512到1024时,上升斜率直线
            if( i == round(382-191/511*j) ) 
                y(i,j) = 255 ;%出现在斜率线附近的点赋值255
            else
                y(i,j) = 0 ;%不在斜率线附近的点赋值0
            end
        end
    end
end   
imshow(y)

%  plot(y(i,j));%绘图预览

%y矩阵4个点拼成1个点
fpga_y_dec = zeros(M , N/4) ;
fpga_y_dec_49152=zeros(49152,1);%将矩阵变为1列
fpga_y_hex = zeros(M*N/4,8) ;
for i = 1:1:M
    for j = 1:1:N/4
        fpga_y_dec(i,j)=y(i,4*j-3)*256*256*256+y(i,4*j-2)*256*256+y(i,4*j-1)*256+y(i,4*j);
        fpga_y_dec_49152(i*256-256+j,1)=fpga_y_dec(i,j);
    end
end




fpga_y_hex= dec2hex(fpga_y_dec_49152);     

        
fid1 = fopen('triangle_192_256.mem','wt');    
%COE文件格式
% fprintf( fid1, 'MEMORY_INITIALIZATION_RADIX = 16;\n');                     
% fprintf( fid1, 'MEMORY_INITIALIZATION_VECTOR =\n');
%输出十进制数据,保存至文件
for i = 1:1:49152
    if(i == 49152)
        fprintf(fid1,'%s%c%c%c%c%c%c%c%c',"0000000000",fpga_y_hex(i,1),fpga_y_hex(i,2),fpga_y_hex(i,3),fpga_y_hex(i,4),fpga_y_hex(i,5),fpga_y_hex(i,6),fpga_y_hex(i,7),fpga_y_hex(i,8)); %最后一个点时,标点为分号,其余时候为逗号
    else
        fprintf(fid1,'%s%c%c%c%c%c%c%c%c\n',"0000000000",fpga_y_hex(i,1),fpga_y_hex(i,2),fpga_y_hex(i,3),fpga_y_hex(i,4),fpga_y_hex(i,5),fpga_y_hex(i,6),fpga_y_hex(i,7),fpga_y_hex(i,8));
    end
end
fclose(fid1);%关闭文件

        生成 如下图所示的三角波图像:

         生成的文件的部分内容如下:

 

 三、仿真xpm_memory_tdpram原语

         仿真xpm_memory_tdpram原语原语,将初始化文件内容读出,观察是否与文件内容一致。

`timescale 1ns/1ps
module	 top();

reg clk_100M = 1'b0;
reg rst = 1'b1;
reg rd_enable =1'b0;
//生成100M时钟
always 
begin
    #5
        clk_100M <= ~clk_100M;
end

//延迟100ns,复位拉高
initial
begin
    #100 rst <= 1'b0;
    #200 rd_enable <= 1'b1;
end

wire [71:0] douta;
wire [71:0] doutb;
reg [15:0] addra =0;
reg [15:0] addrb =0;

wire [71:0] dina;
wire [71:0] dinb;
wire  wea;
wire  web;

//不写入新的数据,仅读
assign dina = 72'b0;
assign dinb = 72'b0;
assign wea = 1'b0;
assign web = 1'b0;

always@(posedge clk_100M)
begin
    if(rd_enable) begin
        addra <= addra + 1'b1;
        addrb <= addrb + 1'b1;
    end
end


xpm_memory_tdpram #(
      .ADDR_WIDTH_A(16),               // DECIMAL,A口地址[15:0]
      .ADDR_WIDTH_B(16),               // DECIMAL,B口地址[15:0]
      .AUTO_SLEEP_TIME(0),            // DECIMAL
      .BYTE_WRITE_WIDTH_A(72),        // DECIMAL A口写宽度为72,4个像素点
      .BYTE_WRITE_WIDTH_B(72),        // DECIMAL B口写宽度为72,4个像素点
      .CASCADE_HEIGHT(0),             // DECIMAL
      .CLOCKING_MODE("common_clock"), // String

      .ECC_MODE("no_ecc"),            // String
//      .MEMORY_INIT_FILE("none"),      // String
      .MEMORY_INIT_FILE("triangle_192_256.mem"),      // String
      .MEMORY_INIT_PARAM("0"),        // String
      .MEMORY_OPTIMIZATION("true"),   // String
      .MEMORY_PRIMITIVE("ultra"),      // String
      .MEMORY_SIZE(3538944),             // DECIMAL 内存bits数,192*1024*18=192*256*72=3538944,生成192行1024列的图像,18为图像颜色的深度
      .MESSAGE_CONTROL(0),            // DECIMAL 禁能消息报告
      .READ_DATA_WIDTH_A(72),         // DECIMAL A口读数据位宽[71:0],4个像素点
      .READ_DATA_WIDTH_B(72),         // DECIMAL B口读数据位宽[71:0],4个像素点
      .READ_LATENCY_A(0),             // DECIMAL
      .READ_LATENCY_B(0),             // DECIMAL
      .READ_RESET_VALUE_A("0"),       // String
      .READ_RESET_VALUE_B("0"),       // String
      .RST_MODE_A("SYNC"),            // String
      .RST_MODE_B("SYNC"),            // String
      .SIM_ASSERT_CHK(0),             // DECIMAL; 0=disable simulation messages, 1=enable simulation messages
      .USE_EMBEDDED_CONSTRAINT(0),    // DECIMAL
      .USE_MEM_INIT(0),               // DECIMAL
      .USE_MEM_INIT_MMI(0),           // DECIMAL
      .WAKEUP_TIME("disable_sleep"),  // String
      .WRITE_DATA_WIDTH_A(72),        // DECIMAL A口读数据位宽[71:0],4个像素点
      .WRITE_DATA_WIDTH_B(72),        // DECIMAL B口读数据位宽[71:0],4个像素点
      .WRITE_MODE_A("no_change"),     // String
      .WRITE_MODE_B("no_change"),     // String
      .WRITE_PROTECT(1)               // DECIMAL,使用写使能信号
   )
ram_inst (
      .dbiterra(),// 1-bit output: 指示A口数据输出有双bits错误发生
      .dbiterrb(),// 1-bit output: 指示B口数据输出有双bits错误发生
      .sbiterra(),// 1-bit output: 指示A口数据输出有单bits错误发生
      .sbiterrb(), // 1-bit output: 指示B口数据输出有单bits错误发生
      .ena(1'b1), //RAM A口使能信号,高电平有效  
      .enb(1'b1), //RAM B口使能信号,高电平有效  
      .injectdbiterra(1'b0),//控制双bits错误注入 
      .injectdbiterrb(1'b0),//控制双bits错误注入 
      .injectsbiterra(1'b0),//控制单bits错误注入 
      .injectsbiterrb(1'b0),//控制单bits错误注入 
      .regcea(1'b1), //输入端口,输出数据路径的上一个寄存器阶段,时钟使能
      .regceb(1'b1), //输入端口,输出数据路径的上一个寄存器阶段,时钟使能
      .rsta(rst), //复位信号,高电平有效 
      .rstb(rst),//复位信号,高电平有效
      .sleep(1'b0), //高电平使能动态降低功耗功能,此处禁能 
      
      .douta(douta), //READ_DATA_WIDTH_A bits 输出,[71:0],B口读数据
      .doutb(doutb), //READ_DATA_WIDTH_B bits 输出,[71:0],B口读数据
      .addra(addra),//ADDR_WIDTH_A bits输入 [15:0]A口写地址
      .addrb(addrb),//ADDR_WIDTH_B bits输入 [15:0]B口写地址
      .clka(clk_100M), //A口输入时钟
      .clkb(clk_100M), //B口输入时钟
      .dina(dina), // WRITE_DATA_WIDTH_A bits A口数据输入[71:0]
      .dinb(dinb),  // WRITE_DATA_WIDTH_B bits B口数据输入[71:0]

      .wea(wea), //A口写使能信号,宽度为 WRITE_DATA_WIDTH_A / BYTE_WRITE_WIDTH_A  =72/72=1 
      .web(web) //B口写使能信号,宽度为 WRITE_DATA_WIDTH_B / BYTE_WRITE_WIDTH_B  =72/72=1 

   );
   

endmodule



        另外,wea的信号宽度为WRITE_DATA_WIDTH_A / BYTE_WRITE_WIDTH_A。 当WRITE_DATA_WIDTH_A=72,BYTE_WRITE_WIDTH_A=9时,wea的信号宽度为72/9=8。

        可以通过wea的某一位或者某几位有效,控制72bits中对应的9bits数据写入到UltraRAM中。比如wea=8'b0000_0011,那么dina[71:0]中的低18bits写入到ultraRAM中,其余bits位不变。

        web同理。

        根据仿真结果,发现,设置READ_LATENCY_A和READ_LATENCY_B为0时,在地址有效后一个时钟后,ultraRAM数据输出。

四、其他需要注意的事项

         使用ultraRAM时,对xpm_memory_tdpram赋值初始化数据,仅可用于仿真,无法用于综合布局布线。(综合时会自动使用BRAM或者报错)

  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。
这个错误是由于文件路径中包含空格而导致的。为了解决这个错误,你需要在文件路径中的包含空格的地方添加双引号。例如,将 "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 ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值