如何实例化XPM内存模块,以使write_mem_info正常工作?

时间:2019-01-25 09:13:19

标签: verilog system-verilog xilinx vivado

我正在尝试为包含HDL和Xilinx IP内核的硬件设计创建一个位文件。它包括一个软核处理器(Pulpino RI5CY内核),该处理器连接到2个独立的BlockRAM控制器。我试图使用XPM(Xilinx参数化宏)来指定处理器所连接的BlockRAM,以便我可以指定它们的内容,而不必不断重新合成我的设计。我按照UG898(从第173页起)中列出的步骤进行操作,但是当我尝试生成MMI文件时,我需要完成步骤18。我收到以下错误消息:

The XPM instance: <kuuga_ila_i/inst_bram/inst/xpm_memory_spram_inst/xpm_memory_base_inst> is part of IP: <kuuga_ila_i/inst_bram>. This XPM instance will be excluded from the .mmi because updatemem is prohibited from making changes to an XPM that is part of an IP.

我尝试了几种方法来缓解此问题,包括尝试手动写入MMI文件以及使用this AR中包含的write_mmi TCL脚本。但是他们俩都无法为我生成所需的文件。

我的直觉是问题出在UG898讨论的第14步中:“通过添加适当的实体和/或模块定义来完成HDL文件的定义”。我尝试在下面包含的代码中执行此操作,然后通过按照UG898再次将该代码作为RTL模块实例化,将其添加到现有的模块设计中。但是由于说明的含糊性以及我无法在线找到完成此操作的人的示例,所以找不到正确的示例进行学习和理解。我可以从某种方式上看到我可能需要做的事,即以另一种方式实例化XPM,但我不知道在将所有内容都连接到现有模块设计中的情况下将如何实现。

用于XPM实例化的Vererilog代码(通常是Xilinx模板的副本,并在其周围添加了模块代码)

module bram
#(
    READ_DATA_WIDTH_A = 32,
    ADDR_WIDTH_A = 32,
    WRITE_DATA_WIDTH_A = 32
)
(
    output  [READ_DATA_WIDTH_A-1:0]     douta,
    input   [ADDR_WIDTH_A-1:0]          addra,
    input                               clk_a,
    input   [WRITE_DATA_WIDTH_A-1:0]    dina,
    input                               ena,
    input                               regcea,
    input                               rst_a,
    input   [3:0]                       wea
);
    xpm_memory_spram #(
      .ADDR_WIDTH_A(ADDR_WIDTH_A),              // DECIMAL
      .AUTO_SLEEP_TIME(0),           // DECIMAL
      .BYTE_WRITE_WIDTH_A(32),       // DECIMAL
      .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(65536),            // DECIMAL
      .MESSAGE_CONTROL(0),           // DECIMAL
      .READ_DATA_WIDTH_A(READ_DATA_WIDTH_A),        // DECIMAL
      .READ_LATENCY_A(2),            // DECIMAL
      .READ_RESET_VALUE_A("0"),      // String
      .USE_MEM_INIT(1),              // DECIMAL
      .WAKEUP_TIME("disable_sleep"), // String
      .WRITE_DATA_WIDTH_A(WRITE_DATA_WIDTH_A),       // DECIMAL
      .WRITE_MODE_A("read_first")    // String
   )
   xpm_memory_spram_inst (

  .douta(douta),                   // READ_DATA_WIDTH_A-bit output: Data output for port A read operations.

  .addra(addra),                   // ADDR_WIDTH_A-bit input: Address for port A write and read operations.
  .clka(clk_a),                     // 1-bit input: Clock signal for port A.
  .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 read or write operations are initiated. Pipelined
                                   // internally.

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

  .rsta(rst_a),                     // 1-bit input: Reset signal for the final port A output register stage.
                                   // Synchronously resets output port douta to the value specified by
                                   // parameter READ_RESET_VALUE_A.

  .wea(wea)                        // WRITE_DATA_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_spram_inst instantiation

endmodule               

是按照步骤14的问题处理还是要实例化尚未发现的XPM?我会以错误的方式进行操作,实际上应该尝试手动生成MMI文件吗?任何帮助将不胜感激。

TL:DR我已经尝试过使用XPM,以便在制作完位文件之后可以设置BlockRAM内容,但是我无法生成MMI文件来这样做,并且它与如何工作有一定关系(我认为)我已经实例化了XPM。

1 个答案:

答案 0 :(得分:0)

因此,我设法解决了眼前的问题,如果您在模块设计的顶级包装文件中实例化XPM实例,并从模块设计中添加外部端口,以将XPM数据通过管道传输到AXI BRAM控制器,则一切按以下步骤进行:可以预期,write_mem_info和updatemem都可以按设计工作。

我不会将问题标记为完整,因为我仍然想知道如果您完全遵循UG898,是否有一种可行的解决方案,但是至少我现在有一种解决方法。