• 同步FIFO的verilog描述


     1 /******************************************************
     2 A fifo controller verilog description.
     3 ******************************************************/
     4 module fifo(datain, rd, wr, rst, clk, dataout, full, empty);
     5 input [7:0] datain;
     6 input rd, wr, rst, clk;
     7 output [7:0] dataout;
     8 output full, empty;
     9 wire [7:0] dataout;
    10 reg full_in, empty_in;
    11 reg [7:0] mem [15:0];
    12 reg [3:0] rp, wp;//其实是一个循环读写的过程,4位二进制数刚好16个状态,也即指示16个深度
    13 assign full = full_in;
    14 assign empty = empty_in;
    15 // memory read out
    16 assign dataout = mem[rp];
    17 // memory write in
    18 always@(posedge clk) begin
    19     if(wr && ~full_in) mem[wp]<=datain;
    20 end
    21 // memory write pointer increment
    22 always@(posedge clk or negedge rst) begin
    23     if(!rst) wp<=0;
    24     else begin
    25       if(wr && ~full_in) wp<= wp+1'b1;
    26     end
    27 end
    28 // memory read pointer increment
    29 always@(posedge clk or negedge rst)begin
    30     if(!rst) rp <= 0;
    31     else begin
    32       if(rd && ~empty_in) rp <= rp + 1'b1;
    33     end
    34 end
    35 // Full signal generate
    36 always@(posedge clk or negedge rst) begin
    37     if(!rst) full_in <= 1'b0;
    38     else begin
    39       if( (~rd && wr)&&((wp==rp-1)||(rp==4'h0&&wp==4'hf)))
    40           full_in <= 1'b1;
    41       else if(full_in && rd) full_in <= 1'b0;
    42     end
    43 end
    44 // Empty signal generate
    45 always@(posedge clk or negedge rst) begin
    46     if(!rst) empty_in <= 1'b1;
    47     else begin
    48       if((rd&&~wr)&&(rp==wp-1 || (rp==4'hf&&wp==4'h0)))
    49         empty_in<=1'b1;
    50       else if(empty_in && wr) empty_in<=1'b0;
    51     end
    52 end
    53 endmodule 
    同步FIFO

      同步FIFO相对简单,但稍微复杂点儿的就是full和empty信号的产生,有两种方法上述代码是常用的,但不很容易理解,解释下,FIFO先入先出,可知读写地址都是从零开始递增,这样才能满足先写进的将来会被先读出来。对于同步FIFO来说,时钟是同一个,如果同时读写,那么FIFO永远都不会满。因为当写指针到FIFO尽头时,会继续从零地址开始写(假设零地址的数据已经被读出,当然就可以覆盖了),如此循环往复。那么到底空满标志如何产生:

      最直观的一种情况,对于full来说,假如一直写,都还没读,此时当wrp=FIFO深度时,应该产生满标志,如果继续写,就会覆盖还未读出的数据,从而使数据失效。

               对于empty来说,假如wrp=0,而rdp=FIFO深度时,应该产生空标志,如果继续读。就会从零地址开始读,而零地址要么是以前的数据要么是空的,所以…

      第二种情况:wrp与rdp之间差值为1,rdp-wrp=1时如果没有读,继续写的话会发生数据覆盖;wrp-rdp=1时如果没有写继续读,会读出错误数据。

      这就是程序中标志位表达形式的原因。

      还有一种简单的方法产生空满标志:

    并不用读写地址判定FIFO是否空满。设计一个计数器,该计数器(pt_cnt)用于指示当前周期中FIFO中数据的个数。由于FIFO中最多只有16个数据,因此采用5位计数器来指示FIFO中数据个数。具体计算如下:

    l  复位的时候,pt_cnt=0;

    l  如果wr_en和rd_en同时有效的时候,pt_cnt不加也不减;表示同时对FIFO进行读写操作的时候,FIFO中的数据个数不变。

    l  如果wr_en有效且full=0,则pt_cont+1;表示写操作且FIFO未满时候,FIFO中的数据个数增加了1;

    l  如果rd_en有效且empty=0,则pt_cont-1; 表示读操作且FIFO未满时候,FIFO中的数据个数减少了1;

    l  如果pt_cnt=0的时候,表示FIFO空,需要设置empty=1;如果pt_cnt=16的时候,表示FIFO现在已经满,需要设置full=1。

    该模块的程序:

     1 module flag_gen(clk,rst,full,emptyp,wr_en,rd_en);
     2 input clk,rst;
     3 input rd_en;
     4 input wr_en;
     5 output full,emptyp;
     6 reg full,emptyp;
     7 reg[4:0]count;
     8 parameter max_count=5'b01111;
     9 always @ (posedge clk or negedge rst)
    10 begin
    11   if(!rst)
    12    count<=0;
    13   else
    14    begin
    15    case({wr_en,rd_en})
    16    2'b00:count<=count;
    17    2'b01:
    18        if(count!==5'b00000)
    19        count<=count-1;
    20    2'b10:
    21        if(count!== max_count)   
    22         count<=count+1;
    23    2'b11:count<=count;
    24    endcase
    25    end
    26 end
    27 always @(count)
    28 begin
    29    if(count==5'b00000)
    30     emptyp<=1;
    31    else
    32     emptyp<=0;
    33 end
    34 always @(count)
    35 begin
    36    if(count== max_count)
    37    full<=1;
    38    else
    39    full<=0;                                 
    40 end
    41 endmodule
    full、empty标志位的产生

    我们又一次见证了位拼接运算符的强大。

  • 相关阅读:
    Windows下好用的git客户端--GitExtentions
    高分辨率下放大netbeans中的小图标
    小书匠使用手册
    win8 telnet VirtualBox中的redhat9
    win8安装新字体
    netbeans设置字体
    win7下Chrome有两个图标的解决方法
    【转】HDU-6035-Colorful Tree
    POJ1703--Find them, Catch them(种类并查集)
    KMP的妙用(利用next数组寻找字符串的循环节)
  • 原文地址:https://www.cnblogs.com/fkl523/p/4046755.html
Copyright © 2020-2023  润新知