IC设计 — 单双端口RAM的设计


1. RAM种类区分

  单端口RAM:读写数据共用一个地址线,一个时钟沿只能进行读或者写;
  伪双端口RAM:写数据和读数据有自己的地址、时钟、读写使能信号;也就是一组端口只能写,一组端口只能读。(读写数据也可共用一个clk,为同步伪双端口ram)
  真双端口RAM:一组端口可读可写,另一组端口也可读可写。(若这两组端口共用一个clk,为同步真双端口ram。若每组有每组的clk,为异步真双端口ram)。
  三种RAM的接口示意图如下所示:
单端口RAM 连线图                     Figure 单端口RAM连线图

在这里插入图片描述                     Figure 伪双端口RAM连线图

在这里插入图片描述                     Figure 真双端口RAM连线图

  从上图可以得出:

RAM类型方式数据读写接口地址接口数量
单端口RAMRAM允许通过一个端口对存储进行读写访问11
伪双端口RAMRAM提供A、B两种接口,A进行写访问,B进行都访问12
真双端口RAMRAM提供A、B两组接口,A、B都可以进行读写访问22

  

2. verilog实现

  依据上述对各种RAM结构的分析,编写verilog代码有:

2.1 单端口RAM

代码如下:

//sigle_port ram
reg [DATA_WIDTH-1:0]   ram_reg[ADDR-1:0];

integer i;
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        for (i=0;i<ADDR;i=i+1)begin
            ram_reg[i] <= {DATA_WIDTH{1'b0}};
        end
    end
    else if(wr)begin
        ram_reg[addr] <= din[DATA_WIDTH-1:0];
    end
end

always @(posedge clk ir negedge rst_n)begin
    if(!rst_n)begin
        dout <= {DATA_WIDTH{1'b0}};
    end
    else if(rd)begin
        dout <= ram_reg[addr];
    end
end 

2.2 伪双端口RAM

代码如下:

//simple_dual_port ram
reg [xx-1:0]            addr_wr;
reg [xx-1:0]            addr_rd;
reg [DATA_WIDTH-1:0]    ram_reg[ADDR-1:0];

//here is synchronize clk, not asynchronize clk
integer i;
always @(posedge clk or negedge rst_n)begin  
    if(!rst_n)begin                          
        for (i=0;i<ADDR;i=i+1)begin          
            ram_reg[i] <= {DATA_WIDTH{1'b0}};
        end                                  
    end                                      
    else if(wr)begin                         
        ram_reg[addr_wr] <= din[DATA_WIDTH-1:0];
    end                                      
end

always @(posedge clk or negedge rst_n)begin
    if(!rst_n)begin
        dout <= {DATA_WIDTH{1'b0}};
    end
    else if(rd)begin
        dout <= ram_reg[addr_rd];
    end
end

2.3 真双端口RAM

代码如下:

//real dual_port ram
wire                    wr_a;
wire                    wr_b;
reg [xx-1:0]            addr_a;
reg [xx-1:0]            addr_b;
reg [DATA_WIDTH-1:0]    din_a;
reg [DATA_WIDTH-1:0]    din_b;
reg [DATA_WIDTH-1:0]    ram_reg[ADDR-1:0]; 

//here is synchronize clk, not asynchronize clk
assign wr_fail = wr_a && wr_b &&(addr_a == addr_b);

integer i;
always @(posedge clk or negedge rst_n)begin  
    if(!rst_n)begin                          
        for (i=0;i<ADDR;i=i+1)begin          
            ram_reg[i] <= {DATA_WIDTH{1'b0}};
        end                                  
    end                                      
    else if(wr_a && !wr_fail)begin                         
        ram_reg[addr_a] <= din_a[DATA_WIDTH-1:0];
    end                                      
end

always @(posedge clk ir negedge rst_n)begin
    if(!rst_n)begin
        dout_a <= {DATA_WIDTH{1'b0}};
    end
    else if(rd_a)begin
        dout_a <= ram_reg[addr_a];
    end
end 

integer j;
always @(posedge clk or negedge rst_n)begin  
    if(!rst_n)begin                          
        for (j=0;j<ADDR;j=j+1)begin          
            ram_reg[i] <= {DATA_WIDTH{1'b0}};
        end                                  
    end                                      
    else if(wr_b && !wr_fail)begin                         
        ram_reg[addr_b] <= din_b[DATA_WIDTH-1:0];
    end                                      
end

always @(posedge clk ir negedge rst_n)begin
    if(!rst_n)begin
        dout_b <= {DATA_WIDTH{1'b0}};
    end
    else if(rd_b)begin
        dout_b <= ram_reg[addr_b];
    end
end
  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值