文章目录

  • 前言
  • 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核定制以及关键参数相关推荐

  1. FPGA逻辑设计回顾(12)RAM以及ROM的RTL设计及其验证

    前言 本文首发:FPGA逻辑设计回顾(12)RAM以及ROM的RTL设计及其验证 RAM以及ROM在FPGA中的实现大体有两种方式,一种是使用IP核定制,一种是RTL设计. 也许有人会反驳,那原语呢? ...

  2. FPGA逻辑设计回顾(11)FPGA以及PC中的RAM与ROM

    文章目录 前言 RAM以及ROM在计算机中的应用 什么是存储器? 什么是硬盘驱动器? 其他类型的存储器 什么是RAM? RAM的类型 SRAM DRAM 什么是ROM? ROM的类型 掩膜ROM PR ...

  3. FPGA逻辑设计回顾(9)DDR的前世今生以及演变过程中的技术差异

    文章目录 前言 DDR的前世SDRAM DDR的今生以及演变版本:DDR/DDR2/DDR3 DDR/DDR2/DDR3/DDR4之间简单对比 速度对比 电压对比 延迟对比 预取差异 电阻端接对比 物 ...

  4. FPGA逻辑设计回顾(10)DDR/DDR2/DDR3中的时序参数的含义

    前言 本文首发自:FPGA逻辑设计回顾(10)DDR/DDR2/DDR3中的时序参数的含义 上篇文章:FPGA逻辑设计回顾(9)DDR的前世今生以及演变过程中的技术差异有提到,制造商会以一系列由破折号 ...

  5. FPGA逻辑设计回顾(8)单比特信号的CDC处理方式之Toggle同步器

    文章目录 前言 脉冲反馈展宽同步器技术补充说明 RTL代码 行为仿真 低电平脉冲的展宽处理 切换同步器的原理与实现 RTL实现 前言 本文首发自:FPGA逻辑设计回顾(8)单比特信号的CDC处理方式之 ...

  6. FPGA逻辑设计回顾(1)新手易犯的逻辑综合错误之always块

    前言 注:本文首发自FPGA逻辑设计回顾(1)新手易犯的逻辑综合错误之always块 本文中用到了如下的小标题: "心中有路"与综合推断 "心中无路"与无从推断 ...

  7. FPGA逻辑设计回顾(3)多比特信号上升沿检测的设计方式与陷阱?

    前言 注:本文首发自FPGA逻辑设计回顾(3)多比特信号上升沿检测的设计方式与陷阱? 在总结本文最后的多比特上升沿检测之前,我们先把备用知识讲清楚,摊开来,以免造成模糊不清的默许! 逻辑运算符与位元运 ...

  8. FPGA逻辑设计回顾(6)多比特信号的CDC处理方式之异步FIFO

    文章目录 前言 异步FIFO的概念 异步FIFO为什么可以解决CDC问题? 异步FIFO的RTL实现 参考资料 前言 异步FIFO是处理多比特信号跨时钟域的最常用方法,简单来说,异步FIFO是双口RA ...

  9. FPGA设计心得(9)基于DDS IP核的任意波形发生器设计

    博文目录 写在前面 正文 设计要求 IP核配置 定制输出数据位宽 定制相位位宽(或频率分辨率) 输出频率 输出正余弦选择以及数据格式 其他设置 电路设计 行为仿真 参考资料 交个朋友 写在前面 数据手 ...

最新文章

  1. layoutSubviews 调用情况
  2. 单片机c语言的按键程序,51单片机按键扫描C程序
  3. C#:异步编程和线程的使用(.NET 4.5 ),异步方法改为同步执行
  4. vlc-android配置实录
  5. BC:带你温习并解读《中国区块链技术和应用发展白皮书》—区块链标准体系框架
  6. MyBitis(iBitis)系列随笔之二:类型别名(typeAliases)与表-对象映射(ORM)
  7. python服务器搭建 实战_实战讲解:如何用Python搭建一个服务器
  8. C++学习之路 | PTA乙级—— 1059 C语言竞赛 (20 分)(精简)
  9. 基于python实现resnet_【深度学习】基于Pytorch的ResNet实现
  10. error: undefined reference to `_imp__glXXX@XX'
  11. 自我理解的KMP 算法 模式匹配
  12. Spring的事务管理难点剖析(4):多线程的困惑
  13. 微机笔记2——8086/8088指令系统
  14. Fit项目分页组件的编写
  15. python中prime_在AP中查找第一个元素,该元素是Python中给定Prime的倍数
  16. golang中字符串常用的命令
  17. Educoder Java面向对象 - 常用类
  18. 数控系统数据采集协同架构,集成马扎克(mazak)、西门子(Siemens)、海德汉(heidenhain)、广数、凯恩帝(knd)、三菱、海德汉、兄弟、哈斯、宝元、新代、发那科(Fanuc)、华中
  19. vmware服务器虚拟化 pdf,VMware数据中心服务器虚拟化解决方案模板_V0.pdf
  20. tomcat连接mysql数据库_tomcat连接常用数据库的用法

热门文章

  1. java 二分查找
  2. java string出现次数_Java String方法获取字符出现次数及字符最大相同部分示例
  3. wincc报表步骤实例_Wincc 如何连接SQL Server 数据库
  4. px4驱动linux,px4开发指南——linux下qgroundcontrol地面站安装
  5. react 引入html文件_javascript – React:如何加载和呈现外部html文件?
  6. HashMap,LinkedHashMap,TreeMap的有序性
  7. arduino彩灯计时器电路_micro:bit是什么?和Arduino和单片机有什么不同?
  8. linux vim编辑器主要作用,Linux-vim编辑器
  9. b丅151组成的充电器电路_BT151S-500R118
  10. mysql 数据索引使用_mysql数据库正确建立索引及使用