IP CORE 之 RAM 设计- ISE 操作工具

2020-12-30 16:22:05 浏览数 (1)

大侠好,欢迎来到FPGA技术江湖,江湖偌大,相见即是缘分。大侠可以关注FPGA技术江湖,在“闯荡江湖”、"行侠仗义"栏里获取其他感兴趣的资源,或者一起煮酒言欢。

本系列将带来FPGA的系统性学习,从最基本的数字电路基础开始,最详细操作步骤,最直白的言语描述,手把手的“傻瓜式”讲解,让电子、信息、通信类专业学生、初入职场小白及打算进阶提升的职业开发者都可以有系统性学习的机会。

系统性的掌握技术开发以及相关要求,对个人就业以及职业发展都有着潜在的帮助,希望对大家有所帮助。后续会陆续更新 Xilinx 的 Vivado、ISE 及相关操作软件的开发的相关内容,学习FPGA设计方法及设计思想的同时,实操结合各类操作软件,会让你在技术学习道路上无比的顺畅,告别技术学习小BUG卡破脑壳,告别目前忽悠性的培训诱导,真正的去学习去实战应用,这种快乐试试你就会懂的。话不多说,上货。

IP CORE 之 RAM 设计 - ISE操作工具

作者:李西锐 校对:陆辉

本篇实现基于叁芯智能科技的SANXIN -B02 FPGA开发板,如有入手开发板,可以登录官方淘宝店购买,还有配套的学习视频。

随机存取存储器(random access memory,RAM)又称作"随机存储器"。存储单元的内容可按需随意取出或存入,且存取的速度与存储单元的位置无关的存储器。这种存储器在断电时将丢失其存储内容,故主要用于存储短时间使用的程序。按照存储单元的工作原理,随机存储器又分为静态随机存储器(Static RAM,SRAM)和动态随机存储器(Dynamic RAM,DRAM)。在FPGA内部的存储块为SRAM。

  • 设计要求

设计一个深度为256,宽度为8的RAM。不需要初始化内容。

  • 设计原理

RAM,此种存储器支持写操作,支持读操作。在存储器建造时,可以进行初始化数据,也可以不进行初始化数据。RAM的初始化文件也是coe文件,原理和ROM类似。

由于设计RAM深度为256,故而地址的宽度为8位。

RAM工作原理为,在时钟上升沿采样到rden为1时,将addr所指示的存储空间的数据进行输出;在时钟上升沿采样到wren为1时,将wdata存储到addr所指示的存储空间中去。

  • 架构设计和信号说明

此模块命名为ram_test。my_ram为ip core。

  • 调用 ip core 之 RAM

建好工程之后,右键点击工程,选择New Source,新建IP核。

找到对应路径,命名为my_ram。

打开IP核库之后,搜索Block Memory即可看到我们的RAM。

点击Next。

点击Finish。

点击Next。

选择默认的Single Port RAM。点击Next。

数据位宽为8,数据深度为256。Enable选择Always Enable。点击Next。

此界面的数据初始化我们不需要做,因为RAM的数据是我们自己写入的,不是提前固化好的,所以这个界面我们保持默认点击Next。

复位端口同样不使用,如果需要,可以勾选上。我们这里保持默认点击Next。

点击Generate。

  • 顶层设计

顶层负责调用my_ram,例化文件在ipcore_dir -> my_ram.veo中。

设计代码为:

代码语言:javascript复制
module ram_test (

  input   wire                  clk,
  input   wire      [7:0]       addr,
  input   wire                  wren,
  input   wire      [7:0]       wdata,
  
  output  wire      [7:0]       rdata
);

  ram_my  ram_my_inst (
      .address      ( addr ),
      .clock        ( clk ),
      .data         ( wdata ),
      .wren         ( wren ),
      .q            ( rdata )
    );

endmodule
  • RTL仿真

在某些地址中,写入一些数据,然后读出来。由于写进去后,还需要读出来,所以地址不在使用随机值,固定在0,100,200,255地址写入随机值。

仿真代码为:

代码语言:javascript复制
`timescale 1ns/1ps

module ram_test_tb;

  reg             clk;
  reg   [7:0]     addr;
  reg             wren;
  reg   [7:0]     wdata;
  
  wire  [7:0]     rdata;
  
  ram_test ram_test_inst(

      .clk          (clk),
      .addr         (addr),
      .wren         (wren),
      .wdata        (wdata),
      
      .rdata        (rdata)
    );
    
  initial clk = 1'b0;
  always # 10 clk = ~clk;
  
  initial begin
    addr = 8'd0;
    wren = 1'b0;
    wdata = 8'd0;
    @ (posedge clk);
    # 2;
    addr = 8'd0;
    wren = 1'b1;
    wdata = {$random} % 256;
    @ (posedge clk);
    # 2;
    addr = 8'd100;
    wren = 1'b1;
    wdata = {$random} % 256;
    @ (posedge clk);
    # 2;
    addr = 8'd200;
    wren = 1'b1;
    wdata = {$random} % 256;
    @ (posedge clk);
    # 2;
    addr = 8'd255;
    wren = 1'b1;
    wdata = {$random} % 256;
    @ (posedge clk);
    # 2;
    addr = 8'd0;
    wren = 1'b0;
    wdata = 8'd0;
    # 200
    @ (posedge clk);
    # 2;
    addr = 8'd0;
    @ (posedge clk);
    # 2;
    addr = 8'd100;
    @ (posedge clk);
    # 2;
    addr = 8'd200;
    @ (posedge clk);
    # 2;
    addr = 8'd255;
    @ (posedge clk);
    # 2;
    addr = 8'd0;
    
    # 200
    $stop;
  end

endmodule

经过设置后,进行RTL仿真。

通过波形图中,可以看出,在地址为0时,写入数据为36;在地址为100时,写入数据为129;在地址为200时,写入数据为9;在地址为255时,写入数据为99。经过一段时间后,对上述几个地址进行读取,输出的数据与写入数据相同(输出时,输出数据要比地址晚两拍)。

- End -

0 人点赞