当前位置:   article > 正文

FPGA-SRAM读写测试_fpga sram读写

fpga sram读写

之前一直没太搞懂这个SRAM 是用来做什么的,现在做完了vga的觉得这个SRAM的作用很大,说白了这就是个储存器,而在我vga的字符的读取显示中,难度最大的也是在存储器上,之前有人建议我在做的时候改用ram可以实现字符的动态显示而不是局限于自己独自开辟的显示区域,下面我就先从SRAM入手,好好的介绍下这几个存储器(最近更ROM  RAM  SRAM )

在有数据传输的地方就会有存储器

SRAM(static RAM):异步传输易失存储器

优点:读写传输迅速,控制时序不复杂(这里我用的特权的板子就直接把他们写的东西拿来用了)

找来任何一颗SRAM芯片的datasheet,会发现它们的时序操作大同小异,在这里总结一些它们共性的东西,也提一些用Verilog简单的快速操作SRAM的技巧。SRAM内部的结构如图所示,

1、要访问实际的Momory区域,FPGA必须送地址(A0-A14)和控制信号(CE  \OE  \WE  ),

2、SRAM内部有与此对应的地址译码(decoder)

3、控制处理电路(control circuit)。

这样,数据总线(I/O0-I/O7)上的数据就可以相应的读或写了。

 

这里就以本实验使用的IS62LV256-45U为例进行说明。其管脚定义如表所示。

序号

管脚

方向

描述

1

A0-A14

Input

地址总线。

2

CEn

Input

芯片使能输入,低有效。

3

OEn

Input

输出使能输入,低有效。

4

WEn

Input

写使能输入,低有效。

5

I/O0-I/O7

Inout

数据输入/输出总线。

6

VCC

Input

电源。

7

GND

Input

数字地。

本设计的硬件原理图如图所示。

 

图6.59 SRAM接口

对于SRAM的读操作时序,其波形如图所示。

 

对于SRAM的写操作时序,其波形如图所示。

 

 

 

代码如下:


top.v:

  1. module top(ext_clk_25m,ext_rst_n,led,
  2. sram_cs_n,sram_we_n,sram_oe_n,
  3. sram_data,sram_addr
  4. );
  5. input ext_clk_25m;
  6. input ext_rst_n;
  7. output led;
  8. output sram_cs_n;
  9. output sram_we_n;
  10. output sram_oe_n;
  11. output [14:0] sram_addr;
  12. inout [7:0] sram_data;
  13. wire clk_12m5;
  14. wire clk_25m;
  15. wire clk_50m;
  16. wire clk_65m;
  17. wire clk_108m;
  18. wire clk_130m;
  19. wire sys_rst_n;
  20. pll_controller uut_pll_controller
  21. (// Clock in ports
  22. .CLK_IN1(ext_clk_25m), // IN
  23. // Clock out ports
  24. .CLK_OUT1(clk_12m5), // OUT
  25. .CLK_OUT2(clk_25m), // OUT
  26. .CLK_OUT3(clk_50m), // OUT
  27. .CLK_OUT4(clk_65m), // OUT
  28. .CLK_OUT5(clk_108m), // OUT
  29. .CLK_OUT6(clk_130m), // OUT
  30. // Status and control signals
  31. .RESET(~ext_rst_n),// IN
  32. .LOCKED(sys_rst_n)
  33. );
  34. //定时写sram测试模块
  35. wire sramwr_req;
  36. wire sramrd_req;
  37. wire [7:0] sramwr_data;
  38. wire [7:0] sramrd_data;
  39. wire [14:0] sramwr_addr;
  40. wire [14:0] sramrd_addr;
  41. test_timing uut_test_timing(
  42. .clk(clk_50m),
  43. .rst_n(sys_rst_n),
  44. .led(led),
  45. .sramwr_req(sramwr_req),
  46. .sramrd_req(sramrd_req),
  47. .sramwr_data(sramwr_data),
  48. .sramrd_data(sramrd_data),
  49. .sramwr_addr(sramwr_addr),
  50. .sramrd_addr(sramrd_addr)
  51. );
  52. //sram基本读写模块
  53. sram_controller uut_sram_controller(
  54. .clk(clk_50m),
  55. .rst_n(sys_rst_n),
  56. .sramwr_req(sramwr_req),
  57. .sramrd_req(sramrd_req),
  58. .sramwr_data(sramwr_data),
  59. .sramrd_data(sramrd_data),
  60. .sramwr_addr(sramwr_addr),
  61. .sramrd_addr(sramrd_addr),
  62. .sram_cs_n(sram_cs_n),
  63. .sram_we_n(sram_we_n),
  64. .sram_oe_n(sram_oe_n),
  65. .sram_addr(sram_addr),
  66. .sram_data(sram_data)
  67. );
  68. endmodule

timing.v:

  1. module test_timing(clk,rst_n,led,sramwr_req,sramrd_req,sramwr_data,sramrd_data,sramwr_addr,sramrd_addr
  2. );
  3. input clk;//输入时钟
  4. input rst_n;//复位信号
  5. output reg led;//LED指示灯
  6. output sramwr_req ;//SRAM写请求信号,高电位有效,用于状态机控制
  7. output sramrd_req ;//SRAM读请求信号,高电位有效,用于状态机控制
  8. output reg [7:0] sramwr_data;//SRAM写入数据寄存器
  9. input [7:0] sramrd_data;//SRAM读出数据寄存器
  10. output reg [14:0]sramwr_addr;//SRAM写入地址寄存器
  11. output reg [14:0]sramrd_addr;//SRAM读取地址寄存器
  12. //一秒定时
  13. reg[25:0] delay;
  14. always@(posedge clk or negedge rst_n)begin
  15. if(rst_n==1'b0)begin
  16. delay<=1'b0;
  17. end
  18. else if(delay<26'd49_999_999)begin
  19. delay<=delay+1'b1;
  20. end
  21. else begin
  22. delay<=1'b0;
  23. end
  24. end
  25. assign sramwr_req =(delay==26'd1000);
  26. assign sramrd_req =(delay==26'd1100);
  27. //定时写入数据寄存器
  28. always@(posedge clk or negedge rst_n)begin
  29. if(rst_n==1'b0)begin
  30. sramwr_data<=8'd0;
  31. end
  32. else if(delay==26'd4000)begin
  33. sramwr_data<=sramrd_data+1'b1;
  34. end
  35. end
  36. //定时SRAM读和写地址寄存器
  37. always@(posedge clk or negedge rst_n)begin
  38. if(rst_n==1'b0)begin
  39. sramwr_addr<=1'b0;
  40. end
  41. else if(delay==26'd4000)begin
  42. sramwr_addr<=sramwr_addr+1'b1;
  43. end
  44. end
  45. always@(posedge clk or negedge rst_n)begin
  46. if(rst_n==1'b0)begin
  47. sramrd_addr<=1'b0;
  48. end
  49. else if(delay==26'd4000)begin
  50. sramrd_addr<=sramrd_addr+1'b1;
  51. end
  52. end
  53. //比较数据
  54. always@(posedge clk or negedge rst_n)begin
  55. if(rst_n==1'b0)begin
  56. led<=1'b1;
  57. end
  58. else if(delay==26'd3000)begin
  59. if(sramrd_data==sramwr_data)begin
  60. led<=1'b0;
  61. end
  62. else begin
  63. led<=1'b1;
  64. end
  65. end
  66. end
  67. endmodule

sram_controller.v:

  1. module sram_controller(clk,rst_n,
  2. sramwr_req,sramrd_req,sramwr_data,sramrd_data,sramwr_addr,sramrd_addr,
  3. sram_cs_n,sram_we_n,sram_oe_n,sram_addr,sram_data
  4. );
  5. input clk;
  6. input rst_n;
  7. //读写控制信号
  8. input sramwr_req;//SRAM写请求信号,高电位有效,用于状态机控制
  9. input sramrd_req;//SRAM读请求信号,高电位有效,用于状态机控制
  10. input [7:0] sramwr_data;//SRAM写入数据寄存器
  11. output reg [7:0]sramrd_data;//SRAM读出数据寄存器
  12. input [14:0] sramwr_addr;//SRAM写入地址寄存器
  13. input [14:0] sramrd_addr;//SRAM读取地址寄存器
  14. //FPGA与芯片的接口信号
  15. output reg sram_cs_n;//SRAM片选信号
  16. output reg sram_we_n;//SRAM写入信号
  17. output reg sram_oe_n;//SRAM输出选通信号
  18. output reg [14:0] sram_addr;//地址总线
  19. inout [7:0] sram_data;//数据总线
  20. `define DELAY_00NS (cnt==3'd0)
  21. `define DELAY_20NS (cnt==3'd1)
  22. `define DELAY_40NS (cnt==3'd2)
  23. `define DELAY_60NS (cnt==3'd3)
  24. parameter IDLE = 4'd0,
  25. WRT0 = 4'd1,
  26. WRT1 = 4'd2,
  27. REA0 = 4'd3,
  28. REA1 = 4'd4;
  29. reg [3:0]state_c;
  30. reg [3:0]state_n;
  31. reg [2:0] cnt;
  32. //延时计数器
  33. always@(posedge clk or negedge rst_n)begin
  34. if(rst_n==1'b0)begin
  35. cnt<=1'b0;
  36. end
  37. else if(state_c==IDLE)begin
  38. cnt<=1'b0;
  39. end
  40. else begin
  41. cnt<=cnt+1'b1;
  42. end
  43. end
  44. //SRAM读写状态机
  45. always@(posedge clk or negedge rst_n)begin
  46. if(rst_n==1'b0)begin
  47. state_c<=IDLE;
  48. end
  49. else begin
  50. state_c<=state_n;
  51. end
  52. end
  53. always@(state_c or sramwr_req or sramrd_req or cnt)begin
  54. case(state_c)
  55. IDLE:if(sramwr_req==1'b1)begin
  56. state_n<=WRT0;
  57. end
  58. else if(sramrd_req==1'b1)begin
  59. state_n<=REA0;
  60. end
  61. else begin
  62. state_n<=IDLE;
  63. end
  64. WRT0:if(`DELAY_60NS)begin
  65. state_n<=WRT1;
  66. end
  67. else begin
  68. state_n<=WRT0;
  69. end
  70. WRT1:state_n<=IDLE;
  71. REA0:if(`DELAY_60NS)begin
  72. state_n<=REA1;
  73. end
  74. else begin
  75. state_n<=REA0;
  76. end
  77. REA1:state_n<=IDLE;
  78. default:state_n<=IDLE;
  79. endcase
  80. end
  81. //地址赋值
  82. always@(posedge clk or negedge rst_n)begin
  83. if(rst_n==1'b0)begin
  84. sram_addr<=15'd0;
  85. end
  86. else if(state_c==WRT0)begin
  87. sram_addr<=sramwr_addr;
  88. end
  89. else if(state_c==WRT1)begin
  90. sram_addr<=15'd0;
  91. end
  92. else if(state_c==REA0)begin
  93. sram_addr<=sramrd_addr;
  94. end
  95. else if(state_c==REA1)begin
  96. sram_addr<=15'd0;
  97. end
  98. end
  99. reg sdlink;
  100. //SRAM读写控制
  101. always@(posedge clk or negedge rst_n)begin
  102. if(rst_n==1'b0)begin
  103. sramrd_data<=8'd0;
  104. end
  105. else if((state_c==REA0)&&`DELAY_60NS)begin
  106. sramrd_data<=sram_data;
  107. end
  108. end
  109. always@(posedge clk or negedge rst_n)begin
  110. if(rst_n==1'b0)begin
  111. sdlink<=1'b0;
  112. end
  113. else if(state_c==WRT0)begin
  114. sdlink<=1'b1;
  115. end
  116. else if(state_c==WRT1)begin
  117. sdlink<=1'b0;
  118. end
  119. end
  120. assign sram_data = sdlink?sramwr_data:8'hzz;
  121. //SRAM片选控制
  122. always@(posedge clk or negedge rst_n)begin
  123. if(rst_n==1'b0)begin
  124. sram_cs_n<=1'b1;
  125. end
  126. else if(state_c==WRT0)begin
  127. if(`DELAY_00NS)begin
  128. sram_cs_n<=1'b1;
  129. end
  130. else begin
  131. sram_cs_n<=1'b0;
  132. end
  133. end
  134. else if(state_c==REA0)begin
  135. sram_cs_n<=1'b0;
  136. end
  137. else begin
  138. sram_cs_n<=1'b1;
  139. end
  140. end
  141. //读选通控制
  142. always@(posedge clk or negedge rst_n)begin
  143. if(rst_n==1'b0)begin
  144. sram_oe_n<=1'b1;
  145. end
  146. else if(state_c==REA0)begin
  147. sram_oe_n<=1'b0;
  148. end
  149. else begin
  150. sram_oe_n<=1'b1;
  151. end
  152. end
  153. //写选通控制
  154. always@(posedge clk or negedge rst_n)begin
  155. if(rst_n==1'b0)begin
  156. sram_we_n<=1'b1;
  157. end
  158. else if(state_c==WRT0)begin
  159. if(`DELAY_20NS)begin
  160. sram_we_n<=1'b0;
  161. end
  162. else if(`DELAY_60NS)begin
  163. sram_we_n<=1'b1;
  164. end
  165. end
  166. end
  167. endmodule

 

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

闽ICP备14008679号