-
Notifications
You must be signed in to change notification settings - Fork 0
/
fallthrough_small_fifo_v2.v
101 lines (87 loc) · 3.21 KB
/
fallthrough_small_fifo_v2.v
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
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
///////////////////////////////////////////////////////////////////////////////
// $Id: small_fifo.v 1998 2007-07-21 01:22:57Z grg $
//
// Module: fallthrough_small_fifo.v
// Project: utils
// Description: small fifo with fallthrough i.e. data valid when rd is high
//
// Change history:
// 7/20/07 -- Set nearly full to 2^MAX_DEPTH_BITS - 1 by default so that it
// goes high a clock cycle early.
// 2/11/09 -- jnaous: Rewrote to make much more efficient.
// 5/11/11 -- hyzeng: Rewrote based on http://www.billauer.co.il/reg_fifo.html
// to improve timing by adding output register
///////////////////////////////////////////////////////////////////////////////
`timescale 1ns/1ps
module fallthrough_small_fifo
#(parameter WIDTH = 72,
parameter MAX_DEPTH_BITS = 3,
parameter PROG_FULL_THRESHOLD = 2**MAX_DEPTH_BITS - 1)
(
input [WIDTH-1:0] din, // Data in
input wr_en, // Write enable
input rd_en, // Read the next word
output reg [WIDTH-1:0] dout, // Data out
output full,
output nearly_full,
output prog_full,
output empty,
input reset,
input clk
);
reg fifo_valid, middle_valid, dout_valid;
reg [(WIDTH-1):0] middle_dout;
wire [(WIDTH-1):0] fifo_dout;
wire fifo_empty, fifo_rd_en;
wire will_update_middle, will_update_dout;
// orig_fifo is just a normal (non-FWFT) synchronous or asynchronous FIFO
small_fifo
#(.WIDTH (WIDTH),
.MAX_DEPTH_BITS (MAX_DEPTH_BITS),
.PROG_FULL_THRESHOLD (PROG_FULL_THRESHOLD))
fifo
(.din (din),
.wr_en (wr_en),
.rd_en (fifo_rd_en),
.dout (fifo_dout),
.full (full),
.nearly_full (nearly_full),
.prog_full (prog_full),
.empty (fifo_empty),
.reset (reset),
.clk (clk)
);
assign will_update_middle = fifo_valid && (middle_valid == will_update_dout);
assign will_update_dout = (middle_valid || fifo_valid) && (rd_en || !dout_valid);
assign fifo_rd_en = (!fifo_empty) && !(middle_valid && dout_valid && fifo_valid);
assign empty = !dout_valid;
always @(posedge clk) begin
if (reset)
begin
fifo_valid <= 0;
middle_valid <= 0;
dout_valid <= 0;
dout <= 0;
middle_dout <= 0;
end
else
begin
if (will_update_middle)
middle_dout <= fifo_dout;
if (will_update_dout)
dout <= middle_valid ? middle_dout : fifo_dout;
if (fifo_rd_en)
fifo_valid <= 1;
else if (will_update_middle || will_update_dout)
fifo_valid <= 0;
if (will_update_middle)
middle_valid <= 1;
else if (will_update_dout)
middle_valid <= 0;
if (will_update_dout)
dout_valid <= 1;
else if (rd_en)
dout_valid <= 0;
end
end
endmodule