FPGA逻辑设计回顾(13)RAM以及ROM的IP核定制以及关键参数
文章目录
- 前言
- RAM IP的定制
- Xilinx的IP定制位置
- Block RAM的定制过程
- 第一页
- 第二页
- 第三页
- 第四页
- 第五页
- Block RAM的延迟讨论
- ROM IP核的定制
- 总结
前言
本文首发:FPGA逻辑设计回顾(13)RAM以及ROM的IP核定制以及关键参数
在后面讲解DDR IP的定制之前,这里先介绍下Xilinx的RAM以及ROM IP比较合适,因为都甚为存储性质的东西,有些东西还是可以作为比较的。
RAM中也有一些参数,也有一些延迟,需要注意!因为有时它的特性并非如我们想象的那样,正确的流程应该是先看数据手册,再使用,但是对于很多设计者来说,总感觉这玩意太简单,但越是这样可能越会用错,不注意延迟,可能会导致时序问题,进而导致功能性问题,最后是整个设计的失败。
好了,我们开始吧。
RAM IP的定制
Xilinx的IP定制位置
关于IP的这个最基础的内容,我们在这里只讲一次,可能没用过Xilinx的朋友以及新手朋友们可能需要:
Xilinx的IP核定制均在IP Catalog内:
Xilinx的RAM IP位于存储元素一类内部,如下图:
继续将小分类打开,可见:
我们的存储老朋友都在,第一个是DDR的控制接口,第二个是使用分布式资源的存储资源,第三个是Block资源的存储元素。
第一个放在后面的文章来讲解,我们先看第三个,Block资源的存储元素,以RAM为例,即BRAM。
Block RAM的定制过程
第一页
双击RAM,进入定制的第一页,第一页我们需要关注的内容如下:
定制的IP的名字只能在定制的时候更改,定制完成之后,不能再次更改,除非你删除自己定制的IP核,再次定制一个新的,那样比较麻烦,因此这里名字要按一个的规则写名字,一般而言,名字易懂即可,例如BRAM_16x1024,表示定制的是一个Block RAM,且位宽为16bit,深度为1024,关键信息一目了然。当然了,如果你的工程里用到了多个这种参数的RAM,你可以在后缀中加入更多的信息,例如功能性的信息,或者标号,即第几个这种RAM。
之后,我们在这一页需要关注的内容就是我们选用什么样的RAM,单端口还是双端口,这看你设计的需求。单端口适合先存储,之后过一段时间再取出,要分时使用,且最重要的是只能使用一个时钟,因为只有一个时钟端口。
对于双端口RAM而言,两边的端口都可以进行读写或存取,但在时序上也要求不能同时操作,例如对同一个地址同时进行读写,双端口的目的在于使用灵活,一端用于写,另一端可以用于读,且可以是不同的时钟域,功能划分清晰。
至于这一页的算法选择,可以关注也可以不关注,每一种选择都各有利弊,看你个人的选择,但我相信在你使用的时候,你可能想不到这一层面,到底我需要哪一种呢?自己也不清楚,还是暂时默认吧,无伤大雅。
第二页
定制第二页,是整个存储器定制的精华,也是我们最需要关注的内容,一般简单选择下就好了,选择满足我们功能的几个选项。
例如宽度与深度,操作模式呢?
可能不太需要吧,我们的使用场景尽量是分时使用,不能说一边写同时读那种吧。(如果你真的需要这种,那就不需要来看这篇博文了)
读写位宽可以不一致,这主要为位宽转换提供了方便,例如存两个数,取一次,就可以将两个数拼接在一起读出,这可以说是一种形式的串并转换了。
使能要不要选呢?
多一个选择多一条路,且这个选择不会对人造成困惑,如果没有特别需求,将其赋值为1即可。
至于输出寄存器放在哪一个位置,这个可以都选择,也可以只选择一个,带来的问题肯定是输出的延迟比较大。
例如我只选择了一个输出寄存器,看看延迟为多少?
延迟为2;
选择两个寄存器:
延迟为3。
但是好处在于选了后时序不会比不选差,原语处的寄存器位于原语内,IP核的寄存器位于FPGA的Fabric内。
该页最终的定制:
输出都是有延迟的,这一点后面的DDR也会有,需要当做常识。
第三页
第三页和第二页是同样的,只不过是定制B端口的内容,没有特别需求,建议保持一致。
第四页
上一页结束其实关键信息都已经选择,这一页对于RAM来说不太重要了,对于ROM来说可能很重要,因为ROM需要初始化内容, 后面就不写入了。
第五页
这一页是总结内容,告诉你的定制耗费了多少资源,输出相对于使能延迟了多少时钟,地址位宽是多少等。
到这里,我们就定制完了一个简单的真双端口BRAM IP核。
点击OK生成IP,之后复制IP核自带的例化模板使用即可。
双击Veo文件,即可得到IP模板:
//----------- Begin Cut here for INSTANTIATION Template ---// INST_TAG
bram_16x1024 your_instance_name (.clka(clka), // input wire clka.rsta(rsta), // input wire rsta.ena(ena), // input wire ena.wea(wea), // input wire [0 : 0] wea.addra(addra), // input wire [9 : 0] addra.dina(dina), // input wire [31 : 0] dina.douta(douta), // output wire [31 : 0] douta.clkb(clkb), // input wire clkb.rstb(rstb), // input wire rstb.enb(enb), // input wire enb.web(web), // input wire [0 : 0] web.addrb(addrb), // input wire [9 : 0] addrb.dinb(dinb), // input wire [31 : 0] dinb.doutb(doutb) // output wire [31 : 0] doutb
);
// INST_TAG_END ------ End INSTANTIATION Template ---------
加入到你的设计即可。
Block RAM的延迟讨论
这里的讨论,最主要的还是讨论下什么时候数据可以使用存入的数据而已,以上述定制的IP为例,我们我们令写使能有效6个时钟,即可入6个数据,然后将这6个数据从另外一端读出。
首先将BRAM例化一下:
`timescale 1ns / 1ps
//
// Engineer: 李锐博恩
// Create Date: 2021/02/06 18:57:57
// Module Name: bram_delay
//module bram_delay(input wire clka,input wire rsta,input wire ena,input wire [0 : 0] wea,input wire [9 : 0] addra,input wire [31 : 0] dina,output wire [31 : 0] douta,input wire clkb,input wire rstb,input wire enb,input wire [0 : 0] web,input wire [9 : 0] addrb,input wire [31 : 0] dinb,output wire [31 : 0] doutb);bram_16x1024 inst_bram_16x1024 (.clka(clka), // input wire clka.rsta(rsta), // input wire rsta.ena(ena), // input wire ena.wea(wea), // input wire [0 : 0] wea.addra(addra), // input wire [9 : 0] addra.dina(dina), // input wire [31 : 0] dina.douta(douta), // output wire [31 : 0] douta.clkb(clkb), // input wire clkb.rstb(rstb), // input wire rstb.enb(enb), // input wire enb.web(web), // input wire [0 : 0] web.addrb(addrb), // input wire [9 : 0] addrb.dinb(dinb), // input wire [31 : 0] dinb.doutb(doutb) // output wire [31 : 0] doutb);endmodule
使能的控制放在测试文件里做:
`timescale 1ns / 1ps
//
// Engineer: 李锐博恩
// Create Date: 2021/02/06 18:57:57
// Module Name: bram_tb
//module bram_tb();reg clk;reg rst;reg wea;reg [9 : 0] addra;reg [31 : 0] dina;wire [31 : 0] douta;reg enb;reg web;reg [9 : 0] addrb;reg [31 : 0] dinb;wire [31 : 0] doutb;localparam PERIOD_CLK = 5;initial beginclk = 0;forever begin#(PERIOD_CLK/2) clk = ~clk;endendinitial beginrst = 1'd1;wea = 1'd0;dina = 32'd0;addra = 10'd0;web = 1'd1;dinb = 32'd0;addrb = 10'd0;enb = 1'd0;//写6个时钟的数据#(15*PERIOD_CLK) rst = #(0.1) 1'd0;#(6*PERIOD_CLK);@(posedge clk);wea = #(0.1*PERIOD_CLK) 1'd1;dina = #(0.1*PERIOD_CLK) 32'h66;#(5 * PERIOD_CLK) beginwea = #(0.1*PERIOD_CLK) 1'd0;end//b端口读取6个数据#(15*PERIOD_CLK);@(posedge clk);enb = #(0.1*PERIOD_CLK) 1'd1;web = #(0.1 * PERIOD_CLK) 1'd0;repeat(5) begin@(posedge clk);addrb = #( 0.1*PERIOD_CLK )addrb + 10'd1;endendalways @(posedge clk or posedge rst) beginif(rst) begindina <= #(0.1) 32'd0;addra <= #(0.1) 10'd0;endelse if(wea)begindina <= #(0.1) dina + 32'd1;addra <= #(0.1) addra + 10'd1;endendbram_delay u_bram_delay(.clka ( clk ),.rsta ( rst ),.ena ( 1'd1 ),.wea ( wea ),.addra ( addra ),.dina ( dina ),.douta ( douta ),.clkb ( clk ),.rstb ( rst ),.enb ( enb ),.web ( web ),.addrb ( addrb ),.dinb ( dinb ),.doutb ( doutb ));endmodule
可见,我们的写使能持续了6个时钟:
这个效果靠的是下面这段测试代码实现:
//写6个时钟的数据#(15*PERIOD_CLK) rst = #(0.1) 1'd0;#(6*PERIOD_CLK);@(posedge clk); //wea的第一个有效周期wea = #(0.1*PERIOD_CLK) 1'd1;dina = #(0.1*PERIOD_CLK) 32'h66;repeat(5) begin //wea的后5个有效周期@(posedge clk);wea = #(0.1*PERIOD_CLK) 1'd1;end@(posedge clk);wea = #(0.1*PERIOD_CLK)1'd0;
读6个数据:
从给地址开始,延迟3拍出数据,这与定制的时候看到的延迟数为3一致。
ROM IP核的定制
关于ROM IP核的定制,没什么好说的,和RAM类似,但有一点就是需要进行初始化,初始化时初始化的数据使用COE文件来提供,而这个COE文件的格式为:
memory_initialization_radix = 16;memory_initialization_vector =23f4 0721 11ff ABe1 0001 1 0A 0 23f4 0721 11ff ABe1 0001 1 0A 0
即正常的文件加上两个开头,一个表明初始化数据的进制:memory_initialization_radix;
另一个表明初始化数据:memory_initialization_vector;
提供一个例子:
memory_initialization_radix = 2;
memory_initialization_vector =
00000000
00000001
00000010
00000011
总结
以上就是这篇文章的所有内容,很简单,主要是提供一个清晰地认识,为以后类似的存储器件作为对比,同时理解参数的延迟很重要,这对逻辑设计的时序十分关键。
FPGA逻辑设计回顾(13)RAM以及ROM的IP核定制以及关键参数相关推荐
- FPGA逻辑设计回顾(12)RAM以及ROM的RTL设计及其验证
前言 本文首发:FPGA逻辑设计回顾(12)RAM以及ROM的RTL设计及其验证 RAM以及ROM在FPGA中的实现大体有两种方式,一种是使用IP核定制,一种是RTL设计. 也许有人会反驳,那原语呢? ...
- FPGA逻辑设计回顾(11)FPGA以及PC中的RAM与ROM
文章目录 前言 RAM以及ROM在计算机中的应用 什么是存储器? 什么是硬盘驱动器? 其他类型的存储器 什么是RAM? RAM的类型 SRAM DRAM 什么是ROM? ROM的类型 掩膜ROM PR ...
- FPGA逻辑设计回顾(9)DDR的前世今生以及演变过程中的技术差异
文章目录 前言 DDR的前世SDRAM DDR的今生以及演变版本:DDR/DDR2/DDR3 DDR/DDR2/DDR3/DDR4之间简单对比 速度对比 电压对比 延迟对比 预取差异 电阻端接对比 物 ...
- FPGA逻辑设计回顾(10)DDR/DDR2/DDR3中的时序参数的含义
前言 本文首发自:FPGA逻辑设计回顾(10)DDR/DDR2/DDR3中的时序参数的含义 上篇文章:FPGA逻辑设计回顾(9)DDR的前世今生以及演变过程中的技术差异有提到,制造商会以一系列由破折号 ...
- FPGA逻辑设计回顾(8)单比特信号的CDC处理方式之Toggle同步器
文章目录 前言 脉冲反馈展宽同步器技术补充说明 RTL代码 行为仿真 低电平脉冲的展宽处理 切换同步器的原理与实现 RTL实现 前言 本文首发自:FPGA逻辑设计回顾(8)单比特信号的CDC处理方式之 ...
- FPGA逻辑设计回顾(1)新手易犯的逻辑综合错误之always块
前言 注:本文首发自FPGA逻辑设计回顾(1)新手易犯的逻辑综合错误之always块 本文中用到了如下的小标题: "心中有路"与综合推断 "心中无路"与无从推断 ...
- FPGA逻辑设计回顾(3)多比特信号上升沿检测的设计方式与陷阱?
前言 注:本文首发自FPGA逻辑设计回顾(3)多比特信号上升沿检测的设计方式与陷阱? 在总结本文最后的多比特上升沿检测之前,我们先把备用知识讲清楚,摊开来,以免造成模糊不清的默许! 逻辑运算符与位元运 ...
- FPGA逻辑设计回顾(6)多比特信号的CDC处理方式之异步FIFO
文章目录 前言 异步FIFO的概念 异步FIFO为什么可以解决CDC问题? 异步FIFO的RTL实现 参考资料 前言 异步FIFO是处理多比特信号跨时钟域的最常用方法,简单来说,异步FIFO是双口RA ...
- FPGA设计心得(9)基于DDS IP核的任意波形发生器设计
博文目录 写在前面 正文 设计要求 IP核配置 定制输出数据位宽 定制相位位宽(或频率分辨率) 输出频率 输出正余弦选择以及数据格式 其他设置 电路设计 行为仿真 参考资料 交个朋友 写在前面 数据手 ...
最新文章
- layoutSubviews 调用情况
- 单片机c语言的按键程序,51单片机按键扫描C程序
- C#:异步编程和线程的使用(.NET 4.5 ),异步方法改为同步执行
- vlc-android配置实录
- BC:带你温习并解读《中国区块链技术和应用发展白皮书》—区块链标准体系框架
- MyBitis(iBitis)系列随笔之二:类型别名(typeAliases)与表-对象映射(ORM)
- python服务器搭建 实战_实战讲解:如何用Python搭建一个服务器
- C++学习之路 | PTA乙级—— 1059 C语言竞赛 (20 分)(精简)
- 基于python实现resnet_【深度学习】基于Pytorch的ResNet实现
- error: undefined reference to `_imp__glXXX@XX'
- 自我理解的KMP 算法 模式匹配
- Spring的事务管理难点剖析(4):多线程的困惑
- 微机笔记2——8086/8088指令系统
- Fit项目分页组件的编写
- python中prime_在AP中查找第一个元素,该元素是Python中给定Prime的倍数
- golang中字符串常用的命令
- Educoder Java面向对象 - 常用类
- 数控系统数据采集协同架构,集成马扎克(mazak)、西门子(Siemens)、海德汉(heidenhain)、广数、凯恩帝(knd)、三菱、海德汉、兄弟、哈斯、宝元、新代、发那科(Fanuc)、华中
- vmware服务器虚拟化 pdf,VMware数据中心服务器虚拟化解决方案模板_V0.pdf
- tomcat连接mysql数据库_tomcat连接常用数据库的用法
热门文章
- java 二分查找
- java string出现次数_Java String方法获取字符出现次数及字符最大相同部分示例
- wincc报表步骤实例_Wincc 如何连接SQL Server 数据库
- px4驱动linux,px4开发指南——linux下qgroundcontrol地面站安装
- react 引入html文件_javascript – React:如何加载和呈现外部html文件?
- HashMap,LinkedHashMap,TreeMap的有序性
- arduino彩灯计时器电路_micro:bit是什么?和Arduino和单片机有什么不同?
- linux vim编辑器主要作用,Linux-vim编辑器
- b丅151组成的充电器电路_BT151S-500R118
- mysql 数据索引使用_mysql数据库正确建立索引及使用