赞
踩
本文纯属学习笔记,使用的FPGA是Xilinx的XC7A35TFGG484-1,使用Vivado调用RAM IP核来实现双端口的数据存储和读取。
①在Memory Type中选择Single Port RAM
Memory Type中的Signal Port RAM为单口RAM,只有一个PORTA,可以读可以写
在Memory Type中选择Simple Dual Port RAM为简单的双口RAM,即PORTA和PORTB全部打开,一个只能写,另一个只能读
在选择为双口的条件下,Memory Type 右侧的 Common Clock亮起,意为如果输入和输出的频率相同则可以勾选此功能,不勾选则输入和输出可以使用不同频率的时钟
在Memory Type中选择Ture Dual Port RAM为真正的的双口RAM,即PORTA和PORTB全部打开,每个都能独立的进行读写
②ECC Option为校验设置:保持默认
③Write Enable为写使能(在ROM时不可用):及使能后一帧数据变为选择的9位,最高位一帧变为数据使能,若为1则同意写入RAM 为0则不写入
④Algorithm Options为算法设置:根据不同场景对RAM使用的块进行组合,这里保持默认
这里我们对简单的双端口的RAM进行配置介绍,关于FPGA内部资源在违章末尾尽心介绍
①Port A Width端口A 的数据位宽:即端口A数据一帧数据的位宽,这里配置为16位
②Port A Depth端口A的数据深度:即端口A数据的个数,这里配置为1024个
③Operation Mode工作模式:工作模式内有Wirte First、Read First、No Change,该功能的作用是如果在对RAM进行读写有冲突时,根据选项可以设置优先进行读还是写
④Enable Port Type使能端口:这里选择使用使能引脚,即在使用该端口前需要将ENA先置1
①Port B Width端口B的宽度:该宽度默认与PortA的Width一致16,也可以进行修改,若修改为8则Port B Depth会自动x2以保持内存大小的一致
②Enable Port Type使能端口:这里选择使用使能引脚,即在使用该端口前需要将ENB先置1
③Primitives Output Register原语输出寄存器:(这里不勾选)勾选此选项及数据在从RAM读出来之后需要先到寄存器然后再从寄存器中读出来,及时钟需要再多一拍。读数据给出地址后的第一个时钟数据从RAM传输到寄存器中,第二个时钟才会再从寄存器中读出来。勾选此选项的目的是为了使数据拥有更好的时序性
其他的保持默认即可
①Load Init File加载初始文件:该功能与ROM一致,可以将生成好的数据文件直接加载到功能内然后直接读取
②Remaining Memory Locations填充剩余内存位置:勾选此功能可以将其余空余的内存地址进行填充填充值可以自定义,默认为0
总结模块,可以看得到RAM内存的使用情况,使用了一个18K的BRAM等信息
之后点击OK然后点Generate就可以了
在下方的IP Sources中找到第一个文件夹下的.veo文件并打开
然后找到例化模块直接粘贴到要调用的层去例化,这里我直接粘贴到testbench文件中去例化
testbench代码:
`timescale 1ns / 1ps module RAM_tb(); reg clk; reg ena; reg wea; reg [9:0]addra; reg [9:0]dina; reg enb; reg [9:0]addrb; wire [9:0]doutb; RAM RAM( .clka(clk),//使用同一时钟 .ena(ena), .wea(wea), .addra(addra), .dina(dina), .clkb(clk),//使用同一时钟 .enb(enb), .addrb(addrb), .doutb(doutb) ); initial clk = 1; always #10 clk = ~clk; initial begin addra = 0;//初始地址 dina = 0;//初始数据 enb = 0; //不使能端口B ena = 1;//使能端口A wea = 1;//使能端口A写入 repeat(1024)begin//循环1024次 #20; dina = dina + 1; //每次循环数据+1 addra = addra + 1;//每次循环地址+1 end ena = 0;//关闭A端口使能 wea = 0;//关闭A端口写入 #20000; addrb = 0;//给读数据的初始地址 enb = 1;//使能B端口进行读取 #20; repeat(1024)begin #20; addrb = addrb + 1 ;//每次地址-1读取数据 end enb = 0; #20000; $stop; end endmodule
仿真结果:
整体效果
写入数据:每一位地址对应写入一个数值写入0-1023
读取数据:从0开始读取0-1023
在vivado软件内选择器件的时候可以看得到内置的Block RAMS有50个块
根据官方手册UG473可以看得到每个块可以被分为两个18K的RAM或者一个36K的RAM
每个36K和18K的RAM可以被分为很多小块,以2Kx18为例子,这里表示一个36KB的RAM块被分成了2K个最高位为18位的RAM,若使用的数据为16位则被分成与位宽预期最接近的块,所以7系列的FPGA最大的内存也就是能存储50*2K=100K个16/18位的数据,所以在存储数据之间需要格外注意需要存储的数据时候能存的下。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。