FPGA简单双端口RAM——IP核

news2024/12/22 19:22:48

文章目录

  • 前言
  • 一、双端口 RAM
    • 1、简单双端口与真双端口
    • 2、简单双端口RAM框图
  • 二、 IP核配置
    • 1、RAM双端口 IP 核配置
    • 2、PLL IP 核配置
  • 三、源码
    • 1、ram_wr(写模块)
    • 2、ram_rd(读模块)
    • 3、ip_2port_ram(顶层文件)
  • 四、仿真
    • 1、仿真文件
    • 2、波形仿真
  • 五、SignalTap II在线验证
  • 六、总结
  • 七、参考资料


前言

环境:
1、Quartus18.0
2、vscode
3、板子型号:原子哥开拓者2(EP4CE10F17C8)
要求:
使用 Altera RAM IP 核生成一个简单双端口的 RAM,然后对 RAM 进行读写操作,并通过 Modelsim 软件进行仿真及 SignalTap 软件进行在线调试。


一、双端口 RAM

由前面的单端口学习我们知道RAM IP核分为单端口RAM以及双端口RAM,即RAM IP核的读写端口数。对于单端口,读写共用一对地址线,所以无法同时读写不同地址的数据。对于双端口,读写地址线是分开的,所以具备同时读写能力

1、简单双端口与真双端口

双端口 RAM 又分为简单双端口 RAM 和真双端口 RAM,顾名思义,简单双端口 RAM 虽然有两个端口,但是一个端口只能用来写,另一个端口只能用来读,所以简单双端口 RAM 也称为伪双端口 RAM。而真双端口 RAM 是指两个端口都可以用来写或者读,可以理解成具有两个独立的单端口的 RAM,一般用于需要多路写入和读出的情况,而不用例化两个单端口的 RAM,在使用上更为方便。

  • 简而言之,在都需要读写的情况下,如果需要多路写入、读出的情况则选择真双端口。

2、简单双端口RAM框图

  • 模块框图:
    在这里插入图片描述
  • 端口框图:
    在这里插入图片描述
  • 端口描述:

data:RAM 写数据端口;
wraddress:RAM 写地址端口;
wren:写使能信号,高电平有效;
byteena:字节使能控制,该功能屏蔽了输入数据,这样仅写入数据中指定字节,未被写入的字节保留之前写入的值。当写入数据的位宽为 16 位、18 位、32 位和 36 位时,M9K 模块将支持字节使能,wren 信号以及字节 byteena 信号一起控制 RAM 模块的写操作。byteena 信号在 RAM IP 核创建过程中是可选的,可选择是否使用字节使能控制功能。
wr_addressstall:写地址时钟使能控制,当 wr_addressstall 信号为高电平时,有效地址时钟使能就会保持之前的地址。wr_addressstall 信号在 RAM IP 核创建过程中是可选的,可选择是否使用地址使能控制功能。
wrclock:写时钟;
wrclocken:写时钟使能信号,高电平有效;
aclr:异步复位信号,高电平有效;
rdaddress:RAM 读地址端口;
rden:读使能信号,高电平有效;
q:从 RAM 中读出的数据;
rd_addressstall:读地址时钟使能控制,当 rd_addressstall 信号为高电平时,有效地址时钟使能就会保持之前的地址。rd_addressstall 信号在 RAM IP 核创建过程中是可选的,可选择是否使用地址使能控制功能。
rdclock:读时钟;
rdclocken:读时钟使能信号,高电平有效;

二、 IP核配置

1、RAM双端口 IP 核配置

  • 查找RAM IP:
    在这里插入图片描述
  • 双击过后添加IP核路径以及命名文件:
    在这里插入图片描述
  • 选择端口类型以及存储器大小:

在这里插入图片描述

上面的选项是选择简单双端口还是真双端口;下面一个是用于指定存储器大小的单位words or bits。

  • 设置RAM的存储深度以及位宽:
    在这里插入图片描述
  • 勾选独立时钟以及读使能信号:
    在这里插入图片描述

“What clocking method do you want to use?”:用于设置双端口 RAM 的时钟,此处选择第二个(Dualclock:use separate ‘read’ and ‘write’ clocks),即写端口和读端口选择独立的时钟。
“Create a ‘rden’ read enable signal”:选择是否勾选读使能信号,如果不勾选则一直在读。

  • 取消寄存输出信号q:
    在这里插入图片描述

这里如果选中的话,从RAM中读到的q会多延时一个时钟周期输出。

  • 保持对RAM的初始化:
    在这里插入图片描述
  • 保持默认,next:
    在这里插入图片描述
  • 勾选ram_2_inst.v 和 ram_2_bb.v:
    在这里插入图片描述
  • 点击finish过后点击YES将IP核添加到工程:
    在这里插入图片描述
  • 效果:
    在这里插入图片描述

2、PLL IP 核配置

由于之前的文章早已详细介绍过,这里不在进行赘述:
IP核简介及PLL_IP核的调用

三、源码

我们配置了IP但我们仍然需要写驱动文件去调用他们。

1、ram_wr(写模块)

module ram_wr (
    input               clk         ,
    input               rst_n       ,

    output              ram_wr_en   ,//写使能
    output reg [4:0]    ram_wr_addr ,//写地址
    output reg [7:0]    ram_wr_data  //写数据
);
/*****************
该写模块中,在计数器从0累加到31时向ram写入数据,在到达63后计数器保持不变
该模块只在上电后写入一次
******************/
reg [5:0] wr_cnt;
//写使能在计数到0~31是为高电平
assign ram_wr_en = ((wr_cnt >= 6'd0) && (wr_cnt <= 6'd31) && rst_n) ? 1'b1 : 1'b0;

//计数器
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)begin
        wr_cnt <= 6'd0;
    end
    else if(wr_cnt == 6'd63)
        wr_cnt <=wr_cnt;
    else
        wr_cnt <= wr_cnt + 1'b1;
end

//产生写数据信号
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)
        ram_wr_data <= 8'd0;
    else if(wr_cnt >= 6'd0 && wr_cnt <= 6'd31)
        ram_wr_data <= ram_wr_data + 1'b1;
    else
        ram_wr_data <= 8'd0;
end

//写地址信号
always @(posedge clk or negedge rst_n) begin
    if(!rst_n)
        ram_wr_addr <= 5'd0;
    else if(wr_cnt >= 6'd0 && wr_cnt <= 6'd31)
        ram_wr_addr <= ram_wr_addr + 1'b1;
    else
        ram_wr_addr <= 5'd0;
end
endmodule

2、ram_rd(读模块)

module ram_rd(
    input               clk             ,
    input               rst_n           ,
    input   [7:0]       ram_rd_data     ,//读数据

    output              ram_rd_en       ,//读使能
    output  reg [4:0]   ram_rd_addr      //读地址
);

reg [5:0] rd_cnt;

assign ram_rd_en = ((rd_cnt >= 6'd0) && (rd_cnt <= 6'd31) && rst_n) ? 1'b1 :1'b0;

//读计数器
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)
        rd_cnt <= 6'd0;
    else if(rd_cnt == 6'd63)
        rd_cnt <= 6'd0;
    else
        rd_cnt <= rd_cnt + 1'b1;
end

//读地址范围
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)
        ram_rd_addr <= 5'd0;
    else if(rd_cnt >= 6'd0 && rd_cnt <= 6'd31)
        ram_rd_addr <= ram_rd_addr + 1'b1;
    else
        ram_rd_addr <= 5'd0;
end
endmodule

3、ip_2port_ram(顶层文件)

module  ip_2port_ram(
    input     sys_clk   ,
    input     sys_rst_n

);

wire clk_50m;
wire clk_25m;
wire locked;
wire rst_n;

wire       ram_wr_en  ;
wire [4:0] ram_wr_addr;
wire [7:0] ram_wr_data;

wire       ram_rd_en  ;
wire [4:0] ram_rd_addr;
wire [7:0] ram_rd_data;

assign rst_n = sys_rst_n & locked;
//锁相环,用于产生两个时钟
pll_clk pll_clk_inst(
	.areset         (~sys_rst_n),
	.inclk0         (sys_clk),
	.c0             (clk_50m),
	.c1             (clk_25m),
	.locked         (locked)
);
//RAM写模块
ram_wr ram_wr_inst(
    .clk            (clk_50m),
    .rst_n          (rst_n),

    .ram_wr_en      (ram_wr_en  ),//写使能
    .ram_wr_addr    (ram_wr_addr),//写地址
    .ram_wr_data    (ram_wr_data) //写数据
);
//RAM读模块
ram_rd ram_rd_inst(
    .clk             (clk_25m),
    .rst_n           (rst_n),

    .ram_rd_en       (ram_rd_en  ),//读使能
    .ram_rd_addr     (ram_rd_addr), //读地址
    .ram_rd_data     (ram_rd_data)//读数据
);
//简单双端口RAM
ram_2 ram_2_inst(
	.data           (ram_wr_data),
	.rdaddress      (ram_rd_addr),
	.rdclock        (clk_25m),
	.rden           (ram_rd_en),
	.wraddress      (ram_wr_addr),
	.wrclock        (clk_50m),
	.wren           (ram_wr_en),
	.q              (ram_rd_data)
);
endmodule

四、仿真

1、仿真文件

`timescale 1ns/1ns
module tb_ip_2port_ram();

parameter T = 20;

reg    sys_clk;
reg    sys_rst_n;

initial begin
    sys_clk = 1'b0;
    sys_rst_n = 1'b0;
    #(T+1)
    sys_rst_n = 1'b1;
    #(3000)
    $stop;
end

always #(T/2) sys_clk = ~sys_clk;

ip_2port_ram ip_2port_ram_inst(
    .sys_clk        (sys_clk),
    .sys_rst_n      (sys_rst_n)
);
endmodule

2、波形仿真

在这里插入图片描述

  • 波形分析:

黄线所在时刻既是写使能时刻也是读使能时刻,所以此时既在写又在读。当 ram 地址为 0 时,写入的数据也是 0;当 ram 地址为 1 时,写入的数据也是 1,我们总共向 ram 中写入 32 个数据。ram 中读出的数据 ram_rd_data 在延时一个时钟周期之后,开始输出数据,输出的数据为 0,1,2……,和我们写入的值是相等的

在这里插入图片描述

  • 波形分析:

只在开始时写入一次,随后不再写入,而是每隔一段时间读取一次

五、SignalTap II在线验证

  • 读状态:
    在这里插入图片描述
  • 分析:

ram_rd_en(读使能)信号拉高之后,ram_addr 从 0 开始增加,也就是说从 ram 的地址 0 开始读数据;ram 中读出的数据 ram_rd_data 在延时一个时钟周期之后,开始输出数据,输出的数据为 0,1,2……,和我们写入的值是相等的。与仿真结果一致。并且每隔一段时间读一遍。

  • 写状态:

额,这里的写状态波形不知道怎的抓不到波形,这里因为写只是上电后写一次,后面不需要再写了,所以我设置了一个上升沿为触发条件,但他还是没有波形。应该是SignalTap II的使用还不太熟练,不太熟悉一些更复杂的操作。


六、总结

今天的实验是在昨天的单端口之上的另一内容,简单双端口可以同时进行读写,比单端口更加丰富。通过这次实验对IP核的配置越发熟练,每天都有在进步!

七、参考资料

以上资料均来自正点原子的教学视频或开拓者2开发教程:原子官方

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

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

相关文章

百度知道上云与架构演进

作者 | 百度知道研发组 导读 百度知道作为上线十多年的老产品线&#xff0c;业务场景多、架构老旧、代码风格不统一&#xff0c;同时业务迭代较快&#xff0c;整体承载流量大&#xff0c;稳定性要求高&#xff0c;给业务全面上云带来不小的挑战。本文基于实践&#xff0c;介绍知…

Nginx配置访问密码

使用得场景 因为想将skywalking对外提供访问&#xff0c;但是skywalking又没有认证功能&#xff0c;所以使用nginx来做。 安装htpasswd 因为需要使用到htpasswd&#xff0c;htpasswd是Apache服务器中生成用户认证的一个工具&#xff0c;如果未安装&#xff0c;则使用如下命令…

Linux底层

一. arm基础知识 基础&#xff1a;c语言 具有一定硬件基础 特点---》前后联系 arm目标&#xff1a; 看懂简单的汇编代码 会看电路图、芯片手册 学会如何用软件控制硬件思想 解决问题的办法 谈谈对嵌入式的理解&#xff1f; 以计算应用为中心&#xff0c;软硬件可裁剪的…

Vue 双重v-for渲染表单,再复制表单编辑之深拷贝

文章目录 前言问题背景实现拷贝表单如何实现深拷贝Object.assignJSON实现的深拷贝递归实现解决循环引用的递归实现require(lodash).cloneDeep() 前言 在做复杂的动态表单&#xff0c;实现业务动态变动&#xff0c;比如有一条需要动态添加的el-form-item中包含了多个输入框&…

Tomcat服务器下载安装及配置教程(IDEA中使用Tomcat)

目录 友情提醒第一章、Tomcat下载与安装1.1&#xff09;Tomcat介绍1.2&#xff09;官网下载 第二章、Tomcat配置环境变量2.1&#xff09;windows环境变量配置2.2&#xff09;验证Tomcat配置是否成功2.3&#xff09;报错解决 第三章、IDEA整合Tomcat3.1&#xff09;打开IDEA开发…

【OAuth2】OAuth2概述及使用GitHub登录第三方网站

【OAuth2】OAuth2概述及使用GitHub登录第三方网站 文章目录 【OAuth2】OAuth2概述及使用GitHub登录第三方网站0. 导言1. OAuth2 简介2. OAuth2 认证授权总体流程3. OAuth2 标准接口4. OAuth2 四种授权模式4.1 授权码模式4.2 简化模式4.3 密码模式4.4 客户端模式 5. GitHub授权登…

2023河南萌新联赛第一场(河南农业大学)

目录 A.你也喜欢数学吗​编辑 E.动物朋友 F.松鼠排序 G.Reverse J.合唱比赛 K.以撒和隐藏房间 L.中位数 A.你也喜欢数学吗 输入描述 第一行一个正整数k(1<k<1e12) 输出描述 输出一行一个整数表示答案 示例1 输入 1 输出 1 示例2 输入 3 输出 10 思路 是等于,将整个…

【itext7】itext7操作PDF文档之添加段落文本内容、添加List列表、添加Image图片、添加Table表格

这篇文章&#xff0c;主要介绍itext7操作PDF文档之添加段落文本内容、添加List列表、添加Image图片、添加Table表格。 目录 一、itext7操作PDF内容 1.1、添加段落文本内容 1.2、添加列表内容 1.3、添加图片 1.4、添加表格 &#xff08;1&#xff09;列宽采用点单位&#…

MySQL之索引(入门级讲解)

目录 一.索引的概念 1.1索引的简介 1.2.索引的优缺点 二.MySQL索引语法 2.1查看索引 2.2创建索引 2.2.1 创建表时创建索引 2.2.2存在的表上创建索引 2.3删除索引 三.索引的数据结构 3.1Btree索引 3.2Hash索引 3.4Hash索引和Btree索引的对比 &#x1f381;个…

基于Kitti数据集的智能驾驶目标检测系统(PyTorch+Pyside6+YOLOv5模型)

摘要&#xff1a;基于Kitti数据集的智能驾驶目标检测系统可用于日常生活中检测与定位行人&#xff08;Pedestrian&#xff09;、面包车&#xff08;Van&#xff09;、坐着的人&#xff08;Person Sitting&#xff09;、汽车&#xff08;Car&#xff09;、卡车&#xff08;Truck…

[2023新教程]M2 Mac安装Anaconda和Pytorch

本文首发于我的学习之路&#xff1a;https://liguang.wang/index.php/archives/80/ 1 背景 最近使用起了Mac Mini&#xff0c;需要安装Anaconda和Pytorch。网上的教程非常老旧&#xff0c;可读性较差&#xff0c;于是记录下自己的安装过程&#xff0c;分享给大家。 2 详细过…

二十三章:Gated-SCNN:Gated Shape CNNs for Semantic Segmentation ——用于语义分割的门控形状卷积神经网络

0.摘要 当前图像分割的最先进方法通过一个密集的图像表示来处理颜色、形状和纹理信息&#xff0c;这些信息都在深度卷积神经网络内部进行处理。然而&#xff0c;这种方法可能不太理想&#xff0c;因为它们包含了与识别相关的非常不同类型的信息。在这里&#xff0c;我们提出了一…

百度文心一言文心千帆大模型 ERNIE-Bot-turbo调用示例(golang版本)

百度的文心一言推出来也有一段时间了&#xff0c;但是接口部分一直没有公开&#xff0c;需要进行申请 最近&#xff0c;有朋友提供了文心千帆大模型的api权限&#xff0c;拿到了必须的参数&#xff0c;现在就来测试一下 下面是使用golang封装的文心千帆 ERNIE-Bot-turbo模型的调…

2023.7新版Pycharm没有Manager Repository(消失)下载镜像源问题

一、旧版本操作无法找到Manager Repository 二、解决方法---点击左侧键 三、点击添加设置小按钮 四、点击号复制进去镜像源网站即可 五、给大家推荐的镜像源网站 这里清华大学的镜像速度是最快的 https://pypi.tuna.tsinghua.edu.cn/simple/ 清华大学镜像http://pypi.douban…

天然气管道压力监测系统:管网安全守护者

随着我国工业的不断发展和能源需求的日益紧缺&#xff0c;天然气作为一种清洁能源正被广泛地开发和利用。然而。每年因天然气泄漏爆炸而造成的事故层出不穷&#xff0c;不仅威胁着人民的生命安全&#xff0c;还会对环境造成严重污染。面对这样的安全隐患&#xff0c;及时采取措…

Orangepi docker Home Assistant部署

手册上多数应用在树莓派用过&#xff0c;发现一个Home Assistant之前没搞过 按照手册先安装docker&#xff0c;使用enable_docker.sh 然后使用 docker run hello-world 来测试docker是否成功&#xff0c;如果hello from docker&#xff0c;即正常 通过以下docker命令搜索hom…

css - display属性

display属性有四个取值&#xff1a;block inline inline-block none 1、block display是类似于h和p标签在网页中默认显示方式&#xff0c;占据整整一行&#xff0c;所以不会与其他元素共同显示在一行之内。常见的block-display元素还有div、ol ul li、form等。如果想对某个blo…

【PHP面试题80】Redis消息发布与订阅功能怎么用的?

文章目录 &#x1f680;一、前言&#x1f680;二、PHP中安装Redis扩展&#x1f680;三、Redis消息发布与订阅&#x1f50e;3.1 创建发布者&#x1f50e;3.2 创建订阅者&#xff1a;&#x1f50e;3.3 运行发布者和订阅者&#xff1a; &#x1f680;四、总结 &#x1f680;一、前…

tomcat 使用部署

--烛光照亮了晚餐&#xff0c;照不出个答案。 不BB。 --部署web项目&#xff08;无 maven 纯web项目&#xff09; 直接把整个项目放到tomcat的webapps目录的下面然后重启tomcat即可 --部署html静态项目 直接把静态html放到tomcat的webapps目录下面即可&#xff0c;不要重命…

spring中bean实例化的三种方式 -- Spring入门(二)

文章目录 前言1.Bean实例化简介2.bean的实例化 -- 构造方法3.bean的实例化 -- 静态工厂实例化4.bean实例化 -- 实例工厂和FactoryBean5.三种bean实例化方式的区别 总结 前言 为了巩固所学的知识&#xff0c;作者尝试着开始发布一些学习笔记类的博客&#xff0c;方便日后回顾。…