Sheller_liu's blog

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

FIFO是英文First In First Out 的缩写,是一种先进先出的数据缓存器,他与普通存储器的区别是没有外部读写地址线,这样使用起来非常简单,但缺点就是只能顺序写入数据,顺序的读出数据, 其数据地址由内部读写指针自动加1完成,不能像普通存储器那样可以由地址线决定读取或写入某个指定的地址。

FIFO般用于不同时钟域之间的数据传输,比如FIFO的一端是AD数据采集, 另一端是计算机的PCI总线,假设其AD采集的速率为16位 100K SPS,那么每秒的数据量为100K×16bit=1.6Mbps,而PCI总线的速度为33MHz,总线宽度32bit,其最大传输速率为 1056Mbps,在两个不同的时钟域间就可以采用FIFO来作为数据缓冲。另外对于不同宽度的数据接口也可以用FIFO,例如单片机位8位数据输出,而 DSP可能是16位数据输入,在单片机与DSP连接时就可以使用FIFO来达到数据匹配的目的。

FIFO的分类根均FIFO工作的时钟域,可以将FIFO分为同步FIFO和异步FIFO。同步FIFO是指读时钟和写时钟为同一个时钟。在时钟沿来临时同时发生读写操作。异步FIFO是指读写时钟不一致,读写时钟是互相独立的。

 FIFO设计的难点 FIFO设计的难点在于怎样判断FIFO的空/满状态。为了保证数据正确的写入或读出,而不发生益处或读空的状态出现,必须保证FIFO在满的情况下,不 能进行写操作。在空的状态下不能进行读操作。怎样判断FIFO的满/空就成了FIFO设计的核心问题。

View Code
 1 module fifo (clk,rstp,din,writep,readp,dout,emptyp,fullp);
 2 input        clk;
 3 input        rstp;
 4 input[15:0]    din;
 5 input        readp;
 6 input        writep;
 7 output[15:0]dout;
 8 output        emptyp;
 9 output        fullp;
10 parameter    DEPTH=2,MAX_COUNT=2'b11;
11 
12 reg            emptyp;
13 reg            fullp;
14 reg[15:0]    dout;
15 reg[(DEPTH-1):0]tail;
16 reg[(DEPTH-1):0]head;
17 reg[(DEPTH-1):0]count;
18 reg[15:0]    fifomem[0:MAX_COUNT];
19 
20 always@(posedge clk) begin
21     if(rstp==1) begin
22         dout<=16'h0000;
23     end
24     else begin
25         dout<=fifomem[tail];
26     end
27 end
28 
29 always@(posedge clk) begin
30     if(rstp==1'b0 && writep==1'b1 && fullp==1'b0) begin
31         fifomem[head]<=din;
32     end
33 end
34 
35 always@(posedge clk) begin
36     if(rstp==1'b1) begin
37         head<=2'b00;
38     end
39     else begin
40         if(writep==1'b1 && fullp==1'b0) begin
41             head<=head+1;
42         end
43     end
44 end
45 
46 always@(posedge clk) begin
47     if(rstp==1'b1) begin
48         tail<=2'b00;
49     end
50     else begin
51         if(readp==1'b1 && emptyp==1'b0) begin
52             tail<=tail+1;
53         end
54     end    
55 end
56 
57 always@(posedge clk) begin
58     if(rstp==1'b1) begin
59         count<=2'b00;
60     end
61     else begin
62         case({readp,writep})
63         2'b00:count<=count;
64         2'b01:
65         if(count!=MAX_COUNT)
66             count<=count+1;
67         2'b10:
68             if(count!=2'b00)
69                 count<=count-1;
70         2'b11:
71             count<=count;
72         endcase
73     end
74 end
75 
76 always@(count) begin
77     if(count==2'b00)
78         emptyp<=1'b1;
79     else
80         emptyp<=1'b0;
81 end
82 
83 always@(count) begin
84     if(count==MAX_COUNT)
85         fullp<=1'b1;
86     else
87         fullp<=1'b0;
88 end
89 endmodule

测试程序:

View Code
  1 module test_fifo;
  2 
  3 reg        clk;
  4 reg        rstp;
  5 reg [15:0]    din;
  6 reg        readp;
  7 reg        writep;
  8 wire [15:0]    dout;
  9 wire        emptyp;
 10 wire        fullp;
 11 
 12 reg [15:0]    value;
 13 fifo U1 (.clk(clk),.rstp(rstp),.din(din),.readp(readp),.writep(writep),.dout(dout),
 14    .emptyp(emptyp),.fullp(fullp));
 15 task read_word;
 16 begin
 17    @(negedge clk);
 18    readp = 1;
 19    @(posedge clk) #5;
 20    readp = 0;
 21 end
 22 endtask
 23    
 24 task write_word;
 25 input [15:0]    value;
 26 begin
 27    @(negedge clk);
 28    din = value;
 29    writep = 1;
 30    @(posedge clk);
 31    #5;
 32    din = 16'hzzzz;
 33    writep = 0;
 34 end
 35 endtask
 36 initial begin
 37    clk = 0;
 38    forever begin
 39       #10 clk = 1;
 40       #10 clk = 0;
 41    end
 42 end
 43 
 44 initial begin
 45   test1;
 46   //test2; 
 47    
 48 end
 49 task test1;
 50 begin
 51    din = 16'hzzzz;
 52    writep = 0;
 53    readp = 0;
 54    rstp = 1;
 55    #50 rstp = 0;
 56    #50;
 57    write_word (16'h1111);
 58    write_word (16'h2222);
 59    write_word (16'h3333); 
 60    read_word;
 61    read_word;               
 62    write_word (16'h4444);   
 63    repeat (6) begin
 64       read_word;
 65    end
 66    
 67    write_word (16'h0001);
 68    write_word (16'h0002);
 69    write_word (16'h0003);
 70    write_word (16'h0004);
 71    write_word (16'h0005);
 72    write_word (16'h0006);
 73    write_word (16'h0007);
 74    write_word (16'h0008);
 75 repeat (6) begin
 76       read_word;
 77    end
 78 end
 79 endtask
 80 task test2;
 81 reg [15:0] writer_counter;
 82 begin
 83    writer_counter = 16'h0001;
 84    din = 16'hzzzz;
 85    writep = 0;
 86    readp = 0;
 87    rstp = 1;
 88    #50   rstp = 0;
 89    #50;
 90    fork
 91       begin
 92          repeat (500) begin
 93             @(negedge clk);
 94             if (fullp == 1'b0) begin
 95                write_word (writer_counter);
 96                #5;
 97                writer_counter = writer_counter + 1;
 98             end
 99                #50;
100          end
101     end
102  
103        begin
104          forever begin
105             @(negedge clk);
106             if (emptyp == 1'b0) begin
107                read_word;
108             end  
109           #50;
110          end
111       end
112    join
113 end
114 endtask
115 
116 
117 
118 endmodule
posted on 2012-10-02 22:17  sheller_liu  阅读(254)  评论(0编辑  收藏  举报