查看: 986|回复: 0

[资料] 只读储存器ROM IP核的调取及应用

[复制链接]
  • TA的每日心情

    2018-11-20 13:41
  • 签到天数: 3 天

    连续签到: 1 天

    [LV.2]偶尔看看I

    发表于 2019-12-17 09:08:58 | 显示全部楼层 |阅读模式
    分享到:
    写在前面的话
    在项目设计中,我们通常需要使用一些固定的数据。如果是使用单片机,那么在数据量比较大的情况下,这些数据就必须存储在外挂的存储芯片中。那么,使用FPGA呢?在数据量不是特别大的情况下,我们可以将这些数据存储到FPGA片内的存储器中,这样既节约了板级成本,又可以保证数据不容易受到外界干扰。那么本节,梦翼师兄和大家一起学习FPGA只读存储器IP核-ROM的设计。
    项目需求
    设计一个ROM控制器,该控制器负责输出0-255递增的地址数据,将此地址总线连接到ROM地址输入端,查看ROM输出的数据是否正确
    操作步骤
    由于ROM是只读存储器,也就是说,我们不能对其内部写入外部数据,那么,我们就需要创建一个ROM的数据初始化文件mIF文件(mif文件用来存放初始数据)

    定义位宽和深度(这里我们选择位宽为8位,深度为256)

    填充数据(在这里我们用软件自带的一种的填充数据的方式,填充上0到255,大家自己在项目中应用的时候,应该填充上自己所需要的初始值)。



    mif文件建立成功(地址从0到255,数据从0开始,每次增加1,所以此时的mif文件中存放的是0到255)。

    在右侧的IP核搜索的编辑区,输入rom,在菜单栏找到并双击rom(在这里我们使用单端口的rom,双端口的rom,自己感兴趣的话,可以自己调用试一试)。

    选择语言类型为Verilog,同时为该IP核命名,然后点击【OK】

    进入rom的设置向导,设置深度和字节的宽度(rom的深度和字节宽度必须要和建立的mif文件保持一致),然后点击【NEXT】。
       
    把输出端口的寄存器去掉(如果不去掉的话,就会使输出延迟一拍。这里我们不需要延迟这一拍,所以去掉),然后点击【NEXT】

    进入如下界面,点击【browse···】(找到我们之前建立的mif文件,添加进来),点击【NEXT】


       
    一直点击【NEXT】,直到出现如下界面,把my_rom_inst.v选择上,然后点击【finish】(完成rom的设置)
       
    顶层架构设计
    Rom是只读存储器,需要我们指定地址,它才能输出对应地址的数据。




    模块功能介绍

    模块名
    功能描述
    Rom_control
    ROM控制模块,产生递增的地址信号
    My_rom
    ROM存储器IP核
    Rom
    系统顶层模块,负责子模块级联
    端口和内部连线描述

    顶层模块端口介绍

    端口名
    端口说明
    Clk
    系统时钟输入
    Rst_n
    系统复位
    q
    数据输出

    系统内部连线介绍

    连线名
    连线说明
    addr
    Rom_control产生的地址信号

    代码解释

    Rom_control模块的代码

    /****************************************************         
    *   Engineer        :   梦翼师兄
    *   QQ               :   761664056
    *   The module function:  输出有效地址
    *****************************************************/
    01  module rom_control (
    02                              clk,        //系统时钟输入
    03                              rst_n,  //系统复位
    04                              addr        //地址输出
    05                          );
    06      // 系统输入
    07      input clk;      //系统时钟输入
    08      input rst_n;    //系统复位
    09      
    10      output reg [7:0] addr;  //地址输出
    11      
    12      // 产生地址电路
    13      always @ (posedge clk or negedge rst_n)
    14          begin
    15              if (!rst_n)
    16              addr <= 0; // 复位的时候地址是0;
    17              else
    18                  if (addr < 255) // 让地址在0到255循环
    19                      addr <= addr + 1;
    20                  else   
    21                      addr <= 0;
    22          end
    23
    24  endmodule

    本模块只是产生了有效的地址信号,让地址信号在0到255之间循环,用于rom的输入,遍历rom全部存储空间,验证rom是否能够正确地输出对应地址的数据。

    Rom模块代码

    /****************************************************         
    *   Engineer        :   梦翼师兄
    *   QQ               :   761664056
    *   The module function:  顶层连接
    *****************************************************/
    01  module rom (
    02                  clk,        //系统时钟输入
    03                  rst_n,  //系统复位
    04                  q           //有效数据输出
    05              );
    06      //系统输入
    07      input clk;          //系统时钟输入
    08      input rst_n;        //系统复位
    09      //系统输出
    10      output [7:0] q; //有效数据输出
    11      //定义中间连线
    12      wire [7:0] addr; //定义地址信号
    13      //实例化rom_control
    14      rom_control rom_control (
    15                                              .clk(clk),      //系统时钟输入
    16                                              .rst_n(rst_n), //系统复位
    17                                              .addr(addr)     //地址输出
    18                                          );
    19      //IP核--rom的调用
    20      my_rom  my_rom_inst (
    21                                  .address ( addr ),      // 地址输入
    22                                  .clock ( clk ),         // 时钟输入
    23                                  .q ( q )                 //有效数据输出
    24                              );
    25
    26  endmodule

    本模块只是用于做连接,没有任何的逻辑。编写完可综合代码之后,查看RTL视图如下:




    由RTL视图可以看出,代码综合以后得到的电路和我们设计的系统框图一致,接下来,编写测试代码如下:

    /****************************************************         
    *   Engineer        :   梦翼师兄
    *   QQ               :   761664056
    *   The module function:  顶层测试
    *****************************************************/
    01   `timescale 1ns/1ps //时间单位和精度定义
    02   module rom_tb;
    03   
    04      //系统输入
    05      reg clk;            //系统时钟输入
    06      reg rst_n;      //系统复位
    07      //系统输出
    08      wire [7:0] q;   //有效数据输出
    09      
    10      initial begin
    11          clk = 1;
    12          rst_n = 0;
    13          # 200.1
    14          rst_n = 1;
    15      end
    16      
    17      always # 10 clk = ~clk;  //50MHz时钟
    18   
    19      rom rom (
    20                      .clk(clk),      //系统时钟输入
    21                      .rst_n(rst_n),  //系统复位
    22                      .q(q)           //有效数据输出
    23                  );
    24   
    25   endmodule


    仿真分析

    当复位信号拉高以后,addr(地址)开始发生变化,q(rom的输出)开始输出有效数据,并且是每一拍都会输出一个有效数据。地址和数据之间存在一拍的延迟是由于rom内部结构导致的。

    在地址循环的同时,对应地址的有效数据也循环输出,证明我们的ip核使用正确。














    回复

    使用道具 举报

    您需要登录后才可以回帖 注册/登录

    本版积分规则

    关闭

    站长推荐上一条 /5 下一条

    手机版|小黑屋|与非网

    GMT+8, 2024-12-19 22:10 , Processed in 0.121471 second(s), 17 queries , MemCache On.

    ICP经营许可证 苏B2-20140176  苏ICP备14012660号-2   苏州灵动帧格网络科技有限公司 版权所有.

    苏公网安备 32059002001037号

    Powered by Discuz! X3.4

    Copyright © 2001-2024, Tencent Cloud.