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


    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的读写操作进行控制。

  • 相关阅读:
    《程序猿面试宝典3》大量错误(50+)纠正表
    STM32定时器的预装载寄存器与影子寄存器之间的关系【转】
    Linux虚拟内存和物理地址的理解【转】
    UNIX系统的显示时间何时会到尽头
    assert函数用法总结【转】
    Sizeof与Strlen的区别【转】
    C语言预处理器命令详解【转】
    C#预处理器指令【转】
    I2C总线信号时序总结【转】
    用状态机实现键盘消抖【转】
  • 原文地址:https://www.cnblogs.com/chensimin1990/p/8073760.html
Copyright © 2020-2023  润新知