相关文章推荐
逃跑的椰子  ·  js date日期格式化_js ...·  1 年前    · 
发财的李子  ·  Resample xarray ...·  1 年前    · 

一、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 y(i,j) = 0 ;%不在斜率线附近的点赋值0 if(j > N/2)%%锯齿波,从512到1024时,上升斜率直线 if( i == round(382-191/511*j) ) y(i,j) = 255 ;%出现在斜率线附近的点赋值255 y(i,j) = 0 ;%不在斜率线附近的点赋值0 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); 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)); %最后一个点时,标点为分号,其余时候为逗号 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)); 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
        clk_100M <= ~clk_100M;
//延迟100ns,复位拉高
initial
begin
    #100 rst <= 1'b0;
    #200 rd_enable <= 1'b1;
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;
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
                                    xpm_memory_sdpram #(
    .ADDR_WIDTH_A           ( 9                         ) , // DECIMAL
    .ADDR_WIDTH_B           ( 9                         ) , // DECIMAL
    .AUTO_SLEEP_TIME        ( 0                         ) , // DECIMAL
    .BYTE_WRITE_W...
                                    书本中对于RAM的三种操作读优先级(read_first)、写优先(write_first)和保持(no_change)使用等效的verilog来描述,简单明了,记录于此。
                                    在vivado里利用 Xilinx Parameterized Macros(XPM) 原语例化的 直接仿真会出现 module找不到的错误, 在tcl里输入一下指令就好了,
set_property XPM_LIBRARIES {XPM_CDC XPM_MEMORY} [current_project]
                                    整理:比特波特首先,什么是XPM?可能很多人没听过也没用过,它的全称是Xilinx Parameterized Macros,也就是Xilinx的参数化的宏,跟原语的例化和使用方式一样。可以在Vivado中的Tools->Language Templates中查看都有哪些XPM可以例化。从上图中可以看出,目前可以例化的XPM主要有三种:跨时钟域处理、FIFO和MEMORY。我们以MEMORY...
                                    在Vmware10中安装的是Ubuntu。使用时,某一天出现如下问题:
Unrecoverable Memory Allocation Failure
之后是ubuntu起不来,一直出现这样的问题。笔者的解决办法是,进入Ubuntu的Recovery模式,对文件系统进行了检测,然后就可以正常使用了。
                                    转:https://zhuanlan.zhihu.com/p/147058600
上一篇文章介绍了 单比特跨时钟域 的不同应用场景的区别(基于Xilinx Parameterized Macros),主要有:
同步Reset (XPM_CDC_SYNC_RESET)
	异步Reset (XPM_CDC_ASYNC_RESET)
	电平信号 (XPM_CDC_SINGLE)
	脉冲信号 (XPM_CDC_PULSE)
这篇我们来看一下这几个Macro的具体设计细节和原理。我会基于Xilinx Guide的
以上三种宏都可以用来实现跨时钟域的处理,FIFO与RAM的跨时钟域处理主要是通过缓存的方式实现。利用宏和IP核来实现FIFO、RAM的例化,功能上相差不大,就是使用方式略有区别。
以下主要介绍一下XPM_CDC,通过程序注释的方式进行介...
                                    目录原语简介原语的分类时钟相关的原语IBUFGIBUFGDSBUFGBUFGPBUFGCEBUFGMUXBUFGDLLDCM接口相关的原语IDDRODDR
原语简介
原语,即primitive,原语类似最底层的描述方法,是不同厂商针对自己FPGA芯片提供的底逻辑资源的描述。因此不同的厂商,原语不同,同一家的FPGA,由于不同系列的芯片内部资源一般不同,原语也是不通用的。使用原语的好处,可以直接例化使用,不用定制IP。我们在进行FPGA开发时的HDL代码在进行综合后的输出就是由原语组成的逻辑网表,因此原语是不