当前位置:网站首页>xpm_memory_tdpram原语的完整使用实例
xpm_memory_tdpram原语的完整使用实例
2022-06-22 02:35:00 【yindq1220】
一、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;
[email protected](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

根据仿真结果,发现,设置READ_LATENCY_A和READ_LATENCY_B为0时,在地址有效后一个时钟后,ultraRAM数据输出。
四、其他需要注意的事项
使用ultraRAM时,对xpm_memory_tdpram赋值初始化数据,仅可用于仿真,无法用于综合布局布线。(综合时会自动使用BRAM或者报错)
边栏推荐
- How does the QT program implement the default selection of a behavior in the selected listwidget
- 关于PMP考试,你想知道的知识都在这里了
- 微软 IE 浏览器于 6 月 15 日被永久关闭
- postgresql根据时间字段的大小来取数
- Linxu modify the permissions of the folder so that everyone can access 777
- What programming does a child learn?
- Flash back when GoLand starts
- PMP项目管理知识该如何运用?
- 如何选择合适的 Neo4j 版本(2022版)
- 【9. 子矩阵和】
猜你喜欢

A short video costs hundreds of thousands of yuan, and the virtual digital man makes a circle with "strength"

【9. 子矩阵和】

EMC辐射发射整改-原理案例分析

The brand, products and services are working together. What will Dongfeng Nissan do next?

LabVIEW开发发电厂合规性测试系统

Li Kou today's question 1108 IP address invalidation

Wechat applet film and television review and exchange platform system graduation design (1) development outline

Ioerror: no translation files found for default language zh cn Solutions for

With the acceleration of industry wide digital transformation, what kind of storage will be more popular?

rt_ Message queue of thread
随机推荐
Neo4j 智能供应链应用源代码简析
Linxu modify the permissions of the folder so that everyone can access 777
Extending kubernetes API with CRD
Unicode decodeerror appears: 'ASCII' codec can't decode byte 0xe9 in position 0: ordinal not in range solution
Chapter 24 image and video processing based on Simulink -- matlab in-depth learning and practical collation
Neo4j 技能树正式发布,助你轻松掌握Neo4j图数据库
With the acceleration of industry wide digital transformation, what kind of storage will be more popular?
【2. 归并排序】
Which Amazon evaluation system is better?
Cmake common command category notes
Li Kou today's question 1108 IP address invalidation
FPGA Xilinx 7 Series FPGA DDR3 hardware design rules
An article thoroughly learns to draw data flow diagrams
Dynamically load assetdatabase of assets
Using OKR for HR digital transformation
Parallel search DSU
Must the database primary key be self incremented? What scenarios do not suggest self augmentation?
EMC輻射發射整改-原理案例分析
A short video costs hundreds of thousands of yuan, and the virtual digital man makes a circle with "strength"
【9. 子矩阵和】