single port ram-------sp ram
1.1 概念
只有一个读写口,同一时刻只能发起读或写。
单口RAM指的是只有一个读写端口,就是只有一组数据线和地址线,就是读和写都是通过这个口来访问RAM,但是同一时刻只能访问一个,要么是读,要么是写。
![在这里插入图片描述](https://img-blog.csdnimg.cn/080cad0970624a69bb509a09861c0e16.png?x-oss-process=image/watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBA5Yay5rWq5bCP6bOE6bG8,size_20,color_FFFFFF,t_70,g_se,x_16#pic_center
注意:
1、RAM的地址位宽决定了RAM的最大深度,比如地址位宽为4,则RAM的最大深度为2^4=16
2、RAM特性读延时,就是RAM发起读,然后读数据有效的周期数,延迟一般是1
1.2 要求
写一组数据到单端口RAM,然后再从该RAM中读出。
1.3 RAM读写代码
下面展示 功能代码
。
`timescale 1ns / 1ps
///
// RAM读写模块 Verilog 功能代码如下:
module sp_ram_a_rw(
input sys_clk ,
input sys_rst_n
);
wire ram_en ;
wire ram_wren ;
wire ram_rden ;
wire [8:0] ram_rd_data ;
reg [7:0] ram_wr_data ;
reg [4:0] ram_addr ;
reg [7:0] ram_rw_cnt ;
assign ram_en = ram_wren | ram_rden ;
assign ram_wren = (ram_rw_cnt >= 8'd0 && ram_rw_cnt <= 8'd31) ? 1'b1:1'b0 ;
assign ram_rden = (ram_rw_cnt >= 8'd32 && ram_rw_cnt <= 8'd63) ? 1'b1:1'b0 ;
always @ (posedge sys_clk or negedge sys_rst_n)
if(!sys_rst_n)
ram_rw_cnt <= 8'd0 ;
else if(ram_rw_cnt == 8'd63)
ram_rw_cnt <= 8'd0 ;
else
ram_rw_cnt <= ram_rw_cnt +1'b1 ;
always @ (posedge sys_clk or negedge sys_rst_n)
if(!sys_rst_n)
ram_wr_data <= 8'd0 ;
else if(ram_rw_cnt >= 8'd0 && ram_rw_cnt <= 8'd31)
ram_wr_data <= ram_wr_data + 1'b1;
else
ram_wr_data <= 8'd0 ;
always @ (posedge sys_clk or negedge sys_rst_n)
if(!sys_rst_n)
ram_addr <= 5'd0 ;
else if(ram_addr == 5'd31)
ram_addr <= 5'd0 ;
else
ram_addr <= ram_addr + 1'b1;
sp_ram_a sp_ram_a_inst(
.clk_a(sys_clk),
.ena (ram_en),
.wea (ram_wren),
.dina (ram_wr_data),
.addra(ram_addr),
.douta(ram_rd_data)
);
endmodule
// RAM控制模型 Verilog 功能代码如下:
module sp_ram_a(
input clk_a ,
input ena ,
input wea ,
input [7:0] dina ,
input [4:0] addra ,
output reg [8:0] douta
);
reg [7:0] ram [31:0] ;
always @ (posedge clk_a)
if(ena && wea) begin
ram[addra] <= dina ;
douta <= 9'd0 ;
end
else if(ena && (wea == 1'b0)) begin
douta <= ram[addra] ;
end
else
douta <= 9'hx ;
endmodule
// RAM仿真 Verilog 功能代码如下:
module tb_sp_ram_a_rw(
);
reg clk ;
reg rst ;
initial begin
clk = 1'b0 ;
rst = 1'b0;
#400
rst = 1'b1;
end
always #10 clk = ~clk ;
sp_ram_a_rw sp_ram_a_rw_inst(
.sys_clk (clk),
.sys_rst_n (rst)
);
endmodule