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

FIFO 的控制逻辑---verilog代码

Posted on 2017-12-20 14:57  沉默改良者  阅读(1372)  评论(0编辑  收藏  举报

FIFO 的控制逻辑---verilog代码

  1 //fifo的例化
  2 wire fifo_full;
  3 wire fifo_empty;
  4 wire [9 : 0] fifo_dout;
  5 wire [14:0]rd_data_count;
  6 wire [14:0]wr_data_count;
  7 
  8 fifo_generator_0 U1 (
  9   .rst(reset_fifo),
 10   .wr_clk(rx_usrclk),                  // input wire wr_clk
 11   .rd_clk(tx_usrclk_1),                // input wire rd_clk
 12   .din(din),                           // input wire [9 : 0] din
 13   .wr_en(wr_en),                       // input wire wr_en
 14   .rd_en(rd_en),                       // input wire rd_en
 15   .dout(fifo_dout),                    // output wire [9 : 0] dout
 16   .full(fifo_full),                    // output wire full
 17   .empty(fifo_empty),                  // output wire empty
 18   .rd_data_count(rd_data_count),       // output wire [9 : 0] rd_data_count
 19   .wr_data_count(wr_data_count)        // output wire [9 : 0] wr_data_count
 20 );
 21 
 22 //fifo的复位方式,通过vio核手动复位
 23 wire reset_fifo;
 24 vio_2 U2 (
 25   .clk(clk_27M),                // input wire clk
 26   .probe_out0(reset_fifo)       // output wire [0 : 0] probe_out0
 27 );
 28 
 29 //*****************************************************************************
 30 //1.fifo写操作的控制
 31 //2.fifo刚开始工作时,先写满一半,然后fifo读操作才开始
 32 //3.fifo达到full状态时,写操作停止,读操作继续,当检测到fifo里面的数据还剩下一
 33 //半时,写操作再次开始工作
 34 //4.fifo达到empty状态时,读操作停止,还需要等待read_start信号的到来才能再次启动
 35 //读操作,即fifo从空的状态写到了一半
 36 //*****************************************************************************
 37 
 38 reg [2:0]i;
 39 reg read_start;
 40 reg wr_en_r;
 41 reg [9:0]din_r;
 42 
 43 always@(posedge rx_usrclk)
 44 begin
 45     if(reset_fifo)
 46         begin
 47             i <= 3'd0;
 48             read_start <= 1'b0;
 49             wr_en_r <= 1'b0;
 50             din_r <= 10'd0;
 51         end
 52     else 
 53         begin
 54             case(i)
 55                 3'd0:
 56                 begin 
 57                     if(!fifo_full) 
 58                         begin 
 59                             wr_en_r <= 1'b1; 
 60                             i<=i+1'b1; 
 61                         end
 62                     else 
 63                         wr_en_r <= 1'b0;
 64                 end
 65 
 66                 3'd1:
 67                 begin
 68                     if(fifo_full)
 69                         begin
 70                             wr_en_r <= 1'b0;
 71                             i<=i+1'b1;        
 72                         end
 73                     else if(fifo_empty)
 74                         read_start <= 1'b0;
 75                     else
 76                         begin
 77                             din_r <= rx_ds1a;   
 78                             if(wr_data_count >=15'd16384)
 79                                 read_start <= 1'b1;
 80                         end
 81                 end
 82 
 83                 3'd2:
 84                 begin
 85                     if(wr_data_count <=15'd16384)
 86                         begin
 87                             wr_en_r <= 1'b1;
 88                             i<=1'd1;
 89                         end
 90                 end
 91 
 92                 default:
 93                 begin
 94                     wr_en_r <= 1'b0;
 95                     read_start <=1'b0;
 96                 end
 97             endcase
 98         end
 99 end
100 
101 wire [9:0]din;
102 wire wr_en;
103 wire [2:0]i_w;
104 wire read_start_w;
105 
106 assign wr_en = rx_ce ? wr_en_r : 1'b0; 
107 assign din = din_r;
108 assign i_w = i;
109 assign read_start_w = read_start;
110 
111 
112 reg rd_en_r;
113 reg [2:0]j;
114 
115 always@(posedge tx_usrclk_1) 
116 begin
117     if(reset_fifo) 
118         begin
119             rd_en_r <= 1'b0;
120             j <= 3'd0;
121         end
122     else 
123         begin
124             case(j)
125                 3'd0:
126                 begin
127                     if(read_start && !fifo_empty)   
128                         begin
129                             rd_en_r <= 1'b1;
130                             j<=j+1'b1;
131                         end
132                     else 
133                             rd_en_r <= 1'b0;
134                 end
135 
136                 3'd1:
137                 begin
138                    if(fifo_empty)
139                        begin
140                           rd_en_r <= 1'b0;
141                           j<=3'd0;
142                        end
143                 end
144                 
145                 default:
146                 begin
147                     rd_en_r <= 1'b0;
148                     j <= 3'd0;
149                 end
150             endcase
151         end
152 end
153 
154 
155 wire rd_en;
156 wire [2:0]j_w;
157 
158 assign j_w = j;
159 assign rd_en = tx_ce[0] ? rd_en_r : 1'b0;      

备注:分两个always块(因为fifo的读和写在不同的时钟域),对fifo的读写操作进行控制。