13 双口 RAM IP 核
双口 RAM IP 核简介
双口 RAM IP 核有两个端口,它又分为伪双端口 RAM 和真双端口 RAM,伪双端口 RAM 一个端口只能读,另一个端口只能
写,真双端口 RAM 两个端口都可以进行读写操作。同时对存储器进行读写操作时就会用到双端口 RAM,例如有一个 FIFO 存储器,需要同时对其进行数据的写入和读出,这时候就需要一个写端口和一个读端口。
伪双端口 RAM
BMG IP 核配置成简单双端口 RAM 的框图如下图所示:

它有两组独立的端口 A 和 B,其中 A 端口只能提供了 DINA 数据总线,只能进行写操作,B 端口只提供了 DOUTB 数据总线,只能进行读操作,此外它相当于单口 RAM 还多出了以下信号线(在常规使用中一般不会关注这些信号线):
- IINJECTSBITERR:Inject Single-Bit Error 的简写,即注入单 bit 错误,仅适用于 Xilinx Zynq-7000 和 7系列芯片的 ECC 配置。
- IINJECTDBITERR:Inject Double-Bit Error 的简写,即注入双 bit 错误,同样仅适用于 Xilinx Zynq-7000和 7 系列芯片的 ECC 配置。
- SBITERR:Single-Bit Error 的简写,即单 bit 错误,标记内存中存在的单 bit 错误,该错误已在输出总线上自动更正。
- DBITERR:Double-Bit Error 的简写,即双 bit 错误,标记内存中存在双 bit 错误,需要注意的是内置的ECC 解码模块不能自动纠正双 bit 错误。
- RDADDRECC:Read Address for ECC Error output 的简写,即读地址 ECC 错误输出,同样仅适用于Xilinx Zynq-7000 和 7 系列芯片的 ECC 配置。
真双口 RAM
BMG IP 核配置成真双端口RAM 的框图如下图所示:

它有两组独立的端口 A 和 B,且每组端口都可进行读写操作。
不同 RAM 端口对比

通过对比可以发现无论是哪种双端口 RAM,其地址线、时钟线、使能线都有两组,所以双端口 RAM 可以实现在不同时钟域下的读/写,且可以同时对不同的地址进行读/写,这便大大提高了我们数据处理的灵活性。
读写冲突和写写冲突
写-写冲突:当两个端口都试图向同一个地址写数据(即两个端口写使能同时有效且写地址相同)时则会产生写-写冲突,发生写-写冲突后对应内存地址的数据为未知。
读-写冲突:一个端口进行读取数据操作,另一个端口进行写入数据操作,当同时操作到同一地址时就会发生读-写冲突,此时如果:
- 写端口为 READ_FIRST 模式,则读端口读出的数据为写入操作前存储在RAM中的数据。
- 写端口为 WRITE_FIRST 或 NO_CHANGE 模式,则读端口读出的数据为无效。
双口 RAM 配置核生成
打开 BMG IP 核的“Customize IP”窗口
- Vivado 工程左侧“Flow Navigator”栏中的“IP Catalog”

- 在“IP Catalog”窗口的搜索栏中输入“Block Memory”关键字后,出现唯一匹配的“Block Memory Generator”

- 双击“Block Memory Generator”后弹出 IP 核的配置界面

BMG IP 核有关伪双口 RAM 的配置
Block Memory Generator IP核的 IP Catalog 窗口如下,主要包括一个IP名称输入框核4个选项卡,页面依次进行介绍。

- 在“Component Name”一栏可以设置该 IP 元件的名称

- “Basic”选项卡

(1)“lnterface Type(接口模式)”:有两种接口模式可选,分别为 Native(常规)接口和 AXI4 接口。AXI4 模式一般是在处理器中的数据需要和 BRAM 交互时才会使用,当不需要与处理器数据进行交互时一般采用 Native 模式。
(2) “Generate address interface with 32 bits”选项为是否生成位宽为 32 的地址接口,勾选后内存的数据位宽也必须设置成 32 的整数倍,一般不做勾选。
(3) “Memory Type(存储类型)”:有五种类型可选,分别为“Single Port RAM(单端口RAM)”、“Simple Dual Port RAM(伪双端口 RAM)”、“True Dual Port RAM(真双端口 RAM)”、“Single Port ROM(单端口 ROM)”和“Dual Port ROM(双端口 ROM)”,这里以单端口 RAM 为例。
(4) “Common Clock”选项:是否启用同步时钟,Port A 和 Port B 在同一个时钟域时可以勾选也可以不勾选,在不同时钟域时不能勾选,否则跨时钟域会出问题。
(5) “ECC Options(ECC 选项)”:ECC纠错码选项只有在伪双端口 RAM 类型下才可以进行配置。
(6) “Write Enable(写使能)”:可以选择是否使用字节写使能功能,启用后可设置字节大小为 8 位或 9 位,需要注意的是启用后内存的数据位宽必须设置为所选字节大小的整数倍。
(7) “Algorithm Options(算法选项)”:算法选项主要用于决定 BRAM 的拼接的方式,一般在BRAM 深度、宽度较大的时候起作用,有三种算法可选,分别为“Minimum Area(最小面积算法)”、“Low Power(低功耗算法)”和“Fixed Primitives(固定单元算法)” - “Port A Options选项卡,Port A实现数据写入操作。

(1)“Memory Size(内存大小)”:用于指定端口宽度和深度、运行模式和使能端口类型。
- Port A Width;数据位宽,单位 bit,本次实验我们设置成 8,可设置的位宽范围为 1~4608。
- Port A Depth;深度,即 RAM 所能访问的地址范围。这里有一点需要注意,那就是写深度和写位宽的乘积不要超过器件本身的 ram 资源的大小。
- Operating Mode;RAM 运作模式,有三种模式可选,分别是Write First(写优先模式)、 Read First(读优先模式)、No Change(不变模式),单口 RAM 一般选 No Change(不变模式)。
- Enable Port Type;使能端口类型。有两种可选,分别为 Use ENA pin(添加使能端口 A 的信号)和 Always Enabled(取消使能信号,端口 A 一直处于使能状态)。
(2)“Port A Optional Output Register”:用于为 RAM 的输出端添加寄存器,Port A 不支持。
(3)“Port A Output Reset Options”:用于配置端口的复位信号。,Port A 不支持
(4)“READ Address Change A”:用于更改端口的读地址,这个功能只在 UltraScale 设备上使用。
- “Port B Options”选项卡,Port B 只支持读操作。

(1)“Memory Size(内存大小)”:用于指定端口宽度和深度、运行模式和使能端口类型。
- Port B Width;数据位宽,其位宽设置必须与 Port A 数据位宽存在倍数关系,通常情况下保持一致。
- Port B Depth;深度,当 Port B 数据位宽、Port A 数据位宽和深度的值确定后,Port B 深度的值就会自动确定。
- Operating Mode;RAM 运作模式,Port B 不可配置。
- Enable Port Type;使能端口类型。有两种可选,分别为 Use ENA pin(添加使能端口 A 的信号)和 Always Enabled(取消使能信号,端口 B 一直处于使能状态)。
(2)“Port B Optional Output Register”:用于为 RAM 的输出端添加寄存器。其作用是提高 BRAM 的运行频率和改善时序,当然为此付出的代价就是每勾选一个寄存器,输出就会延迟一拍。 - Primitives Output Register 使用 BRAM 内部的寄存器打拍输出。
- Core Output Register 使用 SLICE 的寄存器打拍输出。
- SoftECC Input Register 当使用软 ECC 的时候,用 SLICE 的寄存器打拍。
- REGCEA,当使用 Primitives Output Register 或者 Core Output Register 时,可以用 REGCEA 来使能相应的输出。
(3)“Port B Output Reset Options”:用于配置端口的复位信号。可以添加一个复位信号(RSTA Pin)、配置复位时 RAM 输出总线上的数据值(Output Reset Value)、配置是否复位内置锁存器(Reset Memory Latch)、配置复位信号与时钟使能之间的优先级(Reset Priority)。
(4)“READ Address Change B”:用于更改端口的读地址,这个功能只在 UltraScale 设备上使用。
- “Other Options”选项卡

(1)“Pipeline Stages within Mux”:输出端 Mux 选择器的流水线级数。在大位宽、大深度的 BRAM 拼接场景中会用 MUX 来选择输出地址所对应的数据,勾选该选项后可以使输出数据具有更好的时序。
(2)“Memory Initialization(初始化文件)”:选择是否使用本地初始化文件(.coe 文件)来对存储空间进行初始化。
(3)“Structural/UniSim Simulation Model Options”:用于选择结构仿真模型发生碰撞时生成的警告消息和输出的类型。
(4)“Behavioral Simulation Model Options”:用于关闭仿真时的冲突告警和超出范围告警。 - “Summary”选项卡

该界面显示了配置的存储器的类型,消耗的 BRAM 资源等信息,检查没问题可以直接点击“OK”按钮生成 RAM IP 核。

在弹出的“Generate Output Products”窗口直接点击“Generate”即可。

模块设计
本次实验的用 Xilinx BMG IP 核配置成一个伪装双口 RAM 并对其进行读写操作,系统框图如下:

编写代码
大多数情况下伪双口 RAM 都已经满足使用需求,入跨时钟域传输数据、存储数据、FIFO等,所以这里以伪双口 RAM 为例。
生成伪双口 RAM IP 核
伪双口 RAM IP 核的配置如下:



伪双口 RAM IP读写代码编写
在伪双口 RAM IP读写代码先例化一个伪双口 RAM IP核,在复位完成后开始通过 Port A 周期写入数据,当第一次写入到一半时启动 Port B 进行周期读数据,波形图如下:

module ram_ip_rw(input sys_clk,input sys_rst_n
);//端口 A 时钟
wire clka;
//端口 A 使能,高电平使能
reg ena;
//端口 A 写使能,高电平写入
reg wea;
//端口 A 地址
reg [5:0]addra;
//写入端口 A 的数据
wire [7:0]dina;//端口 B 时钟
wire clkb;
//端口 B 使能,高电平使能
reg enb;
//端口 B 地址
reg [5:0]addrb;
//端口 B 读出的数据
wire [7:0]doutb;//端口 A 时钟
assign clka = sys_clk;//端口 A 使能
always @(posedge sys_clk) beginif(!sys_rst_n)ena <= 0;elseena <= 1;
end//端口 A 写使能
always @(posedge sys_clk) beginif(!sys_rst_n)wea <= 0;elsewea <= 1;
end//端口 A 地址,0~63
always @(posedge sys_clk) beginif(!sys_rst_n)addra <= 0;else if((addra < 63) && (wea == 1))addra <= addra + 1;elseaddra <= 0;
end//端口 A 写入数据,从地址0~63依次写入如0~63
assign dina = (wea == 1) ? addra : 0;//端口 B 时钟
assign clkb = sys_clk;//端口 B 使能
always @(posedge sys_clk) beginif(!sys_rst_n)enb <= 0;else if(addra == 31)enb <= 1;
end//端口 B 地址,0~63
always @(posedge sys_clk) beginif(!sys_rst_n)addrb <= 0;else if((addrb < 63) && (enb == 1))addrb <= addrb + 1;elseaddrb <= 0;
end//例化伪双口RAM IP核
blk_mem_gen_0 u_blk_mem_gen_0_inst0(.clka(clka),.ena(ena),.wea(wea),.addra(addra),.dina(dina),.clkb(clkb),.enb(enb),.addrb(addrb),.doutb(doutb)
);endmodule
仿真激励代码编写
仿真激励代码非常简单,只需要例化 单口 RAM IP读写模块 ,然后产生一个周期时钟即可,完整的代码如下:
module tb_ram_ip_rw(
);reg sys_clk; //系统时钟
reg sys_rst_n; //系统复位,低电平有效//信号初始化
initial beginsys_clk = 1'b0;sys_rst_n = 1'b0;#200sys_rst_n = 1'b1;
end//产生时钟
always #20 sys_clk = ~sys_clk;//例化需要仿真的IP核
ram_ip_rw tb_u_ram_ip_rw_inst0(.sys_clk(sys_clk), //系统时钟.sys_rst_n(sys_rst_n) //系统复位,低电平有效
);endmodule
相关文章:
13 双口 RAM IP 核
双口 RAM IP 核简介 双口 RAM IP 核有两个端口,它又分为伪双端口 RAM 和真双端口 RAM,伪双端口 RAM 一个端口只能读,另一个端口只能 写,真双端口 RAM 两个端口都可以进行读写操作。同时对存储器进行读写操作时就会用到双端口 RAM…...
【高级数据结构】Trie树
原理 介绍 高效地存储和查询字符串的数据结构。所以其重点在于:存储、查询两个操作。 存储操作 示例和图片来自:https://blog.csdn.net/qq_42024195/article/details/88364485 假设有这么几个字符串:b,abc,abd&…...
国际化 Vue-i18n的安装与使用 (Vue2.0 / Vue3.0)
国际化 Vue-i18n的安装与使用 (Vue2.0 / Vue3.0) 一、Vue-i18n是什么? Vue-I18n是 Vue.js 的国际化插件。它可以轻松地将一些本地化功能集成到你的 Vue.js 应用程序中。简单来说就是可以帮助用户进行语言的切换” 二、使用步骤 1.引入库 代码…...
Linux 学习笔记(8)
八、 启动引导 1 、 Linux 的启动流程 1) BIOS 自检 2) 启动 GRUB/LILO 3) 运行 Linux kernel 并检测硬件 4) 挂载根文件系统 5) 运行 Linux 系统的第一个进程 init( 其 PID 永远为 1 ,是所有其它进程的父进程 ) 6) init 读取系统引导配置文件…...
【python】1.python3.12.2和pycharm社区版的安装指南
欢迎来CILMY23的博客喔,本篇为【python】1.python3.12.2和pycharm社区版的安装指南,感谢观看,支持的可以给个一键三连,点赞关注收藏。 目录 一、python3.12.2的下载与安装 1.1下载 1.2安装 二、pycharm的安装 2.1下载安装 2…...
Ubuntu将c++编译成.so文件并测试
一、准备cpp和h文件 创建test.cpp 在cpp中定义相加的函数funcAdd,给出函数的细节代码 #include <iostream> using namespace std;int funcAdd(int x, int y) {return xy; }创建test.h 在h中声明定义的函数,不需要任何细节 #ifndef __TEST__ #…...
数据分析-Pandas数据的探查面积图
数据分析-Pandas数据的探查面积图 数据分析和处理中,难免会遇到各种数据,那么数据呈现怎样的规律呢?不管金融数据,风控数据,营销数据等等,莫不如此。如何通过图示展示数据的规律? 数据表&…...
美团分布式 ID 框架 Leaf 介绍和使用
一、Leaf 在当今日益数字化的世界里,软件系统的开发已经成为了几乎所有行业的核心。然而,随着应用程序的规模不断扩大,以及对性能和可扩展性的需求不断增加,传统的软件架构和设计模式也在不断地面临挑战。其中一个主要挑战就是如…...
Ubuntu20.04: UE4.27 中 Source Code 的编辑器下拉框没有 Rider选项
问题描述 最近想用 Rider 作为 UE4 开发的 IDE,但安装好 Rider 后,发现编辑器下拉框中没有 Rider 的选项,我检查了 UE4 的插件,发现 Rider Integration 插件已经安装且启用的。 环境:Ubuntu 20.04 UE4.27 Rider2023…...
【论文阅读-PRIVGUARD】Day4:3节
3 PRIVANALYZER:强制执行隐私政策的静态分析 本节介绍PRIVANALYZER,这是一个用于强制执行由PRIVGUARD追踪的隐私政策的静态分析器**。我们首先回顾LEGALEASE政策语言,我们使用它来正式编码政策,然后描述如何静态地强制执行它们**…...
新一代电话机器人开源PHP源代码
使用easyswoole 框架开发的 新一代电话机器人开源PHP源码 项目地址:https://gitee.com/ddrjcode/robotphp 代理商页面演示地址 http://119.23.229.15:8080 用户名:c0508 密码:123456 包含 AI外呼管理,话术管理,CR…...
dockerdocker-copose_限制容器cpu和内存
本文目录 docker的限制方式限制CPU占用限制内存占用 docker-compose docker的限制方式 限制CPU占用 Docker使用--cpus参数来限制容器的CPU资源。该参数指定了分配给容器的CPU核心数量或百分比。 例子:限制CPU使用个数 docker run --cpus2 <imageName>以上…...
【leetcode】圆圈中最后剩下的数字
目录 1. 问题 2. 思路 3. 代码 4. 运行 1. 问题 本题即为典型的约瑟夫问题,通过递推公式倒推出问题的解。原始问题是从n个人中每隔m个数踢出一个人,原始问题变成从n-1个人中每隔m个数踢出一个人…… 示例 1: 输入: n 5, m 3 输出: 3…...
利用python批量将.shp文件转换坐标生成.geojson文件,再将.geojson转换成.csv文件,最后将csv文件插入数据库表
第一步:.shp批量转.geojson # author: JMY # 创建时间: 2024/2/26 17:12 # 批量将.shp文件生成geojson文件并转换坐标为3857import os import geopandas as gpd# 定义输入和输出文件夹路径 input_folder shp文件 output_folder geojson文件# 定义输入和输出坐标系…...
远程服务器Ubuntu 18.04安装VNC远程桌面
一、安装vnc 1.安装图形化界面工具 # 安装过程中会弹窗让选择配置,选lightdm sudo apt install ubuntu-desktop sudo apt-get install gnome-panel gnome-settings-daemon metacity nautilus gnome-terminal 2.安装vnc sudo apt-get install x11vnc3.安装LightD…...
30天自制操作系统(第23天)
23.1 编写malloc 参考第22天的内容,在绘制窗口前先分配了150*50个字节大小的内存,所以导致该文件经编译后有7.6k左右,能否在其中使用指针呢?当需要开辟空间时,移动指针即可。在之前的章节中也有函数memman_alloc函数可…...
基于Rust语言,和WebAssembly技术,与JavaScript结合,的具体应用场景
基于Rust语言与WebAssembly(Wasm)技术并与JavaScript结合,可以应用于多个场景,特别是在需要高性能和/或低级系统访问的情况下。下面是一些具体的应用场景: 性能密集型任务: Rust加上Wasm适合执行计算密集型任务&#x…...
【MATLAB源码-第154期】基于matlab的OFDM系统多径信道下块状和梳妆两种导频插入方式误码率对比仿真。
操作环境: MATLAB 2022a 1、算法描述 OFDM(Orthogonal Frequency Division Multiplexing,正交频分复用)是一种高效的无线信号传输技术,广泛应用于现代通信系统,如Wi-Fi、LTE和5G。OFDM通过将宽带信道划分…...
Linux 下 socket 编程介绍及 TCP 客户端与服务端创建示例
目录 socket 编程接口TCP 服务端TCP 客户端更多内容 本文介绍了 Linux 下的 socket 编程,及总结了使用 socket 接口实现 TCP 服务端和客户端的示例代码。 socket 编程接口 socket() 函数:用于创建一个新的 socket 描述符: int socket(int …...
JetBrains Gateway Github Copilot 客户端插件和主机插件
JetBrains Gateway可以通过插件支持Github Copilot(需另行注册)。 需要安装插件 客户端,而非插件 主机,如图所示: 大概是因为代码显示在客户端(运行在本地的IDE)?...
浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)
✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...
使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式
一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明:假设每台服务器已…...
.Net框架,除了EF还有很多很多......
文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...
java 实现excel文件转pdf | 无水印 | 无限制
文章目录 目录 文章目录 前言 1.项目远程仓库配置 2.pom文件引入相关依赖 3.代码破解 二、Excel转PDF 1.代码实现 2.Aspose.License.xml 授权文件 总结 前言 java处理excel转pdf一直没找到什么好用的免费jar包工具,自己手写的难度,恐怕高级程序员花费一年的事件,也…...
HTML 列表、表格、表单
1 列表标签 作用:布局内容排列整齐的区域 列表分类:无序列表、有序列表、定义列表。 例如: 1.1 无序列表 标签:ul 嵌套 li,ul是无序列表,li是列表条目。 注意事项: ul 标签里面只能包裹 li…...
css的定位(position)详解:相对定位 绝对定位 固定定位
在 CSS 中,元素的定位通过 position 属性控制,共有 5 种定位模式:static(静态定位)、relative(相对定位)、absolute(绝对定位)、fixed(固定定位)和…...
使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...
华硕a豆14 Air香氛版,美学与科技的馨香融合
在快节奏的现代生活中,我们渴望一个能激发创想、愉悦感官的工作与生活伙伴,它不仅是冰冷的科技工具,更能触动我们内心深处的细腻情感。正是在这样的期许下,华硕a豆14 Air香氛版翩然而至,它以一种前所未有的方式&#x…...
Ubuntu系统多网卡多相机IP设置方法
目录 1、硬件情况 2、如何设置网卡和相机IP 2.1 万兆网卡连接交换机,交换机再连相机 2.1.1 网卡设置 2.1.2 相机设置 2.3 万兆网卡直连相机 1、硬件情况 2个网卡n个相机 电脑系统信息,系统版本:Ubuntu22.04.5 LTS;内核版本…...
Java详解LeetCode 热题 100(26):LeetCode 142. 环形链表 II(Linked List Cycle II)详解
文章目录 1. 题目描述1.1 链表节点定义 2. 理解题目2.1 问题可视化2.2 核心挑战 3. 解法一:HashSet 标记访问法3.1 算法思路3.2 Java代码实现3.3 详细执行过程演示3.4 执行结果示例3.5 复杂度分析3.6 优缺点分析 4. 解法二:Floyd 快慢指针法(…...
