#学习记录#
1 双端口RAM简述
FPGA工程实践中的RAM形式很多,在设计中常用的RAM有单口RAM:SPRAM(single-port RAM)。双口RAM:TPRAM(two-port RAM)和真双口RAM:(dual-port RAM)。在芯片设计中,具体使用哪一种RAM,要根据设计的需要而定,比如读写速度和面积。图1、图2分别给出了双端口RAM的模块图和时序图。
图1 双端口RAM的模块图
图2 双端口RAM时序图
2 双端口RAM的verilog实现
2.1 代码
`timescale 1ns / 1ps
//
// Company:
// Engineer: Mr-pn-junction
//
// Create Date: 2023/12/08 16:01:55
// Design Name:
// Module Name: dp_ram
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module dp_ram #(
parameter dly = 1,
parameter ram_width = 8,
parameter ram_depth = 16,
parameter addr_width = 4)
(
input wr_clk,
input rd_clk,
input rst_n,
input wr_en,
input rd_en,
input [addr_width-1:0] wr_addr,
input [addr_width-1:0] rd_addr,
input [ram_width-1:0] wr_data,
output reg [ram_width-1:0] rd_data
);
reg [ram_width-1:0] mem [ram_depth-1:0];
always @(posedge wr_clk ) begin
if(wr_en)
mem[wr_addr] <= #dly wr_data;
end
always @(posedge rd_clk or negedge rst_n) begin
if(!rst_n)
rd_data <= 8'b0;
else if(rd_en)
rd_data <= #dly mem[rd_addr];
end
endmodule
2.2 testbench
`timescale 1ns / 1ps
//
// Company:
// Engineer: Mr-pn-junction
//
// Create Date: 2023/12/08 16:35:19
// Design Name:
// Module Name: dp_ram_tb
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module dp_ram_tb( );
parameter dly = 1;
parameter ram_width = 8;
parameter ram_depth = 16;
parameter addr_width = 4;
reg wr_clk;
reg rd_clk;
reg wr_en;
reg rd_en;
reg rst_n;
reg [addr_width-1:0] wr_addr;
reg [addr_width-1:0] rd_addr;
reg [ram_width-1:0] wr_data;
wire [ram_width-1:0] rd_data;
dp_ram test (
.wr_clk(wr_clk),
.rd_clk(rd_clk),
.wr_en(wr_en),
.rd_en(rd_en),
.rst_n(rst_n),
.wr_addr(wr_addr),
.rd_addr(rd_addr),
.wr_data(wr_data),
.rd_data(rd_data)
);
initial begin
wr_clk = 1'b0;
rd_clk = 1'b0;
wr_en = 1'b1;
rst_n = 1'b0;
rd_en = 1'b0;
wr_data = 8'b0000_0000;
wr_addr = 4'b0000;
rd_addr = 4'b0000;
#10
rst_n = 1'b1;
#310
wr_en = 1'b0;
rd_en = 1'b1;
#500
$stop;
end
always @(posedge wr_clk or negedge rst_n)begin
if(!rst_n)begin
wr_data =8'b0;
wr_data = 4'b0;
end
else begin
if(wr_en) begin
wr_data = wr_data +8'b0000_0001;
wr_addr = wr_addr + 4'b0001;
end
else begin
wr_data = 8'b0000_00000;
wr_addr = 4'b0000;
end
end
end
always @(posedge rd_clk)begin
if(rd_en) begin
rd_addr = rd_addr + 4'b0001;
end
else begin
rd_addr = 4'b0000;
end
end
always #10 wr_clk = ~wr_clk;
always #15 rd_clk = ~rd_clk;
endmodule
2.3 仿真结果
参考文献
[1] 同步FIFO设计.12.同步和异步FIFO的设计_哔哩哔哩_bilibili
--------------------------------------------------------------------------------------------------------------------------------
因作者水平有限,如有错误请指出。