因为现在所做的工作涉及到对两片SRAM的乒乓读写,所以前段时间一直在调试SRAM的读写问题,现在还算是有那么一点点了解,所以写篇帖子总结一下;
关于SRAM怎样读写的帖子和教程网上已经很多了,无非就是根据时序图和硬件电路,去产生控制信号(即片选信号、读写控制信号), 这里就不详述了。这里主要是介绍两种读SRAM的方法。一种是顺序读取法(根据存入的顺序依次读取),另一种是随机读取法(即想读哪个地址就读哪个地址)。
1:顺序读取法
根据读时钟产生地址,该地址从地址0依次递加,直到把存入的数据读完;
例子:假如读取256个地址则,reg [7:0] rd_addr (读地址) , reg rd_addr_en(读地址使能), rst(复位信号) ,rd_clk(读时钟);
always @ (posedge rd_clk) begin
if(!rst)begin
rd_addr <= 8'd0;
rd_addr_en <= 1'b0;
end
else begin
if(rd_addr == 8'd255)begin
rd_addr <= rd_addr;
rd_addr_en <= 1'b0;
end
else begin
rd_addr <= rd_addr + 1'b1;
rd_addr_en <= 1'b1;
end
end
end
2 : 随机读取法
所谓随机读取法就是根据需要读取存在SRAM中任意地址的数据,比如说我想取出地址100/131/208/19里面的数据,那要怎么做呢?reg [7:0] rd_addr (读地址) , reg rd_addr_en(读地址使能), rst(复位信号) ,rd_clk(读时钟);
(1):先设一个计数器 reg [2:0] cnt;因为要取四个数所以计数计0/1/2/3.
always @ (posedge rd_clk) begin
if(!rst)begin
cnt <= 3'd0;
rd_addr_en <= 1'b0;
end
else begin
if(cnt == 3'd3)
cnt <= cnt;
rd_addr_en <= 1'b0;
else
cnt <= cnt + 1'b1;
rd_addr_en <= 1'b1;
end
end
(2):用case语句产生所需要的地址
always @ (*)begin
case(cnt)
3'd0 : rd_addr = 8'd100;
3'd1 : rd_addr = 8'd131;
3'd2 : rd_addr = 8'd208;
3'd3 : rd_addr = 8'd19;
default : rd_addr =8'd0;
endcase
end
以上就是两种基本的产生SRAM读地址的方式,经过板上调试好使。