Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | // ========== Copyright Header Begin ========================================== |
2 | // | |
3 | // OpenSPARC T2 Processor File: dmu_dsn_ucb_flow.v | |
4 | // Copyright (C) 1995-2007 Sun Microsystems, Inc. All Rights Reserved | |
5 | // 4150 Network Circle, Santa Clara, California 95054, U.S.A. | |
6 | // | |
7 | // * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
8 | // | |
9 | // This program is free software; you can redistribute it and/or modify | |
10 | // it under the terms of the GNU General Public License as published by | |
11 | // the Free Software Foundation; version 2 of the License. | |
12 | // | |
13 | // This program is distributed in the hope that it will be useful, | |
14 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | // GNU General Public License for more details. | |
17 | // | |
18 | // You should have received a copy of the GNU General Public License | |
19 | // along with this program; if not, write to the Free Software | |
20 | // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
21 | // | |
22 | // For the avoidance of doubt, and except that if any non-GPL license | |
23 | // choice is available it will apply instead, Sun elects to use only | |
24 | // the General Public License version 2 (GPLv2) at this time for any | |
25 | // software where a choice of GPL license versions is made | |
26 | // available with the language indicating that GPLv2 or any later version | |
27 | // may be used, or where a choice of which version of the GPL is applied is | |
28 | // otherwise unspecified. | |
29 | // | |
30 | // Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, | |
31 | // CA 95054 USA or visit www.sun.com if you need additional information or | |
32 | // have any questions. | |
33 | // | |
34 | // ========== Copyright Header End ============================================ | |
35 | module dmu_dsn_ucb_flow ( | |
36 | // Globals // | |
37 | enl2clk, | |
38 | reset, | |
39 | // Downstream Path from NCU // | |
40 | ncu_dmu_vld, | |
41 | ncu_dmu_data, | |
42 | dmu_ncu_stall, | |
43 | // Upstream Path to NCU // | |
44 | dmu_ncu_vld, | |
45 | dmu_ncu_data, | |
46 | ncu_dmu_stall, | |
47 | // Local CSR RW cmds // | |
48 | rd_req_vld, | |
49 | wr_req_vld, | |
50 | thr_id_in, | |
51 | buf_id_in, | |
52 | addr_in, | |
53 | data_in, | |
54 | req_acpted, | |
55 | // Local CSR Read Retruns // | |
56 | ack_busy, | |
57 | rd_ack_vld, | |
58 | rd_nack_vld, | |
59 | thr_id_out, | |
60 | buf_id_out, | |
61 | data_out, | |
62 | ucb2ctl_dbg_grp_a_1 | |
63 | ); | |
64 | ||
65 | ||
66 | // Globals | |
67 | input enl2clk; | |
68 | input reset; | |
69 | ||
70 | // Downstream from NCU | |
71 | input ncu_dmu_vld; | |
72 | input [31:0] ncu_dmu_data; | |
73 | output dmu_ncu_stall; | |
74 | ||
75 | // Upstream to NCU | |
76 | output dmu_ncu_vld; | |
77 | output [31:0] dmu_ncu_data; | |
78 | input ncu_dmu_stall; | |
79 | ||
80 | // CMDs to local unit | |
81 | output rd_req_vld; | |
82 | output wr_req_vld; | |
83 | output [5:0] thr_id_in; | |
84 | output [1:0] buf_id_in; | |
85 | output [26:0] addr_in; | |
86 | output [63:0] data_in; | |
87 | input req_acpted; | |
88 | ||
89 | // Ack/Nack from local unit | |
90 | input rd_ack_vld; | |
91 | input rd_nack_vld; | |
92 | input [5:0] thr_id_out; | |
93 | input [1:0] buf_id_out; | |
94 | input [63:0] data_out; | |
95 | output ack_busy; | |
96 | ||
97 | output [`FIRE_DEBUG_WDTH-1:0] ucb2ctl_dbg_grp_a_1; | |
98 | ||
99 | ||
100 | // Local signals | |
101 | wire [2:0] unconnected_size_in; | |
102 | wire indata_buf_vld; | |
103 | wire [127:0] indata_buf; | |
104 | wire dmu_ncu_stall_a1; | |
105 | ||
106 | wire read_pending; | |
107 | wire write_pending; | |
108 | ||
109 | wire rd_buf; | |
110 | wire [1:0] buf_head_next; | |
111 | reg [1:0] buf_head; | |
112 | wire wr_buf; | |
113 | wire [1:0] buf_tail_next; | |
114 | reg [1:0] buf_tail; | |
115 | wire buf_full_next; | |
116 | reg buf_full; | |
117 | wire buf_empty_next; | |
118 | reg buf_empty; | |
119 | wire [116:0] req_in; | |
120 | wire buf0_en; | |
121 | reg [116:0] buf0; | |
122 | wire buf1_en; | |
123 | reg [116:0] buf1; | |
124 | wire [116:0] req_out; | |
125 | wire rd_req_vld_nq; | |
126 | wire wr_req_vld_nq; | |
127 | ||
128 | wire ack_buf_rd; | |
129 | wire ack_buf_wr; | |
130 | reg ack_buf_vld; | |
131 | wire ack_buf_vld_next; | |
132 | reg ack_buf_is_nack; | |
133 | wire [3:0] ack_typ_out; | |
134 | wire [75:0] ack_buf_in; | |
135 | reg [75:0] ack_buf; | |
136 | wire [3:0] ack_buf_vec; | |
137 | ||
138 | wire outdata_buf_busy; | |
139 | wire outdata_buf_wr; | |
140 | wire [127:0] outdata_buf_in; | |
141 | wire [3:0] outdata_vec_in; | |
142 | ||
143 | wire [12:0] addr_in_spare; | |
144 | ||
145 | //////////////////////////////////////////////////////////////////////// | |
146 | // Code starts here | |
147 | //////////////////////////////////////////////////////////////////////// | |
148 | /************************************************************ | |
149 | * Inbound Data | |
150 | ************************************************************/ | |
151 | dmu_dsn_ucb_in32 dmu_dsn_ucb_in32 (.reset(reset), | |
152 | .enl2clk(enl2clk), | |
153 | .vld(ncu_dmu_vld), | |
154 | .data(ncu_dmu_data[31:0]), | |
155 | .stall(dmu_ncu_stall), | |
156 | .indata_buf_vld(indata_buf_vld), | |
157 | .indata_buf(indata_buf[127:0]), | |
158 | .stall_a1(dmu_ncu_stall_a1)); | |
159 | ||
160 | /************************************************************ | |
161 | * Decode inbound packet type | |
162 | ************************************************************/ | |
163 | assign read_pending = (indata_buf[3:0] == 4'b0100) & indata_buf_vld; | |
164 | ||
165 | assign write_pending = (indata_buf[3:0] == 4'b0101) & indata_buf_vld; | |
166 | ||
167 | assign dmu_ncu_stall_a1 = (read_pending | write_pending) & buf_full; | |
168 | ||
169 | /************************************************************ | |
170 | * Inbound buffer | |
171 | ************************************************************/ | |
172 | // Head pointer | |
173 | assign rd_buf = req_acpted; | |
174 | assign buf_head_next[1:0] = reset ? 2'b01 : | |
175 | rd_buf ? {buf_head[0],buf_head[1]} : buf_head[1:0]; | |
176 | /* | |
177 | dff #(2) buf_head_ff (.d(buf_head_next[1:0]), | |
178 | .clk(enl2clk), | |
179 | .q(buf_head[1:0])); | |
180 | */ | |
181 | always @(posedge enl2clk ) | |
182 | begin | |
183 | buf_head[1:0] <= buf_head_next[1:0]; | |
184 | end | |
185 | ||
186 | // Tail pointer | |
187 | assign wr_buf = (read_pending | write_pending) & ~buf_full; | |
188 | ||
189 | assign buf_tail_next[1:0] = reset ? 2'b01 : | |
190 | wr_buf ? {buf_tail[0], buf_tail[1]} : buf_tail[1:0]; | |
191 | /* | |
192 | dff #(2) buf_tail_ff (.d(buf_tail_next[1:0]), | |
193 | .clk(enl2clk), | |
194 | .q(buf_tail[1:0]) ); | |
195 | */ | |
196 | always @(posedge enl2clk ) | |
197 | begin | |
198 | buf_tail[1:0] <= buf_tail_next[1:0]; | |
199 | end | |
200 | ||
201 | // Buffer full | |
202 | assign buf_full_next = (buf_head_next[1:0] == buf_tail_next[1:0]) & wr_buf; | |
203 | /* | |
204 | dffre #(1) buf_full_ff (.d(buf_full_next), | |
205 | .reset(reset), | |
206 | .en(rd_buf|wr_buf), | |
207 | .clk(enl2clk), | |
208 | .q(buf_full) ); | |
209 | */ | |
210 | always @(posedge enl2clk ) begin | |
211 | if (reset) begin | |
212 | buf_full <= 1'b0; | |
213 | end | |
214 | else begin | |
215 | if (rd_buf|wr_buf) buf_full <= buf_full_next; | |
216 | end | |
217 | end | |
218 | ||
219 | // Buffer empty | |
220 | assign buf_empty_next = ((buf_head_next[1:0] == buf_tail_next[1:0]) & rd_buf) | reset; | |
221 | /* | |
222 | dffe #(1) buf_empty_ff (.d(buf_empty_next), | |
223 | .en(rd_buf|wr_buf|reset), | |
224 | .clk(enl2clk), | |
225 | .q(buf_empty) ); | |
226 | */ | |
227 | always @(posedge enl2clk ) | |
228 | begin | |
229 | if (rd_buf|wr_buf|reset) buf_empty <= buf_empty_next; | |
230 | end | |
231 | ||
232 | assign req_in[116:0] = {indata_buf[127:64], | |
233 | indata_buf[54:15], | |
234 | indata_buf[14:12], | |
235 | indata_buf[11:10], | |
236 | indata_buf[9:4], | |
237 | write_pending, | |
238 | read_pending}; | |
239 | ||
240 | // Buffer 0 | |
241 | assign buf0_en = buf_tail[0] & wr_buf; | |
242 | /* | |
243 | dffe #(117) buf0_ff (.d(req_in[116:0]), | |
244 | .en(buf0_en), | |
245 | .clk(enl2clk), | |
246 | .q(buf0[116:0])); | |
247 | */ | |
248 | always @(posedge enl2clk ) | |
249 | if (reset) begin | |
250 | buf0[116:0] <= 117'b0; | |
251 | end | |
252 | else begin | |
253 | if (buf0_en) buf0[116:0] <= req_in[116:0]; | |
254 | end | |
255 | ||
256 | // Buffer 1 | |
257 | assign buf1_en = buf_tail[1] & wr_buf; | |
258 | /* | |
259 | dffe #(117) buf1_ff (.d(req_in[116:0]), | |
260 | .en(buf1_en), | |
261 | .clk(enl2clk), | |
262 | .q(buf1[116:0])); | |
263 | */ | |
264 | always @(posedge enl2clk ) | |
265 | if(reset) begin | |
266 | buf1[116:0] <= 117'b0; | |
267 | end | |
268 | else begin | |
269 | if (buf1_en) buf1[116:0] <= req_in[116:0]; | |
270 | end | |
271 | ||
272 | assign req_out[116:0] = buf_head[0] ? buf0[116:0] : | |
273 | buf_head[1] ? buf1[116:0] : 117'b0; | |
274 | ||
275 | ||
276 | /************************************************************ | |
277 | * Inbound interface to local unit | |
278 | ************************************************************/ | |
279 | assign {data_in[63:0], | |
280 | addr_in_spare[12:0],addr_in[26:0], | |
281 | unconnected_size_in[2:0], | |
282 | buf_id_in[1:0], | |
283 | thr_id_in[5:0], | |
284 | wr_req_vld_nq, | |
285 | rd_req_vld_nq} = req_out[116:0]; | |
286 | ||
287 | assign rd_req_vld = rd_req_vld_nq & ~buf_empty; | |
288 | assign wr_req_vld = wr_req_vld_nq & ~buf_empty; | |
289 | ||
290 | ||
291 | /************************************************************ | |
292 | * Outbound Ack/Nack | |
293 | ************************************************************/ | |
294 | assign ack_buf_wr = rd_ack_vld | rd_nack_vld; | |
295 | ||
296 | assign ack_buf_vld_next = ack_buf_wr ? 1'b1 : | |
297 | ack_buf_rd ? 1'b0 : ack_buf_vld; | |
298 | /* | |
299 | dffr #(1) ack_buf_vld_ff (.d(ack_buf_vld_next), | |
300 | .clk(enl2clk), | |
301 | .reset(reset), | |
302 | .q(ack_buf_vld) ); | |
303 | ||
304 | dffe #(1) ack_buf_is_nack_ff (.d(rd_nack_vld), | |
305 | .en(ack_buf_wr), | |
306 | .clk(enl2clk), | |
307 | .q(ack_buf_is_nack) ); | |
308 | */ | |
309 | always @(posedge enl2clk ) begin | |
310 | if (reset) begin | |
311 | ack_buf_vld <= 1'b0; | |
312 | end | |
313 | else begin | |
314 | ack_buf_vld <= ack_buf_vld_next; | |
315 | end | |
316 | end | |
317 | always @(posedge enl2clk ) | |
318 | if (reset) begin | |
319 | ack_buf_is_nack <= 1'b0; | |
320 | end | |
321 | else begin | |
322 | if (ack_buf_wr) ack_buf_is_nack <= rd_nack_vld; | |
323 | end | |
324 | ||
325 | ||
326 | assign ack_typ_out[3:0] = rd_ack_vld ? 4'b0001: //UCB_READ_ACK | |
327 | 4'b0000; //UCB_READ_NACK | |
328 | ||
329 | assign ack_buf_in[75:0] = {data_out[63:0], | |
330 | buf_id_out[1:0], | |
331 | thr_id_out[5:0], | |
332 | ack_typ_out[3:0] }; | |
333 | /* | |
334 | dffe #(76) ack_buf_ff (.d(ack_buf_in[75:0]), | |
335 | .en(ack_buf_wr), | |
336 | .clk(enl2clk), | |
337 | .q(ack_buf[75:0]) ); | |
338 | */ | |
339 | always @(posedge enl2clk ) | |
340 | if (reset) begin | |
341 | ack_buf[75:0] <= 76'b0; | |
342 | end | |
343 | else begin | |
344 | if (ack_buf_wr) ack_buf[75:0] <= ack_buf_in[75:0]; | |
345 | end | |
346 | ||
347 | assign ack_buf_vec[3:0] = ack_buf_is_nack ? {2'b00,2'b11} : {4'b1111} ; | |
348 | ||
349 | assign ack_busy = ack_buf_vld; | |
350 | ||
351 | assign ack_buf_rd = ~outdata_buf_busy & ack_buf_vld ; | |
352 | ||
353 | assign outdata_buf_wr = ack_buf_rd ; | |
354 | ||
355 | assign outdata_buf_in[127:0] = {ack_buf[75:12], //payload 64bit | |
356 | 9'b0, //reserved [63:55] | |
357 | 40'h00_0000_0000, //40bit addr [54:15] | |
358 | 3'b000, //size [14:12] | |
359 | ack_buf[11:10], //buf_id 2bit | |
360 | ack_buf[9:4], //thr_id 6bit | |
361 | ack_buf[3:0]}; //type 4bit | |
362 | ||
363 | assign outdata_vec_in[3:0] = ack_buf_vec[3:0] ; | |
364 | ||
365 | dmu_dsn_ucb_out32 dmu_dsn_ucb_out32 (.reset(reset), | |
366 | .enl2clk(enl2clk), | |
367 | .vld(dmu_ncu_vld), | |
368 | .data(dmu_ncu_data[31:0]), | |
369 | .stall(ncu_dmu_stall), | |
370 | .outdata_buf_busy(outdata_buf_busy), | |
371 | .outdata_buf_wr(outdata_buf_wr), | |
372 | .outdata_buf_in(outdata_buf_in[127:0]), | |
373 | .outdata_vec_in(outdata_vec_in[3:0]) ); | |
374 | ||
375 | /************************************************************ | |
376 | * debug-- dbg signals for a sub_sel 1 | |
377 | ************************************************************/ | |
378 | assign ucb2ctl_dbg_grp_a_1[`FIRE_DEBUG_WDTH-1:0] = {ncu_dmu_vld,dmu_ncu_stall,read_pending,write_pending, | |
379 | dmu_ncu_stall_a1,rd_nack_vld,dmu_ncu_vld,ncu_dmu_stall}; | |
380 | ||
381 | endmodule // dmu_dsn_ucb_flow | |
382 | ||
383 |