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