1.原理

通过添加数据文件,使ROM看起来不是易失性存储器,


产生256个数据,每个数据的位宽是8




如果前面为x,后面就是x+256-1








2.单端口ROM配置


FPGA内部没有非易失性存储器。调用的ROM和RAM都是用RAM来生成的









3.双端口ROM配置





使用第一种单时钟

默认不选择使能信号


添加了寄存器,输入时钟可以选择更高的频率

对时钟的使能信号,默认不勾选

是否给寄存器添加清0信号。默认不勾选


 4.实验代码
4.实验代码
 



K1按下,给ROM写入一个随机的地址,读取这个地址的数据。K2同理。将读取数据和mif文件对比。





4.1 rom_ctrl.v
module rom_ctrl#(
	parameter CNT_MAX=24'd9_999_999
)
(
	input wire 			sys_clk		,
	input wire 			sys_rst_n	,
	input wire 			key1		,
	input wire 			key2		,
	
	output reg[7:0]	    addr		
);
reg [23:0]cnt_200ms;   //10,000,000个时钟周期,0-9_999_999
reg key1_en		;
reg key2_en		;
always@(sys_clk or negedge sys_rst_n)
	if(sys_rst_n==1'b0)
		cnt_200ms<=24'd0;
	else if((cnt_200ms==CNT_MAX)||(key1_en==1'b1)||(key2_en==1'b1))
		cnt_200ms<=24'd0;
	else
		cnt_200ms<=cnt_200ms+1'b1;
		
always@(sys_clk or negedge sys_rst_n)
	if(sys_rst_n==1'b0)
		key1_en<=1'b0;
	else if(key2==1'b1)
		key1_en<=1'b0;
	else if(key1==1'b1)
		key1_en<=~key1_en;
	else 
		key1_en<=key1_en;
		
always@(sys_clk or negedge sys_rst_n)
	if(sys_rst_n==1'b0)
		key2_en<=1'b0;
	else if(key2==1'b1)
		key2_en<=~key2_en;
	else
		key2_en<=key2_en;
always@(sys_clk or negedge sys_rst_n)
	if(sys_rst_n==1'b0)
		addr<=8'd0;
	else if((cnt_200ms==CNT_MAX)&&(addr==8'd255))
		addr<=8'd0;
	else if(key1_en==1'b1)
		addr<=8'd99;
	else if(key2_en==1'b1)
		addr<=8'd199;
	else if(cnt_200ms==CNT_MAX)
		addr<=addr+1'b1;
	else
		addr<=addr;
	
endmodule4.2 tb_rom_ctrl.v
`timescale 1ns/1ns
module tb_rom_ctrl();
reg sys_clk;
reg sys_rst_n;
reg key1;
reg key2;
wire[7:0] addr;
initial 
	begin
		sys_clk=1'b1;
		sys_rst_n<=1'b0;
		key1<=1'b0;
		key2<=1'b0
		#20
		sys_rst_n<=1'b1;
		#7000     //让数码管完整显示0-255地址,因为一个地址200ns,250*200=500_000
	//key1
		key1<=1'b1;
		#20
		key1<=1'b0;
		#20000
		key1<=1'b1;
		#20
		key1<=1'b0;
	//key2
		key2<=1'b1;
		#20
		key2<=1'b0;
		#20000
		key2<=1'b1;
		#20
		key2<=1'b0;
		#600000
	end
always #10 sys_clk=~sys_clk;
rom_ctrl#(
	CNT_MAX=24'd99
)
rom_ctrl_inst
(
	.sys_clk	(sys_clk	)	,
	.sys_rst_n	(sys_rst_n	),
	.key1		(key1		),
	.key2		(key2		),
	
	.addr		(addr		)
);
endmodule4.3


4.3 rom.v
module rom(
	input wire 			sys_clk     ,
	input wire 			sys_rst_n	,
	input wire 			key1		,
	input wire 			key2		,
	
	output reg 			ds			,
	output reg 			oe			,
	output reg 			shcp		,
	output reg 			stcp		
);
wire key1_flag;
wire key2_flag;
wire [7:0] addr;
wire [7:0] data;
wire  [5:0]point				;
wire  sign	            ;
wire  seg_en    ;
key_filter
#(
	.CNT_MAX(20'd999_999)
)
key_filter_inst
(
	.sys_clk	(sys_clk	)		,
	.sys_rst_n	(sys_rst_n	)	,
	.key_in		(key1	)	,
	
	.key_flag	(key1_flag	)	
);
key_filter
#(
	.CNT_MAX(20'd999_999)
)
key_filter_inst
(
	.sys_clk	(sys_clk	)		,
	.sys_rst_n	(sys_rst_n	)	,
	.key_in		(key2	)	,
	
	.key_flag	(key2_flag	)	
);
rom_ctrl#(
	.CNT_MAX(24'd9_999_999)
)
rom_ctrl_inst
(
	.sys_clk	(sys_clk	)	,
	.sys_rst_n	(sys_rst_n	),
	.key1		(key1_flag		),
	.key2		(key2_flag		),
				
	.addr		(addr		)
);
rom_8x256 rom_8x256_inst
(
	.address (addr),
	.clock   (sys_clk),
	
	.q		  (data)
);
seg_595_dynamic seg_595_dynamic_inst(
	.sys_clk	(sys_clk	)		,
	.sys_rst_n	(sys_rst_n	)	,
	.data		({12'b0,data}	,   
	.point		(6'b000_000		)	,
	.sign		(1'b0			)	,
	.seg_en		(1'b1			)	,
				 			
	.ds			(ds			)	,
	.oe			(oe			)	,
	.shcp		(shcp		)	,
	.stcp		(stcp		)
);
endmodule4.4 tb_rom.v
`timescale 1ns/1ns
module tb_rom();
reg sys_clk     ;
reg sys_rst_n	;
reg key1		;
reg key2		;
				
wire ds			;
wire oe			;
wire shcp		;
wire stcp		;
initial 
	begin
		sys_clk=1'b1;
		sys_rst_n<=1'b0;
		key1<=1'b1;
		key2<=1'b1;
		#20
		sys_rst_n<=1'b1;
		#7000     //让数码管完整显示0-255地址,因为一个地址200ns,250*200=500_000
//key1
		key1<=1'b0;
		#20
		key1<=1'b1;
		#20
		key1<=1'b0;
		#20
		key1<=1'b1;
		#20
		key1<=1'b0;
		#200
		key1<=1'b1;
		#20
		key1<=1'b0;
		#20
		key1<=1'b1;
		#20
		key1<=1'b0;
		#20
		key1<=1'b1;
//key2
		#2000
		key2<=1'b0;
		#20
		key2<=1'b1;
		#20
		key2<=1'b0;
		#20
		key2<=1'b1;
		#20
		key2<=1'b0;
		#200
		key2<=1'b1;
		#20
		key2<=1'b0;
		#20
		key2<=1'b1;
		#20
		key2<=1'b0;
		#20
		key2<=1'b1;
//key2
		#2000
		key2<=1'b0;
		#20
		key2<=1'b1;
		#20
		key2<=1'b0;
		#20
		key2<=1'b1;
		#20
		key2<=1'b0;
		#200
		key2<=1'b1;
		#20
		key2<=1'b0;
		#20
		key2<=1'b1;
		#20
		key2<=1'b0;
		#20
		key2<=1'b1;
	end
always #10 sys_clk=~sys_clk;
rom rom_inst(
	.sys_clk    (sys_clk    ),
	.sys_rst_n	(sys_rst_n	),
	.key1		(key1		),
	.key2		(key2		),
				
	.ds			(ds			),
	.oe			(oe			),
	.shcp		(shcp		),
	.stcp		(stcp		)
);
endmodule


















