dual port ram ---DP RAM
1.1 概念
真双端口RAM有两个独立的读写端口,每个端口都可以独立发起读或者写。
1.2 读写冲突处理
1、读和写冲突:如果读和写同时有效,且读和写是同一个地址时,发生RAM读写冲突,此时会把最新的写数据直接赋给读数据,称为写穿通到读
2、写和写冲突:表示两个端口写使能同时有效且写地址相同,此时需要关断一个写,把两个写端口都需要更新的值处理到一个写端口上面,任何的DP RAM 都不支持写和写冲突。
1.3 三种端口比较
1.4 真双口RAM读写代码
下面展示 功能代码
。
`timescale 1ns / 1ps
///
// 读写模块 Verilog 功能代码如下:
module dp_ram_ab_rw(
input sys_clk,
input sys_rst_n
);
wire ram_wren;
wire ram_rden;
wire [7:0] ram_rd_dataa;
wire [7:0] ram_rd_datab;
wire [7:0] ram_wr_data;
wire [4:0] ram_rd_addr;
wire [4:0] ram_wr_addr;
wire rden_a;
wire rden_b;
wire wen_a;
wire wen_b;
wire [7:0] data_a;
wire [7:0] data_b;
wire [4:0] addr_a;
wire [4:0] addr_b;
reg [7:0] rw_cnt;
reg flag;
assign ram_wren = ((rw_cnt >= 8'd0) && (rw_cnt <= 8'd31))? 1'b1:1'b0 ;
assign ram_rden = ((rw_cnt >= 8'd1) && (rw_cnt <= 8'd31))? 1'b1:1'b0 ;
assign ram_wr_addr = rw_cnt[7:0] ;
assign ram_rd_addr = rw_cnt[7:0] - 1'b1 ;
assign ram_wr_data = rw_cnt[4:0] ;
assign rden_a = flag ? 1'b0 :ram_rden ;
assign wen_a = flag ? ram_wren :1'b0 ;
assign addr_a = flag ? ram_wr_addr : ram_rd_addr ;
assign data_a = flag ? ram_wr_data : 1'b0 ;
assign rden_b = flag ? ram_rden : 1'b0;
assign wen_b = flag ? 1'b0 : ram_wren;
assign addr_b = flag ? ram_rd_addr : ram_wr_addr ;
assign data_b = flag ? 1'b0 : ram_wr_data ;
always @(posedge sys_clk or negedge sys_rst_n)
if(!sys_rst_n)
rw_cnt <= 8'd0 ;
else if(rw_cnt == 8'd63)
rw_cnt <= 8'd0 ;
else
rw_cnt <= rw_cnt + 1'b1 ;
always @(posedge sys_clk or negedge sys_rst_n)
if(!sys_rst_n)
flag <= 1'b0 ;
else if(rw_cnt == 8'd31)
flag <= ~flag ;
dp_ram_ab_ctl dp_ram_ab_ctl_inst(
.clka(sys_clk),
.clkb(sys_clk),
.wena(wen_a),
.wenb(wen_b),
.ena (rden_a),
.enb (rden_b),
.din_a(data_a),
.din_b(data_b),
.addra(addr_a),
.addrb(addr_b),
.dout_a(ram_rd_dataa),
.dout_b(ram_rd_datab)
);
endmodule
// 控制模块 Verilog 功能代码如下:
module dp_ram_ab_ctl(
input clka,
input clkb,
input wena,
input wenb,
input ena,
input enb,
input [7:0] din_a,
input [7:0] din_b,
input [4:0] addra,
input [4:0] addrb,
output reg [7:0] dout_a,
output reg [7:0] dout_b
);
reg [7:0] mem [31:0] ;
always @(posedge clka) begin
if(wena)
mem[addra] <= din_a;
if(wenb)
mem[addrb] <= din_b;
end
always @(posedge clka) begin
if(ena)
dout_a <= mem[addra] ;
else
dout_a <= 8'hx;
end
always @(posedge clka) begin
if(enb)
dout_b <= mem[addra] ;
else
dout_b <= 8'hx;
end
endmodule
// 仿真模块 Verilog 功能代码如下:
module tb_dp_ram_ab(
);
reg clk ;
reg rst ;
initial begin
clk = 1'b0 ;
rst = 1'b0 ;
#300
rst = 1'b1 ;
end
always #10 clk = ~clk ;
dp_ram_ab_rw dp_ram_ab_rw_inst(
.sys_clk(clk),
.sys_rst_n(rst)
);
endmodule