1 |
2 |
kdv |
/*
|
2 |
|
|
* framestore.v
|
3 |
|
|
*
|
4 |
|
|
* Copyright (c) 2007 Koen De Vleeschauwer.
|
5 |
|
|
*
|
6 |
|
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
7 |
|
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
8 |
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
9 |
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
10 |
|
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
11 |
|
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
12 |
|
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
13 |
|
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
14 |
|
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
15 |
|
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
16 |
|
|
* SUCH DAMAGE.
|
17 |
|
|
*/
|
18 |
|
|
|
19 |
|
|
/*
|
20 |
|
|
* Frame Store.
|
21 |
|
|
*
|
22 |
|
|
* Receives memory read and write requests from motion compensation and display;
|
23 |
|
|
* passes the read and write requests on to the memory controller.
|
24 |
|
|
* Receives data read from the memory controller;
|
25 |
|
|
* passes data read on to motion compensation or display.
|
26 |
|
|
*/
|
27 |
|
|
|
28 |
|
|
/*
|
29 |
|
|
|
30 |
|
|
Frame store subsystem
|
31 |
|
|
|
32 |
|
|
+--------------+ +--------------+ +--------------+ +--------------+
|
33 |
|
|
| | -> fwd fifo -> | | | | -> fwd fifo (dta) -> | |
|
34 |
|
|
| | read request (addr) | | | | | | | |
|
35 |
|
|
| | | | | | | | | |
|
36 |
|
|
| motion | -> bwd fifo -> | | | | -> bwd fifo (dta) -> | motion |
|
37 |
|
|
| compensation | read request (addr) | | +------------+ | | || || | compensation |
|
38 |
|
|
| | | | | memory | | | || || | |
|
39 |
|
|
| | -> recon fifo -> | framestore | -> memory request fifo -> | controller | -> memory response fifo -> | framestore | || || | |
|
40 |
|
|
+--------------+ write request (addr,dta) | request | (addr, dta, command) | | (dta) | response | || || +--------------+
|
41 |
|
|
+--------------+ | | | +------------+ | | | || || +--------------+
|
42 |
|
|
| chroma | -> disp fifo -> | | | ^ | | | -> disp fifo (dta) -> | chroma |
|
43 |
|
|
| resampling | read request (addr) | | | + ------------+ | | ||| ||| | resampling |
|
44 |
|
|
+--------------+ | | | mem_res_wr_almost_full | | ||| ||| +--------------+
|
45 |
|
|
+--------------+ | | | | | ||| ||| +--------------+
|
46 |
|
|
| stream input | -> vbuf_write_fifo (dta) -> | | | | | -> vbuf_read_fifo -> | getbits |
|
47 |
|
|
| buffer write | | | | | | (dta) | buffer read |
|
48 |
|
|
+--------------+ | | | | | ||| ||| +--------------+
|
49 |
|
|
+--------------+ | | | | | ||| |||
|
50 |
|
|
| register | -> osd fifo -> | | ---------------------------> tag fifo ----------------------------> | | ||| |||
|
51 |
|
|
| file | write request (addr,dta) | | | (tag) | | ||| |||
|
52 |
|
|
+--------------+ +--------------+ | | +--------------+ ||| |||
|
53 |
|
|
^ ^ ^ | | ^ ||| |||
|
54 |
|
|
| | | | | | ||| |||
|
55 |
|
|
| | +--------------+ | +---------+++ |||
|
56 |
|
|
| |mem_req_wr_almost_full | fwd_wr_dta_full, |||
|
57 |
|
|
| +-------------------------------------+ bwd_wr_dta_full, |||
|
58 |
|
|
| tag_wr_almost_full disp_wr_dta_full |||
|
59 |
|
|
| vbr_wr_full |||
|
60 |
|
|
+--------------------------------------------------------------------------------------------------------+++
|
61 |
|
|
fwd_wr_dta_almost_full,
|
62 |
|
|
bwd_wr_dta_almost_full,
|
63 |
|
|
disp_wr_dta_almost_full,
|
64 |
|
|
vbr_wr_almost_full
|
65 |
|
|
|
66 |
|
|
|
67 |
|
|
Motion compensation issues read requests for forward motion compensation (fwd),
|
68 |
|
|
read requests for backward motion compensation (bwd),
|
69 |
|
|
and write requests for the reconstructed image (recon).
|
70 |
|
|
Chroma upsampling issues read requests for displaying frames (disp).
|
71 |
|
|
The register file issues write requests for updating the on-screen display.
|
72 |
|
|
|
73 |
|
|
Framestore_request prioritizes the incoming requests and joins them into a single queue (memory request fifo, mem_request_fifo).
|
74 |
|
|
When framestore_request sends a read request to the memory controller (mem_ctl) it also writes a tag to the tag fifo (mem_tag_fifo).
|
75 |
|
|
The tag has the value fwd, bwd, or disp, depending upon which fifo issued the read request.
|
76 |
|
|
|
77 |
|
|
The memory controller reads memory requests from the memory request fifo, and issues the corresponding commands to ram.
|
78 |
|
|
If the memory request is a read request, the data read is sent to the memory response fifo (mem_response_fifo).
|
79 |
|
|
|
80 |
|
|
Framestore_response reads data from the memory response fifo, and tags from the tag fifo. The data is written to the fifo that corresponds to the tag (fwd, bwd, disp).
|
81 |
|
|
|
82 |
|
|
There is feedback in the frame store subsystem. The purpose of this feedback is to avoid fifo's overflowing:
|
83 |
|
|
- framestore_request stops handling fwd read requests when the fwd data fifo is almost full (fwd_wr_dta_almost_full)
|
84 |
|
|
- framestore_request stops handling bwd read requests when the bwd data fifo is almost full (bwd_wr_dta_almost_full)
|
85 |
|
|
- framestore_request stops handling disp read requests when the disp data fifo is almost full (disp_wr_dta_almost_full)
|
86 |
|
|
- framestore_request stops handling all requests when the memory request fifo is almost full (mem_req_wr_almost_full)
|
87 |
|
|
- framestore_request stops handling all requests when the tag fifo is almost full (tag_wr_almost_full)
|
88 |
|
|
- the memory controller stops handling requests when the memory controller output fifo is almost full (mem_res_wr_almost_full)
|
89 |
|
|
- framestore_response stops reading the memory response fifo when fwd, bwd or disp fifo is full (fwd_wr_dta_full, bwd_wr_dta_full, disp_wr_dta_full, vbr_wr_full).
|
90 |
|
|
This is a last-ditch attempt to avoid the fifo's overflowing, and - with well-dimensioned fifo's - should happen rarely, if at all.
|
91 |
|
|
|
92 |
|
|
The main feedback loop is the feedback from fwd_wr_dta_almost_full, bwd_wr_dta_almost_full, disp_wr_dta_almost_full and vbr_wr_almost_full to framestore_request.
|
93 |
|
|
*/
|
94 |
|
|
|
95 |
|
|
/*
|
96 |
|
|
* Behavior upon reset
|
97 |
|
|
*
|
98 |
|
|
* Upon reset, framestore_request will go to STATE_CLEAR and
|
99 |
|
|
* write zeroes to the whole of the frame memory.
|
100 |
|
|
* For MP@ML, this takes at least 077fff hex = 491519 dec clock cycles.
|
101 |
|
|
* After having written zeroes to the whole of the frame memory,
|
102 |
|
|
* framestore_request begins accepting memory reads/writes.
|
103 |
|
|
*
|
104 |
|
|
* Upon reset, and simultaneously with framestore_request clearing memory, framestore_response will go into STATE_FLUSH and
|
105 |
|
|
* flush any data in the memory response fifo.
|
106 |
|
|
* This takes 0ffff hex = 65535 clock cyles.
|
107 |
|
|
* After having flushed the memory response fifo,
|
108 |
|
|
* framestore_response begins handling memory read data.
|
109 |
|
|
*
|
110 |
|
|
* As 65535 is less than 491519, framestore_response is guaranteed to begin
|
111 |
|
|
* handling memory read data before framestore_request begins accepting
|
112 |
|
|
* memory reads/writes. This is neccessary, because otherwise
|
113 |
|
|
* framestore_response might flush valid memory read data.
|
114 |
|
|
*
|
115 |
|
|
* The flushing of the memory response fifo upon reset guarantees the decoder
|
116 |
|
|
* does not use stale data if the decoder is reset while decoding,
|
117 |
|
|
* but the external memory controller and memory fifos are not reset.
|
118 |
|
|
* This could happen e.g. when a watchdog-generated reset occurs.
|
119 |
|
|
*/
|
120 |
|
|
|
121 |
|
|
`include "timescale.v"
|
122 |
|
|
`undef DEBUG
|
123 |
|
|
//`define DEBUG 1
|
124 |
|
|
`undef CHECK
|
125 |
|
|
`ifdef __IVERILOG__
|
126 |
|
|
`define CHECK 1
|
127 |
|
|
`endif
|
128 |
|
|
|
129 |
|
|
module framestore(rst, clk, mem_clk,
|
130 |
|
|
fwd_rd_addr_empty, fwd_rd_addr_en, fwd_rd_addr_valid, fwd_rd_addr, fwd_wr_dta_full, fwd_wr_dta_almost_full, fwd_wr_dta_en, fwd_wr_dta_ack, fwd_wr_dta, fwd_rd_dta_almost_empty,
|
131 |
|
|
bwd_rd_addr_empty, bwd_rd_addr_en, bwd_rd_addr_valid, bwd_rd_addr, bwd_wr_dta_full, bwd_wr_dta_almost_full, bwd_wr_dta_en, bwd_wr_dta_ack, bwd_wr_dta, bwd_rd_dta_almost_empty,
|
132 |
|
|
recon_rd_empty, recon_rd_almost_empty, recon_rd_en, recon_rd_valid, recon_rd_addr, recon_rd_dta, recon_wr_almost_full,
|
133 |
|
|
disp_rd_addr_empty, disp_rd_addr_en, disp_rd_addr_valid, disp_rd_addr, disp_wr_dta_full, disp_wr_dta_almost_full, disp_wr_dta_en, disp_wr_dta_ack, disp_wr_dta, disp_rd_dta_almost_empty,
|
134 |
|
|
osd_rd_empty, osd_rd_almost_empty, osd_rd_en, osd_rd_valid, osd_rd_addr, osd_rd_dta, osd_wr_almost_full,
|
135 |
|
|
vbw_rd_empty, vbw_rd_almost_empty, vbw_rd_en, vbw_rd_valid, vbw_rd_dta, vbw_wr_almost_full,
|
136 |
|
|
vbr_wr_full, vbr_wr_almost_full, vbr_wr_dta, vbr_wr_en, vbr_wr_ack, vb_flush, vbr_rd_almost_empty,
|
137 |
|
|
mem_req_rd_cmd, mem_req_rd_addr, mem_req_rd_dta, mem_req_rd_en, mem_req_rd_valid,
|
138 |
|
|
mem_res_wr_dta, mem_res_wr_en, mem_res_wr_almost_full, mem_res_wr_full, mem_res_wr_overflow,
|
139 |
|
|
mem_req_wr_almost_full, mem_req_wr_full, mem_req_wr_overflow,
|
140 |
|
|
tag_wr_almost_full, tag_wr_full, tag_wr_overflow
|
141 |
|
|
);
|
142 |
|
|
|
143 |
|
|
input rst;
|
144 |
|
|
input clk;
|
145 |
|
|
input mem_clk;
|
146 |
|
|
/* motion compensation: reading forward reference frame */
|
147 |
|
|
input fwd_rd_addr_empty;
|
148 |
|
|
output fwd_rd_addr_en;
|
149 |
|
|
input fwd_rd_addr_valid;
|
150 |
|
|
input [21:0]fwd_rd_addr;
|
151 |
|
|
input fwd_wr_dta_full;
|
152 |
|
|
input fwd_wr_dta_almost_full;
|
153 |
|
|
output fwd_wr_dta_en;
|
154 |
|
|
input fwd_wr_dta_ack;
|
155 |
|
|
output [63:0]fwd_wr_dta;
|
156 |
|
|
input fwd_rd_dta_almost_empty;
|
157 |
|
|
/* motion compensation: reading backward reference frame */
|
158 |
|
|
input bwd_rd_addr_empty;
|
159 |
|
|
output bwd_rd_addr_en;
|
160 |
|
|
input bwd_rd_addr_valid;
|
161 |
|
|
input [21:0]bwd_rd_addr;
|
162 |
|
|
input bwd_wr_dta_full;
|
163 |
|
|
input bwd_wr_dta_almost_full;
|
164 |
|
|
output bwd_wr_dta_en;
|
165 |
|
|
input bwd_wr_dta_ack;
|
166 |
|
|
output [63:0]bwd_wr_dta;
|
167 |
|
|
input bwd_rd_dta_almost_empty;
|
168 |
|
|
/* motion compensation: writing reconstructed frame */
|
169 |
|
|
input recon_rd_empty;
|
170 |
|
|
input recon_rd_almost_empty;
|
171 |
|
|
output recon_rd_en;
|
172 |
|
|
input recon_rd_valid;
|
173 |
|
|
input [21:0]recon_rd_addr;
|
174 |
|
|
input [63:0]recon_rd_dta;
|
175 |
|
|
input recon_wr_almost_full;
|
176 |
|
|
/* display: reading reconstructed frame */
|
177 |
|
|
input disp_rd_addr_empty;
|
178 |
|
|
output disp_rd_addr_en;
|
179 |
|
|
input disp_rd_addr_valid;
|
180 |
|
|
input [21:0]disp_rd_addr;
|
181 |
|
|
input disp_wr_dta_full;
|
182 |
|
|
input disp_wr_dta_almost_full;
|
183 |
|
|
output disp_wr_dta_en;
|
184 |
|
|
input disp_wr_dta_ack;
|
185 |
|
|
output [63:0]disp_wr_dta;
|
186 |
|
|
input disp_rd_dta_almost_empty;
|
187 |
|
|
/* video buffer: writing to circular buffer */
|
188 |
|
|
input [63:0]vbw_rd_dta;
|
189 |
|
|
output vbw_rd_en;
|
190 |
|
|
input vbw_rd_valid;
|
191 |
|
|
input vbw_rd_empty;
|
192 |
|
|
input vbw_rd_almost_empty;
|
193 |
|
|
input vbw_wr_almost_full;
|
194 |
|
|
/* video buffer: reading from circular buffer */
|
195 |
|
|
output [63:0]vbr_wr_dta;
|
196 |
|
|
output vbr_wr_en;
|
197 |
|
|
input vbr_wr_ack;
|
198 |
|
|
input vbr_wr_full;
|
199 |
|
|
input vbr_wr_almost_full;
|
200 |
|
|
input vb_flush;
|
201 |
|
|
input vbr_rd_almost_empty;
|
202 |
|
|
/* register file: writing on-screen display */
|
203 |
|
|
input osd_rd_empty;
|
204 |
|
|
input osd_rd_almost_empty;
|
205 |
|
|
output osd_rd_en;
|
206 |
|
|
input osd_rd_valid;
|
207 |
|
|
input [21:0]osd_rd_addr;
|
208 |
|
|
input [63:0]osd_rd_dta;
|
209 |
|
|
input osd_wr_almost_full;
|
210 |
|
|
|
211 |
|
|
/* local fifo registers */
|
212 |
|
|
|
213 |
|
|
wire [1:0]mem_req_wr_cmd;
|
214 |
|
|
wire [21:0]mem_req_wr_addr;
|
215 |
|
|
wire [63:0]mem_req_wr_dta;
|
216 |
|
|
wire mem_req_wr_en;
|
217 |
|
|
output mem_res_wr_full;
|
218 |
|
|
output mem_req_wr_full;
|
219 |
|
|
output mem_req_wr_overflow;
|
220 |
|
|
output mem_req_wr_almost_full;
|
221 |
|
|
output [1:0]mem_req_rd_cmd;
|
222 |
|
|
output [21:0]mem_req_rd_addr;
|
223 |
|
|
output [63:0]mem_req_rd_dta;
|
224 |
|
|
input mem_req_rd_en;
|
225 |
|
|
output mem_req_rd_valid;
|
226 |
|
|
|
227 |
|
|
wire [2:0]tag_wr_dta;
|
228 |
|
|
wire tag_wr_en;
|
229 |
|
|
output tag_wr_overflow;
|
230 |
|
|
output tag_wr_full;
|
231 |
|
|
output tag_wr_almost_full;
|
232 |
|
|
wire [2:0]tag_rd_dta;
|
233 |
|
|
wire tag_rd_en;
|
234 |
|
|
wire tag_rd_empty;
|
235 |
|
|
wire tag_rd_valid;
|
236 |
|
|
|
237 |
|
|
input [63:0]mem_res_wr_dta;
|
238 |
|
|
input mem_res_wr_en;
|
239 |
|
|
output mem_res_wr_overflow;
|
240 |
|
|
output mem_res_wr_almost_full;
|
241 |
|
|
wire [63:0]mem_res_rd_dta;
|
242 |
|
|
wire mem_res_rd_en;
|
243 |
|
|
wire mem_res_rd_empty;
|
244 |
|
|
wire mem_res_rd_valid;
|
245 |
|
|
|
246 |
|
|
`include "fifo_size.v"
|
247 |
|
|
|
248 |
|
|
/* send read/write requests to memory controller */
|
249 |
|
|
framestore_request framestore_request (
|
250 |
|
|
.rst(rst),
|
251 |
|
|
.clk(clk),
|
252 |
|
|
.fwd_rd_addr_empty(fwd_rd_addr_empty),
|
253 |
|
|
.fwd_rd_addr_en(fwd_rd_addr_en),
|
254 |
|
|
.fwd_rd_addr_valid(fwd_rd_addr_valid),
|
255 |
|
|
.fwd_rd_addr(fwd_rd_addr),
|
256 |
|
|
.fwd_wr_dta_full(fwd_wr_dta_full),
|
257 |
|
|
.fwd_wr_dta_almost_full(fwd_wr_dta_almost_full),
|
258 |
|
|
.fwd_rd_dta_almost_empty(fwd_rd_dta_almost_empty),
|
259 |
|
|
.bwd_rd_addr_empty(bwd_rd_addr_empty),
|
260 |
|
|
.bwd_rd_addr_en(bwd_rd_addr_en),
|
261 |
|
|
.bwd_rd_addr_valid(bwd_rd_addr_valid),
|
262 |
|
|
.bwd_rd_addr(bwd_rd_addr),
|
263 |
|
|
.bwd_wr_dta_full(bwd_wr_dta_full),
|
264 |
|
|
.bwd_wr_dta_almost_full(bwd_wr_dta_almost_full),
|
265 |
|
|
.bwd_rd_dta_almost_empty(bwd_rd_dta_almost_empty),
|
266 |
|
|
.recon_rd_empty(recon_rd_empty),
|
267 |
|
|
.recon_rd_almost_empty(recon_rd_almost_empty),
|
268 |
|
|
.recon_rd_en(recon_rd_en),
|
269 |
|
|
.recon_rd_valid(recon_rd_valid),
|
270 |
|
|
.recon_rd_addr(recon_rd_addr),
|
271 |
|
|
.recon_rd_dta(recon_rd_dta),
|
272 |
|
|
.recon_wr_almost_full(recon_wr_almost_full),
|
273 |
|
|
.disp_rd_addr_empty(disp_rd_addr_empty),
|
274 |
|
|
.disp_rd_addr_en(disp_rd_addr_en),
|
275 |
|
|
.disp_rd_addr_valid(disp_rd_addr_valid),
|
276 |
|
|
.disp_rd_addr(disp_rd_addr),
|
277 |
|
|
.disp_wr_dta_full(disp_wr_dta_full),
|
278 |
|
|
.disp_wr_dta_almost_full(disp_wr_dta_almost_full),
|
279 |
|
|
.disp_rd_dta_almost_empty(disp_rd_dta_almost_empty),
|
280 |
|
|
.osd_rd_empty(osd_rd_empty),
|
281 |
|
|
.osd_rd_almost_empty(osd_rd_almost_empty),
|
282 |
|
|
.osd_rd_en(osd_rd_en),
|
283 |
|
|
.osd_rd_valid(osd_rd_valid),
|
284 |
|
|
.osd_rd_addr(osd_rd_addr),
|
285 |
|
|
.osd_rd_dta(osd_rd_dta),
|
286 |
|
|
.osd_wr_almost_full(osd_wr_almost_full),
|
287 |
|
|
.vbw_rd_empty(vbw_rd_empty),
|
288 |
|
|
.vbw_rd_almost_empty(vbw_rd_almost_empty),
|
289 |
|
|
.vbw_rd_en(vbw_rd_en),
|
290 |
|
|
.vbw_rd_valid(vbw_rd_valid),
|
291 |
|
|
.vbw_rd_dta(vbw_rd_dta),
|
292 |
|
|
.vbw_wr_almost_full(vbw_wr_almost_full),
|
293 |
|
|
.vbr_wr_full(vbr_wr_full),
|
294 |
|
|
.vbr_wr_almost_full(vbr_wr_almost_full),
|
295 |
|
|
.vbr_rd_almost_empty(vbr_rd_almost_empty),
|
296 |
|
|
.vb_flush(vb_flush),
|
297 |
|
|
.mem_req_wr_cmd(mem_req_wr_cmd),
|
298 |
|
|
.mem_req_wr_addr(mem_req_wr_addr),
|
299 |
|
|
.mem_req_wr_dta(mem_req_wr_dta),
|
300 |
|
|
.mem_req_wr_en(mem_req_wr_en),
|
301 |
|
|
.mem_req_wr_almost_full(mem_req_wr_almost_full),
|
302 |
|
|
.tag_wr_dta(tag_wr_dta),
|
303 |
|
|
.tag_wr_en(tag_wr_en),
|
304 |
|
|
.tag_wr_almost_full(tag_wr_almost_full)
|
305 |
|
|
);
|
306 |
|
|
|
307 |
|
|
/* accept data read from memory controller */
|
308 |
|
|
framestore_response framestore_response (
|
309 |
|
|
.rst(rst),
|
310 |
|
|
.clk(clk),
|
311 |
|
|
.fwd_wr_dta_full(fwd_wr_dta_full),
|
312 |
|
|
.fwd_wr_dta_almost_full(fwd_wr_dta_almost_full),
|
313 |
|
|
.fwd_wr_dta_en(fwd_wr_dta_en),
|
314 |
|
|
.fwd_wr_dta_ack(fwd_wr_dta_ack),
|
315 |
|
|
.fwd_wr_dta(fwd_wr_dta),
|
316 |
|
|
.bwd_wr_dta_full(bwd_wr_dta_full),
|
317 |
|
|
.bwd_wr_dta_almost_full(bwd_wr_dta_almost_full),
|
318 |
|
|
.bwd_wr_dta_en(bwd_wr_dta_en),
|
319 |
|
|
.bwd_wr_dta_ack(bwd_wr_dta_ack),
|
320 |
|
|
.bwd_wr_dta(bwd_wr_dta),
|
321 |
|
|
.disp_wr_dta_full(disp_wr_dta_full),
|
322 |
|
|
.disp_wr_dta_almost_full(disp_wr_dta_almost_full),
|
323 |
|
|
.disp_wr_dta_en(disp_wr_dta_en),
|
324 |
|
|
.disp_wr_dta_ack(disp_wr_dta_ack),
|
325 |
|
|
.disp_wr_dta(disp_wr_dta),
|
326 |
|
|
.vbr_wr_full(vbr_wr_full),
|
327 |
|
|
.vbr_wr_en(vbr_wr_en),
|
328 |
|
|
.vbr_wr_ack(vbr_wr_ack),
|
329 |
|
|
.vbr_wr_dta(vbr_wr_dta),
|
330 |
|
|
.vbr_wr_almost_full(vbr_wr_almost_full),
|
331 |
|
|
.mem_res_rd_dta(mem_res_rd_dta),
|
332 |
|
|
.mem_res_rd_en(mem_res_rd_en),
|
333 |
|
|
.mem_res_rd_empty(mem_res_rd_empty),
|
334 |
|
|
.mem_res_rd_valid(mem_res_rd_valid),
|
335 |
|
|
.tag_rd_dta(tag_rd_dta),
|
336 |
|
|
.tag_rd_en(tag_rd_en),
|
337 |
|
|
.tag_rd_empty(tag_rd_empty),
|
338 |
|
|
.tag_rd_valid(tag_rd_valid)
|
339 |
|
|
);
|
340 |
|
|
|
341 |
|
|
|
342 |
|
|
/* memory request fifo */
|
343 |
|
|
fifo_dc
|
344 |
|
|
#(.addr_width(MEMREQ_DEPTH),
|
345 |
|
|
.dta_width(9'd88),
|
346 |
|
|
.prog_thresh(MEMREQ_THRESHOLD), // threshold to make framestore_request stop writing before mem_request_fifo overflows
|
347 |
|
|
.FIFO_XILINX(1))
|
348 |
|
|
mem_request_fifo (
|
349 |
|
|
.rst(rst),
|
350 |
|
|
.wr_clk(clk),
|
351 |
|
|
.din({mem_req_wr_cmd, mem_req_wr_addr, mem_req_wr_dta}),
|
352 |
|
|
.wr_en(mem_req_wr_en),
|
353 |
|
|
.full(mem_req_wr_full),
|
354 |
|
|
.wr_ack(),
|
355 |
|
|
.overflow(mem_req_wr_overflow),
|
356 |
|
|
.prog_full(mem_req_wr_almost_full),
|
357 |
|
|
.rd_clk(mem_clk),
|
358 |
|
|
.dout({mem_req_rd_cmd, mem_req_rd_addr, mem_req_rd_dta}),
|
359 |
|
|
.rd_en(mem_req_rd_en),
|
360 |
|
|
.empty(),
|
361 |
|
|
.valid(mem_req_rd_valid),
|
362 |
|
|
.underflow(),
|
363 |
|
|
.prog_empty()
|
364 |
|
|
);
|
365 |
|
|
|
366 |
|
|
/*
|
367 |
|
|
* Each memory request includes a a tag.
|
368 |
|
|
* Data read from memory is accompanied by the same tag as the memory read request.
|
369 |
|
|
* This allows the frame store to determine who (motion compensation, display)
|
370 |
|
|
* asked for this data, and who should get it.
|
371 |
|
|
*/
|
372 |
|
|
|
373 |
|
|
/* tag fifo */
|
374 |
|
|
fifo_sc
|
375 |
|
|
#(.addr_width(MEMTAG_DEPTH), // tag fifo size must be bigger - because of memory controller latency - than mem_req and mem_resp fifo's together.
|
376 |
|
|
// maximum number of tags stored: size of memory request fifo + number of requests in process in memory controller + size of memory response fifo
|
377 |
|
|
.dta_width(3),
|
378 |
|
|
.prog_thresh(MEMTAG_THRESHOLD)) // threshold to make framestore_request stop writing before tag_fifo overflows
|
379 |
|
|
mem_tag_fifo (
|
380 |
|
|
.rst(rst),
|
381 |
|
|
.clk(clk),
|
382 |
|
|
.din(tag_wr_dta),
|
383 |
|
|
.wr_en(tag_wr_en),
|
384 |
|
|
.full(tag_wr_full),
|
385 |
|
|
.wr_ack(),
|
386 |
|
|
.overflow(tag_wr_overflow),
|
387 |
|
|
.prog_full(tag_wr_almost_full),
|
388 |
|
|
.dout(tag_rd_dta),
|
389 |
|
|
.rd_en(tag_rd_en),
|
390 |
|
|
.empty(tag_rd_empty),
|
391 |
|
|
.valid(tag_rd_valid),
|
392 |
|
|
.underflow(),
|
393 |
|
|
.prog_empty()
|
394 |
|
|
);
|
395 |
|
|
|
396 |
|
|
/* memory response fifo */
|
397 |
|
|
fifo_dc
|
398 |
|
|
#(.addr_width(MEMRESP_DEPTH),
|
399 |
|
|
.dta_width(9'd64),
|
400 |
|
|
.prog_thresh(MEMRESP_THRESHOLD), // threshold to make mem_ctl stop writing before mem_response_fifo overflows
|
401 |
|
|
.FIFO_XILINX(1))
|
402 |
|
|
mem_response_fifo (
|
403 |
|
|
.rst(rst),
|
404 |
|
|
.wr_clk(mem_clk),
|
405 |
|
|
.din(mem_res_wr_dta),
|
406 |
|
|
.wr_en(mem_res_wr_en),
|
407 |
|
|
.full(mem_res_wr_full),
|
408 |
|
|
.wr_ack(),
|
409 |
|
|
.overflow(mem_res_wr_overflow),
|
410 |
|
|
.prog_full(mem_res_wr_almost_full),
|
411 |
|
|
.rd_clk(clk),
|
412 |
|
|
.dout(mem_res_rd_dta),
|
413 |
|
|
.rd_en(mem_res_rd_en),
|
414 |
|
|
.empty(mem_res_rd_empty),
|
415 |
|
|
.valid(mem_res_rd_valid),
|
416 |
|
|
.underflow(),
|
417 |
|
|
.prog_empty()
|
418 |
|
|
);
|
419 |
|
|
|
420 |
|
|
`ifdef CHECK
|
421 |
|
|
/*
|
422 |
|
|
* diagnostic messages.
|
423 |
|
|
* Should fifo overflow occur, carefully consider changes in fifo_size.v
|
424 |
|
|
*/
|
425 |
|
|
|
426 |
|
|
always @(posedge clk)
|
427 |
|
|
if (mem_req_wr_overflow)
|
428 |
|
|
begin
|
429 |
|
|
#0 $display("%m\t*** error: mem_req fifo overflow. **");
|
430 |
|
|
$stop;
|
431 |
|
|
end
|
432 |
|
|
|
433 |
|
|
always @(posedge clk)
|
434 |
|
|
if (tag_wr_overflow)
|
435 |
|
|
begin
|
436 |
|
|
#0 $display("%m\t*** error: tag fifo overflow. ***");
|
437 |
|
|
$stop;
|
438 |
|
|
end
|
439 |
|
|
|
440 |
|
|
always @(posedge clk)
|
441 |
|
|
if (mem_res_wr_overflow)
|
442 |
|
|
begin
|
443 |
|
|
#0 $display("%m\t*** error: mem_res. fifo overflow. ***");
|
444 |
|
|
$stop;
|
445 |
|
|
end
|
446 |
|
|
`endif
|
447 |
|
|
|
448 |
|
|
endmodule
|
449 |
|
|
/* not truncated */
|