@@ -30,6 +30,10 @@ class _FIFOInterface:
30
30
Bit width for the data.
31
31
depth : int
32
32
Depth of the FIFO.
33
+ fwft : bool (optional)
34
+ Enable the FIFO to have "first word fall through". The first
35
+ word written to an otherwise empty FIFO will be put on the
36
+ output without doing a read first.
33
37
34
38
Attributes
35
39
----------
@@ -48,7 +52,8 @@ class _FIFOInterface:
48
52
Acknowledge `dout`. If asserted, the next entry will be
49
53
available on the next cycle (if `readable` is high then).
50
54
"""
51
- def __init__ (self , width , depth ):
55
+
56
+ def __init__ (self , width , depth , fwft = False ):
52
57
self .we = Signal ()
53
58
self .writable = Signal () # not full
54
59
self .re = Signal ()
@@ -77,7 +82,7 @@ def write(self, data):
77
82
yield
78
83
79
84
80
- class SyncFIFO (Module , _FIFOInterface ):
85
+ class SyncFIFO (Module , _FIFOInterfaceWithFirstWordFallThrough ):
81
86
"""Synchronous FIFO (first in, first out)
82
87
83
88
Read and write interfaces are accessed from the same clock domain.
@@ -94,7 +99,7 @@ class SyncFIFO(Module, _FIFOInterface):
94
99
__doc__ = __doc__ .format (interface = _FIFOInterface .__doc__ )
95
100
96
101
def __init__ (self , width , depth , fwft = True ):
97
- _FIFOInterface .__init__ (self , width , depth )
102
+ _FIFOInterface .__init__ (self , width , depth , fwft )
98
103
99
104
self .level = Signal (max = depth + 1 )
100
105
self .replace = Signal ()
@@ -146,11 +151,18 @@ def __init__(self, width, depth, fwft=True):
146
151
147
152
148
153
class SyncFIFOBuffered (Module , _FIFOInterface ):
149
- """Has an interface compatible with SyncFIFO with fwft=True,
150
- but does not use asynchronous RAM reads that are not compatible
151
- with block RAMs. Increases latency by one cycle."""
152
- def __init__ (self , width , depth ):
153
- _FIFOInterface .__init__ (self , width , depth )
154
+ """SyncFIFO compatible with "first word fall through" without using async memory.
155
+
156
+ The SyncFIFOBuffered has an interface compatible with SyncFIFO with
157
+ `fwft=True` but does not use asynchronous RAM reads that are not compatible
158
+ with block RAMs. Increases latency by one cycle.
159
+
160
+ This is useful for providing a SyncFIFO when the FPGA part doesn't provide
161
+ block ram with an asynchronous read port, like the Lattice iCE40 parts.
162
+ """
163
+ def __init__ (self , width , depth , fwft = True ):
164
+ assert fwft , "fwft should be set, otherwise just use a SyncFIFO."
165
+ _FIFOInterface .__init__ (self , width , depth , False )
154
166
self .submodules .fifo = fifo = SyncFIFO (width , depth , False )
155
167
156
168
self .writable = fifo .writable
@@ -182,8 +194,9 @@ class AsyncFIFO(Module, _FIFOInterface):
182
194
"""
183
195
__doc__ = __doc__ .format (interface = _FIFOInterface .__doc__ )
184
196
185
- def __init__ (self , width , depth ):
186
- _FIFOInterface .__init__ (self , width , depth )
197
+ def __init__ (self , width , depth , fwft = False ):
198
+ assert not fwft , "fwft is not supported on the AsyncFIFO."
199
+ _FIFOInterface .__init__ (self , width , depth , fwft = False )
187
200
188
201
###
189
202
@@ -235,8 +248,8 @@ class AsyncFIFOBuffered(Module, _FIFOInterface):
235
248
"""Improves timing when it breaks due to sluggish clock-to-output
236
249
delay in e.g. Xilinx block RAMs. Increases latency by one cycle."""
237
250
def __init__ (self , width , depth ):
238
- _FIFOInterface .__init__ (self , width , depth )
239
- self .submodules .fifo = fifo = AsyncFIFO (width , depth )
251
+ _FIFOInterface .__init__ (self , width , depth , fwft = False )
252
+ self .submodules .fifo = fifo = AsyncFIFO (width , depth , fwft )
240
253
241
254
self .writable = fifo .writable
242
255
self .din = fifo .din
0 commit comments