source: trunk/MultiChannelUSB/fifo.v@ 28

Last change on this file since 28 was 27, checked in by demin, 15 years ago

initial commit

File size: 2.5 KB
Line 
1// Listing 4.20
2module fifo
3 #(
4 parameter B=8, // number of bits in a word
5 W=4 // number of address bits
6 )
7 (
8 input wire clk, reset,
9 input wire rd, wr,
10 input wire [B-1:0] w_data,
11 output wire empty, full,
12 output wire [B-1:0] r_data
13 );
14
15 //signal declaration
16 reg [B-1:0] array_reg [2**W-1:0]; // register array
17 reg [W-1:0] w_ptr_reg, w_ptr_next, w_ptr_succ;
18 reg [W-1:0] r_ptr_reg, r_ptr_next, r_ptr_succ;
19 reg full_reg, empty_reg, full_next, empty_next;
20 wire wr_en;
21
22 // body
23 // register file write operation
24 always @(posedge clk)
25 if (wr_en)
26 array_reg[w_ptr_reg] <= w_data;
27 // register file read operation
28 assign r_data = array_reg[r_ptr_reg];
29 // write enabled only when FIFO is not full
30 assign wr_en = wr & ~full_reg;
31
32 // fifo control logic
33 // register for read and write pointers
34 always @(posedge clk, posedge reset)
35 if (reset)
36 begin
37 w_ptr_reg <= 0;
38 r_ptr_reg <= 0;
39 full_reg <= 1'b0;
40 empty_reg <= 1'b1;
41 end
42 else
43 begin
44 w_ptr_reg <= w_ptr_next;
45 r_ptr_reg <= r_ptr_next;
46 full_reg <= full_next;
47 empty_reg <= empty_next;
48 end
49
50 // next-state logic for read and write pointers
51 always @*
52 begin
53 // successive pointer values
54 w_ptr_succ = w_ptr_reg + 1;
55 r_ptr_succ = r_ptr_reg + 1;
56 // default: keep old values
57 w_ptr_next = w_ptr_reg;
58 r_ptr_next = r_ptr_reg;
59 full_next = full_reg;
60 empty_next = empty_reg;
61 case ({wr, rd})
62 // 2'b00: no op
63 2'b01: // read
64 if (~empty_reg) // not empty
65 begin
66 r_ptr_next = r_ptr_succ;
67 full_next = 1'b0;
68 if (r_ptr_succ==w_ptr_reg)
69 empty_next = 1'b1;
70 end
71 2'b10: // write
72 if (~full_reg) // not full
73 begin
74 w_ptr_next = w_ptr_succ;
75 empty_next = 1'b0;
76 if (w_ptr_succ==r_ptr_reg)
77 full_next = 1'b1;
78 end
79 2'b11: // write and read
80 begin
81 w_ptr_next = w_ptr_succ;
82 r_ptr_next = r_ptr_succ;
83 end
84 endcase
85 end
86
87 // output
88 assign full = full_reg;
89 assign empty = empty_reg;
90
91endmodule
92
Note: See TracBrowser for help on using the repository browser.