【FPGA】单端口RAM的设计(同步读、同步写)

举报
李锐博恩 发表于 2021/07/15 02:14:59 2021/07/15
【摘要】 Single Port RAM  Synchronous Read/Write 这篇博文介绍单端口同步读写RAM,在之前的博文中,也介绍过类似的设计:【Verilog HDL 训练】第 13 天(存储器、SRAM) 在这篇博文中,与知识星球里的伙伴们交流,真是让我受益匪浅呀。 单端口同步读写RAM的设计没什么可描述的,代码不麻烦,看起来最为清晰: 输入输出...

Single Port RAM  Synchronous Read/Write

这篇博文介绍单端口同步读写RAM,在之前的博文中,也介绍过类似的设计:【Verilog HDL 训练】第 13 天(存储器、SRAM)

在这篇博文中,与知识星球里的伙伴们交流,真是让我受益匪浅呀。


单端口同步读写RAM的设计没什么可描述的,代码不麻烦,看起来最为清晰:

输入输出:

//--------------Input Ports----------------------- 
input                  clk         ;
input [ADDR_WIDTH-1:0] address     ;
input                  cs          ;
input                  we          ;
input                  oe          ; 

//--------------Inout Ports----------------------- 
inout [DATA_WIDTH-1:0]  data       ;

对RAM的读写相对于时钟clk同步,当输入条件(cs、we、oe)满足的情况下,对inout端口 data同步读写。


给出Verilog HDL描述文件:


  
  1. `timescale 1ns / 1ps
  2. //
  3. // Engineer: Jiashan Lee
  4. // Create Date: 2019/05/21 15:46:55
  5. // Design Name: ram_sp_sr_sw
  6. // Module Name: ram_sp_sr_sw
  7. // Function : Synchronous read write RAM
  8. // Revision 0.01 - File Created
  9. // Additional Comments:
  10. //
  11. module ram_sp_sr_sw (
  12. clk , // Clock Input
  13. address , // Address Input
  14. data , // Data bi-directional
  15. cs , // Chip Select
  16. we , // Write Enable/Read Enable
  17. oe // Output Enable
  18. );
  19. parameter DATA_WIDTH = 8 ;
  20. parameter ADDR_WIDTH = 8 ;
  21. parameter RAM_DEPTH = 1 << ADDR_WIDTH;
  22. //--------------Input Ports-----------------------
  23. input clk ;
  24. input [ADDR_WIDTH-1:0] address ;
  25. input cs ;
  26. input we ;
  27. input oe ;
  28. //--------------Inout Ports-----------------------
  29. inout [DATA_WIDTH-1:0] data ;
  30. //--------------Internal variables----------------
  31. reg [DATA_WIDTH-1:0] data_out ;
  32. reg [DATA_WIDTH-1:0] mem [0:RAM_DEPTH-1];
  33. reg oe_r;
  34. //initialization
  35. // synopsys_translate_off
  36. integer i;
  37. initial begin
  38. for(i=0; i < RAM_DEPTH; i = i + 1) begin
  39. mem[i] = 8'h00;
  40. end
  41. end
  42. // synopsys_translate_on
  43. //--------------Code Starts Here------------------
  44. // Tri-State Buffer control
  45. // output : When we = 0, oe = 1, cs = 1
  46. assign data = (cs && oe && !we) ? data_out : 8'bz;
  47. // Memory Write Block
  48. // Write Operation : When we = 1, cs = 1
  49. always @ (posedge clk)
  50. begin : MEM_WRITE
  51. if ( cs && we ) begin
  52. mem[address] <= data;
  53. end
  54. end
  55. // Memory Read Block
  56. // Read Operation : When we = 0, oe = 1, cs = 1
  57. always @ (posedge clk)
  58. begin : MEM_READ
  59. if (cs && !we && oe) begin
  60. data_out <= mem[address];
  61. /* oe_r <= 1;
  62. end else begin
  63. oe_r <= 0; */
  64. end
  65. end
  66. endmodule // End of Module ram_sp_sr_sw

且对这个RAM设计进行功能仿真,验证功能是否正确:

测试代码:


  
  1. `timescale 1ns / 1ps
  2. //
  3. // Create Date: 2019/05/21 16:00:12
  4. // Design Name:
  5. // Module Name: ram_sp_sr_sw_tb
  6. //
  7. module ram_sp_sr_sw_tb(
  8. );
  9. reg clk; // Clock Input
  10. reg [7 : 0] address; // address Input
  11. wire [7 : 0] data; // Data bi-directional
  12. reg cs; // Chip Select
  13. reg we; // Write Enable/Read Enable
  14. reg oe; // Output Enable
  15. reg [7 : 0] data_in;
  16. assign data = (cs && we && !oe) ? data_in : 8'dz;
  17. integer i;
  18. initial begin
  19. clk = 0;
  20. forever
  21. #2 clk = ~clk;
  22. end
  23. initial begin
  24. cs = 1'b0;
  25. we = 1'b0;
  26. oe = 1'b0;
  27. address = 8'd0;
  28. data_in = 8'h00;
  29. #20
  30. @(negedge clk) begin//read
  31. cs = 1'b1;
  32. oe = 1'b1;
  33. end
  34. for (i = 0; i < 256; i = i + 1) begin
  35. @(negedge clk)
  36. address = i;
  37. end
  38. @(negedge clk) begin//write
  39. we = 1'b1;
  40. oe = 1'b0;
  41. end
  42. for (i = 0; i < 256; i = i + 1) begin
  43. @(negedge clk) begin
  44. address = i;
  45. //此处如何给输入数据?
  46. data_in = data_in + 1;
  47. end
  48. end
  49. @(negedge clk) begin//read
  50. we = 1'b0;
  51. oe = 1'b1;
  52. end
  53. for (i = 0; i < 256; i = i + 1) begin
  54. @(negedge clk)
  55. address = i;
  56. end
  57. @(negedge clk)
  58. cs = 1'b0;
  59. //#100 $finish;
  60. #100 $stop;
  61. end
  62. ram_sp_sr_sw u_ram(
  63. .clk(clk) , // Clock Input
  64. .address(address) , // address Input
  65. .data(data) , // Data bi-directional
  66. .cs(cs) , // Chip Select
  67. .we(we) , // Write Enable/Read Enable
  68. .oe(oe) // Output Enable
  69. );
  70. endmodule

 

由于内存初始化为0,所以刚开始读出来的数据肯定为0:

读完256个初识数据后,开始对此RAM写入数据(地址0出写1,地址1出写2,类推,最后在地址255处写0):

写完数据之后,我们又开始读数据,看看写入的数据是否正确:

可见,在地址0处读出的数据为1,地址1处读出数据为2,类推,最后再地址255处读出数据为0.

读出数据与写入数据一致,我们的设计没有问题。

最后给出RTL原理图:


参考链接:

Single Port RAM Synchronous Read/Write

【Verilog HDL 训练】第 13 天(存储器、SRAM)

 

 

 

文章来源: reborn.blog.csdn.net,作者:李锐博恩,版权归原作者所有,如需转载,请联系作者。

原文链接:reborn.blog.csdn.net/article/details/90639422

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。