原创 基于ISSI-IS61LV25616编写的fifo控制器(请热心网友大胆斧正,不吝赐教,重谢)

2012-8-5 20:02 2070 8 11 分类: FPGA/CPLD

20120805200201577.jpg

/**
  ******************************************************************************
  * @file     fifo_usv2.v
  * @author   西殿源
  * @version  V2
  * @date     08/05/2012
  * @brief    自己的fifo
  * @info  1. 相对于V1版,响应更及时:当前时刻检测到写fifo请求,即在之后的一个clk内完成写sram操作
       当前时刻检测到读fifo请求,即在之后的半个clk内完成读sram操作
     2. 当同时有读写fifo请求时,写优先,并自动在延后一个clk后执行读操作
     3. 当读写在相邻的clk的上时,是否有潜在的亚稳态,尚需思之;但经硬件验证,能达到与quartus自带IP相同的效果
  ******************************************************************************
  */

module fifo_usv2
 #(parameter WIDH = 10)
 (
 input clk,  //输入时钟
 input rst_n, //异步复位,低电平有效
 input wr_ff, //fifo写使能
 input rd_ff, //fifo读使能
 input [15:0]  dat_in,    //fifo写入数据
 output reg [15:0] dat_ro_ff,  //fifo输出数据
 output reg [WIDH-1:0]  num_ff, //fifo缓冲计数
 output reg  emp_ff,     //fifo空信号
 output reg  ful_ff,     //fifo满信号
 
 output reg [17:0] addr_sram,  //sram地址总线
 inout [15:0]  data_sram,   //sram数据总线
 output cs_sram,      //sram片选信号
 output [1:0] byte_sram,   //sram高低字节使能
 output reg oe_sram,     //sram读出使能
 output reg wr_sram     //sram写入使能
 );
 
 

 parameter FIFO_DEP = 2^WIDH; //FIFO缓存深度
 parameter SRAM_STA = 18'd0; //外部sram起始地址
 parameter YES = 1'b1;
 parameter NO  = 1'b0;
 parameter HI = 1'b1;
 parameter LO  = 1'b0;
 
 reg [WIDH-1:0] wr_pit;  //写指针,指向下一次要写sram的地址
 reg [WIDH-1:0] rd_pit;  //读指针,指向下一次要读sram的地址
 
 reg wr_r;      //写fifo内部寄存器
 reg rd_r;      //读fifo内部寄存器
 reg rd_exe;      //执行读操作
 reg rd_sim;      //=1时表明同时有fifo读写操作,暂存读信号
 wire rd_p;      //当前时刻有读fifo请求,或由于前一时刻fifo读写冲突时,此时执行读操作
 reg [15:0] data_sram_r;  //sram数据端口双向,作为输出寄存器
 reg sram_dir;     //sram数据端口方向控制
 
 reg d2_en;
 reg [1:0] d2_cnt;
 
 assign byte_sram = 2'b10; //高低字节使能,8位工作方式
 assign cs_sram = 1'b0;  //片选sram
 assign data_sram = sram_dir? data_sram_r : 16'bz; //sram_dir = 1时作为输出端口;= 0时 作为输入
 
 
 assign rd_p = rd_sim || rd_ff; //两者满足其一即可执行读操作
 
 //检测读写fifo的请求,并协调对应的sram读写操作
 always @(posedge clk,negedge rst_n) begin
  if(!rst_n) begin
   addr_sram <= 18'd0;
   wr_pit <= 10'd0;
   rd_pit <= 10'd0;
   wr_sram <= HI;   //
   oe_sram <= HI;
   rd_sim <= NO;   //复位后,无读写fifo冲突
   sram_dir <= NO;  //复位后,外接sram的数据总线高阻,作为输入
   end
  else if(wr_ff) begin      //写fifo请求优先于读fifo请求
   if(rd_ff) rd_sim <= YES; //如果检测到同时有读fifo请求,记录此请求,并延后1个clk再执行读fifo
   else ;
   addr_sram <= wr_pit;     //sram地址,写fifo即写外部sram
   wr_pit <= wr_pit + 1;    //更新sram写指针
   sram_dir <= YES;      //sram总线方向位输出
   data_sram_r <= dat_in;    //将fifo的入口数据写入输出寄存器
   wr_sram <= LO;       //
   end
  else if(rd_p) begin
   wr_sram <= HI; 
   rd_sim <= NO;  //如果上一个clk同时出现读写fifo请求,则本时刻是延时一个clk周期的读fifo操作,清除之前的读fifo记录
   addr_sram <= rd_pit;  //sram地址,读fifo即读外部的sram
   rd_pit <= rd_pit + 1; //更新sram读指针
   sram_dir <= NO;
   oe_sram <= LO;
   end
  else begin   //无读写fifo请求,清楚读写标志
   wr_sram <= HI;
   oe_sram <= HI;
   end
 end
 
 //计算fifo的缓存状态,空?已占用资源?
 always @(posedge clk,negedge rst_n) begin
  if(!rst_n) begin
   num_ff <= 0;
   emp_ff <= YES;
   end
  else if (wr_pit == rd_pit) begin
   emp_ff <= YES;
   num_ff <= 0;
   end
  else if (wr_pit > rd_pit) begin
   emp_ff <= NO;
   num_ff <= wr_pit - rd_pit;
   end
  else begin
   emp_ff <= NO;
   num_ff <= wr_pit + 1024 - rd_pit;
   end
 end
 //计算fifo的缓存状态,满?
 always @(posedge clk,negedge rst_n) begin
  if(!rst_n) begin
   ful_ff <= NO;
   end
  else if(num_ff == 1023) begin
   ful_ff <= YES;
   end
  else begin
   ful_ff <= NO;
   end
 end


 //检测到fifo读请求时,从sram读出数据至fifo的出口端
 always @(negedge clk,negedge rst_n) begin
  if(!rst_n) dat_ro_ff <= 16'dz;
  else if(!oe_sram) dat_ro_ff <= data_sram;  //将数据从总线读到fifo的出口端
  else ;
 end
 

endmodule


 
 
 
 

PARTNER CONTENT

文章评论3条评论)

登录后参与讨论

用户1752181 2014-6-13 15:48

空满操作好像不是很对,FIFO不是写满了之后就不能再进行写了么?读空了之后就不能再进行读了么?但是上面的代码好像没有对这部分进行正确控制。

用户377235 2012-8-15 21:16

表示新手,路过

用户1629256 2012-8-5 20:05

再次说明一下,真心希望热心网友在代码风格,代码优化上,大胆斧正,不吝赐教

相关推荐阅读
用户1629256 2012-09-10 21:37
[Craftor原创]精通ModelSim脚本(1)
[Craftor原创]精通ModelSim脚本(1) ModelSim之强大是毋庸置疑的。而ModelSim脚本语言的强大,也同样让人佩服得五体投地。在此文中,Craftor将一...
用户1629256 2012-09-10 11:29
SDRAM 控制器 基本版 V2.3
看看V1版实在太凌乱,现在对代码风格进行革新,共有两个小版本 V2.2两段式+同步输出+独热编码  V2.3两段式+同步输出。。这里有一些我自己的思想:1.两段式状态机也可以做到同步输出;2.延时...
用户1629256 2012-09-10 11:06
调用modelsim 不用每次都编译库文件 转载 谢谢观赏
Quartus II调用modelsim无缝仿真   本篇文章为转载,写的不错,最近在学modelsim仿真,网上的教程很乱,把自己认为不错的整理贴出来,后面有机会会写个详细...
用户1629256 2012-09-04 11:17
SDRAM控制器,V1版,最基本功能,仍在升级中。。。。
  以上是上电200us后,对SDRAM的初始化时序图:左数第一条黄线是对所有bank预充电,第二条到第三条黄线是8个刷新周期,第四条黄线是模式寄存器设置。 以上是对SDRAM...
用户1629256 2012-08-09 10:13
评论:@阿松的博客 博客中提到的“让低端FPGA也能跑nios”
强悍...
EE直播间
更多
我要评论
3
8
关闭 站长推荐上一条 /3 下一条