全球最实用的IT互联网信息网站!

AI人工智能P2P分享&下载搜索网页发布信息网站地图

当前位置:诺佳网 > 电子/半导体 > 存储技术 >

单口RAM、同步FIFO、异步FIFO的设计

时间:2023-10-09 11:10

人气:

作者:admin

标签: 单口    异步  fifo  同步  RAM 

导读:if((!empty re)(!full we))// 同时读写,计数不变;...

单口 RAM

module BRAM_PORTA(
input clka,
input ena,
input wea,
input [3:0]  addra,
input [15:0] dina,
output reg [15:0] douta
);


reg [15:0] mem [15:0];


always @(posedge clka)begin
    if(ena)begin
        if(wea)begin//写数据
            mem[addra] <= dina;
            douta      <= 16'bzzzzzzzzzzzzzzzz;
        end
        else begin  //读数据
            douta      <= mem[addra];
            mem[addra] <= mem[addra];
        end
    end 
    else
        douta <= 16'bzzzzzzzzzzzzzzzz;
end


endmodule

同步 FIFO

`define INDEX 6
`define WIDTH 16
`define DEPTH 64
module Sync_FIFO(
input clk,
input rst_n,
input re,
input we,
input [`WIDTH-1:0] din,
output empty,
output full,
output reg [`INDEX-1:0] fifo_cnt,
output reg [`WIDTH-1:0] dout
);


reg [`WIDTH-1:0] mem [`DEPTH-1:0];
reg [`INDEX-1:0] raddr;
reg [`INDEX-1:0] waddr;


// 1、空满标志;
assign empty = (fifo_cnt == 0) ? 1:0;
assign full  = (fifo_cnt == `DEPTH-1) ? 1:0;


// 2、读写计数;
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)
        fifo_cnt <= 0;
    else begin
        if((!empty && re)&&(!full && we))// 同时读写,计数不变;
            fifo_cnt <= fifo_cnt;
        else if(!empty && re)// 读数据,计数减一;
            fifo_cnt <= fifo_cnt - 1'b1;
        else if(!full && we)// 写数据,计数加一;
            fifo_cnt <= fifo_cnt + 1'b1;
        else
            fifo_cnt <= fifo_cnt;
    end  
end


// 3、读写数据;
always @(posedge clk or negedge rst_n)begin// 读数据;
    if(!rst_n)
        dout <= 0;
    else begin
        if(!empty && re)
            dout <= mem[raddr];
        else
            dout <= dout;
    end  
end
always @(posedge clk)begin// 写数据;
        if(!full && we)
            mem[raddr] <= din;
        else
            mem[raddr] <= mem[waddr];
end


// 4、读写地址;
always @(posedge clk or negedge rst_n)begin// 写地址;
    if(!rst_n)
        waddr <= 0;
    else begin
        if(!full && we)
            waddr <= waddr + 1'b1;
        else
            waddr <= waddr;
    end  
end
always @(posedge clk or negedge rst_n)begin// 读地址;
    if(!rst_n)
        raddr <= 0;
    else begin
        if(!empty && re)
            raddr <= raddr + 1'b1;
        else
            raddr <= raddr;
    end  
end


endmodule

异步 FIFO

`define INDEX 6  // FIFO 索引;
`define WIDTH 16 // FIFO 宽度;
`define DEPTH 64 // FIFO 深度;
module Async_FIFO(
input rd_clk,
input wr_clk,
input rst_n,
input re,
input we,
input [`WIDTH-1:0] din,
output empty,
output full,
output [`WIDTH-1:0] dout
);


reg  [`WIDTH-1:0] mem [`DEPTH-1:0];
wire [`INDEX-1:0] raddr;
wire [`INDEX-1:0] waddr;
reg  [`INDEX:0] wbin,rbin;
wire [`INDEX:0] wbin_next,rbin_next,wgray_next,rgray_next;
reg  [`INDEX:0] rp,wr1_rp,wr2_rp,wp,rd1_wp,rd2_wp;


// 1、空满标志;
// 可能需要延时;
assign empty = (rd2_wp == rgray_next) ? 1:0;
assign full  = ({~wr2_rp[`INDEX:`INDEX-1],wr2_rp[`INDEX-2:0]} == wgray_next) ? 1:0;// 高两位不同,取反;


// 2、读计数;
// 产生读地址 raddr + 读地址自增 + 将普通二进制码转化为格雷码,并赋给读指针 rp;
// 将读指针 rp 同步到写时钟域;
always @(posedge rd_clk or negedge rst_n)begin
    if(!rst_n)
        {rbin,rp} <= 0;
    else
        {rbin,rp} <= {rbin_next,rgray_next};
end


assign raddr = rbin[`INDEX-1:0];// 抛弃高位;
assign rbin_next = rbin + (!empty && re);// 地址加一;
assign rgray_next = rbin_next ^ (rbin_next > > 1);// 转为格雷码,右移 + 异或;


always @(posedge wr_clk or negedge rst_n)begin
    if(!rst_n)
        {wr2_rp,wr1_rp} <= 0;
    else
        {wr2_rp,wr1_rp} <= {wr1_rp,rp}; 
end


// 3、写计数;
// 产生写地址 waddr + 写地址自增 + 将普通二进制码转化为格雷码,并赋给写指针 wp;
// 将写指针 wp 同步到读时钟域;
always @(posedge wr_clk or negedge rst_n)begin
    if(!rst_n)
        {wbin,wp} <= 0;
    else
        {wbin,wp} <= {wbin_next,wgray_next};
end


assign waddr = wbin[`INDEX-1:0];// 抛弃高位;
assign wbin_next = wbin + (!full && we);// 地址加一;
assign wgray_next = wbin_next ^ (wbin_next > > 1);// 转为格雷码,右移 + 异或;


always @(posedge rd_clk or negedge rst_n)begin
    if(!rst_n)
        {rd2_wp,rd1_wp} <= 0;
    else
        {rd2_wp,rd1_wp} <= {rd1_wp,wp}; // 多比特的,但是只有单比特发生变化,属于单比特处理领域;
end


// 4、异步读数据;
assign dout = mem[raddr];


// 5、同步写数据;
always @(posedge wr_clk)begin
        if(!full && we)
            mem[waddr] <= din;
        else
            mem[waddr] <= mem[waddr];
end


endmodule
温馨提示:以上内容整理于网络,仅供参考,如果对您有帮助,留下您的阅读感言吧!
相关阅读
本类排行
相关标签
本类推荐

CPU | 内存 | 硬盘 | 显卡 | 显示器 | 主板 | 电源 | 键鼠 | 网站地图

Copyright © 2025-2035 诺佳网 版权所有 备案号:赣ICP备2025066733号
本站资料均来源互联网收集整理,作品版权归作者所有,如果侵犯了您的版权,请跟我们联系。

关注微信