forked from tanchou/Verilog
		
	
		
			
				
	
	
		
			49 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			Verilog
		
	
	
	
	
	
			
		
		
	
	
			49 lines
		
	
	
		
			1.3 KiB
		
	
	
	
		
			Verilog
		
	
	
	
	
	
|  module fifo #(
 | |
| 	parameter       SIZE = 16,
 | |
| 	parameter       WIDTH = 8
 | |
| )(
 | |
|     input wire              clk,
 | |
|     input wire              wr_en,
 | |
|     input wire[WIDTH-1:0]   wr_data,
 | |
|     input wire              rd_en,
 | |
|     output reg[WIDTH-1:0]   rd_data,
 | |
| 
 | |
|     output wire             full,
 | |
|     output wire             empty
 | |
| );
 | |
| 
 | |
|     localparam LOGSIZE = $clog2(SIZE);
 | |
| 
 | |
|     reg [WIDTH-1:0]         fifo[0:SIZE-1];
 | |
|     reg [LOGSIZE-1:0]               wr_ptr;
 | |
|     reg [LOGSIZE-1:0]               rd_ptr;
 | |
|     reg [LOGSIZE:0]               count;
 | |
| 
 | |
|     assign full = (count == SIZE);
 | |
|     assign empty = (count == 0);
 | |
| 
 | |
|     initial begin
 | |
|         wr_ptr = 0;
 | |
|         rd_ptr = 0;
 | |
|         count = 0;
 | |
|     end
 | |
| 
 | |
|     always @(posedge clk) begin // IN
 | |
|         rd_data <= fifo[rd_ptr];
 | |
|         if (wr_en && !full && rd_en && !empty)  begin
 | |
|             fifo[wr_ptr] <= wr_data;
 | |
|             wr_ptr <= (wr_ptr == SIZE - 1) ? 0 :  (wr_ptr + 1) ;
 | |
|             rd_ptr <= (rd_ptr == SIZE - 1) ? 0 :  (rd_ptr + 1) ;
 | |
|         end else if (wr_en && !full) begin
 | |
|             fifo[wr_ptr] <= wr_data;
 | |
|             wr_ptr <= (wr_ptr == SIZE - 1) ? 0 :  (wr_ptr + 1) ;
 | |
|             count <= count + 1;
 | |
|         end else if (rd_en && !empty) begin // OUT
 | |
|             rd_ptr <= (rd_ptr == SIZE - 1) ? 0 :  (rd_ptr + 1) ;
 | |
|             count <= count - 1;
 | |
|         end
 | |
| 
 | |
|     end
 | |
|     
 | |
| endmodule
 |