Skip to content

Commit 452b357

Browse files
committed
Added single clock fifo modules (two variants)
1 parent cb22428 commit 452b357

File tree

6 files changed

+935
-234
lines changed

6 files changed

+935
-234
lines changed

fifo.sv

Lines changed: 0 additions & 125 deletions
This file was deleted.

fifo_single_clock_reg_v1.sv

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
//------------------------------------------------------------------------------
2+
// fifo_single_clock_reg_v1.sv
3+
// Konstantin Pavlov, pavlovconst@gmail.com
4+
//------------------------------------------------------------------------------
5+
6+
// INFO ------------------------------------------------------------------------
7+
// Single-clock FIFO buffer implementation, also known as "queue"
8+
//
9+
// Features:
10+
// - single clock operation
11+
// - configurable depth and data width
12+
// - one write- and one read- port in "FWFT" or "normal" mode
13+
// - protected against overflow and underflow
14+
// - simultaneous read and write operations supported if not full and not empty
15+
// - only read operation is performed when (full && r_req && w_req)
16+
// - only write operation is performed when (empty && r_req && w_req)
17+
//
18+
// See also "lifo.sv" module for similar LIFO buffer implementation
19+
20+
21+
/* --- INSTANTIATION TEMPLATE BEGIN ---
22+
23+
fifo_single_clock_reg_v1 #(
24+
.FWFT_MODE( "TRUE" ),
25+
.DEPTH( 8 ),
26+
.DATA_W( 32 )
27+
) FF1 (
28+
.clk( clk ),
29+
.nrst( 1'b1 ),
30+
31+
.w_req( ),
32+
.w_data( ),
33+
34+
.r_req( ),
35+
.r_data( ),
36+
37+
.cnt( ),
38+
.empty( ),
39+
.full( )
40+
);
41+
42+
--- INSTANTIATION TEMPLATE END ---*/
43+
44+
module fifo_single_clock_reg_v1 #( parameter
45+
46+
FWFT_MODE = "TRUE", // "TRUE" - first word fall-trrough" mode
47+
// "FALSE" - normal fifo mode
48+
49+
DEPTH = 8, // max elements count == DEPTH, DEPTH MUST be power of 2
50+
DEPTH_W = $clog2(DEPTH)+1, // elements counter width, extra bit to store
51+
// "fifo full" state, see cnt[] variable comments
52+
53+
DATA_W = 32 // data field width
54+
)(
55+
56+
input clk,
57+
input nrst, // inverted reset
58+
59+
// input port
60+
input w_req,
61+
input [DATA_W-1:0] w_data,
62+
63+
// output port
64+
input r_req,
65+
output logic [DATA_W-1:0] r_data,
66+
67+
// helper ports
68+
output logic [DEPTH_W-1:0] cnt = '0,
69+
output logic empty,
70+
output logic full,
71+
72+
output logic fail
73+
);
74+
75+
// fifo data
76+
logic [DEPTH-1:0][DATA_W-1:0] data = '0;
77+
78+
// data output buffer for normal fifo mode
79+
logic [DATA_W-1:0] data_buf = '0;
80+
81+
// cnt[] vector always holds fifo elements count
82+
// data[cnt[]] points to the first empty fifo slot
83+
// when fifo is full data[cnt[]] points "outside" of data[]
84+
85+
// filtered requests
86+
logic w_req_f;
87+
assign w_req_f = w_req && ~full;
88+
89+
logic r_req_f;
90+
assign r_req_f = r_req && ~empty;
91+
92+
93+
integer i;
94+
always_ff @(posedge clk) begin
95+
if ( ~nrst ) begin
96+
data <= '0;
97+
cnt[DEPTH_W-1:0] <= '0;
98+
data_buf[DATA_W-1:0] <= '0;
99+
end else begin
100+
unique case ({w_req_f, r_req_f})
101+
2'b00: ; // nothing
102+
103+
2'b01: begin // reading out
104+
for ( i = (DEPTH-1); i > 0; i-- ) begin
105+
data[i-1] <= data[i];
106+
end
107+
cnt[DEPTH_W-1:0] <= cnt[DEPTH_W-1:0] - 1'b1;
108+
end
109+
110+
2'b10: begin // writing in
111+
data[cnt[DEPTH_W-1:0]] <= w_data[DATA_W-1:0];
112+
cnt[DEPTH_W-1:0] <= cnt[DEPTH_W-1:0] + 1'b1;
113+
end
114+
115+
2'b11: begin // simultaneously reading and writing
116+
for ( i = (DEPTH-1); i > 0; i-- ) begin
117+
data[i-1] <= data[i];
118+
end
119+
data[cnt[DEPTH_W-1:0]-1] <= w_data[DATA_W-1:0];
120+
// data counter does not change here
121+
end
122+
endcase
123+
124+
// data buffer works only for normal fifo mode
125+
if( r_req_f ) begin
126+
data_buf[DATA_W-1:0] <= data[0];
127+
end
128+
end
129+
end
130+
131+
132+
always_comb begin
133+
empty = ( cnt[DEPTH_W-1:0] == '0 );
134+
full = ( cnt[DEPTH_W-1:0] == DEPTH );
135+
136+
if( FWFT_MODE == "TRUE" ) begin
137+
if (~empty) begin
138+
r_data[DATA_W-1:0] = data[0]; // first-word fall-through mode
139+
end else begin
140+
r_data[DATA_W-1:0] = '0;
141+
end
142+
end else begin
143+
r_data[DATA_W-1:0] = data_buf[DATA_W-1:0]; // normal mode
144+
end
145+
146+
fail = ( empty && r_req ) ||
147+
( full && w_req );
148+
end
149+
150+
endmodule

0 commit comments

Comments
 (0)