URAM使用说明:xpm_memory_tdpram 原语调用 uram

1,xpm_memory_tdpram 原语调用 uram,及参数说明

             此原语使用类似于真正的双端口RAM。可以通过端口A和端口B同时读取和写入内存。

                    xpm_memory_tdpram基本结构如下图所示

                                        

        为了便于使用,我将该原语实例化,以下为我使用该原语调用uram的实例。该实例将常用接口引出,使用类似于普通ram。

module uram
#(
    parameter   p_wdith_addr_a              = 19                                ,
    parameter   p_wdith_wdata               = 72                                ,
    parameter   p_wdith_addr_b              = 19                                ,
    parameter   p_wdith_rdata               = 72                                ,
    parameter   p_memory_size               = 524287* 72                        ,
    parameter   p_read_delay                = 13                                ,
    parameter   p_byte_with                 = 8                                 ,
    parameter   p_wea_with                  = 27                                ,
    parameter   p_web_with                  = 1
)
(
    input                                                       clk             ,
    input                                                       rst_n           ,
    //port a
    input       [ p_wea_with-1     : 0 ]                        wea             ,
    input       [ p_wdith_wdata-1  : 0 ]                        dina            ,

    input                                                       ena             ,
    input       [ p_wdith_addr_a-1 : 0 ]                        addra           ,
    output      [ p_wdith_rdata-1  : 0 ]                        douta           ,
    // port b
    input       [ p_web_with-1     : 0 ]                        web             ,
    input       [ p_wdith_addr_b-1 : 0 ]                        addrb           ,
    input       [ p_wdith_wdata-1  : 0 ]                        dinb            ,

    input                                                       enb             ,
    output      [ p_wdith_rdata-1 : 0  ]                        doutb



 );





// xpm_memory_tdpram : In order to incorporate this function into the design,
//      Verilog      : the following instance declaration needs to be placed
//     instance      : in the body of the design code.  The instance name
//    declaration    : (xpm_memory_tdpram_inst) and/or the port declarations within the
//       code        : parenthesis may be changed to properly reference and
//                   : connect this function to the design.  All inputs
//                   : and outputs must be connected.

//  Please reference the appropriate libraries guide for additional information on the XPM modules.

//  <-----Cut code below this line---->

   // xpm_memory_tdpram: True Dual Port RAM
   // Xilinx Parameterized Macro, version 2019.1

   xpm_memory_tdpram #(
      .ADDR_WIDTH_A             (p_wdith_addr_a ),    // DECIMAL
      .ADDR_WIDTH_B             (p_wdith_addr_b ),    // DECIMAL
      .AUTO_SLEEP_TIME          (0              ),    // DECIMAL
      .BYTE_WRITE_WIDTH_A       (p_byte_with    ),    // DECIMAL
      .BYTE_WRITE_WIDTH_B       (p_wdith_rdata  ),    // 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         ("ultra"        ),    // String
      .MEMORY_SIZE              (p_memory_size  ),    // DECIMAL
      .MESSAGE_CONTROL          (0              ),    // DECIMAL
      .READ_DATA_WIDTH_A        (p_wdith_rdata  ),    // DECIMAL
      .READ_DATA_WIDTH_B        (p_wdith_rdata  ),    // DECIMAL
      .READ_LATENCY_A           (p_read_delay   ),    // DECIMAL
      .READ_LATENCY_B           (p_read_delay   ),    // 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             (1              ),    // DECIMAL
      .WAKEUP_TIME              ("disable_sleep"),    // String
      .WRITE_DATA_WIDTH_A       (p_wdith_wdata  ),    // DECIMAL
      .WRITE_DATA_WIDTH_B       (p_wdith_wdata  ),    // DECIMAL
      .WRITE_MODE_A             ("no_change"    ),    // String
      .WRITE_MODE_B             ("no_change"    )     // String
   )
   xpm_memory_tdpram_inst (
      .dbiterra             (                   ), // 1-bit output: Status signal to indicate double bit error occurrence
                                                   // on the data output of port A.

      .dbiterrb             (                   ), // 1-bit output: Status signal to indicate double bit error occurrence
                                                   // on the data output of port A.

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

      .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 and read operations.
      .addrb                (addrb              ), // ADDR_WIDTH_B-bit input: Address for port B write and read operations.
      .clka                 (clk                ), // 1-bit input: Clock signal for port A. Also clocks port B when
                                                   // parameter CLOCKING_MODE is "common_clock".

      .clkb                 (clk                ), // 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.
      .dinb                 (dinb               ), // WRITE_DATA_WIDTH_B-bit input: Data input for port B 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.
      .enb                  (enb                ),  // 1-bit input: Memory enable signal for port B. Must be high on clock
                                                   // cycles when read or write 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).

      .injectdbiterrb       (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).

      .injectsbiterrb       (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).

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

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

      .rsta                 (~rst_n             ),  // 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.

      .rstb                 (~rst_n             ), // 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                  (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.

      .web                  (web                )   // WRITE_DATA_WIDTH_B-bit input: Write enable vector for port B input
                                                    // data port dinb. 1 bit wide when word-wide writes are used. In
                                                    // byte-wide write configurations, each bit controls the writing one
                                                    // byte of dinb to address addrb. For example, to synchronously write
                                                    // only bits [15-8] of dinb when WRITE_DATA_WIDTH_B is 32, web would be
                                                    // 4'b0010.

   );

   关于该原语的部分参数说明

     为方便使用我将关于uram的相关参数已引出,由于a端口b端口相互独立 ,这里只介绍a端口相关参数(b端口同理),

 ADDR_WIDTH_A: 地址(addra)位宽,范围在1~20之间

READ_DATA_WIDTH_A :读数据(douta)位宽,必须为72的整数倍

WRITE_DATA_WIDTH_A:写数据(dina)位宽等于 READ_DATA_WIDTH_A 

MEMORY_SIZE :调用ram的大小 ,等于(2^ ADDR_WIDTH_A)* READ_DATA_WIDTH_A    

BYTE_WRITE_WIDTH_A  :此选项将决定 wea的位宽,根据实际使用建议设置为8或者等     于 READ_DATA_WIDTH_A   

      说明 :wea 位宽等于  READ_DATA_WIDTH_A  / BYTE_WRITE_WIDTH_A 

 wea的功能为控制dina具体哪几位的写入 ,

以  READ_DATA_WIDTH_A =72 ,BYTE_WRITE_WIDTH_A=8为例,此时wea的位宽为9位

当wea== 9‘b000_000_001时只有dina[7:0]能被写入,

当wea== 9‘b000_000_111 时只有dina[23:0]能被写入,

当wea== 9‘b111_111_111时 dina[71:0]能被写入。

(注 :当ena 和 wea作用时写入才有效)

    READ_LATENCY_A: 范围0~100,为输出延时多少个时钟周期。当读操作有效时经过多少个时钟周期,数据会被读出。(具体设置多少,在注意事项中会进行说明)

  下图时序为 READ_LATENCY_A等于10,wea位宽为1的 一个简单的读写时序

 2,调用uram时的注意事项及其它说明                  

 1,关于  READ_LATENCY_A 的具体设置 ,官方的推荐是

     当调用的uram资源大于2MB时,输出延时必须要大于 8个时钟周期,因为Vivado合成器使用的默认级联高度为8。但在实际使用中根据调用的uram资源越多延迟就应该越大,否则在综合过程中会报错 ,而不仅仅是等于9个或者10个时钟周期 。建议以9为基数 每多调用2MB的uram资源延时就要多一个时钟周期 。

2,关于BYTE_WRITE_WIDTH_A 能否设置为除了 8和 READ_DATA_WIDTH_A   以外的其它值

理论上是  可以设置为 1 到READ_DATA_WIDTH_A的任意值经过笔者自己测试,仿真时设置任意值都可以 ,但在实际工程中使用时 ,只有设置1和 READ_DATA_WIDTH_A 时才能综合成功。具体原因未知。

3,设计时要尽量避免A,B端口同时对一个地址进行写操作。

4,uram不支持复位清零 ,要清除数据需要对每个地址进行写0 操作。

5,当调用的uram的资源过多,可以尝试将一个原语拆分为多个原语来控制,减小扇出,从而优化时序。

6,其它参数相关说明如果想具体了解,可以浏览xilinx文档ug974 182页。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值