[米联客-XILINX-H3_CZ08_7100] FPGA程序设计基础实验连载-27浅谈XILINX BRAM的基本使用

软件版本:VIVADO2021.1

操作系统:WIN10 64bit

硬件平台:适用 XILINX A7/K7/Z7/ZU/KU 系列 FPGA

实验平台:米联客-MLK-H3-CZ08-7100开发板

板卡获取平台:https://milianke.tmall.com/

登录“米联客”FPGA社区 http://www.uisrc.com 视频课程、答疑解惑!

目录

1概述

2 BRAM RAM的应用形式

2.1单口ROM (Single-Port ROM)

2.2双口ROM(Dual-port ROM)

2.3单口RAM(Single-port RAM)

2.4简单双口RAM(Simple Dual-port RAM)

2.5真双口RAM(True Dual-port RAM)

3 BLOCK RAM的读写模式

3.1先写模式(Write First Mode)

3.2先读模式(Read First Mode)

3.3不变模式(No Change Mode)

4支持字节写入(BYTE Write)

5访问冲突 (Collision Behavior)

5.1异步时钟处理原则

5.2同步时钟处理原则

5.3简单的双端口RAM冲突

6输出寄存器

6.1通过无输出寄存器输出方式读取

6.2通过Primitives Output Register读取数据并实现rEad使能延迟

6.3使用两个流水线阶段读取数据的延迟

7添加BRAM IP

8读写BRAM代码

9仿真文件

10仿真结果


1概述

对于BRAM 详细的说明在XILINX 官方文档,pg058中有说明,我们这里仅对课程涉及的内容讲解。

Xlinx系列FPGA,包含两种RAM:Block RAM和分布式RAM(Distributed RAM),他们的区别在于,Block RAM是内嵌专用的RAM,而Distributed RAM需要消耗珍贵的逻辑资源组成。前者具有更高的时序性能,而后者由于分布在不通的位置,延迟较大。

2 BRAM RAM的应用形式

2.1单口ROM (Single-Port ROM)

单口ROM,就是数据只读的,需要在IP初始化的时候,对ROM进行初始化,而且只有一个读接口。

2.2双口ROM(Dual-port ROM)

端口A和端口B可以同时访问ROM

2.3单口RAM(Single-port RAM)

2.4简单双口RAM(Simple Dual-port RAM)

A端口写,B端口读

2.5真双口RAM(True Dual-port RAM)

A 端口和B端口都可以读或者写

3 BLOCK RAM的读写模式

支持3种模式,分别是Write First Mode, Read First Mode, No Change Mode

3.1先写模式(Write First Mode)

这种模式下:

1)写操作:设置WEA为1写入当前地址的数据,在下一个时钟DOUTA会输出这个地址新写入的数据

2)读操作:设置WEA为0读出当前地址的数据,在下一个时钟DOUTA会输出这个地址的数据

3.2先读模式(Read First Mode)

这种模式下:

1)写操作:设置WEA为1写入当前地址的数据,而且在下一个时钟DOUTA会输出这个地址的原先的数据

2)读操作:设置WEA为0读出当前地址的数据,在下一个时钟DOUTA会输出这个地址的数据

3.3不变模式(No Change Mode)

这种模式下:

1)写操作:设置WEA为1写入当前地址的数据,和前面两种方式不一样,DOUT保存不变

2)读操作:设置WEA为0读出当前地址的数据,在下一个时钟DOUTA会输出这个地址的数据

4支持字节写入(BYTE Write)

另外,BRAM还具备BYTE Write功能,这样可以只对某一个字节进行修改,从下图时序图可以看出,只要控制WEA就可以控制对具体哪一个BYTE进行写控制。

5访问冲突 (Collision Behavior)

BRAM 很好用,但是需要注意冲突的问题,就是对于同一个地址写或者读的时候需要注意。

5.1异步时钟处理原则

使用异步时钟,当一个端口将数据写入存储位置时,另一端口在指定的时间内不得读取或写入该位置。 器件数据手册中定义了该时钟到时钟的建立时间,以及其他Block RAM切换特性。这里说到的“ 时钟到时钟的建立时间”我还没注意到哪一个文档有说明。所以异步时钟可以通过长期的稳定性测试获取到这个时间间隔。

5.2同步时钟处理原则

同步写冲突:如果两个端口都试图写到内存中的同一位置,则会发生写写冲突。 内存位置的结果内容未知。 请注意,Write-Write冲突会影响内存内容,而Write-Read冲突只会影响数据输出

使用字节写入:使用字节写入时,在同一数据字中写入单独的字节时,存储器内容不会损坏。 仅当两个端口都试图写入同一字节时,RAM内容才会损坏。 下图说明了这种情况。 假设addra = addrb = 0

同步读写冲突:如果一个端口尝试写入内存位置而另一个端口读取相同的位置,则可能发生同步读写冲突。 虽然在写-读冲突中存储器的内容没有损坏,但是输出数据的有效性取决于写端口的工作模式。

a: 如果写入端口处于READ_FIRST模式,则另一个端口可以可靠地读取旧的存储器内容。

b: 如果写入端口处于WRITE_FIRST或NO_CHANGE模式,则读取端口的输出上的数据无效。

c: 如果是字节写入,则只有更新的字节在读取端口输出上无效,但是RAM中的内容是对的

下图说明了读写冲突和字节写入的影响。 当端口A处于WRITE_FIRST模式和READ_FIRST模式时,显示doutb。 假定addra = addrb = 0,端口B始终处于读取状态,并且所有内存位置均初始化为0。RAM的内容在读写冲突中不会被破坏。

5.3简单的双端口RAM冲突

对于简单双端口RAM,无论时钟如何,都可以使用READ_FIRST,WRITE_FIRST和NO_CHANGE工作模式。

简单双端口RAM就像真正的双端口RAM,其中仅连接了A端口的Write接口和B端口的Read接口。 工作模式定义了A或B端口的读写关系,并且仅在地址冲突期间影响A和B端口之间的关系。

对于同步时钟和冲突期间,可以配置端口A的写模式,以便对端口B的读操作可以产生数据(作用类似于READ_FIRST),也可以产生未定义的数据(Xs)。 因此,始终建议在配置为简单双端口RAM时使用READ_FIRST。 对于异步时钟,Xilinx建议将端口A的写入模式设置为WRITE_FIRST以确保碰撞安全。 有关此行为的详细信息,请参阅pg058第51页的冲突行为。

对于7系列设备,当RAM_MODE设置为ture dual port时,选定的操作模式将传递到Block RAM。 对于将RAM_MODE设置为simple dual port的原语,写模式为READ_FIRST用于同步时钟,而WRITE_FIRST用于异步时钟。

对于基于UltraScale架构的设备,没有限制,并且无论时钟如何,所选的操作模式总是传递给Block RAM原语。这一段说明,这种高级模式我们暂时不涉及。

其他内存冲突限制:地址空间重叠

7系列FPGA Block RAM存储器在以下配置中具有附加的冲突限制:

•当配置为真双端口(ture dual port)

•当CLKA(端口A)和CLKB(端口B)异步时

•在同时执行读写操作的应用程序中

•使用配置为READ_FIRST的写入模式配置端口A,端口B或两个端口时

上面文字描述中很多都在讲解冲突,其实对于我们的具体应用而言,更多时候我们BRAM是做乒乓使用的,也就是读地址和写地址,都是不会同时发生,而且时钟是同步的,这样就不容易发生冲突导致的数据破坏和不正确。

6输出寄存器

BRAM 可以设置有寄存器输出和无寄存器输出,下图是BRAM的框图结构

下图是有寄存器和无寄存器输出,可以达到的最高时钟频率的数据表,所以增加寄存器输出可以提高速度。我们例子中由于用到的演示时钟并没有很高所以不需要增加寄存器输出。

6.1通过无输出寄存器输出方式读取

6.2通过Primitives Output Register读取数据并实现rEad使能延迟

6.3使用两个流水线阶段读取数据的延迟

7添加BRAM IP

设置简单双口RAM

设置BRAM的端口A的宽度和深度

设置BRAM的端口B的宽度和深度,并且没有寄存器输出

这一页默认

单击OK

8读写BRAM代码

本代码的设计和FIFO使用非常类似

1)、写操作:写操作不断进行,每次写入1024个数据

2)、读操作:读操作是在每次写入达到512个数据开始的,当然实际上读操作完全可以和写操作同时进行,错开512个数据是为了方便观察现象。

/*************BRAM IP 测试********************************************
--BLOCK RAM 是FPGA内部自带的资源,BLOCK RAM分为硬核BLOCK RAM 和分布式BLOCK RAM(逻辑实现)
--BLCOK RAM 属于FPGA稀有资源,具有非常高效的访问速度和效率,比如FIFO实际也是用过BLOCK RAM实现
--本实验实现对 BLOCK RAM IP的仿真测试
*********************************************************************/
`timescale 1ns / 1ns //仿真时间刻度/精度module bram_test(
input I_rstn, //系统复位输入
input I_sysclk_p,
input I_sysclk_n //系统时钟输入
);wire I_clk;
IBUFGDS CLK_U(
.I(I_sysclk_p),
.IB(I_sysclk_n),
.O(I_clk)
);reg [9:0]addra;    //通道A 地址
reg [7:0]wr_frame; //帧计数器
reg [1:0]WR_S;     //写状态机
reg ena;           //通道A使能
reg wea;           //通道A写使能reg [9:0]addrb;   //读通道B地址
reg [1:0]RD_S;    //读状态机
reg enb;          //通道B使能wire [31:0] dina;    //bram 数据输入
wire [31:0] doutb;   //bram 数据输出assign dina = {wr_frame,wr_frame,addra[7:0],addra[7:0]};  //输入的数据包{帧信号,帧信号,通道A地址,通道A地址}always @(posedge I_clk)beginif(!I_rstn)begin //复位重置相关寄存器wr_frame <= 8'd0;addra    <= 9'd0;ena      <= 1'b1;wea      <= 1'b0; WR_S     <= 2'd0;endelse begincase(WR_S)0:beginaddra  <= 10'd0; //设置地址从0开始ena    <= 1'd1;  //设置通道A使能wea    <= 1'b1;  //设置写使能WR_S   <= 2'd1;  //下一个状态end1:beginif(addra != 10'd1023)begin //如果写地址不等于1023,wea   <= 1'b1; //设置写使能ena   <= 1'b1; //设置通道A使能addra <= addra + 1'b1;//那么通道A地址,每个时钟地址增加1endelse begin //否则代表完成了1帧数据写入到BRAMwea   <= 1'b0; //设置写使能为0,停止写ena   <= 1'b0; //设置通道A使能为0wr_frame <= wr_frame +1'b1;//帧计数器WR_S   <= 2'd2;//下一个状态endend2:beginif(RD_S == 2'd2) //如果读操作完成WR_S   <= 2'd0; //回到状态0重新开始enddefault:WR_S   <= 2'd0;endcaseend
endalways @(posedge I_clk)beginif(!I_rstn)begin //复位重置相关寄存器addrb    <= 9'd0;enb      <= 1'b0;RD_S     <= 2'd0;endelse begincase(RD_S)0:beginenb     <= 1'b0; //设置读使能0addrb   <= 10'd0; //设置读地址从0开始if(addra == 10'd512)begin//读数据在写数据的第512个地址开始enb   <= 1'b1; //使能读通道RD_S  <= 2'd1; //下一状态end   end1:beginenb    <= 1'b1;//设置读使能1if(addrb != 10'd1023)如果读地址不等于1023,addrb  <= addrb + 1'b1;//那么通道B地址,每个时钟地址增加1else RD_S   <= 2'd2;//下一状态end2:beginRD_S   <= 2'd0;//下一状态enddefault:RD_S   <= 2'd0;endcaseend
end   
//例化BRAM IP,简单双口RAM
blk_mem_gen_0 bram_inst (.clka(I_clk),    //通道A时钟输入.ena(ena),          //通道A使能.wea(wea),          //写使能.addra(addra),      //通道A地址.dina(dina),        //通道A数据输入.clkb(I_clk),    //通道B时钟输入.enb(enb),          //通道B使能.addrb(addrb),      //通道B地址.doutb(doutb)       //通道B数据输出); endmodule

9仿真文件

/*********************仿真文件****************************************
*********************************************************************/
`timescale 1ns / 1ns//仿真时间刻度/精度module tb_bram_test;localparam  SYS_TIME = 10 ;//定义时钟周期 单位nsreg   I_sysclk_p;
reg   I_sysclk_n; //系统时钟
reg   I_rstn;   //系统复位//例化bram_test 
bram_test bram_test_inst
(
.I_sysclk_p(I_sysclk_p),
.I_sysclk_n(I_sysclk_n),
.I_rstn(I_rstn)
);//初始化
initial beginI_sysclk_p  = 1'b0;I_sysclk_n  = 1'b1;I_rstn = 1'b0;#100;//产生100ns的系统复位I_rstn = 1'b1;//复位完成
end//产生仿真时钟
always #(SYS_TIME/2) I_sysclk_p= ~I_sysclk_p;
always #(SYS_TIME/2) I_sysclk_n= ~I_sysclk_n;                   endmodule

10仿真结果

箭头1 写开始

箭头2 写完1024个数据

箭头3 当写数据达到512个后开始读

箭头4 读完1024个数据

上图中,数据采用Primitives Output Register 方式数据延迟了3个时钟,这一点需要注意

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/52969.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C#/WinForm 演示遗传算法

一、一览 二、遗传算法流程 种群初始&#xff1a;随机生成一组N个DNA&#xff0c;每个DNA上都有S个基因&#xff0c;每个DNA都有自己的r值&#xff08;适度值&#xff09;。r最大的DNA为种群最优。 选择操作&#xff1a;将每个DNA的r值占总体的比例作为新一代选取的概率&#…

2024 【Delphi 12】苹果ios开发环境配置(五星保姆级)

目录 一、创建证书 1. 创建证书签名请求&#xff1a;&#xff08;在苹果电脑上操作&#xff09;&#xff1a; .certSigningRequest 文件 2. 创建证书&#xff1a;在苹果的 开发者网站 上操作 重复以上步骤并下载对应的证书文件如下&#xff1a; 3. 创建标识符&#xff08;…

Debezium+Kafka:Oracle 11g 数据实时同步至 DolphinDB 运维手册

目前我们已经支持基于开源技术 Debezium Kafka&#xff0c;从 Mysql 和 Oracle 11g 实时同步数据到 DolphinDB 中。由于当前方案涉及到四个程序的部署&#xff0c;而且具体的 Source 同步任务和 Sink 同步任务还需要额外管理&#xff0c;在运维上具有一定难度。 本文将基于 O…

Ecology10中的CAS身份认证问题

单点登录&#xff08;SSO&#xff09;是一种身份验证解决方案&#xff0c;可让用户通过一次性用户身份验证登录多个应用程序和网站。实现SSO的方式有很多种&#xff0c;比如Kerberos、SAML、OAuth2、JWT、OpenID、CAS、LDAP等。 CAS CAS (Central Authentication Service) 最初…

西中区2024年度安全知识竞赛活动方案

为有效预防安全生产事故的发生&#xff0c;深化西中区全体员工对安全生产的认识&#xff0c;切实提升全体人员的安全意识和自我保护能力&#xff0c;夯实安全知识基础&#xff0c;丰富安全文化内涵&#xff0c;推动安全生产工作更加规范化、系统化&#xff0c;根据西中区安全生…

git 回滚的三种方式

按照从旧到新的顺序 你依次提交了 1 2 3 4 5 现在你想回到1 如何操作 第一种方法 hard reset git reset --hard 执行命令后 你会发现 效果实现了 东西都回到了那次更改 但是2345的更改都没了 并且你会发现 你有更新 这是因为这个hard reset 只会改本地的 远程的不改 一更新就…

EasyCVR视频汇聚平台:巧妙解决WebRTC无法播放H.265视频的难题

随着科技的飞速发展&#xff0c;视频监控已经成为现代安全管理不可或缺的一部分&#xff0c;广泛应用于智慧工地、智慧煤矿、智慧工厂、智慧社区和智慧校园等多个领域。在这个过程中&#xff0c;视频编码技术和实时通信技术显得尤为重要。EasyCVR视频汇聚平台&#xff0c;凭借其…

Python爬虫(一文通)

Python爬虫&#xff08;基本篇&#xff09; 一&#xff1a;静态页面爬取 Requests库的使用 1&#xff09;基本概念安装基本代码格式 应用领域&#xff1a;适合处理**静态页面数据和简单的 HTTP 请求响应**。 Requests库的讲解 含义&#xff1a;requests 库是 Python 中一个…

机器人外呼有哪些优势?

机器人外呼&#xff0c;作为一种结合了计算机技术和人工智能技术的自动化工具&#xff0c;具有多重显著优势。以下是其主要优势的详细阐述&#xff1a; ### 1. 高效性 * **大幅提升工作效率**&#xff1a;机器人外呼可以全天候、不间断地进行工作&#xff0c;不受时间、地点和…

pytest+pycharm+HTMLTestReportCN实现接口自动化

前提&#xff1a;已安装pycharm&#xff0c;已配置python环境 第一步&#xff1a;新建一个py类&#xff0c;用来执行all的测试用例 import HTMLTestReportCN import unittest, os, yagmail# -*- coding: utf-8 -*- """ Time &#xff1a; 2024/9/2 14:50 Auth …

/单元测试

承接上文 统一异常处理&#xff0c;封装结果-CSDN博客 ******************************************** 登录业务 Service public class EmployeeServiceImpl extends ServiceImpl<EmployeeMapper, Employee> implements EmployeeService {Resourceprivate JwtUtils j…

数据库透明加密的定义与原理

数据库透明加密(TDE)是一种先进的加密技术&#xff0c;主要用于保护存储在数据库中的敏感数据&#xff0c;防止未经授权的访问和数据泄露。以下是对数据库透明加密的详细解析&#xff1a; 一、定义与原理 定义&#xff1a;数据库透明加密是一种在数据库管理系统(DBMS)中集成加密…

苹果笔记本电脑能不能玩游戏?苹果电脑玩游戏咋样?

过去Mac玩不了游戏最大的问题&#xff0c;就是图形API自成一体&#xff0c;苹果既不支持微软的DirectX&#xff0c;同时为了推广自家的Metal图形API&#xff0c;又对OpenGL和Vulkan两大主流的通用API敬而远之。游戏生态、硬件瓶颈让苹果电脑不适合玩游戏。 不过说到底&#xf…

点餐收银小程序

一、项目概述 Hi&#xff0c;大家好&#xff0c;今天分享的项目是《点餐收银小程序》。 系统含管理员/商家/用户三种角色&#xff0c;商家能维护菜式类别、维护菜品信息&#xff0c;用户在小程序能够选择门店&#xff0c;查看门店下各个分类的菜式信息&#xff0c;并进行加购…

ai免费生成ppt软件有哪些?我推荐秒出PPT

现在市面上的ai生成PPT软件非常的多。有收费的&#xff0c;也有不收费的&#xff0c;生成的效果也各不相同。要选择一个性价比高的确实难度不小。 我在使用了不少的产品之后&#xff0c;说一说我的心得。 首先就是&#xff0c;大部分免费的ai生成ppt产品并不好用。我怕不排除…

Cortex-A7的运行模式和寄存器组详解

0 参考资料 ARM Cortex-A(armV7)编程手册V4.0.pdf ARM体系结构与编程第2版2 Cortex-A7运行模式 2.1 运行模式 Cortex-A7共有9种运行模式&#xff0c;如下图所示&#xff1a; 除了用户模式之外其它模式均属于特权模式&#xff0c;在特权模式下处理器可以访问所有系统资源&am…

Golang | Leetcode Golang题解之第384题打乱数组

题目&#xff1a; 题解&#xff1a; type Solution struct {nums, original []int }func Constructor(nums []int) Solution {return Solution{nums, append([]int(nil), nums...)} }func (s *Solution) Reset() []int {copy(s.nums, s.original)return s.nums }func (s *Solu…

使用docker容器部署考试系统

8.30 回顾 1、使用harbor仓库 python --version yum -y update yum -y install python2-pip 部署考试系统 使用docker部署project-exam-system 1、在一台主机内&#xff0c;实现容器的编排看&#xff0c;发布考试系统 2、环境准备 docker docker-compose docker脚本 …

【Next】2. 项目构建

打开 Next.js 的官方文档&#xff1a;https://nextjs.org/docs/getting-started/installation&#xff08;国内文档不够新&#xff09; Next.js 版本 14.2 &#xff0c; Node.js 的版本要求必须 > 18.18。 Next 有两种开发模式&#xff0c;下面讲新的 APP Router。 创建项…

【R语言】基于Biomod2集成平台探究物种分布区的构建流程(SDMs)(持续更新中。。。。。。)

Species Distribution Models 1.写在前面2.物种分布模型介绍3.输入数据准备及预处理3.1.如何从GBIF网站上获取分布点数据&#xff08;基于rgbif包&#xff09;3.2.分布点稀疏处理&#xff08;基于spThin函数&#xff09;3.3.如何获取环境变量数据&#xff08;基于getData函数&a…