当前位置:   article > 正文

FPGA开发实验(6)- IP核之双端口RAM实验_fpga ram仿真

fpga ram仿真

一、双端口RAN简介与实验任务

1.1双端口RAM

简单双端口 RAM 的端口 A 只能写不能读,端口 B 只能读不能写。
与单端口不同的是,伪双端口RAM有两路时钟信号CLKA/CLKB。两个独立的地址ADDRA和ADDRB;PortA提供数据总线,PortB提供数据总线。

1.2实验任务

本章实验任务是将 Xilinx BMG IP 核配置成一个同步的伪双端口 RAM 并对其进行读写操作,然后通过仿真观察波形是否正确,最后将设计下载到 FPGA 开发板中,并通过在线调试工具对实验结果进行观察。

二、程序设计

2.1RAM IP核的配置
“Basic”选项卡配置界面如下图所示。
在这里插入图片描述
对“Port A Options”和“Port B Options”选项卡进行配置,如下图所示:
在这里插入图片描述在这里插入图片描述

2.2 模块的设计

总体模块框图如下图所示:
在这里插入图片描述
RTL代码ip_2port_ram.v如下:

module ip_2port_ram(
    input sys_clk   ,
    input sys_rst_n
);

wire rd_flag;
wire ram_rd_en;
wire [5:0] ram_rd_addr;
wire [7:0] ram_rd_data;
wire ram_wr_en;
wire ram_wr_we;
wire [5:0] ram_wr_addr;
wire [7:0] ram_wr_data;

ram_rd u_ram_rd(
    .clk        (sys_clk),
    .rst_n      (sys_rst_n),
    .rd_flag    (rd_flag),
    .ram_rd_en  (ram_rd_en),
    .ram_rd_addr(ram_rd_addr),
    .ram_rd_data(ram_rd_data)
);

ram_wr u_ram_wr( 
    .clk        (sys_clk),
    .rst_n      (sys_rst_n),
    .rd_flag    (rd_flag),
    .ram_wr_en  (ram_wr_en),
    .ram_wr_we  (ram_wr_we),
    .ram_wr_addr(ram_wr_addr),
    .ram_wr_data(ram_wr_data)
);

blk_mem_gen_0 your_instance_name (
  .clka(sys_clk),    // input wire clka
  .ena(ram_wr_en),      // input wire ena
  .wea(ram_wr_we),      // input wire [0 : 0] wea
  .addra(ram_wr_addr),  // input wire [5 : 0] addra
  .dina(ram_wr_data),    // input wire [7 : 0] dina
  .clkb(sys_clk),    // input wire clkb
  .enb(ram_rd_en),      // input wire enb
  .addrb(ram_rd_addr),  // input wire [5 : 0] addrb
  .doutb(ram_rd_data)  // output wire [7 : 0] doutb
);

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

写数据模块框图如下图:
在这里插入图片描述
RTL代码ram_wr.v如下

module ram_wr(
    input clk   ,
    input rst_n ,
    
    output reg rd_flag,
    output reg ram_wr_en,
    output ram_wr_we,
    output reg [5:0] ram_wr_addr,
    output reg [7:0] ram_wr_data
);

assign ram_wr_we = ram_wr_en;

always @(posedge clk or negedge rst_n) begin
    if(!rst_n) begin 
        ram_wr_en <= 1'b0;
    end
    else begin
        ram_wr_en <= 1'b1;
    end
end

always @(posedge clk or negedge rst_n) begin
    if(!rst_n)
        ram_wr_addr <= 6'd0;
    else if(ram_wr_addr == 6'd63 && ram_wr_en)
        ram_wr_addr <= 6'd0;
    else if(ram_wr_en)
        ram_wr_addr <= ram_wr_addr + 6'b1;
    else 
        ram_wr_addr <= ram_wr_addr;
end

always @(posedge clk or negedge rst_n) begin
    if(!rst_n)
        rd_flag <= 1'b0;
    else if(ram_wr_addr == 6'd32)
        rd_flag <= 1'b1;
    else
        rd_flag <= rd_flag;
end

always @(posedge clk or negedge rst_n) begin
    if(!rst_n)
        ram_wr_data <= 8'd0;
    else if(ram_wr_data >= 8'd200 && ram_wr_en)
        ram_wr_data <= 8'd0;
    else if(ram_wr_en)
        ram_wr_data <= ram_wr_data + 8'd2;
    else    
        ram_wr_data <= ram_wr_data;
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

读数据模块框图如下图:
在这里插入图片描述
RTL代码ram_rd.v如下:

module ram_rd(
    input clk   ,
    input rst_n ,
    input rd_flag,
    
    output ram_rd_en,
    output reg [5:0] ram_rd_addr,
    input [7:0] ram_rd_data
);

assign ram_rd_en = rd_flag;

always @(posedge clk or negedge rst_n) begin
    if(!rst_n) 
        ram_rd_addr <= 6'd0;
    else if(ram_rd_addr == 6'd63 && rd_flag)
        ram_rd_addr <= 6'd0;
    else if(rd_flag)
        ram_rd_addr <= ram_rd_addr + 6'd1;
    else
        ram_rd_addr <= ram_rd_addr;
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

2.3 通过Vivado 自带仿真器仿真

仿真代码:

`timescale 1ns/1ps

module tb_ip_2port_ram();

parameter CLK_PERIOD = 20;

reg sys_clk; //周期20ns
reg sys_rst_n;


initial begin
    sys_clk <= 1'b0;
    sys_rst_n <= 1'b0;
    #200 
    sys_rst_n <= 1'b1;
end

always #(CLK_PERIOD/2) sys_clk = ~sys_clk;


ip_2port_ram u_ip_2port_ram(
    .sys_clk    (sys_clk),
    .sys_rst_n  (sys_rst_n)
);

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

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

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

闽ICP备14008679号