-
Notifications
You must be signed in to change notification settings - Fork 1
/
fifo.sv
79 lines (71 loc) · 1.58 KB
/
fifo.sv
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
module fifo
#(
parameter int width = 40,
parameter int addr_bits = 3
)
(
input clock,
input reset,
input ren,
output [width-1:0] rdata,
input wen,
input [width-1:0] wdata,
output reg [addr_bits:0] count
);
parameter int depth = 2 ** addr_bits;
reg [width-1:0] buffer[0:depth-1];
reg [addr_bits:0] waddr;
reg [addr_bits-1:0] raddr;
wire empty = count == 0;
wire full = count == depth;
wire raccept = ren && (wen || !empty);
wire waccept = wen && (ren || !full);
always_ff@(posedge clock or posedge reset) begin
if (reset) begin
count <= 0;
end else begin
case ({waccept, raccept})
2'b00: count <= count;
2'b01: count <= count - 1'b1;
2'b10: count <= count + 1'b1;
2'b11: count <= count;
endcase
end
end
assign rdata = count == 0 ? wdata : buffer[raddr[addr_bits-1:0]];
always_ff@(posedge clock or posedge reset) begin
if (reset) begin
waddr <= 0;
end else begin
if (waccept) begin
buffer[waddr[addr_bits-1:0]] <= wdata;
if (raddr == depth - 1 && raccept) begin
waddr <= waddr - depth + 1;
end else begin
waddr <= waddr + 1;
end
end else begin
if (raddr == depth - 1 && raccept) begin
waddr <= waddr - depth;
end else begin
waddr <= waddr;
end
end
end
end
always_ff@(posedge clock or posedge reset) begin
if (reset) begin
raddr <= 0;
end else begin
if (raccept) begin
if (raddr == depth - 1) begin
raddr <= 0;
end else begin
raddr <= raddr + 1;
end
end else begin
raddr <= raddr;
end
end
end
endmodule