RAM IP核

1.原理

数据使能信号充当掩码的作用。1表示1字节就是8个位有效。

2.1 ram_ctrl.v

module ram_ctrl#(
	parameter CNT_MAX=24'd9_999_999
)
(
	input wire			sys_clk			,
	input wire 			sys_rst_n		,
	input wire 			wr_flag			,
	input wire 			rd_flag			,
	
	output reg 			wr_en			,
	output reg [7:0]	addr			,
	output reg[7:0]	    wr_data			,
	output reg 			rd_en
);

reg [23:0] cnt_200ms;

assign wr_data=(wr_en==1'b1)?(addr):1'b0;

always@(posedge sys_clk or negedge sys_rst_n)
	if(sys_rst_n==1'b0)
		wr_en<=1'b0;
	else if(addr==8'd255)
		wr_en<=1'b0;
	else if(wr_flag==1'b1)
		wr_en<=1'b1;
	else
		wr_en<=wr_en;
		
		
always@(posedge sys_clk or negedge sys_rst_n)
	if(sys_rst_n==1'b0)
		rd_en<=1'b0;
	else if(wr_flag==1'b1)
		rd_en<=1'b0;
	else if((rd_flag==1'b1)&&(wr_en==1'b0))
		rd_en<=1'b1;
	else  
		rd_en<=rd_en;
	
	  
always@(posedge sys_clk or negedge sys_rst_n)
	if(sys_rst_n==1'b0)
		addr<=8'd0;
	else if(((addr==8'd255)&&(wr_en==1'b1))||((addr==8'd255)&&(cnt_200ms==24'd255))||rd_flag==1'b1||wr_flag==1'b1)
		addr<=8'd0;
	else if((wr_en==1'b1)||((rd_en==1'b1)&&(cnt_200ms==CNT_MAX)))
		addr<=addr+1'b1;
	else
		addr<=addr;
		

always@(posedge sys_clk or negedge sys_rst_n)
	if(sys_rst_n==1'b0)
		cnt_200ms<=24'd0;
	else if((wr_flag==1'b1)||(cnt_200ms==CNT_MAX)||(rd_flag==1'b1))
		cnt_200ms<=24'd0;
	else if(rd_en==1'b1)
		cnt_200ms<=cnt_200ms+1'b1;
	else
		cnt_200ms<=24'd0;

endmodule		

2.2 tb_ram_ctrl.v

`timescale 1ns/1ns
module tb_ram_ctrl();

reg sys_clk		 ;
reg sys_rst_n    ;
reg wr_flag	     ;
reg rd_flag	     ;
			
wire wr_en		 ;
wire [7:0] addr		;
wire [7:0]wr_data	 ;
wire rd_en   ; 
wire [7:0] data_out   ;

initial
	begin
		sys_clk=1'b1;
		sys_rst_n<=1'b0;
		wr_flag<=1'b0;
		rd_flag<=1'b0;
		#20
		sys_rst_n<=1'b1;
		#1000
	//rd_flag
		rd_flag<=1'b1;
		#20
		rd_flag<=1'b0;
		#60000   //一个数据显示11个时钟周期,256个数据,256*11=2816个时钟周期,就是2816*20=56320
	//wr_flag
		wr_flag<=1'b1;
		#20
		wr_flag<=1'b0;
		#60000   //20*256=5120
	//rd_flag
		rd_flag<=1'b1;
		#20
		rd_flag<=1'b0;
	end
				
assign #10 sys_clk=~sys_clk;
		

ram_ctrl#(
	.CNT_MAX (4'd10)
)
ram_ctrl_inst
(
	.sys_clk	(sys_clk	)		,
	.sys_rst_n	(sys_rst_n)	,
	.wr_flag	(wr_flag	)		,
	.rd_flag	(rd_flag	)		,
	
	.wr_en		(wr_en		)	,
	.addr		(addr		)	,
	.wr_data	(wr_data	)		,
	.rd_en      (rd_en    )
);

ram_8x256_one ram_8x256_one_inst
(
.aclr	(~sys_rst_n),
.address(addr),
.clock	(sys_clk),
.data	(wr_data),
.rden	(rd_en),
.wren	(wr_en),
.q		(data_out)
);

endmodule

2.3 ram.v

module ram(
	input wire 		sys_clk			,
	input wire 		sys_rst_n		,
	input wire 		wr_key			,
	input wire 		rd_key			,
	
	output wire 	ds				,
	output wire 	oe				,
	output wire 	shcp			,
	output wire 	stcp
);

wire  wr_flag;
wire  rd_flag;
wire wr_en	  ;
wire [7:0]addr	  ;
wire [7:0]wr_data  ;
wire rd_en    ;
wire [7:0]data_out;


key_filter
#(
	.CNT_MAX       (20'd999_999)
)
key_filter_wr_inst
(
	.sys_clk		(sys_clk	)	,
	.sys_rst_n		(sys_rst_n	),
	.key_in			(wr_key	),
                     
	.key_flag		(wr_flag	)
);


key_filter
#(
	.CNT_MAX      (20'd999_999)
)
key_filter_rd_inst
(
	.sys_clk		(sys_clk	)	,
	.sys_rst_n		(sys_rst_n	),
	.key_in			(rd_key	),
                     
	.key_flag		(rd_flag	)
);


ram_ctrl #(
	.CNT_MAX(24'd9_999_999)
)
(
	.sys_clk	(sys_clk)		,
	.sys_rst_n	(sys_rst_n)	,
	.wr_flag	(wr_flag)		,
	.rd_flag	(rd_flag)		,
	
	.wr_en		(wr_en	)	,
	.addr		(addr	)	,
	.wr_data	(wr_data)	,
	.rd_en     ( rd_en  )
);


ram_8x256_one ram_8x256_one_inst
(
.aclr	(~sys_rst_n),
.address(addr),
.clock	(sys_clk),
.data	(wr_data),
.rden	(rd_en),
.wren	(wr_en),
.q		(data_out)
);

seg_595_dynamic(
	.sys_clk	(sys_clk)		,
	.sys_rst_n	(sys_rst_n)	,
	.data		({12'b0,data_out})	,
	.point		(6'b000_000)	,
	.sign		(1'b0)	,
	.seg_en		(1'b1)	,
	
	.ds			(ds	)	,
	.oe			(oe	)	,
	.shcp		(shcp)	,
	.stcp		(stcp)
);

endmodule

2.4 tb_ram.v

`timescale 1ns/1ns
module tb_ram();

reg sys_clk		 ;
reg sys_rst_n    ;
reg wr_key		 ;
reg rd_key		 ;
				 
wire ds			     ;
wire oe			     ;
wire shcp		     ;
wire stcp            ;

initial 
	begin
		sys_clk=1'b1;
		sys_rst_n<=1'b0;
		wr_key=1'b1;
		rd_key=1'b1;
		#20
		sys_rst_n<=1'b1;
		#1000
//读操作rd_key
//模拟产生读操作按键前抖动
		rd_key=1'b0;
		#20
		rd_key=1'b1;
		#20
		rd_key=1'b0;
		#20
		rd_key=1'b1;
		#20
//模拟产生的稳定状态
		rd_key=1'b0;
		#200
//模拟产生按键信号的后抖动
		rd_key=1'b1;
		#20
		rd_key=1'b0;
		#20
		rd_key=1'b1;
		#20
		rd_key=1'b0;
		#20
		rd_key=1'b1;
//此时就会读出在ip核事先初始化的数据
		#200000
//模拟读数据的过程
//
		wr_key=1'b0;
        #20
        wr_key=1'b1;
        #20
        wr_key=1'b0;
        #20
        wr_key=1'b1;
        #20
//模拟稳定状态
        wr_key=1'b0;
        #200
//后抖动
        wr_key=1'b1;
        #20
		wr_key=1'b0;
		#20
		wr_key=1'b1;
		#20
		wr_key=1'b0;
		#20
		wr_key=1'b1;
		#1000
//rd_key
		rd_key=1'b0;
		#20
		rd_key=1'b1;
		#20
		rd_key=1'b0;
		#20
		rd_key=1'b1;
		#20
		rd_key=1'b0;
		#200
		rd_key=1'b1;
		#20
		rd_key=1'b0;
		#20
		rd_key=1'b1;
		#20
		rd_key=1'b0;
		#20
		rd_key=1'b1;
		#200000
//在读数据的过程中再次按下读操作按键
		rd_key=1'b0;
		#20
		rd_key=1'b1;
		#20
		rd_key=1'b0;
		#20
		rd_key=1'b1;
		#20
		rd_key=1'b0;
		#200
		rd_key=1'b1;
		#20
		rd_key=1'b0;
		#20
		rd_key=1'b1;
		#20
		rd_key=1'b0;
		#20
		rd_key=1'b1;
		#200000  
	end
	
always #10 sys_clk=~sys_clk;

defparam ram_inst.key_filter_wr_inst.CNT_MAX=9;
defparam ram_inst.key_filter_wr_inst.CNT_MAX=9;
defparam ram_inst.ram_ctrl_inst.CNT_MAX=99;


ram ram_inst(
	.sys_clk	(sys_clk	)		,
	.sys_rst_n	(sys_rst_n)	,
	.wr_key		(wr_key		)	,
	.rd_key		(rd_key		)	,
	
	.ds			(ds			)	,
	.oe			(oe			)	,
	.shcp		(shcp		)	,
	.stcp       (stcp     )
);




endmodule

对顶层模块的仿真主要是查看各个模块之间的信号传递是否正确,因为之前各个模块已经仿真过了。

总的过程就是刚开始读初始化的数据,然后再次读一次发现还是从0地址开始读,然后在读的过程中按下写的按钮,此时就不再读了,数据定格在最后的一瞬间,再次按下读按钮,又从0地址开始读写入的数据。

相关推荐
一口一口吃成大V2 小时前
FPGA随记——FPGA时序优化小经验
fpga开发
贾saisai3 小时前
Xilinx系FPGA学习笔记(九)DDR3学习
笔记·学习·fpga开发
redcocal8 小时前
地平线秋招
python·嵌入式硬件·算法·fpga开发·求职招聘
思尔芯S2C1 天前
高密原型验证系统解决方案(下篇)
fpga开发·soc设计·debugging·fpga原型验证·prototyping·深度调试·多fpga 调试
坚持每天写程序1 天前
xilinx vivado PULLMODE 设置思路
fpga开发
redcocal2 天前
地平线内推码 kbrfck
c++·嵌入式硬件·mcu·算法·fpga开发·求职招聘
邹莉斯3 天前
FPGA基本结构和简单原理
fpga开发·硬件工程
悲喜自渡7213 天前
易灵思FPGA开发(一)——软件安装
fpga开发
ZxsLoves3 天前
【【通信协议ARP的verilog实现】】
fpga开发
爱奔跑的虎子3 天前
FPGA与Matlab图像处理之伽马校正
图像处理·matlab·fpga开发·fpga·vivado·xilinx