同步FIFO的设计

时间:2021-05-07 23:32:28
 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