单端口ram读写

项目名称

单端口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上的数据 

猜你喜欢

转载自blog.csdn.net/weixin_43533751/article/details/106977617
RAM