1、ROM IP 的创建
1.1、pROM
双击即可进入 pROM 配置界面,如下所示:
下面对上图所示的几个部分进行简要介绍:
1、pROM 为 16K 块状只读存储器,其数据宽度和深度配置如下表所示:
BSRAM 容量 | 数据宽度 | 地址深度 |
---|---|---|
16Kbits | 1 | 14 |
2 | 13 | |
4 | 12 | |
8 | 11 | |
16 | 10 | |
32 | 9 |
2、读模式配置,可支持 2 种读模式:bypass 模式(旁路模式)和 pipeline 模式(流水线读模式),两种模式如下所示:
bypass 模式下的波形图如下图所示:
pipeline 模式下的波形图如下图所示:
3、资源利用情况,当配置完成的时候,可以点击 Calculate 计算 LUT、DFF 等利用情况。
4、 复位模式配置,支持同步复位(Synchronous)和异步复位(Asynchronous)。
5、 配置初始值,初始值以二进制、十六进制或带地址十六进制的格式写在初始化文件中。 Memory Initialization File 选取的初始化文件可通过手写或者 IDE 菜单栏File -> New -> MemoryInitialization File 产生。
1.2、ROM16
双击即可进入 ROM16 配置界面,如下所示:
上图所示的 1、2、3 与 pROM 功能是一样的,这里不再进行说明,该 IP 只有两个信号,一个输入,一个输出,其中输入 AD 为地址信号,DO 对应的是其地址对应的数据信号,其时序波形图如下图所示:
ROM16 是数据位宽为 1 的只读存储器,由地址确定输出存储在 ROM 对应位置的数据。双击即可进行配置,其配置界面如下图所示:
2、实战任务
设计一个 FPGA 系统,将一个周期的正弦波波形数据存储在 ROM 中,分成 256 个采样点,并通过 FPGA 输出端口将这些数据传输到 GAO 在线逻辑分析仪上显示。确保在线逻辑分析仪能够实时捕获和显示正弦波的波形特征,以便观察和分析波形,验证 FPGA 设计的正确性。此方法不仅用于波形分析,还有助于调试和优化 FPGA 内部逻辑,以确保系统的精确性和稳定性。
3、ROM 实验
3.1、新建一个 mi 格式的文件
首先选择文件类型 -> Memory Initialization File,操作如下所示:
弹出 New File 对话框,给文件命名为 sine_init,文件默认保存至工程目录的 src 文件夹下,然后点击 OK,如下所示。
3.2、配置文件格式
点击 OK 之后,会弹出 sine_init.mi 文件配置界面,将 File Format 选择为 HEX 格式,Depth 选择 256,Width 选择 8 ,点击 Update 进行文件更新,如下图所示:
我们先保存文件,打开src文件夹下的 sine_init.mi 文件,内容如下图所示:
从上图可以看出文件的最开始显示的就是文件格式、地址深度以及数据位宽。
3.3、数据
我们这里可以从网上去找对应的数据,我这里是通过 Python 生成的:数据下载地址 sine_init数据集
下载后数据如下所示:
我们这个 sine_init.mi 文件里面存储的数据得是 16 进制的,如果不是则会报错。
3.4、配置 pROM
接下来我们开始配置 IP 核的 pROM 的最终配置界面如下图所示:
设置数据位宽为 8,数据深度为 256 用于存储我们正弦波波形表,读模式设置为 Bypass,复位模式设置为 Synchronous 。
再点击 OK 之后,就会直接打开例化文件 Gowin_pROM.v,如下图所示:
4、程序编写
rom_top.v 仿真文件代码如下:
module rom_top(
input sys_clk, //全局时钟
input sys_rst_n, //全局复位,低电平有效
output wire [7:0] dout // pROM 数据输出
);
reg [7:0]addr; //地址
always @(posedge sys_clk or negedge sys_rst_n) begin
if(!sys_rst_n)
addr<=0;
else
addr<=addr+1'b1; //地址加一
end
Gowin_pROM u_Gowin_pROM(
.dout(dout), //output [7:0] dout
.clk(sys_clk), //input clk
.oce(1'b1), //input oce
.ce(1'b1), //input ce
.reset(~sys_rst_n), //input reset
.ad(addr) //input [7:0] ad
);
endmodule
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
代码解析:
第 11 - 16 行:根据 sys_clk 时钟频率对 addr 进行加一处理。
第 18 - 25 行:对 pROM 的模块进行端口绑定。
5、仿真编写
rom_mod.v 仿真文件代码如下:
`timescale 10ns/10ns
module rom_mod(); // 定义模块 rom_mod
//reg define
reg sys_clk; // 系统时钟信号
reg sys_rst_n; // 系统复位信号,低有效
reg [7:0] addr; // 8位地址信号
//wire define
wire [7:0] dout; // 从 ROM 读取的数据输出
always #10 sys_clk = ~sys_clk; // 每 10ns 反转一次时钟信号
integer i = 0; // 用来声明变量
GSR GSR(.GSRI(1'b1)); //在对 FIFO 或者 SP IP 核等(或其它在底层转换 GSR 时调用了全局复位的 IP/原语)进行仿真时,在仿真代码中需要添加如下这一段代码,否则联合仿真时就会报错。
initial begin
sys_clk = 1'b0; // 初始化时钟为低
sys_rst_n = 0; // 初始化复位信号为低电平(表示复位状态)
#200;
sys_rst_n = 1; // 开始执行
addr = 0; // 初始化地址为 0
#20;
// 循环地址从 0 到 2559(2560 次访问)
for(i = 0; i < 2560; i = i + 1) begin
#20; // 每次循环等待 20ns
addr = addr + 1'b1; // 地址自增
end
$stop; // 停止仿真
#1000;
end
Gowin_pROM u_Gowin_pROM(
.dout(dout), // 输出数据
.clk(sys_clk), // 时钟信号
.oce(1'b1), // 输出使能信号,始终使能
.ce(1'b1), // 使能信号,始终使能
.reset(~sys_rst_n), // 复位信号,低有效
.ad(addr) // 地址输入
);
endmodule
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
代码解析:
第 13 行:由于 pROM IP 中用到了全局变量 GSR,由于仿真不具有这个变量,所以需要在仿真文件中加上 GSR GSR(.GSRI(1'b1))这样一句话,不然仿真会报错。
第 15 行:integer 用于声明整数变量。它的特点包括:整数类型范围通常为 32 位有符号整数,可以在过程内部或过程外部声明。
第 27 - 30 行:地址数从 0 自加到 2560。由于本次实验配置的 pROM 深度为 256,第一次增加到 255 后会重新从 0 开始自加,这样可以循环十次。
接下来打开 Modelsim 软件对代码进行仿真,需要添加文件如下图所示:
再运行仿真一段时间后,仿真的波形如下图所示:
注:我这里添加的时候,只添加的 dout 端口进行仿真,其余数据我们这里用不到,而截图中添加了两个没有仿真波形,主要是将 dout 波形往下排好观察波形。
可通过在信号 dout 右键依次选择 Format->Analog(automatic),如下图所示。
设置完成之后,我们就可以看到如下图所示的正弦波。说明我们仿真没有问题。
6、I/O 引脚绑定
进行 I/O 约束,这里只需要对 clk 与 reset_n 进行约束即可,管脚分配如下表所示:
信号 | 方向 | 引脚 | 端口作用 | 电平标准 |
---|---|---|---|---|
sys_clk | input | T7 | 时钟 | LVCMOS33 |
sys_rst_n | input | F10 | 复位 | LVCMOS33 |
Gowin 软件中 I/O Constraints 界面如下图所示:
7、在线逻辑分析仪
这里需要创建一个触发信号,我们选择 dout[7:0] 信号,设置触发条件为 dout 不等于 0 。如下图所示:
采样时钟为 sys_clk,捕获信号为 dout[7:0],如下所示:
需要本章节需要配置的文件包括(时钟约束、I/O引脚绑定、GAO 文件配置)如下所示:
然后点击综合,直到没错,就点击 进入在线逻辑分析仪界面,下载程序,然后点击 运行,抓取波形如下图所示:
根据上图观察,dout[7:0] 数据显示周期性变化,并从数据 00 开始变化,高云的在线逻辑分析仪也可以将数据转换成模拟量进行分析的功能,右击需要观察的信号,选中 Format->Unsigned Line Chart,然后点击 ,观察完整波形,如下图所示。
正弦波如下图所示:
至此,我们的 ROM 实验就完成,希望大家能够多多练习,因为 ROM 在实际应用中非常常用。