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

单口 rammodule 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;endendmodule同步 fifo
`define index 6`define width 16`define depth 64module 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 endalways @(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 endalways @(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 endendmodule异步 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} > 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} > 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];endendmodule

关于开关电源测试规范探讨
三星李在镕赴日与材料供应商交涉 将建立新方案应对日本的制裁
朵唯S5手机高清图赏
UC-3.0版本是未来融合通信新方向吗?
南非三大运营商力挺华为 华为成为鹏城云脑28亿单一采购的大赢家
单口RAM、同步FIFO、异步FIFO的设计
48所全自动高精度太阳能电池测试分选设备研制成功
MODBUS RTU转CCLINK协议网关
NV080C教育设备语音芯片方案
三星、富士康供应商莱尔科技成功登陆科创板
金银河李小云:“锂电池电极智能制造先进方法”的精彩演讲
字母检索线路板词汇中英文对照
如何用KIT_AURIX_TC275_LITE板卡实现多核点灯
工业连续超声波振动筛电源发生器设计
UltraSoC和Agile Analog携手共同抵御网络攻击
USB带宽科普
Diodes推出PowerDI5封装的超势垒整流器(SBR)系列
iphone13什么时候可以买,iphone13怎么预定
CAD中怎么能让图块能遮挡住后面的图形?如何能更轻松创建区域覆盖(wipeout)?
康佳特推出耐用的四核模块conga-TR4