1 module scfifo #( 2 parameter ND = 16, 3 parameter DW = 16 ) ( 4 input clk, 5 input rst_n, 6 input wren, 7 input rden, 8 input [DW-1:0] din, 9 output [DW-1:0] dout, 10 output full, 11 output empty 12 ); 13 14 localparam AW = $clog2(ND); 15 16 // Memory Registers 17 reg [DW-1:0] mem[ND-1:0]; 18 reg [AW-1:0] wadr, radr; 19 reg wr_full; 20 reg rd_empty; 21 22 // Write Memory Data 23 always@(posedge clk) 24 if(wren & ~wr_full) mem[wadr] <= din; 25 26 // Write Pointer 27 always@(posedge clk, negedge rst_n) 28 begin 29 if(~rst_n) 30 wadr <= 'd0; 31 else begin 32 if(wren & ~wr_full) 33 wadr <= wadr + 1'd1; 34 end 35 end 36 37 // Read Pointer 38 always@(posedge clk, negedge rst_n) 39 begin 40 if(~rst_n) 41 radr <= 'd0; 42 else begin 43 if(rden & ~rd_empty) 44 radr <= radr + 1'd1; 45 end 46 end 47 48 // Write Full Status 49 always@(posedge clk, negedge rst_n) 50 begin 51 if(~rst_n) 52 wr_full <= 1'b0; 53 else begin 54 if(~rden & wren & ((wadr == radr - 1'd1) || (~|radr && &wadr))) 55 wr_full <= 1'b1; 56 else if(rden & wr_full) 57 wr_full <= 1'b0; 58 end 59 end 60 61 // Read Empty Status 62 always@(posedge clk, negedge rst_n) 63 begin 64 if(~rst_n) 65 rd_empty <= 1'b1; 66 else begin 67 if(rden & ~wren & ((radr == wadr - 1'd1) || (~|wadr && &radr))) 68 rd_empty <= 1'b1; 69 else if(wren & rd_empty) 70 rd_empty <= 1'b0; 71 end 72 end 73 74 // Read Data and FIFO Status 75 assign dout = mem[radr]; 76 assign full = wr_full; 77 assign empty = rd_empty; 78 79 endmodule