赞
踩
简单双端口 RAM 的端口 A 只能写不能读,端口 B 只能读不能写。
与单端口不同的是,伪双端口RAM有两路时钟信号CLKA/CLKB。两个独立的地址ADDRA和ADDRB;PortA提供写数据总线,PortB提供读数据总线。
本章实验任务是将 Xilinx BMG IP 核配置成一个同步的伪双端口 RAM 并对其进行读写操作,然后通过仿真观察波形是否正确,最后将设计下载到 FPGA 开发板中,并通过在线调试工具对实验结果进行观察。
2.1RAM IP核的配置
“Basic”选项卡配置界面如下图所示。
对“Port A Options”和“Port B Options”选项卡进行配置,如下图所示:
总体模块框图如下图所示:
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
写数据模块框图如下图:
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
读数据模块框图如下图:
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
仿真代码:
`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
仿真结果:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。