当前位置:   article > 正文

Xilink 简单双口ram ip的读写仿真_xilinx 双口ram

xilinx 双口ram

        简单双口RAM有两个端口Port A和port B,其中Port A用于写数据,Port B用于读数据,读写接口可以独立时钟工作。这一点和真双口RAM是有区别的,真双口RAM的A B两个Port都可以进行读写操作。        

         RAM是FPGA中重要的数据结构,可用于数据的缓存和跨时钟域信号处理。本文就xilink 的简单双口RAM 进行读写测试。

         本文对简单双口RAM做如下仿真:先对Port A进行连续写操作128次,每次数据和地址加1,结束后开始从Port B口读对应128个地址的数据,读写时钟独立,对比读写数据是否一致。

仿真结果如下:

数据写入仿真

数据读出仿真,数据在地址变化后延迟一个时钟输出。

ram ip的设置如下

注意不要勾选 Primitives Output Regster,不然Port B数据会延迟两个周期。

简单双口RAM的接口定义如下

直接上代码 dual_ram_top.v

  1. `timescale 1ns / 1ps
  2. //
  3. // Company:
  4. // Engineer:
  5. //
  6. // Create Date: 2024/03/22 20:18:12
  7. // Design Name:
  8. // Module Name: dual_ram_top
  9. // Project Name:
  10. // Target Devices:
  11. // Tool Versions:
  12. // Description:
  13. //
  14. // Dependencies:
  15. //
  16. // Revision:
  17. // Revision 0.01 - File Created
  18. // Additional Comments:
  19. //
  20. //
  21. module dual_ram_top(
  22. input clka,
  23. input clkb,
  24. input rst_n,
  25. output [7:0] doutb
  26. );
  27. reg [7:0]dina;
  28. reg [12:0] addra;
  29. reg ena;
  30. reg wea;
  31. reg [3:0] wr_state;
  32. always@(posedge clka or negedge rst_n) begin
  33. if(!rst_n) begin
  34. wr_state <= 4'd0;
  35. ena <= 1'b0;
  36. wea <= 1'b0;
  37. dina <= 8'd0;
  38. addra <= 13'd0;
  39. end
  40. else begin
  41. case(wr_state)
  42. 4'd0:begin
  43. wr_state <= 4'd1;
  44. wea <= 1'b1; // 写使能
  45. end
  46. 4'd1:begin
  47. wr_state <= 4'd2;
  48. addra <= 13'd0;
  49. dina <= 8'd0;
  50. ena <= 1'b1;
  51. end
  52. 4'd2:begin
  53. if(addra == 13'd127) begin
  54. wr_state <= 4'd3;
  55. ena <= 1'b0;
  56. addra <= 13'd0;
  57. dina <= 8'd0;
  58. end
  59. else begin
  60. wr_state <= wr_state;
  61. addra <= addra + 13'd1;
  62. dina <= dina + 8'd1;
  63. ena <= 1'b1;
  64. end
  65. end
  66. 4'd3:begin // write end
  67. wr_state <= 4'd4;
  68. wea <= 1'b0; // 读使能
  69. end
  70. 4'd4:begin
  71. wr_state <= wr_state;
  72. end
  73. endcase
  74. end
  75. end
  76. wire rd_start;
  77. assign rd_start =(wr_state==4'd4)?1:0;
  78. reg [12:0] addrb;
  79. reg enb;
  80. reg [3:0] rd_state;
  81. always@(posedge clkb or negedge rst_n) begin
  82. if(!rst_n) begin
  83. rd_state <= 4'd0;
  84. enb <= 1'b0;
  85. addrb <= 13'd0;
  86. end
  87. else begin
  88. case(rd_state)
  89. 4'd0:begin
  90. if(rd_start) begin
  91. rd_state <= 4'd1;
  92. enb <= 1'd1;
  93. addrb <= 13'd0;
  94. end
  95. else begin
  96. rd_state <= rd_state;
  97. enb <= 1'd0;
  98. addrb <= 13'd0;
  99. end
  100. end
  101. 4'd1:begin
  102. if(addrb == 13'd127) begin
  103. rd_state <= 4'd2;
  104. enb <= 1'd0;
  105. addrb <= 13'd0;
  106. end
  107. else begin
  108. rd_state <= rd_state;
  109. enb <= 1'd1;
  110. addrb <= addrb +13'd1;
  111. end
  112. end
  113. 4'd2:begin
  114. rd_state <= rd_state;
  115. enb <= 1'd0;
  116. addrb <= 13'd0;
  117. end
  118. endcase
  119. end
  120. end
  121. blk_mem_gen_0 blk_mem_gen_uut0 (
  122. .clka(clka), // input wire clka
  123. .ena(ena), // input wire ena
  124. .wea(wea), // input wire [0 : 0] wea
  125. .addra(addra), // input wire [12 : 0] addra
  126. .dina(dina), // input wire [7 : 0] dina
  127. .clkb(clkb), // input wire clkb
  128. .enb(enb), // input wire enb
  129. .addrb(addrb), // input wire [12 : 0] addrb
  130. .doutb(doutb) // output wire [7 : 0] doutb
  131. );
  132. endmodule

仿真测试代码ram_wr_top.v

  1. `timescale 1ns / 1ps
  2. //
  3. // Company:
  4. // Engineer:
  5. //
  6. // Create Date: 2024/03/22 22:27:59
  7. // Design Name:
  8. // Module Name: ram_wr_top
  9. // Project Name:
  10. // Target Devices:
  11. // Tool Versions:
  12. // Description:
  13. //
  14. // Dependencies:
  15. //
  16. // Revision:
  17. // Revision 0.01 - File Created
  18. // Additional Comments:
  19. //
  20. //
  21. module ram_wr_top(
  22. );
  23. reg clka;
  24. reg clkb;
  25. reg rst_n;
  26. wire [7:0]doutb;
  27. localparam clk_prioda = 50;
  28. localparam clk_priodb = 20;
  29. initial begin
  30. clka =1'b0;
  31. clkb = 1'b0;
  32. rst_n = 1'b0;
  33. #(100)
  34. rst_n = ~rst_n;
  35. end
  36. always#(clk_prioda/2) clka = ~clka;
  37. always#(clk_priodb/2) clkb = ~clkb;
  38. dual_ram_top dual_ram_top_uut0(
  39. .clka(clka),
  40. .clkb(clkb),
  41. .rst_n(rst_n),
  42. .doutb(doutb)
  43. );
  44. endmodule

通过连续读写对比 验证了IP读写的一致性。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/586010
推荐阅读
相关标签
  

闽ICP备14008679号