文章目录

  • 前言
  • 设计介绍
  • 关于仿真
  • 老生常谈
  • 最后想说的话

前言

RAM是一个好东西,FIFO也是,关键是适应你的设计场景,本文是一个记录性质的博文,所以也没必要什么都交代清楚了,只是在项目开发中,有过FIFO和RAM的取舍思考,最终 RAM更符合需求。
想到哪里写到哪里吧,正双口RAM,一边是A端口,另一边是B端口,A端口用于dsp总线(emif总线)写,写入RAM中,同时另一边仅仅用于读取写入的数据,可以说是一边写一边读了。

既然A端口是供dsp总线写,那么肯定有地址,因此这里选择RAM而非FIFO的因素大些(至于为什么想到了FIFO,还不是因为边读边写嘛)。

设计介绍

关于设计介绍,其实前言也已经说明了本次使用RAM的背景,也就是选择RAM的原因。
继续想到哪里说到哪里:
对于RAM的使用,在FPGA开发中,这里理所当然地使用了IP核,尽管我之前也写过多篇博文自己写过多种RAM,无论是同步读写,或者异步读写都有。
其中一些链接:同步读写双端口RAM

其实直接在我的博文首页搜索框中搜索RAM 即可:

博文首页地址:
申请了新域名,还挺满意!


当然,加上一系列综合属性,也可以控制FPGA使用资源了。
好了,这里就不磨叽了,直接使用IP核,还是比较信得过IP核,比较成熟,反正以后也是做FPGA的(又不是做IC逻辑设计),用IP核理所当然呢。
在IP的定制中,可以选择原语输出以及IP输出是否寄存?
当然,原语是更下层的东西,被iP核包裹,因此,如果选择某一个寄存,则输出肯定会延迟一拍,当然,选择二者都寄存,延迟两拍。
本设计选择了IP核寄存,又因为输出固有的一拍延迟,共两拍延迟(如果不信,可以都选上,看看最后结果是不是延迟三拍):

这在心里要有底,后面仿真会用到这里的信息。
由于A端口用来写,B端口用来读,因此A端口的输出douta就是废弃了,B端口的写数据dinb也废弃了,我的例化如下:

关于仿真

其实以上所说还都是废话,或者说不是我想 记录的东西,我想记录的东西在仿真方面:
先说正常的情况,在行为仿真时候,我们在时钟的下降沿给地址以及要写入a端口的数据,设计仿真文件如下:

`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2020/05/07 17:58:42
// Design Name:
// Module Name: gt0_data_gen_tb
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//module gt0_data_gen_tb();// User Interfacewire  [15:0]  TX_DATA_OUT;wire  [1:0]   TXCTRL_OUT;// System Interfacereg         USER_CLK;reg         SYSTEM_RESET; // Dsp Interfacereg  [10:0]    dsp_addr;reg  [15:0]    dsp_data;//____________________ generate clk ________________________________________initial beginUSER_CLK = 0;forever begin#5 USER_CLK = ~USER_CLK;end // end // // always begin// USER_CLK = 0;// #5   USER_CLK = ~ USER_CLK;// end // //__________________ generate address and data  ______________________________initial beginSYSTEM_RESET = 1;  dsp_addr = 0;dsp_data = 0;#14 SYSTEM_RESET = 0;#7forever begin@(negedge USER_CLK) begindsp_addr = dsp_addr + 1;dsp_data = dsp_data + 2;end // endend // //___________________ instantiate the module under test ______________________gt0_data_gen inst_gt0_data_gen(.TX_DATA_OUT  (TX_DATA_OUT),.TXCTRL_OUT   (TXCTRL_OUT),.USER_CLK     (USER_CLK),.SYSTEM_RESET (SYSTEM_RESET),.dsp_addr     (dsp_addr),.dsp_data     (dsp_data));endmodule

关键语句为:

initial beginSYSTEM_RESET = 1;  dsp_addr = 0;dsp_data = 0;#14 SYSTEM_RESET = 0;#7forever begin@(negedge USER_CLK) begindsp_addr = dsp_addr + 1;dsp_data = dsp_data + 2;end // endend //

我们进行行为仿真结果如下:
可见,在b端口给地址后,延迟两拍输出结果。符合预期:

当然,如果在上升沿给A端口地址和数据的话,因为是行为仿真,不考虑组合逻辑延迟之类的,我们肯定也能得到同样的结论,因为这是事实:

针对002地址输出,延迟两拍没有问题。
但对比下降沿存储时候还是有区别的,区别就是001地址哪去了?
(这里不得不提出必要说明,B端口的地址是A端口的地址延迟一拍所得!):

在上升沿对ram进行存储数据时候,仿真情况貌似看不出来B地址对A地址进行了延迟。
这一点在下降沿存储时候是可以看出的。
单纯的地址对比:
下降沿对A端口写数据:

上升沿对A端口写数据:

B端口001地址被吞了吗?

老生常谈

这还是一个老生常谈的话题:
先这样说吧,事实上,怎么会有这么巧的事情呢?
我们都知道,这个IP核在对A端口写数据是在时钟上升沿写数据的,而你在时钟上升沿给数据和地址,放在现实情况中,也就是板子上,存在延迟,就是建立时间不满足嘛!所以仿真的时候在下降沿或者什么地方(只要不是上升沿)给地址和数据,就不会出现这种仿真现象。
好了,你又要说了,那行为仿真不是没有延迟吗?也就是理想情况呀,即使在上升沿给数据以及地址,就写不进数据到RAM中吗?
当然不是呀,你不是也看了吗?从B端口也能读出写进去的数据呀!
只不过出现的问题是地址没有相对于写地址延迟明显的一个时钟?
其实不然,因为地址是你在仿真文件中直接给的,然后进入设计文件中,然后寄存地址,这一操作属于同步到时钟域操作,如果在寄存一拍,则就是同一个时钟域内的操作了,就可以明显看出一个时钟的延迟。

最后想说的话

这篇博客属于想到哪里写到哪来,到这里也告一段落了,至于这一篇博客最后的问题,和上升沿检测仿真时候一样,如果使用当前信号与延迟一拍的信号进行逻辑操作取得上升沿,也会出现这种情况,原因一致,何不同步一下,在延迟一拍,然后再取上升沿呢?
这就是解决之道。
最后想说的是,设想每年都会新建立一个微信群,供应届同行找工作讨论问题所用。
目前已经有两个群了,第一个是我那一届2019秋招,群已满,对于2020秋招,又新建了一个,供应届以及有兴趣的非应届的加入,共同讨论FPGA以及IC设计问题:

路过的同行可以加我微信(ljs521615)之后,进群,记得备注CSDN,我才知道是CSDN过来的。
IC/FPGA技术交流群2020

FPGA设计心得(1)真双口RAM使用及其仿真问题记录相关推荐

  1. xilinx 真双口RAM的primitives /core output 区别

    软件平台 Vivado 2016.4 属性设置说明 1在 ip catalog -> block memory generator . 这里仅介绍真双口RAM, 真双口RAM支持A/B两个口可读 ...

  2. 数字 IC 技能拓展(24)单口、伪双口、真双口 RAM、单口、双口 ROM 的区别与联系

    正文         打开 IP Catalog,搜索 Block Memory Generator,即可看到其 Memory Type 可分为 5 中,分别是单口 RAM(Single Port R ...

  3. 单口RAM、伪双口RAM、真双口RAM、单口ROM、双口ROM的区别

    单口RAM与伪双口RAM.真双口RAM的区别在于: 单口RAM只有一个时钟(clka)(时钟上升沿到来时对数据进行写入或读出).一组输入输出数据线(dina&douta).一组地址线(addr ...

  4. FPGA设计心得(4)Aurora IP core 的定制详情记录

    文章目录 写在前面 IP核定制页面预览 IP核定制详解 lane width Line Rate GT REFCLK (MHz) INIT clk (MHz) DRP clk (MHz) Datafl ...

  5. 最详细的FPGA的双口RAM乒乓操作与数据处理实例(第一部分)

    首先说明一下 代码都是自己完全手写的,如果有人看了我的代码,欢迎指出不足,写的不好也不要嘲笑,一个字一个字写出来的. - 1.目的 测试双口RAM的乒乓操作的功能,研究RAM输入输出操作,以及乒乓操作 ...

  6. FPGA:双口RAM

    Xilinx IP核构建双口RAM 双口RAM IP核配置 Verilog代码 top文件 testbench 仿真图 双口RAM 利用Xilinx提供的IP核构建真双口RAM,通过状态机实现从A口写 ...

  7. Vivado 双口RAM 的调用和实现

    1.双口RAM概述 双口RAM(dual port RAM)在异构系统中应用广泛,通过双口RAM,不同硬件架构的芯片可以实现数据的交互,从而实现通信.例如,一般情况下,ARM与DSP之间的通信,可以利 ...

  8. 面试准备FPGAor数字IC(三)-边沿检测、门控时钟、单双口RAM、亚稳态等

    边沿检测 思路:每个时钟的上升沿寄存数据,然后在每个时钟的上升沿判断 比如上升沿检测:a_n &&!a;下降沿检测!a_n && a; Verliog: module ...

  9. 单口RAM、双口RAM、FIFO

    单口RAM.双口RAM.FIFO 单口与双口 单口与双口的区别在于,单口只有一组数据线与地址线,因此读写不能同时进行:而双口有两组数据线与地址线,读写可同时进行:FIFO读写可同时进行,可以看作是双口 ...

最新文章

  1. 【java开发系列】—— JDK安装
  2. .NET Conf 2021 回顾
  3. android surfaceflinger 代码,android surfaceflinger测试程序
  4. Unity官方教程Ruby大冒险的自学笔记
  5. [转]Objective-C 语言特性
  6. 甘肃省计算机能力vf考试题库,计算机等级考试二级VF模拟试题十及答案解析
  7. python 学习过程总结
  8. 信用卡-可恶的招商银行,可恶的循环利息
  9. 6. 区别值类型和引用类型。
  10. 2021-2025年中国乙酰丙酸乙酯行业市场供需与战略研究报告
  11. cornerstone4.0下载安装
  12. 北京市植被指数(NDVI)数据
  13. Eclipse主题设置
  14. STM32实现四驱小车(二)通信任务——遥控器SBUS通信
  15. 华为android手机怎么解锁,华为手机如何解锁 华为手机解锁方法【图文详解】
  16. 一种基于区块链的物联网架构设计
  17. html5移动端海报制作,H5制作利器,教你分分钟制作高/大/上H5海报!
  18. oCPC和CPC之间的区别
  19. 计算机项目管理缩写,项目管理英文缩写!!!
  20. PR和AE有什么区别?

热门文章

  1. Quzrtz 使用oracle集群无法正常启动问题解决
  2. Memcached进程挂掉自动重启脚本
  3. Sun 认证考试是否合适于你?
  4. java自动布局_动态视图的自动布局约束
  5. kind富文本编辑器_富文本编辑器原理探索
  6. android intent例程,Android开发(四)| 探究活动(详解Intent+大量实例)
  7. python操作手机京东_Python实现自动上京东抢手机
  8. findwindowex子窗口类型有哪几种_光学玻璃有哪几种类别?一文告诉你
  9. 数据仓库中宽表的设计原则_实际项目中交互设计原则的运用
  10. matlab messagebox函数,[MATLAB]在C#中引用MATLAB函数