存储器实验--FPGA中ROM定制与读出实验

一. 实验目的

1、掌握FPGA中ROM的设置,作为只读存储器ROM的工作特性和配置方法;
2、在初始化存储器编辑窗口用文本编辑器编辑coe文件配置ROM;
3、理解同步ROM与异步ROM的区别,并掌握调用 xilinx库IP实例化ROM的设计方法;
4、验证FPGA中ROM的功能。

二.实验设备及环境

装有 Xilinx Vivado 的 Windows 7计算机,FPGA。

三.实验任务

ALTERA的FPGA中有许多可调用的模块库,可构成如rom、ram、fifo等存储器结构。CPU中的重要部件,如RAM、ROM可直接调用他们构成,因此在FPGA中利用嵌入式阵列块EAB可以构成各种结构的存储器,ROM是其中的一种。由于ROM是只读存储器,所以它的数据口是单向的输出端口,ROM中的数据是在对FPGA现场配置时,通过配置文件一起写入存储单元的。
实验中主要应掌握以下三方面的内容:
(1)ROM的参数设置;
(2)ROM中数据的写入,即coe初始化文件的编写;
(3)ISE工具中调用库IP实例化ROM的方法;
(4)进行上板验证,并记录实验数据。

四. 实验步骤

这里仅给出实验源代码,具体实验步骤请看书

同步ROM的instmem.ceo文件内容如下:
memory_initialization_radix = 16;
memory_initialization_vector =
3c010000
24010004
20050004
0c000018
25122520
8c890000
01244022
20050003
20a5ffff
34a8ffff
2009ffff
312affff
01493025
01463824
10a00001
08000008
2005ffff
000543c0
00084400
00084403
000843c2
08000017
00004020
8c890000
20840004
01094020
20a5ffff
14a0fffb
00081000
03e00008

inst_rom_display.v文件内容如下:
`timescale 1ns / 1ps
//*************************************************************************
// > 文件名: inst_rom_display.v
// > 描述 :异步指令存储器显示模块,调用FPGA板上的IO接口和触摸屏
// > 作者 : LOONGSON
// > 日期 : 2016-04-14
//*************************************************************************
module inst_rom_display(
//时钟与复位信号
input clk,
input resetn, //后缀"n"代表低电平有效

//触摸屏相关接口,不需要更改
output lcd_rst,
output lcd_cs,
output lcd_rs,
output lcd_wr,
output lcd_rd,
inout[15:0] lcd_data_io,
output lcd_bl_ctr,
inout ct_int,
inout ct_sda,
output ct_scl,
output ct_rstn
);
//-----{调用数据储存器模块}begin
//数据存储器多增加一个读端口,用于读出特定内存地址显示在触摸屏上
reg [31:0] addr;
wire [31:0] inst;

inst_rom inst_rom_module(
.clka (clk ),
.addra (addr[9:2] ),
.douta (inst )
);
//-----{调用寄存器堆模块}end

//---------------------{调用触摸屏模块}begin--------------------//
//-----{实例化触摸屏}begin
//此小节不需要更改
reg display_valid;
reg [39:0] display_name;
reg [31:0] display_value;
wire [5 :0] display_number;
wire input_valid;
wire [31:0] input_value;

lcd_module lcd_module(
.clk (clk ), //10Mhz
.resetn (resetn ),

//调用触摸屏的接口
.display_valid (display_valid ),
.display_name (display_name ),
.display_value (display_value ),
.display_number (display_number),
.input_valid (input_valid ),
.input_value (input_value ),

//lcd触摸屏相关接口,不需要更改
.lcd_rst (lcd_rst ),
.lcd_cs (lcd_cs ),
.lcd_rs (lcd_rs ),
.lcd_wr (lcd_wr ),
.lcd_rd (lcd_rd ),
.lcd_data_io (lcd_data_io ),
.lcd_bl_ctr (lcd_bl_ctr ),
.ct_int (ct_int ),
.ct_sda (ct_sda ),
.ct_scl (ct_scl ),
.ct_rstn (ct_rstn )
);
//-----{实例化触摸屏}end

//-----{从触摸屏获取输入}begin
//根据实际需要输入的数修改此小节,
//建议对每一个数的输入,编写单独一个always块
always @(posedge clk)
begin
if (!resetn)
begin
addr <= 32'd0;
end
else if (input_valid)
begin
addr[31:2] <= input_value[31:2];
end
end
//-----{从触摸屏获取输入}end

//-----{输出到触摸屏显示}begin
//根据需要显示的数修改此小节,
//触摸屏上共有44块显示区域,可显示44组32位数据
//44块显示区域从1开始编号,编号为1~44,
always @(posedge clk)
begin
case(display_number)
6'd1:
begin
display_valid <= 1'b1;
display_name <= "ADDR ";
display_value <= addr;
end
6'd2:
begin
display_valid <= 1'b1;
display_name <= "INST ";
display_value <= inst;
end
default :
begin
display_valid <= 1'b0;
display_name <= 40'd0;
display_value <= 32'd0;
end
endcase
end
//-----{输出到触摸屏显示}end
//----------------------{调用触摸屏模块}end---------------------//

inst_rom_tb.v的文件内容如下:
`timescale 1ns / 1ps
module rom_techbeach();

reg clk;
reg flag;
reg [5:0] rom_a;
wire [31:0] rom_data;

always #10 clk=~clk;
always @(posedge clk)
begin
if(!flag)
rom_a<=1'b0;
else if(rom_a==5'd31)
rom_a<=1'b0;
else
rom_a<=rom_a+1'b1;
end
inst_rom inst_rom(
.clka (clk),
.addra (rom_a),
.douta (rom_data)
);
initial begin
clk=1'b0;
flag=1'b0;
#100
flag=1'b1;