Verilog基础之十三、ROM实现

本文详细介绍了FPGA设计中ROM的实现,包括非IP核设计方法,通过读取txt文件初始化ROM,并展示了测试代码和仿真结果。接着,文章讲解了如何使用IP核创建ROM,特别是通过coe文件初始化,并提供了设计代码和测试代码。此外,还介绍了在Modelsim中设置模拟信号显示和信号范围的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、前言

二、非IP核设计

2.1 工程设计文件读取初始化

2.2 测试代码

2.3 仿真结果

三、IP核创建ROM

3.1 IP核生成ROM

3.2 设计代码

3.3 测试代码

3.4 仿真结果

四、modelsim设置

4.1 模拟信号显示

4.2 信号范围显示设置

五、数据文件


一、前言

    对于工程中的存储逻辑分为两种,一种是可读可写的RAM,另一种是只能读取的ROM,两者的数据读取都是通过地址来查找。对于ROM,因为是只能读取不能写入,里面的数据在初始化时进行存入。

二、非IP核设计

    通常ROM的实现是调用IP核,在IP核创建时使用coe文件进行初始化,coe文件中存储了初始化的数据,工程设计中IP核和data文件(如txt文件)读取两种方式来设计ROM。

2.1 工程设计文件读取初始化

    设计用初始化ROM使用txt文件的数据,使用了正弦波,方波,三角波三种波形的txt文件数据,初始化都再对齐进行读取,存储器的数据宽度为8,深度为512。

module ROM( rst,clk,o_sine,o_squ,o_tri );
input clk;
input rst;   //复位信号
output  o_sine,o_squ,o_tri;
reg [7:0] o_sine,o_squ,o_tri;    //存储的数据位宽为8位
//parameter INIT_FILE = "../dat/ram_init.dat"reg [7:0] ROM [255:0];
parameter SINE_FILE = "sine.txt";  //正弦波形数据
parameter SQUARE_FILE = "square.txt";  //方波数据
parameter TRI_FILE = "triangle.txt";   //三角波数据
reg [7:0] sine_rom [511:0];       //存储器的深度为512
reg [7:0] square_rom[511:0];
reg [7:0] tri_rom [511:0];
reg [8:0] cnt;
initial
begin: file 
$readmemh(SINE_FILE, sine_rom);    //对数据进行读取
$readmemh(SQUARE_FILE, square_rom);
$readmemh(TRI_FILE, tri_rom);
end
always@(posedge clk,negedge rst)
begin
if(!rst)
begin
o_sine<=8'b0;
o_squ<=8'b0;
o_tri<=8'b0;
cnt<=0;
end
else if(cnt<512)
begin
o_sine<=sine_rom[cnt];
o_squ<=square_rom[cnt];
o_tri<=tri_rom[cnt];
cnt<=cnt+1;
end
else
cnt<=0;
end

2.2 测试代码

`timescale 1ns / 1ps
module ROM_tb(  );
reg rst,clk;
wire [7:0] o_sine,o_squ,o_tri;
initial 
begin
clk=0;
rst=1;      //低电平复位信号赋初始值1
#40 rst=0;
#60 rst=1;
end

ROM ROM_test(.rst(rst),.clk(clk),.o_sine(o_sine),.o_squ(o_squ),.o_tri(o_tri) );
always #1 clk=~clk;    //时钟周期为2ns
endmodule

2.3 仿真结果

结果中红色,绿色,粉红分别为正弦波,方波,三角波,因clk周期为2ns,深度为512,故一个大波形周期为1024ns,根据1、2号框的坐标差3169-2145=1024ns符合预期。

三、IP核创建ROM

    本章节介绍使用ROM的IP核穿穿件ROM,并通过coe文件进行初始化ROM,再进行读取,使用的器件为xc7k480tffv1156-1

3.1 IP核生成ROM

    Flow Navigator窗口中IP Catalog进行创建

双击IP Catalog进入创建界面,在Search栏输入ROM,选择分布式方式创建

memory config配置界面中Depth为存储器深度,Data Width为存储数据的宽度,类型为ROM

Port config配置界面默认即可,重点为RST&Initialization界面

coe文件格式,第一行指定数据的进制,第二行为数据,以空格区分不同的地址,如7d和7b表示两个不同地址的数据。

3.2 设计代码

module ROM_top( clk,rst,addr,data);
input clk,rst;
output [8:0] addr;
output [7:0] data;
ROM_IP ROM_addr(.clk(clk),.rst(rst),.addr(addr));  //调用ROM_IP获取地址
dist_mem_gen_0 IP_test(.a(addr),.spo(data));	//调用ROM的IP核读取数据

endmodule

获取地址的代码

module ROM_IP( clk,rst,addr);
input clk,rst;
output reg [8:0] addr;
always@(posedge clk,negedge rst)
begin
if(!rst)
    addr<=9'b0;
else
    addr<=addr+1;
end
endmodule

文件结构

3.3 测试代码

module ROMIP_tb;
reg clk,rst;
wire [8:0] addr;
wire [7:0] data;
initial
begin
clk=0;
rst=0;
#40 rst=1;
end
always#1 clk=~clk;  //时钟clk周期为2
ROM_top ROM_toptest(.clk(clk),.rst(rst),.addr(addr),.data(data));
endmodule

3.4 仿真结果

输出结果为正弦波,周期为1024ns

四、modelsim设置

4.1 模拟信号显示

modelsim默认显示数字信号,需要显示模拟信号时,如上述章节结果中的正弦波,三角波显示时,进入“Format->Format->analog(automatic)”,即显示为模拟信号

4.2 信号范围显示设置

    在4.1中设置模拟信号显示后,容易出现该信号与其他信号重叠  ,下图中不仅重叠,也显示不全

原因为信号显示的高度height默认为17,将其调大即可,设置路径Format->Height

此处为140

设置后显示信号完整直观

五、数据文件

初始化用到正弦波,三角波的数据文件coe和txt获取路径,下载后将文件直接放入和.v文件同路径目录下即可无需修改源文件中代码路径直接使用

链接:https://pan.baidu.com/s/1MEsTEZJdDjaxNTUB9RF8ww  

提取码:60eu

Verilog ROM(只读存储器)是一种数字电路元件,用于存储固定的数据。它通常用于存储由设计人员预定义的常量或查找表数据,以供电路使用。 在Verilog实现ROM的读操作相对简单。首先,我们需要定义ROM的地址和数据位宽。地址位宽会决定ROM的大小,例如,一个8位地址可以访问256个数据元素。数据位宽取决于所存储数据的大小。 然后,我们需要用initial块初始化ROM的内容。在初始化块中,我们把需要存储的数据分配给ROM的不同地址。例如,假设我们有一个8位地址和8位数据的ROM,并希望存储从0到7的数字。我们可以按以下方式初始化: initial begin rom[0] = 8'b00000000; rom[1] = 8'b00000001; rom[2] = 8'b00000010; rom[3] = 8'b00000011; rom[4] = 8'b00000100; rom[5] = 8'b00000101; rom[6] = 8'b00000110; rom[7] = 8'b00000111; end 这样,ROM的内容就会在仿真或实际硬件中被初始化。 当我们想要读取ROM中的数据时,我们只需要提供一个有效的地址,并将ROM的数据输出到需要的地方。例如,如果我们想要读取地址为3的数据,我们可以使用: data_out = rom[3]; 其中,data_out是一个用于存储ROM数据的变量。读取的数据可以在仿真或实际硬件中使用。 重要的是要记住,ROM是只读存储器,因此我们无法通过Verilog代码进行写入操作。ROM的内容只能在初始化时定义,并且不能在运行时更改。 综上所述,Verilog中的ROM使用initial块进行初始化,并通过给定地址来读取数据。注意,ROM是只读的,不支持写入操作。
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FPGA芯中的小蚂蚁

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值