FPGA 单端口RAM IP核使用 vivado仿真
一、各类存储器简介
ROM:只读,只有读接口(读地址、读数据)
RAM:可读可写,有读接口(读地址、读数据)和写接口(写使能、写数据、写地址),默认任何时刻都能读,没有读使能,大小和位宽查手册,需要持续供电才能将数据保存在其中(易失性存储器),断电数据丢失
- 单端口RAM:读写共用一个数据通道,读写不能同时进行
- 伪双端口RAM:两个数据通道,一个用来读一个用来写
- 真双端口RAM:两个数据通道,都可以用来读或写
DRAM:动态随机存取存储器,数据存储在电容器中,通过保持电荷实现数据存储(比如电容器充电和放电分别为1和0),价格低,消耗功率高,最常用作计算机的主存储器,需要不断刷新(由于电容器内部用于分隔导电板的电介质不是完美的绝缘体,电容器易放电导致电荷泄漏),以同步或异步模式运行,存储容量为1GB-16GB
SRAM:静态随机存取存储器,数据存储在晶体管中,通过改变晶体管的导通状态进而改变电平高低,需要恒定的功率流,速度快,用于高速缓存,存储容量为1MB-16MB
SDRAM:同步动态随机存储器(与CPU频率同步、存储阵列需要不断刷新来保证数据不丢失、自由指定地址进行数据读写),通过电容充放电实现数据存储,内部分为多个bank,通过流水线操作提高速度(一个bank处于预充电状态,正在经历访问延迟时,另一个bank可进行读取),存储容量大、速度快、价格低,控制逻辑复杂、对时序要求高
DDR:双倍速率同步动态随机存储器,命令和操作只在时钟的上升沿发生,数据传输在时钟上升沿和下降沿发生,每个时钟周期发送两倍数据
FIFO和RAM的差别:FIFO是先入先出,没有读写地址,只能按顺序读写数据,RAM可以读写任意地址,FIFO常用于数据传输通道中,用于缓存数据,避免数据丢失,RAM常用于存储指令或者中间的数据
二、原理
IP核配置图
信号名称 | 信号功能 |
dina | 端口a的写数据信号 |
addr | 端口a的读写地址信号 |
wea | 端口a的写使能信号,高电平为写,低电平为读 |
ena | 端口a的使能信号,高电平为使能端口a,低电平端口a被禁止,取消此信号后端口a一直有效(可选信号) |
rsta | 端口a的复位信号(可选信号) |
regcea | 端口a输出寄存器使能信号,高电平douta保持最后一次输出(可选信号) |
clka | 端口a的时钟信号 |
douta | 端口a数据输出 |
三、vivado仿真
新建工程:打开vivado-Quick Start-Create Project-Next-输入工程名和位置(注意工程名和位置中都不能出现中文和空格)-勾选Create project subdirectory(为工程在指定存储路径下建立独立的文件夹)-勾选RTL Project-勾选Do not specifysources at this time(此时不定义源文件)-选择FPGA开发板(我用的是xc7k325tfbg676-3)-Next-Finish
创建RAM IP核:Flow Navigator-IP Catalog-Search:block memory-Block Memory Generator
配置IP核:component name(器件名称,默认即可,不用修改)-basic-interface type(接口类型,默认native)-memory type选择single port ram-write enable中取消勾选字节写使能byte write enable-algorithm options-algorithm选最小面积minimum area-ok
port A options-memory size-write width写数据位宽选择8-write depth写深度选择32-operating mode选no change-enable port type选use ena pin-port A optional output registers都不勾选-port A output reset options勾选RSTA pin-output reset value为0-ok
创建模块ram_rw.v:
project manager-add sources-add or create design sources-next-create file-输入文件名ram_rw.v-ok-finish
module ram_rw(input clk,input rst_n,//端口复位,为0时复位input [7:0] r_data,//读数据output reg [7:0] w_data,//写数据output ram_we,//写使能output reg [4:0] ram_addr,//读写地址output ram_en//端口使能);(* DONT_TOUCH = "TRUE" *) reg [5:0] wr_cnt;//读写计数,因为没有规定输入输出,所以加上前缀括号assign ram_en = rst_n;//端口使能assign ram_we = (wr_cnt<=6'd31 && ram_en==1)? 1'b1 : 1'b0;//写使能:读写计数器在0-31为写,32-63为读,6'd31为6位四进制数,数值为31//读写计数信号设计
always @(posedge clk or negedge rst_n) begin if(!rst_n)wr_cnt <= 0;//复位时读写计数为0else if(wr_cnt==6'd63)wr_cnt <= 0;//读写计数为63,赋值为0,准备重新计数elsewr_cnt <= wr_cnt + 1;//其他情况,每次计数加1
end//读写地址信号设计
always @(posedge clk or negedge rst_n) begin if(!rst_n)ram_addr <= 0;//复位时读写地址为0else if(ram_addr==5'd31)ram_addr <= 0;//读写地址为31,赋值为0,重新开始计数else ram_addr <= ram_addr + 1;//其他情况,每次地址加1
end//写数据信号设计
always @(posedge clk or negedge rst_n) begin if(!rst_n)w_data <= 0;//复位时写数据为0else if(wr_cnt <= 6'd31)w_data <= w_data + 1;//读写计数在0-31为写else w_data <= 0;//其他情况,写数据为0
end//读数据信号设计
always @(posedge clk or negedge rst_n) begin if(!rst_n)r_data <= 0;//复位时读数据为0else if(wr_cnt >= 6'd32 && wr_cnt <= 6'd63)r_data <= r_data + 1;//读写计数在32-63为读else r_data <= 0;//其他情况,读数据为0
endendmodule
本部分的功能:对一个数据位宽为8、深度为32的单端口RAM 进行读写操作设计,注意一个always设计一个信号,对于每个信号的设计,要覆盖到其所有情况
例化IP核blk_mem_gen_0及ram_rw 模块:
sources-IP sources-找到.veo文件,查看例化ram IP核的模板
blk_mem_gen_0 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 [4 : 0] addra.dina(dina), // input wire [7 : 0] dina.douta(douta), // output wire [7 : 0] douta.rsta_busy(rsta_busy) // output wire rsta_busy
);
创建顶层模块ipram:
module ipram(input sys_clk,input sys_rst);wire [7:0] r_data;wire [7:0] w_data;wire ram_en;wire ram_we;wire [4:0] ram_addr;ram_rw ram_rw_inst(.clk (sys_clk),//例化本质上就是调用的过程,顶层模块ipram调用读写模块ram_rw,括号内为顶层模块的信号名.rst_n (sys_rst),.r_data (r_data),.w_data (w_data),.ram_we (ram_we),.ram_addr(ram_addr),.ram_en (ram_en) );blk_mem_gen_0 blk_mem_gen_1 (//顶层模块ipram调用ram IP核blk_mem_gen_0.clka (sys_clk), // input wire clka.rsta (sys_rst), // input wire rsta.ena (ram_en), // input wire ena.wea (ram_we), // input wire [0 : 0] wea.addra (ram_addr), // input wire [4 : 0] addra.dina (w_data), // input wire [7 : 0] dina.douta (r_data) // output wire [7 : 0] douta//.rsta_busy(rsta_busy) // output wire rsta_busy顶层模块没有用到此信号
);endmodule
仿真程序:
module tb_ram_ip();(* DONT_TOUCH = "TRUE" *) reg sys_clk;//输入信号
(* DONT_TOUCH = "TRUE" *) reg sys_rst;ipram ipram_inst(.sys_clk(sys_clk),//仿真模块tb_ram_ip调用顶层模块ipram.sys_rst(sys_rst)
);
initial begin sys_clk = 0;sys_rst = 0;#10//等待复位完成sys_rst = 1;#256$stop;
end
always #5 sys_clk = ~sys_clk;//10ns一个周期,产生100MHz时钟源endmodule
参考文献:
一文看懂SDRAM、DRAM和DDR的差别
【Vivado】ram ip核的使用_想学fpga的小猪同学的博客-CSDN博客_vivado移位寄存器FIFO RAM的差异与共同点_IC小鸽的博客-CSDN博客_fifo和ram的区别
Vivado 双口RAM IP核的使用_耐心的小黑的博客-CSDN博客
FPGA 单端口RAM IP核使用 vivado仿真相关推荐
- FPGA中ROM IP与RAM IP核配置与调用
目录 一.ROM IP核 1.简介 2.创建立初始化文件 3.配置 4.调用 4.1 整体设计 4.2 编写rtl代码: 4.3 仿真验证 二.RAM IP核 1.简介 2.配置 3.调用 3.1 整 ...
- SPI和RAM IP核
学习目的: (1) 熟悉SPI接口和它的读写时序: (2) 复习Verilog仿真语句中的$readmemb命令和$display命令: (3) 掌握SPI接口写时序操作的硬件语言描述流程(本例仅以写 ...
- ZYNQ之FPGA学习----RAM IP核使用实验
1 RAM IP核介绍 RAM 的英文全称是 Random Access Memory, 即随机存取存储器, 它可以随时把数据写入任一指定地址的存储单元,也可以随时从任一指定地址中读出数据,其读写速度 ...
- 【FPGA】单端口RAM的设计(异步读、异步写)
前面有博文写了同步读写和异步读.同步写的单端口RAM设计: [FPGA]单端口RAM的设计(同步读.同步写) [FPGA]单端口RAM的设计(异步读.同步写) 这篇博文讲异步读写: 在博文:[FPGA ...
- 弟中弟级,基于Vivado的IP核封装以及仿真调用,FPGA入门小玩
弟中弟级,基于Vivado的IP核封装以及仿真调用,FPGA入门小玩 IP核:知识产权核,指某一方提供的.形式为逻辑单元的可重用模块.IP核通常已经通过了设计验证,设计人员以IP核为基础进行设计,可以 ...
- ISE使用中RAM IP核配置及ram测试(两种测试)
简单总结ISE中RAM的ip核配置过程以及相关的端口. 分类 ram分为分布式ram(distributed ram)以及块ram(block ram) 前者是自己用寄存器搭建的,这里理解可以转至Vi ...
- 单端口RAM、伪双端口RAM、双端口RAM、以及FIFO的区别
FPGA设计中,存储器是必不可少的.FPGA中常见的存储器件有RAM以及FIFO,RAM又可细分为单端口RAM.伪双端口RAM和双端口RAM.之前对其基本概念与使用已经进行了介绍,现在只重点将他们进行 ...
- Xilinx RAM IP核的使用
背景 RAM和ROM也是类似的,由于这也是常用的IP核,所有完全有必要在这里记录一下,以后用到了实际后,再补充到实际工程中.随机存储器(RAM),它可以随时从任一指定地址读出数据,也可以随时把数据写入 ...
- verilog基础篇RAM IP核的使用
在该页面中,我们去掉了q output port(去掉输出寄存器),并且添加了一个rden读使能信号,所谓rden读使能信号就是,当该信号为高电平时,我们才可以读取RAM IP核中的数据. 其余的页面 ...
最新文章
- 转 前端工程师凭什么这么值钱?
- 第三次学JAVA再学不好就吃翔(part82)--泛型
- 漫画:什么是HashMap
- java toast_Android中Toast的用法简介
- 『震惊』秘密报告披露转基因食品危害
- 简约的PHP留言板开源版网站源码
- NUnit单元测试笔记
- VMWARE 之 vSphere vCenter 安装基本配置
- 机械设备行业经销商管理系统细致化经销商管理,让渠道管理更可控
- 关于Linux性能调优中系统CPU监测信息统计的一些笔记
- TuX2:用于机器学习的分布式图计算
- 太赞了,英伟达又一突破,输入关键词就可以生成直逼摄影师的大片
- ios app上架审核被拒及解决总结
- Quartus II 操作入门
- 设计数据密集型应用(一),DDIA
- c 全国计算机二级考试真题及答案,全国计算机二级考试《C语言》真题练习及答案...
- Single Image Haze Removal Using Dark Channel Prior
- 手机qq表白代码大全可复制_街机游戏大全~手机版
- 精彩回顾|2019决策易“绩效驱动,团队赋能”大会圆满落幕
- C语言贪吃蛇,单双人模式
热门文章
- 从Java字符串中移除Emojis字符的多种方法
- 机票报价高并发实施的关键路径
- 泰捷we30c系统语言,系统简洁、稳定,开机无广告 泰捷方盒WE30C升级版日常体验...
- Python 练习实例100例—2
- win7 64位 web项目OCX控件无法加载原因
- OpenCV_电路板焊点的定位
- Reed-Muller码 (RM码):RM码的布尔函数(Boolean Functions)表示
- 【深度学习之模型优化】模型剪枝、模型量化、知识蒸馏概述
- 如何使用迅捷CAD编辑器将CAD导出为PDF
- 利用ArcGIS做一张“三调“土地利用现状图(附三调符号库下载)