当前位置:   article > 正文

Vivado RAM随机存取存储器 IP核的使用_vivado中ram的使用

vivado中ram的使用

实验简介

本文纯属学习笔记,使用的FPGA是Xilinx的XC7A35TFGG484-1,使用Vivado调用RAM IP核来实现双端口的数据存储和读取。

操作方法

一、在IP Catalog中搜索RAM选择Block Memory Generator

在这里插入图片描述

二、配置过程

Basic

在这里插入图片描述
①在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使用的块进行组合,这里保持默认

Port A Options

这里我们对简单的双端口的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 Options

在这里插入图片描述
①Port B Width端口B的宽度:该宽度默认与PortA的Width一致16,也可以进行修改,若修改为8则Port B Depth会自动x2以保持内存大小的一致
②Enable Port Type使能端口:这里选择使用使能引脚,即在使用该端口前需要将ENB先置1
③Primitives Output Register原语输出寄存器:(这里不勾选)勾选此选项及数据在从RAM读出来之后需要先到寄存器然后再从寄存器中读出来,及时钟需要再多一拍。读数据给出地址后的第一个时钟数据从RAM传输到寄存器中,第二个时钟才会再从寄存器中读出来。勾选此选项的目的是为了使数据拥有更好的时序性
其他的保持默认即可

Other Options

在这里插入图片描述
①Load Init File加载初始文件:该功能与ROM一致,可以将生成好的数据文件直接加载到功能内然后直接读取
②Remaining Memory Locations填充剩余内存位置:勾选此功能可以将其余空余的内存地址进行填充填充值可以自定义,默认为0

Summary

总结模块,可以看得到RAM内存的使用情况,使用了一个18K的BRAM等信息
f4.png)

之后点击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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57

仿真结果:
整体效果
在这里插入图片描述

写入数据:每一位地址对应写入一个数值写入0-1023
在这里插入图片描述

读取数据:从0开始读取0-1023
在这里插入图片描述

关于内置RAM资源

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位的数据,所以在存储数据之间需要格外注意需要存储的数据时候能存的下。
在这里插入图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/658912
推荐阅读
  

闽ICP备14008679号