ROM 是只读存储器(Read-Only Memory)的简称,是一种只能读出事先所存数据的固态半导体存储器。其特性是一旦储存资料就无法再将之改变或删除,且资料不会因为电源关闭而消失。而事实上在 FPGA 中通过 IP 核生成的 ROM 或 RAM 调用的都是 FPGA 内部的RAM 资源,掉电内容都会丢失(这也很容易解释,FPGA 芯片内部本来就没有掉电非易失存储器单元)。用 IP 核生成的 ROM 模块只是提前添加了数据文件(.coe 格式),在 FPGA 运行时通过数据文件给 ROM 模块初始化,才使得 ROM 模块像个真正”的掉电非易失存储器;也正是这个原因,ROM 模块的内容必须提前在数据文件中写死,无法在电路中修改。
2.ROM的初始化文件介绍
ROM 作为只读存储器,在进行 IP 核设置时需要指定初始化文件,即写入存储器中的数据,数据要以规定的格式才能正确写入 ROM,这种格式就是 coe 文件.coe 是 Vivado 规定的一种文件格式,如下图所示
如上图所示,该文件的格式较为简单,**第一行是定义数据的格式,其中 16 表示数据格式为 16 进制,**也可将数据格式定义为二进制和八进制,只需将 16 改为 2 或 8 即可。其中第 3 到第 18 行是 16*8bit 大小 ROM 的初始化数据。 上面用到了两个关键字,memory_initialization_radix 和 memory_initialization_vector。其中,memory_initialization_radix 是 ROM 初始化数值进制设置,对应后面 Value 值可设置 2,10,16,分别表示 2 进制,10 进制,16 进制。memory_initialization_vector 是 ROM 初始化数据向量,对应后面 Value 值就是填写 ROM 初始化的数据,数据与数据之间通过空格或逗号隔开,数据个数不允许超过设置 ROM 的深度(可以少于设置的深度),数据不允许为负数。 下图为在第三部分自己编写coe文件时的界面:
注:Key 和 Value 里面填写内容不区分大小写。
3.分布式ROM和块ROM简介
我们先新建 Vivado 工程,单击 IP Catalog,在右边窗口 Search 位置输入 rom,在 Memories &Storage Elements 下可以看到有两个与 ROM 相关的 IP,一个是 Distributed Memory Generator(分布式ROM),另一个是 Block Memory Generator(块ROM)。
前面仿真分布式 ROM 我们是自己编写 testbench 文件进行仿真,下面介绍一种 Vivado比较方便的功能,可以快速生成一个 Example Design 及相关的仿真文件。使用该功能对 IP的仿真和使用有很多可以值得借鉴的经验。在 PROJECT 窗口的 IP Sources 中找到我们生成的 block ROM IP ,右键找到 Open IP Example Design。
会弹出打开一个新的 Vivado 的窗口,并打开了 Example project。
可以看到,自动生成了一个顶层文件和相应的仿真 tb 文件。这个时候可以直接点击SIMULATION 下的 Run Simulation,点击 Run Behavioral Simulation 进行仿真,然后RUN ALL。 可以在 Vivado 下面 Tcl Console 窗口看到,打印信息,仿真测试成功。这个打印信息是tb 文件里的,可以在 tb 文件中找到这句话出处。
这里 tb 文件代码是 VHDL 语言编写,从代码上来看,仿真正确成功会打印“Test Completed Successfully”,仿真错误会打印"Simulation Failed",从 Tcl Console 窗口打印信息就可以比较清晰的看到仿真是 OK 的。 将 rom IP 的信号加入波形显示窗口,然后重新仿真