RAM IP核简介及实验

本文转载自:Linest-5的CSDN博客

注:本文由作者授权转发,如需转载请联系作者本人

RAM简介:
RAM(Random Access Memory),即随机存取存储器。它是双端口的,它可以随时把数据写入任一指定地址的存储单元,也可以随时从任一指定地址中读出数据,其读写速度是由时钟频率决定的。RAM主要用来存放程序及程序执行过程中产生的中间数据、运算结果等。

一片RAM中分为许多小格,每一片容量为36k,根据设定的位宽决定了这片RAM可以存放分为几格,位宽一啊不能设定为1、2、4、8、16、32等,每相邻的两片RAM可以合成一片RAM,这片RAM同样是双端口,可以独立的完成读写操作,且在读和写都可以配置位宽。

  • 单端口:只有一个端口,读写数据不能同时进行,共用数据通道。
  • 伪双端口:拥有两个数据通道,一个用来写一个用来读。
  • 真双端口:拥有两个数据通道,两个通道都可以用来读或写。
  • 建立工程:

    1、打开vivado,选择add sources->add or creat a new sources名称为ip_ram->finish即可。

    2、添加ram ip,ip catalog-> 搜索ram选择block memory generate(bram),双击打开配置界面,配置如下图,配置成单端口、写位宽和读位宽为8,写深度和读深度便会自动配置,operating mode既可以设置成write frist也可以no change,这个设置项的影响是在读和写数据时的优先级。


    3、在添加一个文件,用于描述在读和写的过程,文件名取为ram_rw,代码如下:

    module ram_rw(
    input clk,
    input rst,

    output reg ram_en,
    output reg rw,
    output reg [4:0] ram_addr,
    output reg [7:0] ram_wr_data
    );

    reg [5:0] rw_cnt;

    always@(posedge clk or negedge rst)begin
    if(rst)
    ram_en<=1'b0;
    else
    ram_en<=1'b1;
    end

    //rw_cnt
    always @(posedge clk or posedge rst) begin
    if (rst) begin
    rw_cnt <= 6'd0;
    end
    else if (rw_cnt == 6'd63) begin
    rw_cnt <= 6'd0;
    end
    else begin
    rw_cnt <= rw_cnt + 6'd1;
    end
    end

    //ram_wr_data
    always @(posedge clk or posedge rst) begin
    if (rst) begin
    ram_wr_data <= 8'd0;
    end
    else if ((rw_cnt <= 6'd31) && ram_en == 1'b1) begin
    ram_wr_data <= ram_wr_data + 8'd1;
    end
    else begin
    ram_wr_data <= ram_wr_data;
    end
    end

    //rw
    always @(posedge clk or posedge rst) begin
    if (rst) begin
    rw <= 1'b1;
    end
    else if (rw_cnt <= 6'd31) begin
    rw <= 1'b1;
    end
    else begin
    rw <= 1'b0;
    end
    end

    //ram_addr
    always @(posedge clk or posedge rst) begin
    if (rst) begin
    ram_addr <= 5'd0;
    end
    else begin
    ram_addr <= rw_cnt[4:0];
    end
    end

    endmodule

    4、编辑ip_ram代码:

    根据ip sources中的ip选项中选择instantiation template(例化模板),选择veo文件,复制其例化模板粘贴至ip_ram中,并手动例化ram_rw中的代码块,并定义了系统时钟和复位。

    5、添加ILA IP
    zcu106_xrt_platform.txt

    添加ila ip用来探测信号,同样的操作在ip catalog中搜索ila双击打开配置界面,因为要探测五个信号:ram使能信号、读写操作信号、ram地址信号、ram读写数据信号、最后输出的信号douta。所以number of probes 探针的数量为5,在每个探针的位宽中配置相对应的数据位宽。同样的在ip sources中的veo文件拷贝ila的例化模板,粘贴到顶层模块ip_ram的代码中,最终其代码如下:

    module ip_ram(
    input sys_clk,
    input sys_rst

    );
    wire ram_en;
    wire rw;
    wire [4:0] ram_addr;
    wire [7:0] ram_wr_data;
    wire [7:0] douta;
    ram_rw ram_rw_u(
    .clk (sys_clk),
    .rst (sys_rst),
    .ram_en (ram_en),
    .rw (rw),
    .ram_addr (ram_addr),
    .ram_wr_data(ram_wr_data)
    );

    blk_mem_gen_0 blk_mem_gen_0_u (
    .clka(sys_clk), // input wire clka
    .ena(ram_en), // input wire ena
    .wea(rw), // input wire [0 : 0] wea
    .addra(ram_addr), // input wire [4 : 0] addra
    .dina(ram_wr_data), // input wire [7 : 0] dina
    .douta(douta) // output wire [7 : 0] douta
    );

    ila_0 your_instance_name (
    .clk(sys_clk), // input wire clk

    .probe0(ram_en), // input wire [0:0] probe0
    .probe1(rw), // input wire [0:0] probe1
    .probe2(ram_addr), // input wire [4:0] probe2
    .probe3(ram_wr_data), // input wire [7:0] probe3
    .probe4(douta) // input wire [7:0] probe4
    );
    endmodule

    6、综合文件:

    点击run synthesis进行综合,综合完成后可点击open synthesis design查看相应的框架图如下:

    7、绑定管脚并生成bitstream

    本实验只用到了PL端的资源,因此需要对引脚进行绑定,只需要绑定两个管脚:时钟和复位,在Layout中选择i/o planing即可对引脚进行配置,在zedboard原理图可以查阅GCLK可以看出时钟的管脚为Y9,而PL端的复位按键集成在了BTNL中,因此查阅可知其管脚为N15,两个管脚的电压均为lvcmos3.3v,ctrl+s保存对约束文件命名为ip_ram即可自动生成约束文件。最后generate bitstream即可。

    8、连接板子:

    连接开发板并上电,点击open target->auto connect->program device再点击启动即可看到通过ila探测到的信号,通过看时序图即可验证设计是否正确。

    最新文章

    最新文章