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地址开始读写入的数据。

相关推荐

  1. 补上ROS键盘遥控机器人的keys_to_twist_ramps.py文件

    2024-04-02 15:22:02       16 阅读
  2. Kafka硬干货

    2024-04-02 15:22:02       19 阅读
  3. RAM IP<span style='color:red;'>核</span>

    RAM IP

    2024-04-02 15:22:02      21 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-02 15:22:02       18 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-02 15:22:02       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-02 15:22:02       18 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-02 15:22:02       20 阅读

热门阅读

  1. 1-31 正则表达式 String Buffer String Builder

    2024-04-02 15:22:02       17 阅读
  2. 【docker】基础背景 & Windows安装docker(WSL2)

    2024-04-02 15:22:02       13 阅读
  3. 关于oracle切换mysql8总结

    2024-04-02 15:22:02       13 阅读
  4. mysql调优

    2024-04-02 15:22:02       14 阅读
  5. Redis中的serverCron函数(一)

    2024-04-02 15:22:02       15 阅读
  6. POSTGRESQL中时间戳的奥秘timestamptz

    2024-04-02 15:22:02       18 阅读
  7. postcss简介

    2024-04-02 15:22:02       19 阅读