Как создать экземпляры модулей памяти XPM, чтобы write_mem_info работал правильно?

Я пытаюсь создать битовый файл для дизайна оборудования, который включает IP-ядра HDL и Xilinx. Он включает в себя программный процессор (Pulpino RI5CY Core), подключенный к 2 отдельным контроллерам BlockRAM. Я пытаюсь использовать XPM (параметризованные макросы Xilinx) для указания блоков RAM, к которым подключен процессор, чтобы я мог указывать их содержимое без постоянного повторного синтеза моего дизайна. Я выполнил шаги, изложенные в 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 и использование сценария write_mmi TCL, который включен в этот AR. Но им обоим не удалось создать мне нужный файл.

Моя интуиция подсказывает, что проблема в шаге 14, где UG898 говорит о: «Завершите определение файла HDL, добавив соответствующий объект и / или определение модуля». Я попытался сделать это в приведенном ниже коде, а затем добавил его в свой существующий дизайн блока, снова создав экземпляр этого кода как RTL-модуля в соответствии с UG898. Но из-за двусмысленности инструкций и моей неспособности найти в Интернете пример того, кто сделал это, я не могу найти правильный пример для изучения и понимания. Я в некоторой степени понимаю, что мне может понадобиться сделать с точки зрения создания экземпляра XPM другим способом, но я не знаю, как это было бы возможно, при этом все еще соединяя все в моем существующем дизайне блоков.

Код Verilog для создания экземпляра XPM (в основном копия шаблона 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.


person Jonathan Rainer    schedule 25.01.2019    source источник


Ответы (1)


Итак, мне удалось решить мою непосредственную проблему: если вы создадите экземпляры XPM в файле оболочки верхнего уровня для блочного дизайна и добавите внешние порты из блочного дизайна для передачи данных XPM в контроллер AXI BRAM, все будет происходить так, как ожидалось. и как write_mem_info, так и updatemem работают, как задумано.

Я пока не буду отмечать вопрос как завершенный, потому что мне все еще хотелось бы знать, есть ли решение, которое работает, если вы точно будете следовать UG898, но, по крайней мере, у меня есть обходной путь.

person Jonathan Rainer    schedule 28.01.2019