RAM设计-单端口+伪双端口+双端口

定义:
1.单端口:读写数据共用一个地址线,一个时钟沿只能进行读写中的一种
2.伪双端口:读写数据有自己的时钟、地址、使能信号,时钟可以复用,一组端口只能读,一组端口只能写
3.双端口:两组端口均可读可写
Tips:端口组的定义:有自己的地址

  • 单端口RAM
 module ram_single(
 input clk,
 input rst_n,
 input sel,
 input en,
 input [3:0] addr,
 input [7:0] wdata,
 input wr,
 output [7:0] rdata
);
reg [7:0] rdata;
reg [7:0] mem [15:0];
wire wr_en,rd_en;
// sel 多个RAM的选通信号
assign wr_en = wr & sel & en;
assign rd_en = rd & sel & en;
//write data to mem
always @(posedge clk)
if(!rst_n) 
	for(i=0;i<=15;i=i+1)
		mem[i] <= 0;
else if(wr_en)
	mem[addr] <= wdata;
//read data from mem
always @(posedge clk )
if(!rst_n) rdata <= 0;
else if(rd_en) rdata <= mem[addr];
endmodule
  • 伪双端口RAM
module ram_doubleF(
input rst_n,
input en,
input sel,
// port a
input clka,
input wr_a,
input [3:0] waddr_a,
input [7:0] wdata_a,
// port b
input clkb,
input rd_b,
input [3:0] raddr_b,
output [7:0] rdata_b
);
reg [7:0]mem[15:0];
wire wr_en,rd_en;
// sel 多个RAM的选通信号
assign wr_en = wr_a & sel & en;
assign rd_en = rd_b & sel & en;
//write data to mem
always @(posedge clk_a)
if(!rst_n) 
	for(i=0;i<=15;i=i+1)
		mem[i] <= 0;
else if(wr_en)
	mem[waddr_a] <= wdata_a;
//read data from mem
always @(posedge clk_b )
if(!rst_n) rdata_b <= 0;
else if(rd_en) rdata_b <= mem[raddr_b];
endmodule
  • 双端口RAM
module ram_doubleT(
input clk,
input sel,
input rst_en,
// port a
input en_a,
input [3:0] addr_a,
input [7:0] wdata_a,
input wr_a,
output reg [7:0] rdata_a,
// port b
input en_b,
input [3:0] addr_b,
input [7:0] wdata_b,
input wr_b,
output reg [7:0] rdata_b
);
reg [7:0]mem[15:0];
wire wr_en_a, wr_en_b, rd_en_a, rd_en_b, conflict;
assign wr_en_a=sel & en_a & wr_a ;
assign wr_en_b=sel & en_b & wr_b ;
assign rd_en_a=sel & en_a & !wr_a;
assign rd_en_b=sel & en_b & !wr_b;
assign conflict=wr_en_a & wr_en_b & (addr_a==addr_b);
// write data
always@(posedge clk or negedge rst_n)
	if(!rst_n)
		for(i=0; i<16; i=i+1)
		mem[i] <=0;
	else begin
	if(wr_en_a & !conflict)
		mem[addr_a]<=wdata_a;
	if(wr_en_b & !conflict)
		mem[addr_b]<=wdata_b;
	end
// read data
always@(posedge clk or negedge rst_n)
	if(!rst_n)
		begin rdata_a<=0; rdata_b<=0; end
	else begin
	if(rd_en_a) rdata_a<=mem[addr_a]; 
//两个if必须并列,否则就是只能执行一个
	if(rd_en_b) rdata_b<=mem[addr_b];
	end
endmodule

猜你喜欢

转载自blog.csdn.net/weixin_43194246/article/details/108595611