目录

一、ROM IP核

1.简介

2.创建立初始化文件

3.配置

4.调用

4.1 整体设计

4.2 编写rtl代码:

4.3 仿真验证

二、RAM IP核

1.简介

2.配置

3.调用

3.1 整体设计

3.2 rtl代码

3.3  仿真验证

前言:

本人使用的是野火家Xilinx Spartan6系列开发板及配套教程,写博客记录自己的学习。

开发软件:ise14.7     仿真:modelsim 10.5

一、ROM IP核

1.简介

ROM 是只读存储器(Read-Only Memory)的简称,是一种只能读出预先锁存数据的固态半导体存储器。其特性是一旦储存资料就无法再改变或删除,且资料不会因为电源关闭而消失。

ROM IP核是在 FPGA 中通过 IP 核生成的,调用的都是 FPGA 内部的 RAM 资源,掉电内容都会丢失(因为FPGA 芯片内部没有掉电非易失存储器单元)。所以要让 ROM 模块像个掉电非易失存储器要提前添加了数据文件(.coe 格式),让其上电就可以初始化。需注意不同的FPGA生产厂商后缀名是不一样的,Xilinx系列开发板是 .coe而Altera是 .mif。

Xilinx 推出的 ROM IP 核分为两种类型:单端口 ROM(Single-Port Rom)和双端口ROM(Dual-Port ROM),常用的是单端口。单端口 ROM 提供一个读地址端口和一个读数据端口,只能进行读操作;双端口 ROM 与单端口 ROM 类似,区别是其提供两个读地址端口和两个读数据端口,可看做两个单口 RAM 拼接而成。在使用ADDDRA与CLKA并使能ENA的情况下,ROM模块可以工作。

2.创建立初始化文件

第一行MEMORY_INITIALIZATION_RADIX=10; 是定义数据的格式,其中 10表示数据格式为 10进制,也可将数据格式定义为二、八、十六进制。 后面 MEMORY_INITIALIZATION_VECTOR= 是ROM 的初始化数据。

将文本格式(.txt)改为.coe就完成了初始化文件的创建。

3.配置

由于我已经配置完了,方便大家看我把教程提供的配置过程贴出来。

1.新建工程后,添加ROM IP核

2.选择我们需要生成的 IP 核

3.对前面过程 IP 核存储空间等信息的确认

4.    其中1 显示的是配置的 IP 核的输入输出接口框图; 2 框中是配置接口类型选择“本地”即可;3 框的“Datasheet”是下载 Xilinx 的官方 ROM & RAM 核数据手册,这个感兴趣可以看看。

5.  其中1选择 IP 核类型,选择“Single Port Rom”单端口 ROM。

在2中选择用于实现内存的算法,其中 Minimum Area 为最小面积算法; Low Power 为低功耗算法; Fixed Primitives 为固定单元算法;这里按默认选择Minimum Area 即可。

6.    1框中可设置存储数据的位宽和深度, “Read Width”是设置数据位宽,设置为 8 位; Read Depth 是设置数据深度,设置为 256;这样我们设置的 ROM ip核最大能存储的数据即为 256 x 8bit。
       2 框是选择启用类型,可以选择“Use ENA Pin” 添加 ENA 脚,利用该信号去使能端口的读写和复位, 这里我们省去麻烦不添加该信号, 默认选择“Always Enabled”始终启用即可。

7.   其中1是加载数据文件,就是前面创建的 ROM 初始化文件,勾选上“ Load Init File”点击 Browse 进行添加.coe 初始化文件。注意如果文件地址显示为红色这说明文件格式或者地址等有误,可以点击show查看。

8.   框中选项是选择是否创建复位信号,这里按默认不勾选即可。

9.    最后一步点击 Generate 完成单端口 ROM IP 核的生成。

配置完成会生成如下 .xco 文件

4.调用

实验目标:读出存储在ROM IP核中的数据。

4.1 整体设计

4.2 编写rtl代码:

打开工程目录下的 ROM IP 核保存位置,找到 rom.veo文件。

打开rom.veo文件,为了将ip核信号与顶层模块中信号连接,将红框内容复制到顶层模块中。

`timescale  1ns/1nsmodule  rom_top(input   wire            sys_clk     ,  input   wire            sys_rst_n    ,  output  wire      [7:0]  douta);
reg     [7:0]  addra; always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0)addra <= 8'd0;else if(addra == 8'd4)addra <= 8'd0;else addra <= addra + 1'b1;
//调用IP核
rom rom_inst(.clka (sys_clk),    .addra(addra),  .douta(douta)
);
endmodule

4.3 仿真验证

代码:

`timescale 1ns / 1nsmodule tb_rom_top();reg           sys_clk;reg           sys_rst_n;wire   [7:0] douta;    initial beginsys_clk = 1'b1;sys_rst_n <= 1'b0;#20sys_rst_n <= 1'b1;
end always #10 sys_clk = ~ sys_clk;rom_top rom_top_inst(.sys_clk   (sys_clk),.sys_rst_n  (sys_rst_n),.douta     (douta  ) );
endmodule

仿真结果:

由仿真结果来看,我们可以知道两点一、读取数据是按照先寻址的方式,二、观察地址8’d0可知,先存入的数据会被后来数据覆盖。

二、RAM IP核

1.简介

RAM 是随机存取存储器( Random Access Memory)的简称,是一个易失性存储器。RAM 工作时可以随时从任何一个指定的地址写入或读出数据,这是其与 ROM 的最大区别。 ROM 是只读存储器,而 RAM 是可写可读存储器。在FPGA中ROM本质只用到了RAM 资源的读数据端口。

Xilinx 推出的 RAM IP 核分为两种类型:单端口RAM 和双端口RAM。其中双端口RAM 又分为简单双端口 RAM 和真正双端口 RAM。对于单端口RAM,读写操作共用一组地址线,读写操作不能同时进行。单端口RAM各管脚作用:

DINA:写入数据位

DOUTA:读出数据位

ADDRA:读或写数据时地址位,读写不可同时进行

WEA:写使能端,高为写入数据,低为读出数据

ENA:读写信号使能端,高ROM读写功能有效,低禁止读或写

RSTA:复位端

REGCEA:读出寄存器使能端,当REGCEA为高电平时,DOUTA保持最后一次输出的数据。

CLKA: 时钟信号

2.配置

RAM配置过程中,输入的数据可以随时输入的,故不用事先创建初始化文件。下面详细介绍操作模式的意思。

操作模式:RAM 读写操作模式共分为三种。
Write First(写优先模式) : 若我们在同一个时钟沿下对同一个地址进行读写,则读出的数据为写入的数据。这里使用常规的写优先模式。
Read First(读优先模式) : 若我们在同一个时钟沿下对同一个地址进行读写, 则读出的数据为该地址写入数据前存储的数据。
No Change(不变模式) : 在该模式下不能同时进行读写操作, 输出数据为同时读写操作前输出的数据。

配置完成产生.xco文件

3.调用

实验目标:先写入数据,再读出数据

3.1 整体设计

3.2 rtl代码

`timescale  1ns/1nsmodule  ram
#(parameter CNT_MAX = 25'd999_999    //20ms
)
(input   wire            sys_clk     ,   input   wire            sys_rst_n   ,   output  wire    [7:0]   douta
);
reg             wea        ;   //写使能
reg    [24:0]   cnt_20ms   ;
reg    [3:0]    cnt        ;
reg    [7:0]    addr       ;   //地址线
reg    [7:0]    dina       ;   //写数据//计时20ms
always@(posedge sys_clk or  negedge sys_rst_n)if(sys_rst_n == 1'b0)cnt_20ms <= 25'b0;else if (cnt_20ms == CNT_MAX)cnt_20ms <= 25'b0;else cnt_20ms <= cnt_20ms + 1'b1;
//cnt:以20ms为单位,计0-8个数
always@(posedge sys_clk or  negedge sys_rst_n)if(sys_rst_n == 1'b0)cnt <= 4'b0;else if(cnt == 4'd9 && cnt_20ms == CNT_MAX)cnt <= 4'd0;else if(cnt_20ms == CNT_MAX)cnt <= cnt + 1'b1;
//addr:地址
always@(posedge sys_clk or  negedge sys_rst_n)if(sys_rst_n == 1'b0)addr <= 8'd0;else if(cnt < 4'd4 && cnt_20ms == CNT_MAX)addr <= addr + 8'd1;else if ((cnt > 4'd4 && cnt < 4'd9) && cnt_20ms == CNT_MAX)addr <= addr - 8'd1;always@(posedge sys_clk or  negedge sys_rst_n)if(sys_rst_n == 1'b0)wea <= 1'b0;else if (cnt == 4'd4 && cnt_20ms == CNT_MAX)wea <= 1'b0;else if (cnt < 4'd5)wea <= 1'b1;   //存入数else wea <= 1'b0;   //读取数据
always@(posedge sys_clk or  negedge sys_rst_n)if(sys_rst_n == 1'b0)dina <= 8'd2;else if (dina  == 8'd10  &&  cnt_20ms == CNT_MAX )dina <= 8'd2;else if (cnt_20ms == CNT_MAX)dina <= dina + 8'd2;//调用ip核  RAM是建立的RAM ip核
ram_ip   ram_ip_inst
(.addra      (addr       ), .clka       (sys_clk    ), .dina       (dina       ), .wea        (wea        ), .douta      (douta    )
);
endmodule

3.3  仿真验证

仿真代码:

`timescale  1ns/1nsmodule  ram
#(parameter CNT_MAX = 25'd999_999    //20ms
)
(input   wire            sys_clk     ,   input   wire            sys_rst_n   ,   output  wire    [7:0]   douta
);
reg             wea        ;   //写使能
reg    [24:0]   cnt_20ms   ;
reg    [3:0]    cnt        ;
reg    [7:0]    addr       ;   //地址线
reg    [7:0]    dina       ;   //写数据//计时20ms
always@(posedge sys_clk or  negedge sys_rst_n)if(sys_rst_n == 1'b0)cnt_20ms <= 25'b0;else if (cnt_20ms == CNT_MAX)cnt_20ms <= 25'b0;else cnt_20ms <= cnt_20ms + 1'b1;
//cnt:以20ms为单位,计0-8个数
always@(posedge sys_clk or  negedge sys_rst_n)if(sys_rst_n == 1'b0)cnt <= 4'b0;else if(cnt == 4'd9 && cnt_20ms == CNT_MAX)cnt <= 4'd0;else if(cnt_20ms == CNT_MAX)cnt <= cnt + 1'b1;
//addr:地址
always@(posedge sys_clk or  negedge sys_rst_n)if(sys_rst_n == 1'b0)addr <= 8'd0;else if(cnt < 4'd4 && cnt_20ms == CNT_MAX)addr <= addr + 8'd1;else if ((cnt > 4'd4 && cnt < 4'd9) && cnt_20ms == CNT_MAX)  //addr数据维持addr <= addr - 8'd1;always@(posedge sys_clk or  negedge sys_rst_n)if(sys_rst_n == 1'b0)wea <= 1'b0;else if (cnt == 4'd4 && cnt_20ms == CNT_MAX)  //占用一个脉冲,使wea严格对齐cnt。cnt为0-4是wea为高,5—9为低wea <= 1'b0;else if (cnt < 4'd5)wea <= 1'b1;   //存入数else wea <= 1'b0;    //读取数据  always@(posedge sys_clk or  negedge sys_rst_n)if(sys_rst_n == 1'b0)dina <= 8'd2;else if (dina  == 8'd10  &&  cnt_20ms == CNT_MAX )dina <= 8'd2;else if (cnt_20ms == CNT_MAX)dina <= dina + 8'd2;//调用ip核  RAM是建立的RAM ip核
ram_ip   ram_ip_inst
(.addra      (addr       ), .clka       (sys_clk    ), .dina       (dina       ), .wea        (wea        ), .douta      (douta    )
);
endmodule

仿真结果:

由仿真结果说明,当wea为低电平时,写数据功能失效,此时按照地址读数据。

FPGA中ROM IP与RAM IP核配置与调用相关推荐

  1. 【RAM IP】RAM IP核简介及实验

    RAM简介: RAM(Random Access Memory),即随机存取存储器.它是双端口的,它可以随时把数据写入任一指定地址的存储单元,也可以随时从任一指定地址中读出数据,其读写速度是由时钟频率 ...

  2. FPGA中DDR3 MIG ip核使用说明

    此篇是我在学习中做的归纳与总结,其中如果存在版权或知识错误请直接联系我,欢迎留言. PS:本着知识共享的原则,此篇博客可以随意转载,但请标明出处! 目录 1.DDR3工作原理 简介: DDR基础操作步 ...

  3. Quartus ii 中ROM ip核的应用

    ROM: read only memory: 掉电不丢失数据 RAM可以被配置为ROM 实验内容: 将一组固定数据(三角波)存储在FPGA中使用IP核构建的片上ROM中,开发板上电后,系统开始从ROM ...

  4. FPGA 单端口RAM IP核使用 vivado仿真

    一.各类存储器简介 ROM:只读,只有读接口(读地址.读数据) RAM:可读可写,有读接口(读地址.读数据)和写接口(写使能.写数据.写地址),默认任何时刻都能读,没有读使能,大小和位宽查手册,需要持 ...

  5. ZYNQ之FPGA学习----RAM IP核使用实验

    1 RAM IP核介绍 RAM 的英文全称是 Random Access Memory, 即随机存取存储器, 它可以随时把数据写入任一指定地址的存储单元,也可以随时从任一指定地址中读出数据,其读写速度 ...

  6. FPGA中ISE软件调用IP核导入(.coe)文件并绘制正弦函数

    作为一个FPGA小白,本人在学习FPGA软件的过程中看到了这个例子,网上也有相关的教程,奈何实在写的不清楚,我自己花了挺久才弄懂,为了在以后学习中少走弯路,把自己学习到的做个教程吧,供同样是小白的同学 ...

  7. FPGA中如何使用加法器IP核设计累加器

    使用加法器IP核设计累加器 前言 一.顺序累加器设计 二.滑动累加器设计 总结 前言 在之前的一个项目中,我的工程一部分运算中主频达到了400MHz时钟.当时的运算需要用到cnt累加器,但是在最后的综 ...

  8. SPI和RAM IP核

    学习目的: (1) 熟悉SPI接口和它的读写时序: (2) 复习Verilog仿真语句中的$readmemb命令和$display命令: (3) 掌握SPI接口写时序操作的硬件语言描述流程(本例仅以写 ...

  9. ISE使用中RAM IP核配置及ram测试(两种测试)

    简单总结ISE中RAM的ip核配置过程以及相关的端口. 分类 ram分为分布式ram(distributed ram)以及块ram(block ram) 前者是自己用寄存器搭建的,这里理解可以转至Vi ...

最新文章

  1. nginx访问日志,错误日志参数说明
  2. 边工作边刷题:70天一遍leetcode: day 98
  3. Vue3 --- vue-router4 编程导航
  4. 此“小霸王”非彼小霸王?官方声明:小霸王并未破产!
  5. 简单python脚本实例-30个Python 小例子,帮你快速上手Python
  6. 通过bin-log对mysql进行数据恢复
  7. 讯飞输入法pad版x86_讯飞输入法Pad版x86版
  8. Python爬虫学习,记一次抓包获取js,从js函数中取数据的过程
  9. 迅雷x导入未完成任务失败的解决办法。
  10. 知道吗?借助InterSystems Caché数据库,欧洲航天局正在绘制银河系最大的地图
  11. Python 测试题(覆盖了大多数的基础知识和进阶)
  12. 中国古代兵器与兵书·铁马驰骋
  13. 编写函数,对传送过来的三个数选出最大值和最小值,并通过形参传回调用函数
  14. 4.树和二叉树——数据结构 (严蔚敏C语言版)
  15. 关于公众号的运营干货与常用的工具
  16. idea中java文件都不能运行变成橙色文件
  17. python合成心形_python如何绘制心形
  18. 【C++实现】编译原理 免考小队 NFA转换为等价的DFA
  19. GK_Zone与GK_CM的区别
  20. Golang配合QQ机器人获取Pixiv ea7e6c5a5f673669f0d56d8f39056eae每日列表并发送涩图(未完)

热门文章

  1. 【论文】文本相似度计算方法综述
  2. 海外SDK之----------苹果支付
  3. VSCode配置C++环境【报错interpreter=mi】
  4. 0基础成功转行Python自动化测试工程师,年薪30W+,经验总结都在这(建议收藏)
  5. JEECG Excel 工具类
  6. php获取蓝凑云文件列表,PHP获取蓝奏云直链方法
  7. xcode mac app_IOS苹果APP签名详解
  8. iphone手游模拟器_如何将iPhone用作手电筒
  9. 学习vba之按列合并将选定区域的单元格合并成一列
  10. 微博实时号权重是什么,如何养成高权重高的号