1、伪双端口ram与单端口ram区别是有两个端口,一个端口只能读,一个端口只能写,由此得名。这里往伪双端口ram中写入32个8位信号。之后延迟一个时钟读取。
2、Verilog主要由三部分,tb测试信号、伪双端口ram、伪双端口读写测试。
`timescale 1ns/1ps
module tb();
reg clk;
reg rst_n;
initial begin
clk=1'b0;
rst_n=1'b0;
#100
rst_n=1'b1;
end
always #10 clk=~clk;
dual_ram u_dual_ram(
.clk (clk),
.rst_n (rst_n)
);
endmodule
module ram(
input clk,
input wr_en,
input re_en,
input [4:0] wr_addr,
input [4:0] re_addr,
input [7:0] data,
output reg [7:0] q
);
reg [7:0] ram[31:0];
always@(posedge clk)begin
if(wr_en)
ram[wr_addr]<=data;
end
always@(posedge clk)begin
if(re_en)
q<=ram[re_addr];
else
q<=8'hxx;
end
endmodule
module dual_ram(
input clk,
input rst_n
);
wire wr_en;
wire re_en;
reg [4:0] wr_addr;
reg [4:0] re_addr;
reg [7:0] wr_data;
wire [7:0] re_data;
reg [5:0] cnt;
assign wr_en=(cnt>=6'd0)&&(cnt<=6'd31)? 1'b1:1'b0; //enable signal
assign re_en=(cnt>=6'd1)&&(cnt<=6'd32)? 1'b1:1'b0;
always@(posedge clk or negedge rst_n)begin //wr or re control
if(!rst_n)
cnt<=6'd0;
else if(cnt==6'd63)
cnt<=6'd0;
else cnt<=cnt+1'b1;
end
always@(posedge clk or negedge rst_n)begin //wr_addr control
if(!rst_n)
wr_addr<=5'd0;
else if(wr_en)
wr_addr<=wr_addr+1'b1;
else wr_addr<=5'd0;
end
always@(posedge clk or negedge rst_n)begin //re_addr control
if(!rst_n)
re_addr<=5'd0;
else if(re_en)
re_addr<=re_addr+1'b1;
else re_addr<=5'd0;
end
always@(posedge clk or negedge rst_n)begin //wr_data control
if(!rst_n)
wr_data<=8'd0;
else if(wr_en)
wr_data<=wr_data+1'b1;
else wr_data<=8'd0;
end
ram u_ram(
.clk (clk),
.wr_en (wr_en),
.re_en (re_en),
.wr_addr (wr_addr),
.re_addr (re_addr),
.data (wr_data),
.q (re_data)
);
endmodule
3、得到综合后的电路如下图
4、测试波形如下,这边解释一下,读端口相较于写端口的数据延迟了两个周期是因为,读端口本身带有一个延迟信号,然后代码中又延迟了一位,因此有两个时钟周期的延迟。