Article directory
Preface
FPGA itself is SRAM architecture, and the program will disappear after power off. So how to use FPGA to implement a ROM? We can use the RAM resources inside the FPGA to implement ROM, but this is not a real ROM, but every time it is powered on. The initialized values will be written to RAM first . The Vivado software provides an IP core for ROM. We only need to instantiate a ROM through the IP core and read the data stored in the ROM according to the ROM read timing. This section will introduce how to use the ROM inside the FPGA and the program's data reading operation on the ROM. This experiment is similar to the FPGA on-chip RAM read and write test experiment operation, you can refer to it.
1. Prepare ROM initialization file
For ROM, we need to prepare the data in advance, so that when the FPGA is actually running, the pre-stored data in the ROM can be directly read. The on-chip ROM of Xilinx FPGA supports initialization data configuration. I created a ROM initialization file named "rom_init.coe" here, which will be used later.
Copy the following content into it:
MEMORY_INITIALIZATION_RADIX=16; //表示ROM内容的数据格式是16进制
MEMORY_INITIALIZATION_VECTOR=
11,
22,
33,
44,
55,
66,
77,
88,
99,
aa,
bb,
cc,
dd,
ee,
ff,
00,
a1,
a2,
a3,
a4,
a5,
a6,
a7,
a8,
b1,
b2,
b3,
b4,
b5,
b6,
b7,
b8; //每个数据后面用逗号或者空格或者换行符隔开,最后一个数据后面加分号
The content format of the ROM initialization file is relatively simple. The first line is the defined data format. Lines 3 to 34 are the initialization data of this 32*8bit size ROM. Each line of numbers is followed by a comma, and the last line of numbers ends with a minute. Number.
2. Create and configure projects
1. Create a project
Create a new rom_test project
and put the rom_init.coe file just now into the current project directory.
2. Add ROM IP core
①. Click on the IP Catalog in the picture below, search for rom in the interface that pops up on the right, find Block Memory Generator, and double-click to open it.
②. Configure the Basic option bar as shown below.
③. Configure the Port A Option bar as shown below.
Uncheck Primitives Output Register. Its function is to add a register to the output data. This can effectively improve the timing, but the readout The data will lag behind the address by two cycles, so in many cases, this function is not used and the read data can be kept behind the address by one cycle.
④. Check Load Init File under Other Options, then click Browse to find the file rom_init.coe created in the first step, and click OK.
⑤. Click Generate in the pop-up dialog box to generate the ROM IP.
3. Add ILA IP core
①. Click on the PROJECT MANAGER bar on the left -> IP Catalog or Window -> IP Catalog under the menu bar. Then search for ILA under the IP Catalog window that appears on the right. Double-click to select ILA under Debug for IP configuration. The steps are as shown in the figure below
② , General Option Add two probes to collect the address and data we read. We set the depth of sampling data larger, as shown in the figure below ③.
In Probe_Ports (0…7), PROBE0 is used to collect the 5-bit address, and PROBE1 is used Collect 8-bit data and click OK, as shown in the figure below
④, click OK, and then click Generate to generate the ILA IP
3. Programming
1. Create a new test program
Create a new rom_test.v source file and copy the following program blocks to
rom_test.v
`timescale 1ns / 1ps
module rom_test(
input sys_clk, //50MHz时钟
input rst_n //复位,低电平有效
);
wire [7:0] rom_data; //ROM读出数据
reg [4:0] rom_addr; //ROM输入地址
//产生ROM地址读取数据
always @ (posedge sys_clk or negedge rst_n)
begin
if(!rst_n)
rom_addr <= 10'd0;
else
rom_addr <= rom_addr+1'b1;
end
//实例化ROM
rom_ip rom_ip_inst
(
.clka (sys_clk), //inoput clka
.addra (rom_addr), //input [4:0] addra
.douta (rom_data) //output [7:0] douta
);
//实例化逻辑分析仪
ila_0 ila_m0
(
.clk (sys_clk),
.probe0 (rom_addr),
.probe1 (rom_data)
);
endmodule
2. Create a new simulation file
Create a new vtf_rom_tb.v simulation file and copy the following program blocks to
vtf_rom_tb.v
`timescale 1ns / 1ps
module vtf_rom_tb;
// Inputs
reg sys_clk;
reg rst_n;
// Instantiate the Unit Under Test (UUT)
rom_test uut (
.sys_clk (sys_clk),
.rst_n (rst_n)
);
initial
begin
// Initialize Inputs
sys_clk = 0;
rst_n = 0;
// Wait 100 ns for global reset to finish
#100;
rst_n = 1;
end
always #10 sys_clk = ~ sys_clk; //20ns一个周期,产生50MHz时钟源
endmodule
4. Carry out simulation
1. Click Run Simulation -> Run Behavioral Simulation to perform simulation
2. Drag the address and data signals in the ROM into the observation window
3. Click Run for 200us, you can see the simulation waveform as shown below
You can see that address 0 corresponds to data 0x11, address 1 corresponds to data 0x22..., which is consistent with our previous ROM initialization file of "rom_init.coe"
5. Download to FPGA
1. Pin constraints and timing constraints
rst_n -> T11
clk -> U18
Create a new pin constraint file rom.xdc, copy the following statements and save it
set_property PACKAGE_PIN T11 [get_ports rst_n]
set_property IOSTANDARD LVCMOS33 [get_ports rst_n]
set_property PACKAGE_PIN U18 [get_ports sys_clk]
set_property IOSTANDARD LVCMOS33 [get_ports sys_clk]
create_clock -period 20.000 -name sys_clk -waveform {
0.000 10.000} [get_ports sys_clk]
2. Generate a bit file
. Click "Generate Bitstream" to directly generate a bit file.
3. Download the program.
Connect the JTAG and power cable, power on the board, and download the program.
4. Analyze the waveform with a logic analyzer
and view the read memory in decimal format. and data, set the trigger condition to "rom address is 0", you can see that the data at address 0 is 0x11, and the data at rom address 31 is 0xb8, it can be seen that the expected results are met.
6. Self-pickup of resources
FPGA on-chip ROM test experiment
My qq: 2442391036, welcome to communicate!