URAM:提供更多的内存

什么是URAM

关于URAM的详细信息,可以去xilinx官网搜索文件WP477。文档中都是中文,非常好容易理解。URAM与BRAM以及DRAM相比,资源多了许多。当芯片中的BRAM资源不够使用的时候,可以考虑URAM。

URAM:提供更多的内存_第1张图片

如何使用URAM

URAM使用起来也比较方便,强烈推荐使用XPM原语的方式。直接选用如下的模板,选择简单双端口RAM。然后复制旁边的模板到工程中,修改模板中的参数,就可以使用URAM了。并且这个模板不仅仅可以使用URAM,也还可以推导出BRAM,DRAM等。

URAM:提供更多的内存_第2张图片

关于模板中的参数,详细的介绍一下。

xpm_memory_sdpram #(
  .ADDR_WIDTH_A(18),              // DECIMAL    端口A的地址,写入数据的地址
  .ADDR_WIDTH_B(18),              // DECIMAL    B的地址,读出数据的地址
  .AUTO_SLEEP_TIME(0),            // DECIMAL    不使能自动休眠特性
  .BYTE_WRITE_WIDTH_A(72),        // DECIMAL    写端口是多少bit,和WRITE_DATA_WIDTH_A对应
  .CASCADE_HEIGHT(0),             // DECIMAL    让VIVADO自己选择   
  .CLOCKING_MODE("common_clock"), // String     A\B共用一个时钟
  .ECC_MODE("no_ecc"),            // String     不使用ECC
  .MEMORY_INIT_FILE("none"),      // String     不进行内存初始化
  .MEMORY_INIT_PARAM("0"),        // String     不进行内存初始化
  .MEMORY_OPTIMIZATION("true"),   // String     优化内存
  .MEMORY_PRIMITIVE("ultra"),     // String     使用URAM,可以选择其他综合方式。
  .MEMORY_SIZE(18874368),         // DECIMAL    2^ADDR_WIDTH_A * BYTE_WRITE_WIDTH_A
  .MESSAGE_CONTROL(0),            // DECIMAL    禁用动态报告
  .READ_DATA_WIDTH_B(72),         // 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(72),        // DECIMAL
  .WRITE_MODE_B("read_first")      // String
   )
   xpm_memory_sdpram_inst1 (
      .dbiterrb(),             // 1-bit output: Status signal to indicate double bit error occurrence
                                       // on the data output of port B.   指示B的错误状态

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

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

      .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(),                     // WRITE_DATA_WIDTH_A-bit input: Data input for port A write operations.
      .ena(1'b1),                       // 1-bit input: Memory enable signal for port A. Must be high on clock
                                       // cycles when write operations are initiated. Pipelined internally.

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

      .injectdbiterra(1'b0), // 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(1'b0), // 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(1'b1),                 // 1-bit input: Clock Enable for the last register stage on the output
                                       // data path.

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

      .sleep(1'b0),                   // 1-bit input: sleep signal to enable the dynamic power saving feature.
      .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.

   );

这些parameter参数可以在模板中找到对应的解释,很容易理解。以上配置方式,把所有的URAM资源都使用了。因为我使用的是ZU5EV,所以URAM资源就只有18Mb。计算公式是2^ADDR_WIDTH_A*BYTE_WRITE_WIDTH_A/1024/1024=2^18*72/1024/1024=18Mb。

最后,可以仿真,看看能不能写入以及读取数据。这里我就不仿真了。

编译完之后可以查看资源利用情况,来确认URAM是否使用上。

URAM:提供更多的内存_第3张图片

你可能感兴趣的:(FPGA知识分享,fpga开发)