IP核的使用之ROM(Vivado) |
您所在的位置:网站首页 › vivado顶层文件无效 › IP核的使用之ROM(Vivado) |
存储类IP核——ROM
文章目录
存储类IP核——ROM一.引言二.ROM IP核及相关内容扫盲1.ROM简介2.ROM的初始化文件介绍3.分布式ROM和块ROM简介4.单端口ROM和双端口ROM简介
三.分布式ROM IP核的创建四.分布式ROM IP核的测试仿真五.块ROM IP核的创建六.块ROM IP核的测试仿真
一.引言
在理论给大家介绍什么是ROM之前,先设想这么一个实际场景:现在有某芯片,它拥有500个寄存器,且需要在上电的时候由FPGA向这些寄存器中写入初始值,假设初始值已经通过相应的文档给出了具体值,这些值都是已知的。 这类实际需求有哪些特点呢? 1.数据量比较多 2.数据值都是已知的 3.数据内容不需要换 我们可以用什么办法来解决这个问题呢? 我们需要用一个存储器将这些数据先起来,使用的时候读取存储器就可以了。这个存储器只需要支持读功能就可以了。这就是ROM(read only memory) 实际应用有哪些呢? 1.DDS信号发生器(固定波形数据的形式) 2.对应CMOS摄像头初始化的应用 二.ROM IP核及相关内容扫盲 1.ROM简介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 规定的一种文件格式,如下图所示 我们先新建 Vivado 工程,单击 IP Catalog,在右边窗口 Search 位置输入 rom,在 Memories &Storage Elements 下可以看到有两个与 ROM 相关的 IP,一个是 Distributed Memory Generator(分布式ROM),另一个是 Block Memory Generator(块ROM)。 对于单端口 ROM 提供一个读地址端口和一个读数据端口,只能进行读操作;双端口 ROM 与单端口 ROM 类似,区别是其提供两个读地址端口和两个读数据端口,基本上可以看做两个单口 RAM 拼接而成。下面是 ROM 不同配置模式存储器的接口信号图 Distributed Memory Generator(分布式ROM) 是使用 LUT 资源创建的内存结构。主要可以用于创建以下内存类型: (1)Distributed ROM (2)Distributed Single-Port RAM (3)Distributed Dual-Port RAM (4)Distributed Simple Dual-Port RAM 使用Distributed Memory Generator 去生成的 ROM IP 是基于 LUT 的分布式 ROM 资源来创建深度为 16,位宽为 1bit 的 ROM,并通过生成一个基于结构的总线多路复用器来创建一个更深、更宽ROM。在 ROM 生成时,通过 vivado 加载一个内存初始化文件(COE 文件)来初始化该 ROM,IP 生成完后,ROM 存储的数据就固定了。分布式 ROM 原理图示意图和其实现框图如下。 这里除了实现例化需要仿真的文件以及时钟创建,还实现了地址数从 0 自加到 2559d,但是由于本 ROM 的最大数据个数是 255d,因此在 address第一次加满 255 后会重新从 0 开始自加,这样就有十个地址数循环。ROM_tb.v 文件代码如下: `timescale 1ns/1ns `define CLK_PERIOD 20 module ROM_tb; reg clk; reg [7:0]addr; wire [7:0]dout; wire [7:0]dout_reg; initial clk = 1; always #(`CLK_PERIOD/2) clk = ~clk; dist_mem_rom_ip rom ( .a(addr), // input wire [7 : 0] a .clk(clk), // input wire clk .spo(dout), // output wire [7 : 0] spo .qspo(dout_reg) // output wire [7 : 0] qspo ); integer i = 0; initial begin addr = 0; #21; for(i=0;i |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |