ROM-IP

1.原理

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

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

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

2.单端口ROM配置

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

3.双端口ROM配置

使用第一种单时钟

默认不选择使能信号

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

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

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

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;
	
endmodule

4.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		)
);

endmodule

4.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		)
);

endmodule

4.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
相关推荐
9527华安1 小时前
FPGA实时红外相机采集输出系统,提供工程源码和技术支持
图像处理·fpga开发·红外相机
博览鸿蒙3 小时前
FPGA自学之路:到底有多崎岖?
fpga开发
搬砖的小码农_Sky6 小时前
硬件设计:RS485电平标准
单片机·嵌入式硬件·fpga开发
搬砖的小码农_Sky6 小时前
硬件设计:LVDS电平标准
嵌入式硬件·fpga开发
∑狸猫不是猫7 小时前
(15)CT137A- 按键消抖设计
fpga开发
我爱C编程7 小时前
基于FPGA的2ASK+帧同步系统verilog开发,包含testbench,高斯信道,误码统计,可设置SNR
fpga开发·信道·帧同步·snr·2ask·误码统计
可知可知不可知20 小时前
明解FPGA中LUT原理
fpga开发
如何学会学习?21 小时前
3. FPGA内部存储资源
fpga开发
szxinmai主板定制专家21 小时前
【国产NI替代】基于A7 FPGA+AI的16振动(16bits)终端PCIE数据采集板卡
人工智能·fpga开发
stm 学习ing1 天前
HDLBits训练6
经验分享·笔记·fpga开发·fpga·eda·verilog hdl·vhdl