项目名称
单端口ram读写
设计要求
将0-1023存入ram中并读出,整个过程完成一次读写操作,即只读写一次
设计架构
拉高写使能,只要给出写地址和写数据就可以自动向ram中写入数据
拉高读使能,由于写地址和读地址公用,下一个周期就可以读出数据
特别要注意的是,如果没有读使能,只要给出地址,无论写使能wren是高还是低,一定会把地址指向的数据读出来,即没有读使能只要地址上有数据,数据就会被读出。
如果给出读使能,读使能无效则数据不会被读出。
状态转移图
代码设计
verilog代码设计
创建ram ip core,存储的最大数据为1023,,10位,存储深度为0-1023共1024个数据
顶层模块设计
module ram_top(
input clk,
input rst_n,
output [9:0]q
);
wire wren;
wire [9:0] data;
wire [9:0] addr;
ram_ctrl ram_ctrl(
.clk(clk),
.rst_n(rst_n),
.addr(addr),
.data(data),
.wren(wren)
);
ram ram(
.address(addr),
.clock(clk),
.data(data),
.wren(wren),
.q(q)
);
endmodule
ram控制模块设计
module ram_ctrl(
input clk,
input rst_n,
output reg[9:0] addr,
output reg[9:0] data,
output reg wren
);
reg state;//状态寄存器写和读
localparam write=0;
localparam read=1;
always@(posedge clk or negedge rst_n)
if(!rst_n)
begin
state<=write;
addr<=10'd0;
data<=10'd0;
wren<=0;
end
else begin
case(state)
write:begin
wren<=1;
if(addr<10'd1023)
begin
addr<=addr+1'b1;
data<=data+1'b1;
end
else
begin
wren<=0;
addr<=1'b0;
data<=1'b0;
state<=read;
end
end
read :begin
if(addr<10'd1023)
addr<=addr+1'b1;
else
begin
addr<=10'd1023;
end
end
default:state<=write;
endcase
end
endmodule
仿真代码
`timescale 1ns/1ns
module ram_top_tb;
reg clk;
reg rst_n;
wire [9:0]q;
ram_top ram_top(
.clk(clk),
.rst_n(rst_n),
.q(q)
);
initial clk=0;
always #10 clk=~clk;
initial begin
rst_n=0;
#200;
rst_n=1;
#60000
$stop;
end
endmodule
仿真结果
开始写数据的时候,同样会有数据输出,原因在前面已经解释过了,数据输出慢一拍。 写使能关闭后,数据被读出。
当数据被全部读出后,地址保持在1023,数据也保持在地址为1023上的数据