XILINX-VIVADO IP参数化方法(XPM)

这篇具有很好参考价值的文章主要介绍了XILINX-VIVADO IP参数化方法(XPM)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一 、XPM简介

       XPM全称是Xilinx Parameterized Macros,是XILINX提供的一种IP参数化方法。传统的IP调用,我们需要进入到IP Catolog里选择自己需要的IP,这种调用方式的优点是比较直观,参数的设置图形化;但是它的弊端也很明显,就是每次修改IP参数都需要进入到图形化界面来修改然后保存。对于一些同质化比较高的项目,比如一个1K的视频图像处理项目,要移植成一个2K的版本;图像的分辨率发生了变化,工程里使用到的参数也会全部发生变化,我们需要把工程里面所有的IP全部重新设置一遍来进行更新,这样效率无疑是非常低的。Xilinx的工程师们考虑到用户的参数化设计需求,为一些常用的基础IP提供参数化模板。

     注意这里是说的常用基础IP,那么到底包括哪些IP呢?

    我们打开一个工程,点击工具导航栏的Tools --> 选择 Language Templates,这是一个宝库,里面有Xilinx提供的各种设计模板约束模板,其中就包括XPM.

XILINX-VIVADO IP参数化方法(XPM),FPGA设计优化,# 器件结构,fpga开发

 从上图可以看到XPM主要包括3大类: XPM_CDC(跨时钟处理)、XPM_FIFO、和XPM_MEMORY。这里涉及的子类有点多,关于每一项的具体使用方法,我不一一赘述;大家有需要可以参考官方文档UG953第二章,这里简单的以一个Simple daul port ram举例XPM的使用方法。

二、XPM的使用

这里以XPM_MEMORY中的simple daul port ram为例说明XPM如何使用。

2.1 XPM模板

首先附上language temple提供的语法模板:


   // xpm_memory_sdpram: Simple Dual Port RAM
   // Xilinx Parameterized Macro, version 2019.2

   xpm_memory_sdpram #(
      .ADDR_WIDTH_A(6),               // DECIMAL
      .ADDR_WIDTH_B(6),               // DECIMAL
      .AUTO_SLEEP_TIME(0),            // DECIMAL
      .BYTE_WRITE_WIDTH_A(32),        // DECIMAL
      .CASCADE_HEIGHT(0),             // DECIMAL
      .CLOCKING_MODE("common_clock"), // String
      .ECC_MODE("no_ecc"),            // String
      .MEMORY_INIT_FILE("none"),      // String
      .MEMORY_INIT_PARAM("0"),        // String
      .MEMORY_OPTIMIZATION("true"),   // String
      .MEMORY_PRIMITIVE("auto"),      // String
      .MEMORY_SIZE(2048),             // DECIMAL
      .MESSAGE_CONTROL(0),            // DECIMAL
      .READ_DATA_WIDTH_B(32),         // DECIMAL
      .READ_LATENCY_B(2),             // DECIMAL
      .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(1),               // DECIMAL
      .WAKEUP_TIME("disable_sleep"),  // String
      .WRITE_DATA_WIDTH_A(32),        // DECIMAL
      .WRITE_MODE_B("no_change")      // String
   )
   xpm_memory_sdpram_inst (
      .dbiterrb(dbiterrb),         // 1-bit output: 
                                   // Status signal to indicate double bit error occurrence
                                   // on the data output of port B.

      .doutb(doutb),              // READ_DATA_WIDTH_B-bit output: 
                                  // Data output for port B read operations.
      .sbiterrb(sbiterrb),        // 1-bit output: 
                                  // Status signal to indicate single bit error occurrence
                                  // on the data output of port B.

      .addra(addra),             // ADDR_WIDTH_A-bit input: 
                                 // Address for port A write operations.
      .addrb(addrb),             // ADDR_WIDTH_B-bit input: 
                                 // Address for port B read operations.
      .clka(clka),               // 1-bit input: Clock signal for port A. 
                                 // Also clocks port B when
                                 // parameter CLOCKING_MODE is "common_clock".

      .clkb(clkb),               // 1-bit input: 
                                 // Clock signal for port B when parameter CLOCKING_MODE is
                                 // "independent_clock". 
                                 // Unused when parameter CLOCKING_MODE is
                                 // "common_clock".

      .dina(dina),              // WRITE_DATA_WIDTH_A-bit input: 
                                // Data input for port A write operations.
      .ena(ena),                // 1-bit input: Memory enable signal for port A. 
                                // Must be high on clock
                                // cycles when write operations are initiated. 
                                // Pipelined internally.

      .enb(enb),                // 1-bit input: Memory enable signal for port B.
                                // Must be high on clock cycles when read operations
                                // are initiated.  Pipelined internally.

      .injectdbiterra(injectdbiterra), // 1-bit input: Controls double bit error 
                                       // injection on input data when ECC enabled 
                                       // (Error injection capability is not available in
                                       // "decode_only" mode).

      .injectsbiterra(injectsbiterra), // 1-bit input: Controls single bit error 
                                       // injection on input data when ECC enabled 
                                       // (Error injection capability is not available in
                                       // "decode_only" mode).

      .regceb(regceb),                 // 1-bit input: Clock Enable for 
                                       // the last register stage on the output data path.

      .rstb(rstb),                     // 1-bit input: Reset signal for the final port B                       
                                       // output register stage.Synchronously resets output
                            // port doutb to the value specified by parameter ESET_VALUE_B.

      .sleep(sleep),       // 1-bit input: sleep signal to enable the dynamic power
                           // saving feature.
      .wea(wea)            // WRITE_DATA_WIDTH_A/BYTE_WRITE_WIDTH_A-bit input: write enable             
                           // vector for port A input data port dina. 
                           // 1 bit wide when word-wide writes are used.
                           // In byte-wide write configurations, each bit controls the
                           // writing one byte of dina to address addra. For example, to
                           // synchronously write only bits [15-8] of dina when  
                           // WRITE_DATA_WIDTH_A is 32, wea would be 4'b0010.

   );

   // End of xpm_memory_sdpram_inst instantiation
				
				

这个模板主要包括两个部分:参数列表(parameter list) 和 端口列表(port list)。

端口列表的大部分端口信号和我们传统调用IP所生成的端口信号差不多,重点是参数列表,每一个参数代表什么意义,弄懂了XPM的参数列表,我们才能正常使用这一XPM模板。

2.2 parameter list说明

首先来看一下在GUI 界面我们也能看得到的常见参数:

1:地址位宽:ADDR_WIDTH_A/B

      这个参数就是表示A/B端口的寻址地址的宽度,比如设置SDP_RAM的深度1024,则地址的取值范围至少是0~1023,那么地址的位宽须 ≥10;

     如果AB端口的数据位宽不一致,则AB端口的地址位宽也会不一致,这一点需要注意;

    地址位宽的计算建议是通过function函数输入深度直接计算,这样能避免出错。

function integer clogb2 (input integer depth);
    begin
        for(clogb2=0; depth>0; clogb2=clogb2+1) 
            depth = depth >> 1;                          
    end
endfunction

localparam  C_DPRAM_ADDR_WIDTH = clogb2(C_DPRAM_DEPTH - 1)  ;

2、数据位宽WRITE_DATA_WIDTH_A 和 READ_DATA_WIDTH_B  

  顾名思义这个就是A/B端口的数据位宽,当AB端口需要设置不同位宽时,需要给A/B分别设置不同的值;需要注意的是当ECC功能开启,对位宽的设置有限制,具体可以查阅UG953;

  BYTE_WRITE_WIDTH_A:必须是能被WRITE_DATA_WIDTH_A 整除,例如WRITE_DATA_WIDTH_A =32;BYTE_WRITE_WIDTH_A=8;那么写使能wea的位宽就会有4bit,可以通过使能wea的相应bit决定让哪一个byte生效。

3、RAM的大小 MEMORY_SIZE

     需要注意的是这个参数的单位是bits,可根据端口的位宽和深度计算;

    例如:我们需要调用一个2Kx32bits大小的RAM,则需要设置MEMORY_SIZE:65536。

4、读延时设置:READ_LATENCY_B

     下发读地址后,delay多少个clkb输出数据到doutb。例如设置Lantency = 2,其时序如下:

    XILINX-VIVADO IP参数化方法(XPM),FPGA设计优化,# 器件结构,fpga开发

 5、读优先 or 写优先 :WRITE_MODE_B

     有三种选项:"no _change", "read _first", "write _first";

6、时钟模式

   CLOCKING_MODE:"common_clock",   "independent_clock"                                                   设置AB端口的时钟是共用时钟还是独立时钟,如果选择“common_clock”,即使B端口接入了自己的时钟,综合工具也会默认使用clka 的时钟。

7、MEMORY类型:MEMORY _PRIMITIVE

     有"auto",  "block", "distributed", "ultra" 4种选项;

     这里需要注意的是:当使能了ECC 或者A/B侧非对称时,这个参数会被强制置为“auto”,想设置“block” 或 “ultra”都无法生效。这里所谓的A/B侧非对称,是指数据位宽和地址位宽不一致。

NOTE: There
may be a behavior mismatch if Block RAM or Ultra RAM specific features, like ECC or Asymmetry, are selected with MEMORY_PRIMITIVE set to "auto".

8、自动优化使能: MEMORY_OPTIMIZATION

“true” : 使能优化,综合工具会根据接入的信号位宽、地址位宽自动优化没有使用的存储单元;      “false”: 关闭优化;

9、初始化相关:

 USE_MEM_INIT : 当需要初始化时,需要将参数USE_MEM_INIT置“1”,否则初始化不会生效。

MEMORY_INIT_FILE :初始化文件、mem格式、ASCII编码、文件内容只包含十六进制数;传参时只用文件名,不用路径,如果需要使用文件初始化,则将mem文件随设计文件一起加入工程的文件列表。

Specify "none" (including quotes) for no memory  nitialization, or specify the name of a memory initialization file- Enter only the name of the file with .mem extension, including quotes but without path (e.g. "my_file.mem"). File format must be ASCII and consist of only hexadecimal values organized into the specified depth by narrowest data width generic value of the memory. See the Memory File (MEM) section for more information on the syntax. Initialization of memory happens through the file name specified only when parameter MEMORY_INIT_PARAM value is equal to "". | When using XPM_MEMORY in a
project, add the specified file to the Vivado project as a design source.

MEMORY_INIT _PARAM:参数初始化,是初始化的另外一种方式,相当于直接把初始化内容写在参数列表,比较笨,一般不这么用,仅限于RAM很小,或者只需要初始化前几个地址时可以考虑使用;

For example, if the narrowest data width is 8, and the depth of memory is 8 locations, then the parameter value should be passed as shown below.
parameter MEMORY_INIT_PARAM = "AB,CD,EF,1,2,34,56,78"
Where "AB" is the 0th location and "78" is the 7thlocation.

 其他诸如ECC、和sleep相关设置可以使用默认设置,也可以参考官方文档自己研究研究。

2.3 端口说明

 XILINX-VIVADO IP参数化方法(XPM),FPGA设计优化,# 器件结构,fpga开发

 XILINX-VIVADO IP参数化方法(XPM),FPGA设计优化,# 器件结构,fpga开发

除了sleep 和ECC相关的port ,基本都是常规的data、addr、clk 、rst 和en信号;

如果对于ECC(错误校验)和sleep(睡眠)有需要的童鞋可以参考UG953,我一般都不使能这两项。

三、XPM的封装

      首先说说,我们为什么要对它进行封装?

     从上面的模板我们可以看到整个XPM的例化代码非常冗长,而且里面很多的参数和端口在用户侧都不需要,如果直接用这个模板进行例化,会导致我们的代码可读性非常差;另一方面,如果涉及到平台切换,比如从6系切换到7系,或者切换到Ultrascale,甚至是切换到其他品牌的FPGA,各个系列/品牌的XPM模板可能是不一样的,如果我们不做封装,那么每一个调用XPM的地方我们都需要回去修改,如果我们将原厂的模板封装成自己的模板,然后引出要用的参数,我们只用修改几个种类的模板即可,可以极大提高移植的效率。

下面附上我自己的一个模板为例:

module xpm_sdpram_wrapper#
(
    parameter                         C_ADDR_WIDTH_A  = 'd8 ,  
    parameter                         C_DATA_WIDTH_A  = 'd8 ,  
    parameter                         C_ADDR_WIDTH_B  = 'd8 ,  
    parameter                         C_DATA_WIDTH_B  = 'd8 ,  
    parameter                         C_RD_LATENCY    = 'd1 
)
(
    I_clk_a  ,
    I_ena    ,
    I_addr_a ,
    I_data_a ,

    I_clk_b  ,
    I_rst_b  ,
    I_enb    ,
    I_addr_b ,
    O_data_b  

);
   localparam   C_DEPTH = 2**C_ADDR_WIDTH_A   ;
   localparam   C_SIZE  = C_DEPTH * C_DATA_WIDTH_A  ;

    input                             I_clk_a  ;
    input                             I_ena    ;
    input [C_ADDR_WIDTH_A-1:0]        I_addr_a ;
    input [C_DATA_WIDTH_A-1:0]        I_data_a ;

    input                             I_clk_b  ;
    input                             I_rst_b  ;
    input                             I_enb    ;
    input [C_ADDR_WIDTH_B-1:0]        I_addr_b ;
    output[C_DATA_WIDTH_B-1:0]        O_data_b ;


   xpm_memory_sdpram #(
      // A-port-parameter
      .RST_MODE_A             ("SYNC"                  ),    // "SYNC"  or  "ASYNC"      
      .ADDR_WIDTH_A           (C_ADDR_WIDTH_A          ),     
      .WRITE_DATA_WIDTH_A     (C_DATA_WIDTH_A          ),     
      .BYTE_WRITE_WIDTH_A     (C_DATA_WIDTH_A          ),  
      //B-PORT 
      .RST_MODE_B             ("SYNC"                  ),   // "SYNC"  or  "ASYNC"       
      .ADDR_WIDTH_B           (C_ADDR_WIDTH_B          ),                        
      .READ_DATA_WIDTH_B      (C_DATA_WIDTH_B          ),         
      .READ_LATENCY_B         (C_RD_LATENCY            ),             
      .READ_RESET_VALUE_B     ("0"                     ),                 

      // COMMON       
      .MEMORY_SIZE            (C_SIZE                  ), 
      .MESSAGE_CONTROL        (0                       ), 
      .SIM_ASSERT_CHK         (0                       ), 
      .CASCADE_HEIGHT         (0                       ),             
      .CLOCKING_MODE          ("common_clock"          ), 
      .ECC_MODE               ("no_ecc"                ),            
      .MEMORY_INIT_FILE       ("none"                  ),      
      .MEMORY_INIT_PARAM      ("0"                     ),        
      .MEMORY_OPTIMIZATION    ("true"                  ),   
      .MEMORY_PRIMITIVE       ("block"                 ),       
      .USE_EMBEDDED_CONSTRAINT(0                       ),
      .AUTO_SLEEP_TIME        (0                       ),           
      .USE_MEM_INIT           (1                       ),               
      .WAKEUP_TIME            ("disable_sleep"         ),  
      .WRITE_MODE_B           ("no_change"             )      
   )  U_gen_NHP     (
      // a-port-io 
      .clka                   (I_clk_a                 ), //
      .ena                    (I_ena                   ), //      
      .addra                  (I_addr_a                ), //
      .dina                   (I_data_a                ), //

      .wea                    (1'b1                    ),  //      
      //b-port-io
      .clkb                   (I_clk_b                 ), //
      .rstb                   (I_rst_b                 ), //
      .enb                    (I_enb                   ), //
      .addrb                  (I_addr_b                ), //
      .doutb                  (O_data_b                ), //

      .dbiterrb               (                        ), //
      .sbiterrb               (                        ), //      
      .injectdbiterra         (1'b0                    ), //
      .injectsbiterra         (1'b0                    ), //
      .regceb                 (1'b0                    ), //
      .sleep                  (1'b0                    ) //

   );

endmodule

参考文档:

 UG953(7series)

UG974(Ultrascale)文章来源地址https://www.toymoban.com/news/detail-694993.html

到了这里,关于XILINX-VIVADO IP参数化方法(XPM)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Xilinx FPGA开发环境vivado使用流程

    第一步:点击Add Sources按钮 第二步:选择add or create design sources按钮,即添加设计文件 第三步:选择create file 文件新建完成后: 此时可以定义I/O端口,我们选择自己在程序中编写。 第四步:在编辑器中编写verilog程序 XDC文件里主要是完成管脚的约束,时钟的约束,以及组的约

    2024年02月03日
    浏览(58)
  • Xilinx FPGA DDR3设计(三)DDR3 IP核详解及读写测试

    引言 :本文我们介绍下Xilinx DDR3 IP核的重要架构、IP核信号管脚定义、读写操作时序、IP核详细配置以及简单的读写测试。 7系列FPGA DDR接口解决方案如图1所示。 图1、7系列FPGA DDR3解决方案 1.1 用户FPGA逻辑(User FPGA Logic) 如图1中①所示,用户FPGA逻辑块是任何需要连接到外部

    2024年02月06日
    浏览(52)
  • Vivado | FPGA开发工具(Xilinx系列芯片)

    官网下载地址 最详细的Vivado安装教程 Vivado的安装以及使用_入门

    2024年02月12日
    浏览(59)
  • 【FPGA】 xilinx vivado中AXI4通信协议详解

    AXI是ARM 1996年提出的微控制器总线家族AMBA中的一部分。AXI的第一个版本出现在AMBA3.0,发布于2003年。当前的最新的版本发布于2010年。AXI 4总线和别的总线一样,都用来传输bits信息 (包含了数据或者地址) 。AXI4总线有三种类型,分别是AXI4、AXI4-Lite、AXI4-Stream AXI4:主要面向高性能

    2024年04月28日
    浏览(42)
  • 基于Xilinx vivado FFT ip进行信号频谱测量

    本文章使用Xilinx的fft ip完成了经过参数化的任意个信号的基频测量,完整代码以及代码解释在文章中给出。如有错误,希望指出。 ps:只使用了fft ip进行频率测量未测量幅度,为防止错误不对幅度测量进行讲解,且幅度测量因为未使用其中获得的幅度是未经处理的原始数据,

    2024年01月20日
    浏览(30)
  • Xilinx FPGA SPIx4 配置速度50M约束语句(Vivado开发环境)

    qspi_50m.xdc文件: 等同于图形化配置方式:

    2024年02月22日
    浏览(61)
  • Xilinx Vivado LDPC IP core,TSN IP core. 各种IP core

    1.Xilinx Vivado 官方 LDPC IP core; 2.Xilinx Vivado 官方 TSN IP core; 3.Xilinx Vivado 官方 Turbo码IP core; 4.各种其它Xilinx Vivado 官方 IP core。         LDPC码即低密度奇偶校验码(Low Density Parity Check Code,LDPC),它由Robert G.Gallager博士于1963年提出的一类具有稀疏校验矩阵的线性分组码,不仅有

    2024年02月14日
    浏览(35)
  • Xilinx FPGA未使用管脚上下拉状态配置(ISE和Vivado环境)

    ISE开发环境 ISE开发环境,可在如下Bit流文件生成选项中配置。 右键点击 Generate Programming File ,选择 Process Properties , 在弹出的窗口选择 Configuration Options-Unused Pin ,选择 Pull Down、Pull Up或者Float 。 可以看到,除了未使用管脚,一些系统管脚,比如JTAG,Program、Done管脚等等都可

    2024年02月06日
    浏览(47)
  • 关于 xilinx sdk软核elf文件与xilinx vivado bit文件合并的方法

    xilinx 软核elf文件与xilinx vivado bit文件合并的方法 一、背景 在版本的Vivado 配套的 软件工具是 SDK ,当vivado中使用软核时候,需要将软核生成的elf文件与vivado生成的bit文件合并成一个最终的BIT文件,然后再将此BIT文件下载到FPGA中,或者转化为MCS文件固化到Flash中,这样才不用每

    2024年02月08日
    浏览(53)
  • xilinx FPGA 板子vivado无法识别 Labtoolstcl 44-27] No hardware targets exist on the server [localhost:3121]

    1.我之前用的是miniB -USB 的线, 然后先要检查驱动问题,打开 设备管理器 查看,应该是 如果端口中没有就是在其他设备中,此时需要去 下载XCP的驱动 ,或者去搜索一下你的USB线的驱动,但是即使这个识别了vivado里面还是No hardware targets exist on the server [localhost:3121] 2.这个时候

    2024年02月03日
    浏览(38)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包