Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / design / sys / iop / niu / rtl / niu_pio_ucb.v
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: niu_pio_ucb.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////////////////////////////////////////////////////////////////////////////////
36//
37//
38// Copyright (C) 2020 by Sun Microsystems, Inc.
39//
40// All rights reserved. No part of this design may be reproduced,
41// stored in a retrieval system, or transmitted, in any form or by
42// any means, electronic, mechanical, photocopying, recording, or
43// otherwise, without prior written permission of Sun Microsystems,
44// Inc.
45//
46// Sun Proprietary/Confidential
47//
48//
49// Primary Contact: Jimmy.Lau@sun.com x48745
50// Description: Unit Control Block for NIU interface to NCU,
51// basing on Niagra design's ucb_flow_jbi module.
52// This module is customized for N2's NIU block.
53//
54// - provides 1+2 deep buffer for incoming requests
55// from NCU
56// - provides single buffer for returns going back to
57// NCU
58// - Downstream data bus width : 32' + 2' control
59// - Upstream data bus widht : 32' + 2' control
60//
61// Revision: 1. March 08, 2004 - John Lo
62// Changed modules name from
63// ucb_bus_in32_niu.v to niu_pio_ucb_in32
64// ucb_bus_out32_niu.v to niu_pio_ucb_out32
65// ucb_flow_niu.v to niu_pio_ucb
66//
67// Changed enl2clk to clk.
68//
69//
70// Revision: 2. September 01, 2004 - Jimmy Lau
71// Changed addr_in from [39:0] to [25:0].
72//
73//
74////////////////////////////////////////////////////////////////////////////////
75
76
77
78
79module niu_pio_ucb (
80 // Globals //
81 niu_clk,
82 niu_reset_l,
83 // Downstream Path from NCU //
84 ncu_niu_vld,
85 ncu_niu_data,
86 niu_ncu_stall,
87 // Upstream Path to NCU //
88 niu_ncu_vld,
89 niu_ncu_data,
90 ncu_niu_stall,
91 // Local CSR RW cmds //
92 rd_req_vld,
93 wr_req_vld,
94 thr_id_in,
95 buf_id_in,
96 addr_in,
97 data_in,
98 req_accepted,
99 // Local CSR Read Retruns //
100 rack_busy,
101 rd_ack_vld,
102 rd_nack_vld,
103 thr_id_out,
104 buf_id_out,
105 data_out,
106 // Local INT //
107 int_busy,
108 int_vld,
109 dev_id
110 );
111
112
113// Globals
114input niu_clk;
115input niu_reset_l;
116
117// Downstream from NCU
118input ncu_niu_vld;
119input [31:0] ncu_niu_data;
120output niu_ncu_stall;
121
122// Upstream to NCU
123output niu_ncu_vld;
124output [31:0] niu_ncu_data;
125input ncu_niu_stall;
126
127// CMDs to local unit
128output rd_req_vld;
129output wr_req_vld;
130output [5:0] thr_id_in;
131output [1:0] buf_id_in;
132output [26:0] addr_in;
133output [63:0] data_in;
134input req_accepted;
135
136// Ack/Nack from local unit
137input rd_ack_vld;
138input rd_nack_vld;
139input [5:0] thr_id_out;
140input [1:0] buf_id_out;
141input [63:0] data_out;
142output rack_busy;
143
144// Interrupt from local unit
145input int_vld;
146input [6:0] dev_id; // interrupt device ID
147output int_busy;
148
149
150
151
152// Local signals
153wire [2:0] unconnected_size_in;
154wire [12:0] unconnected_addr_39_27;
155wire [8:0] unconnected_rsvd;
156wire indata_buf_vld;
157wire [127:0] indata_buf;
158wire niu_ncu_stall_a1;
159
160wire read_pending;
161wire write_pending;
162
163wire rd_buf;
164wire [1:0] buf_head_next;
165wire [1:0] buf_head;
166wire wr_buf;
167wire [1:0] buf_tail_next;
168wire [1:0] buf_tail;
169wire buf_full_next;
170wire buf_full;
171wire buf_empty_next;
172wire buf_empty;
173wire [103:0] req_in;
174wire buf0_en;
175wire [103:0] buf0;
176wire buf1_en;
177wire [103:0] buf1;
178wire [103:0] req_out;
179wire rd_req_vld_nq;
180wire wr_req_vld_nq;
181
182wire ack_buf_rd;
183wire ack_buf_wr;
184wire ack_buf_vld;
185wire ack_buf_vld_next;
186wire ack_buf_is_nack;
187wire [3:0] ack_typ_out;
188wire [75:0] ack_buf_in;
189wire [75:0] ack_buf;
190wire [3:0] ack_buf_vec;
191
192wire int_buf_rd;
193wire int_buf_wr;
194wire int_buf_vld;
195wire int_buf_vld_next;
196//wire [56:0] int_buf_in;
197//wire [56:0] int_buf;
198wire [6:0] int_buf_in;
199wire [6:0] int_buf;
200wire [3:0] int_buf_vec;
201
202wire int_last_rd;
203wire outdata_buf_busy;
204wire outdata_buf_wr;
205wire [127:0] outdata_buf_in;
206wire [3:0] outdata_vec_in;
207
208
209////////////////////////////////////////////////////////////////////////
210// Code starts here
211////////////////////////////////////////////////////////////////////////
212/************************************************************
213 * Inbound Data
214 ************************************************************/
215niu_pio_ucb_in32 niu_pio_ucb_in32 (.reset(niu_reset_l),
216 .clk(niu_clk),
217 .vld(ncu_niu_vld),
218 .data(ncu_niu_data[31:0]),
219 .stall(niu_ncu_stall),
220 .indata_buf_vld(indata_buf_vld),
221 .indata_buf(indata_buf[127:0]),
222 .stall_a1(niu_ncu_stall_a1));
223
224/************************************************************
225 * Decode inbound packet type
226 ************************************************************/
227assign read_pending = (indata_buf[3:0] == 4'b0100) & indata_buf_vld;
228
229assign write_pending = (indata_buf[3:0] == 4'b0101) & indata_buf_vld;
230
231assign niu_ncu_stall_a1 = (read_pending | write_pending) & buf_full;
232
233/************************************************************
234 * Inbound buffer
235 ************************************************************/
236// Head pointer
237assign rd_buf = req_accepted;
238assign buf_head_next[1:0] = niu_reset_l ? 2'b01 :
239 rd_buf ? {buf_head[0],buf_head[1]} : buf_head[1:0];
240
241df1 #(2) buf_head_ff (.d(buf_head_next[1:0]),
242 .clk(niu_clk),
243 .q(buf_head[1:0]));
244
245// Tail pointer
246assign wr_buf = (read_pending | write_pending) & ~buf_full;
247
248assign buf_tail_next[1:0] = niu_reset_l ? 2'b01 :
249 wr_buf ? {buf_tail[0], buf_tail[1]} : buf_tail[1:0];
250
251df1 #(2) buf_tail_ff (.d(buf_tail_next[1:0]),
252 .clk(niu_clk),
253 .q(buf_tail[1:0]) );
254
255// Buffer full
256assign buf_full_next = (buf_head_next[1:0] == buf_tail_next[1:0]) & wr_buf;
257dffre #(1) buf_full_ff (.d(buf_full_next),
258 .reset(niu_reset_l),
259 .en(rd_buf|wr_buf),
260 .clk(niu_clk),
261 .q(buf_full) );
262
263// Buffer empty
264assign buf_empty_next = ((buf_head_next[1:0] == buf_tail_next[1:0]) & rd_buf) | niu_reset_l;
265dffe #(1) buf_empty_ff (.d(buf_empty_next),
266 .en(rd_buf|wr_buf|niu_reset_l),
267 .clk(niu_clk),
268 .q(buf_empty) );
269
270assign unconnected_addr_39_27[12:0] = indata_buf[54:42];
271assign unconnected_rsvd[8:0] = indata_buf[63:55];
272assign req_in[103:0] = {indata_buf[127:64],
273 indata_buf[41:15],
274 indata_buf[14:12],
275 indata_buf[11:10],
276 indata_buf[9:4],
277 write_pending,
278 read_pending};
279
280// Buffer 0
281assign buf0_en = buf_tail[0] & wr_buf;
282dffre #(104) buf0_ff (.d(req_in[103:0]),
283 .reset(niu_reset_l),
284 .en(buf0_en),
285 .clk(niu_clk),
286 .q(buf0[103:0]));
287// Buffer 1
288assign buf1_en = buf_tail[1] & wr_buf;
289dffre #(104) buf1_ff (.d(req_in[103:0]),
290 .reset(niu_reset_l),
291 .en(buf1_en),
292 .clk(niu_clk),
293 .q(buf1[103:0]));
294
295assign req_out[103:0] = buf_head[0] ? buf0[103:0] :
296 buf_head[1] ? buf1[103:0] : 104'b0;
297
298
299/************************************************************
300* Inbound interface to local unit
301************************************************************/
302assign {data_in[7:0],
303 data_in[15:8],
304 data_in[23:16],
305 data_in[31:24],
306 data_in[39:32],
307 data_in[47:40],
308 data_in[55:48],
309 data_in[63:56],
310 addr_in[26:0],
311 unconnected_size_in[2:0],
312 buf_id_in[1:0],
313 thr_id_in[5:0],
314 wr_req_vld_nq,
315 rd_req_vld_nq} = req_out[103:0];
316
317assign rd_req_vld = rd_req_vld_nq & ~buf_empty;
318assign wr_req_vld = wr_req_vld_nq & ~buf_empty;
319
320
321/************************************************************
322 * Outbound Ack/Nack
323 ************************************************************/
324assign ack_buf_wr = rd_ack_vld | rd_nack_vld;
325
326assign ack_buf_vld_next = ack_buf_wr ? 1'b1 :
327 ack_buf_rd ? 1'b0 : ack_buf_vld;
328
329dffr #(1) ack_buf_vld_ff (.d(ack_buf_vld_next),
330 .clk(niu_clk),
331 .reset(niu_reset_l),
332 .q(ack_buf_vld) );
333
334dffre #(1) ack_buf_is_nack_ff (.d(rd_nack_vld),
335 .reset(niu_reset_l),
336 .en(ack_buf_wr),
337 .clk(niu_clk),
338 .q(ack_buf_is_nack) );
339
340assign ack_typ_out[3:0] = rd_ack_vld ? 4'b0001: //UCB_READ_ACK
341 4'b0000; //UCB_READ_NACK
342
343assign ack_buf_in[75:0] = {data_out[7:0],
344 data_out[15:8],
345 data_out[23:16],
346 data_out[31:24],
347 data_out[39:32],
348 data_out[47:40],
349 data_out[55:48],
350 data_out[63:56],
351 buf_id_out[1:0],
352 thr_id_out[5:0],
353 ack_typ_out[3:0] };
354
355dffre #(76) ack_buf_ff (.d(ack_buf_in[75:0]),
356 .reset(niu_reset_l),
357 .en(ack_buf_wr),
358 .clk(niu_clk),
359 .q(ack_buf[75:0]) );
360
361assign ack_buf_vec[3:0] = ack_buf_is_nack ? {2'b00,2'b11} : {4'b1111} ;
362
363assign rack_busy = ack_buf_vld;
364
365
366/************************************************************
367 * Outbound Interrupt
368 ************************************************************/
369assign int_buf_wr = int_vld;
370
371assign int_buf_vld_next = int_buf_wr ? 1'b1 :
372 int_buf_rd ? 1'b0 : int_buf_vld;
373
374dffr #(1) int_buf_vld_ff (.d(int_buf_vld_next),
375 .clk(niu_clk),
376 .reset(niu_reset_l),
377 .q(int_buf_vld));
378
379/*
380assign int_buf_in[56:0] = {int_vec[5:0],
381 int_stat[31:0],
382 dev_id[8:0],
383 int_thr_id[5:0],
384 int_typ};
385*/
386
387assign int_buf_in[6:0] = dev_id[6:0] ;
388
389dffre #(7) int_buf_ff (.d(int_buf_in[6:0]),
390 .reset(niu_reset_l),
391 .en(int_buf_wr),
392 .clk(niu_clk),
393 .q(int_buf[6:0]));
394
395assign int_buf_vec = {2'b00,2'b11};
396
397assign int_busy = int_buf_vld;
398
399
400/************************************************************
401 * Outbound ack/interrupt Arbitration
402 ************************************************************/
403dffre #(1) int_last_rd_ff (.d(int_buf_rd),
404 .en(ack_buf_rd|int_buf_rd),
405 .reset(niu_reset_l),
406 .clk(niu_clk),
407 .q(int_last_rd));
408
409assign ack_buf_rd = ~outdata_buf_busy & ack_buf_vld &
410 (~int_buf_vld | int_last_rd);
411
412assign int_buf_rd = ~outdata_buf_busy & int_buf_vld &
413 (~ack_buf_vld | ~int_last_rd);
414
415assign outdata_buf_wr = ack_buf_rd | int_buf_rd;
416
417assign outdata_buf_in[127:0] = ack_buf_rd ? {ack_buf[75:12], //payload 64bit
418 9'b0, //reserved [63:55]
419 40'h00_0000_0000, //40bit addr [54:15]
420 3'b000, //size [14:12]
421 ack_buf[11:10], //buf_id 2bit
422 ack_buf[9:4], //thr_id 6bit
423 ack_buf[3:0]}: //type 4bit
424 {64'h0000_0000_0000_0000,
425 7'b000_0000, // reserved[63:57]
426 6'b0, //int_vec 6bit
427 32'b0, //int_stat 32bit
428 {2'b0,int_buf[6:0]}, //dev_id 9bit
429 6'b0, //thr_id 6bit
430 4'b1000}; //pkt_typ 4bit,plain int
431
432assign outdata_vec_in[3:0] = ack_buf_rd ? ack_buf_vec[3:0] : int_buf_vec[3:0] ;
433
434niu_pio_ucb_out32 niu_pio_ucb_out32 (.reset(niu_reset_l),
435 .clk(niu_clk),
436 .vld(niu_ncu_vld),
437 .data(niu_ncu_data[31:0]),
438 .stall(ncu_niu_stall),
439 .outdata_buf_busy(outdata_buf_busy),
440 .outdata_buf_wr(outdata_buf_wr),
441 .outdata_buf_in(outdata_buf_in[127:0]),
442 .outdata_vec_in(outdata_vec_in[3:0]) );
443
444
445endmodule
446
447