Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / design / sys / iop / niu / rtl / niu_smx_xtb.v
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: niu_smx_xtb.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
36module niu_smx_xtb(
37/*AUTOARG*/
38 // Outputs
39 rdreq_rst_xtb_wr, wreq_rst_xtb_wr, xtb_rdata, xtb_rd_ack,
40 xtb_rdata_err, tid_valid_set, tid_valid_set_addr, tid_newarr_set,
41 tid_newarr_set_addr, tohdl_xtb_rdata, tohdl_xtb_rd_ack,
42 tohdl_xtb_rdata_err, mb0_smx_table_64x146_scan_out,
43 niu_mb0_smx_table_data_out,
44 // Inputs
45 clk, iol2clk, reset_l, rdreq_xtb_wr, rdreq_xtb_waddr, rdreq_xtb_wdata,
46 wreq_xtb_wr, wreq_xtb_waddr, wreq_xtb_wdata, xtb_rd, xtb_raddr,
47 xtb_rcvfile_update, xtb_rcvfile_update_addr, tohdl_xtb_rd,
48 tohdl_xtb_raddr, tcu_aclk, tcu_bclk,
49 tcu_se_scancollar_in,
50 tcu_array_wr_inhibit, mb0_smx_table_64x146_scan_in,
51 niu_mb0_smx_table_64x146_wdata, niu_mb0_smx_table_64x146_rd_addr,
52 niu_mb0_smx_table_64x146_wr_addr, niu_mb0_smx_table_64x146_wr_en,
53 niu_mb0_smx_table_64x146_rd_en, niu_mb0_run,
54 pio_xtb_err_inject_cfg
55 );
56
57input clk;
58input iol2clk;
59input reset_l;
60
61// rdreq if
62input rdreq_xtb_wr;
63input [5:0] rdreq_xtb_waddr;
64input [127:0] rdreq_xtb_wdata;
65output rdreq_rst_xtb_wr;
66
67// wreq if
68input wreq_xtb_wr;
69input [5:0] wreq_xtb_waddr;
70input [127:0] wreq_xtb_wdata;
71output wreq_rst_xtb_wr;
72
73// resp dmc sm if
74input xtb_rd;
75input [5:0] xtb_raddr;
76output [128:0] xtb_rdata; // {rcvcnt, xtb_rdata}
77output xtb_rd_ack; // rst client rd signal
78output xtb_rdata_err;
79
80input xtb_rcvfile_update;
81input [5:0] xtb_rcvfile_update_addr;
82
83
84// status if
85output tid_valid_set; // set by req_cmd
86output [5:0] tid_valid_set_addr;
87output tid_newarr_set; // set by req_cmd
88output [5:0] tid_newarr_set_addr;
89
90
91
92// timeout handler; arb with resp dmc
93input tohdl_xtb_rd;
94input [5:0] tohdl_xtb_raddr;
95output [118:0] tohdl_xtb_rdata; // {xtb_rdata}; rcvcnt not part of
96output tohdl_xtb_rd_ack; // rst client rd signal
97output tohdl_xtb_rdata_err;
98 // client must rst rd in next cycle
99
100// mbist if
101input tcu_aclk;
102input tcu_bclk;
103input tcu_se_scancollar_in;
104input tcu_array_wr_inhibit;
105input mb0_smx_table_64x146_scan_in;
106output mb0_smx_table_64x146_scan_out;
107
108input [7:0] niu_mb0_smx_table_64x146_wdata;
109input [5:0] niu_mb0_smx_table_64x146_rd_addr;
110input [5:0] niu_mb0_smx_table_64x146_wr_addr;
111input niu_mb0_smx_table_64x146_wr_en;
112input niu_mb0_smx_table_64x146_rd_en;
113input niu_mb0_run;
114
115output [145:0] niu_mb0_smx_table_data_out;
116
117// pio i/f
118input [2:0] pio_xtb_err_inject_cfg; // [0] - one pkt
119 // [1] - alt pkt
120 // [2] - all pkt
121
122// wire [4:0] rdreq_xtb_raddr= xtb_raddr[4:0];
123// wire [4:0] wreq_xtb_raddr= xtb_raddr[4:0];
124
125// wire rdreq_xtb_rd= xtb_rd;
126// wire wreq_xtb_rd= xtb_rd;
127
128// wire [143:0] wreq_xtb_rdata;
129// wire [143:0] rdreq_xtb_rdata;
130
131wire [145:0] sel_xtb_rdata;
132
133wire [145:0] niu_mb0_smx_table_data_out= sel_xtb_rdata;
134
135
136// wire [143:0] sel_xtb_rdata;
137
138// wire [143:0] sel_xtb_rdata= (xtb_raddr[5])? wreq_xtb_rdata : rdreq_xtb_rdata;
139
140// or arb rd/wr, rd steal wr cycles
141// during wr writes 4 data ???
142// if use one ram 144bx64 ??
143
144reg rdreq_rst_xtb_wr_n;
145wire rdreq_rst_xtb_wr= rdreq_rst_xtb_wr_n;
146reg wreq_rst_xtb_wr_n;
147wire wreq_rst_xtb_wr= wreq_rst_xtb_wr_n;
148
149reg first_choice;
150reg first_choice_n;
151always @(posedge clk) begin
152 if(!reset_l) begin
153 first_choice<= `SMX_PD 1'b0; // 0-wr, 1- rd
154 end
155 else begin
156 first_choice<= `SMX_PD first_choice_n; // 0-wr, 1- rd
157 end
158end
159
160always @(/*AUTOSENSE*/first_choice or rdreq_xtb_wr or wreq_xtb_wr) begin
161 first_choice_n= first_choice;
162 rdreq_rst_xtb_wr_n= 1'b0;
163 wreq_rst_xtb_wr_n= 1'b0;
164 case({first_choice, wreq_xtb_wr, rdreq_xtb_wr})
165 3'b000: begin
166 first_choice_n= first_choice;
167 rdreq_rst_xtb_wr_n= 1'b0;
168 wreq_rst_xtb_wr_n= 1'b0;
169 end
170 3'b001: begin // rd
171 first_choice_n= 1'b0; // wr first nxt
172 rdreq_rst_xtb_wr_n= 1'b1;
173 wreq_rst_xtb_wr_n= 1'b0;
174 end
175 3'b010: begin // wr
176 first_choice_n= 1'b1; // rd first nxt
177 rdreq_rst_xtb_wr_n= 1'b0;
178 wreq_rst_xtb_wr_n= 1'b1;
179 end
180 3'b011: begin // wr, rd; wr first
181 first_choice_n= 1'b1; // rd first nxt
182 rdreq_rst_xtb_wr_n= 1'b0;
183 wreq_rst_xtb_wr_n= 1'b1;
184 end
185 3'b100: begin //
186 first_choice_n= first_choice;
187 rdreq_rst_xtb_wr_n= 1'b0;
188 wreq_rst_xtb_wr_n= 1'b0;
189 end
190 3'b101: begin // rd
191 first_choice_n= 1'b0; // wr first nxt
192 rdreq_rst_xtb_wr_n= 1'b1;
193 wreq_rst_xtb_wr_n= 1'b0;
194 end
195 3'b110: begin // wr
196 first_choice_n= 1'b1; // rd first nxt
197 rdreq_rst_xtb_wr_n= 1'b0;
198 wreq_rst_xtb_wr_n= 1'b1;
199 end
200 3'b111: begin // rd, wr; rd first
201 first_choice_n= 1'b0; // wr first nxt
202 rdreq_rst_xtb_wr_n= 1'b1;
203 wreq_rst_xtb_wr_n= 1'b0;
204 end
205 endcase
206end
207
208wire xtb_rd_ack_n;
209wire tohdl_xtb_rd_ack_n;
210wire [5:0] sel_xtb_raddr;
211reg xtb_busy;
212reg xtb_rd_ack_r2; // ram data avail
213reg xtb_rd_ack_r3; // extra stage for err check
214reg xtb_rd_ack;
215reg tohdl_xtb_rd_ack_r2;
216reg tohdl_xtb_rd_ack_r3;
217reg tohdl_xtb_rd_ack;
218reg [145:0] xtb_rdata_r3;
219reg [145:0] xtb_rdata_r4;
220
221// move xtb_raddr_r1 one cycle earlier
222//reg xtb_rd_ack_r1; // ram input
223//reg tohdl_xtb_rd_ack_r1;
224//reg [5:0] sel_xtb_raddr_r1; // ram input
225
226wire xtb_rd_ack_r1= xtb_rd_ack_n;
227wire tohdl_xtb_rd_ack_r1= tohdl_xtb_rd_ack_n;
228wire [5:0] sel_xtb_raddr_r1= sel_xtb_raddr;
229
230wire xtb_rd_n= (xtb_rd_ack_r1 | tohdl_xtb_rd_ack_r1);
231
232reg xtb_rdata_perr;
233wire xtb_rdata_err= xtb_rdata_perr;
234reg tohdl_xtb_rdata_perr;
235wire tohdl_xtb_rdata_err= tohdl_xtb_rdata_perr;
236reg [145:0] tohdl_xtb_rdata_r4;
237wire [118:0] tohdl_xtb_rdata= tohdl_xtb_rdata_r4[118:0];
238
239niu_smx_arb_2c #(6) arb_xtb_rd(
240 .clk (clk),
241 .reset_l (reset_l),
242 .req_a (xtb_rd & ~xtb_busy),
243 .req_b (tohdl_xtb_rd & ~xtb_busy),
244 .muxin_a (xtb_raddr [5:0]),
245 .muxin_b (tohdl_xtb_raddr [5:0]),
246 .ack_a (xtb_rd_ack_n),
247 .ack_b (tohdl_xtb_rd_ack_n),
248 .selout (sel_xtb_raddr [5:0])
249 );
250
251always @(posedge clk) begin
252 if(!reset_l) begin
253 xtb_busy<= `SMX_PD 1'b0;
254 end
255 else begin
256 if(xtb_rd_ack_n | tohdl_xtb_rd_ack_n) xtb_busy<= `SMX_PD 1'b1;
257 else if (xtb_rd_ack | tohdl_xtb_rd_ack) xtb_busy<= `SMX_PD 1'b0;
258 end
259end
260
261wire [5:0] sel_xtb_waddr= (rdreq_rst_xtb_wr_n)?
262 rdreq_xtb_waddr : wreq_xtb_waddr;
263wire [127:0] sel_xtb_wdata= (rdreq_rst_xtb_wr_n)?
264 rdreq_xtb_wdata : wreq_xtb_wdata;
265
266wire tid_valid_set= rdreq_rst_xtb_wr_n|wreq_rst_xtb_wr_n;
267wire [5:0] tid_valid_set_addr= sel_xtb_waddr;
268wire tid_newarr_set= rdreq_rst_xtb_wr_n|wreq_rst_xtb_wr_n;
269wire [5:0] tid_newarr_set_addr= sel_xtb_waddr;
270
271
272wire [7:0] xtb_parity_wdata_n;
273niu_smx_gen_siudp gen_xtb_par_wdata(// gen parity per N2 ras
274 .data (sel_xtb_wdata [127:0]),
275 .parity (xtb_parity_wdata_n [7:0])
276 );
277
278wire [145:0] concat_niu_mb0_smx_table_64x146_wdata={
279 niu_mb0_smx_table_64x146_wdata[1:0],
280 niu_mb0_smx_table_64x146_wdata,
281 niu_mb0_smx_table_64x146_wdata,
282 niu_mb0_smx_table_64x146_wdata,
283 niu_mb0_smx_table_64x146_wdata,
284 niu_mb0_smx_table_64x146_wdata,
285 niu_mb0_smx_table_64x146_wdata,
286 niu_mb0_smx_table_64x146_wdata,
287 niu_mb0_smx_table_64x146_wdata,
288 niu_mb0_smx_table_64x146_wdata,
289 niu_mb0_smx_table_64x146_wdata,
290 niu_mb0_smx_table_64x146_wdata,
291 niu_mb0_smx_table_64x146_wdata,
292 niu_mb0_smx_table_64x146_wdata,
293 niu_mb0_smx_table_64x146_wdata,
294 niu_mb0_smx_table_64x146_wdata,
295 niu_mb0_smx_table_64x146_wdata,
296 niu_mb0_smx_table_64x146_wdata,
297 niu_mb0_smx_table_64x146_wdata
298 };
299
300niu_ram_64_146 xtb_ram(
301 .tcu_aclk (tcu_aclk),
302 .tcu_bclk (tcu_bclk),
303 .tcu_se_scancollar_in (tcu_se_scancollar_in),
304 .tcu_array_wr_inhibit (tcu_array_wr_inhibit),
305 .scan_in (mb0_smx_table_64x146_scan_in),
306 .scan_out (mb0_smx_table_64x146_scan_out),
307 .mbi_wdata (concat_niu_mb0_smx_table_64x146_wdata [145:0]),
308 .mbi_rd_adr (niu_mb0_smx_table_64x146_rd_addr [5:0]),
309 .mbi_wr_adr (niu_mb0_smx_table_64x146_wr_addr [5:0]),
310 .mbi_wr_en (niu_mb0_smx_table_64x146_wr_en),
311 .mbi_rd_en (niu_mb0_smx_table_64x146_rd_en),
312 .mbi_run (niu_mb0_run),
313 .clk (iol2clk),
314 .wt_enable (rdreq_xtb_wr | wreq_xtb_wr),
315 .addr_wt (sel_xtb_waddr[5:0]),
316 .data_inp ({10'h0, xtb_parity_wdata_n, sel_xtb_wdata[127:0]}),
317 .cs_rd (xtb_rd_n),
318 .addr_rd (sel_xtb_raddr_r1[5:0]),
319 .data_out (sel_xtb_rdata[145:0])
320 );
321
322wire err_inject_enable_n;
323wire [127:0] xtb_rdata_r3_n= (err_inject_enable_n)?
324 {xtb_rdata_r3[127:1], ~xtb_rdata_r3[0]}:
325 xtb_rdata_r3[127:0];
326
327
328wire [7:0] xtb_parity_rdata_n;
329niu_smx_gen_siudp gen_xtb_par_rdata(// gen parity per N2 ras
330 .data (xtb_rdata_r3_n [127:0]),
331 .parity (xtb_parity_rdata_n [7:0])
332 );
333wire xtb_rdata_perr_n= |(xtb_parity_rdata_n ^ xtb_rdata_r3[135:128]);
334
335// move xtb_rd_r1 one cycle earlier
336// xtb_rd_ack_r1<= `SMX_PD 1'b0;
337// tohdl_xtb_rd_ack_r1<= `SMX_PD 1'b0;
338// xtb_rd_ack_r1<= `SMX_PD xtb_rd_ack_n ;
339// tohdl_xtb_rd_ack_r1<= `SMX_PD tohdl_xtb_rd_ack_n;
340
341always @(posedge clk) begin
342 if(!reset_l) begin
343 xtb_rd_ack_r2<= `SMX_PD 1'b0;
344 xtb_rd_ack_r3<= `SMX_PD 1'b0;
345 xtb_rd_ack<= `SMX_PD 1'b0;
346 tohdl_xtb_rd_ack_r2<= `SMX_PD 1'b0;
347 tohdl_xtb_rd_ack_r3<= `SMX_PD 1'b0;
348 tohdl_xtb_rd_ack<= `SMX_PD 1'b0;
349 end
350 else begin
351 xtb_rd_ack_r2<= `SMX_PD xtb_rd_ack_r1 ; // rdata avail at r2
352 xtb_rd_ack_r3<= `SMX_PD xtb_rd_ack_r2 ; // extra cycle for ecc
353 xtb_rd_ack<= `SMX_PD xtb_rd_ack_r3;
354 tohdl_xtb_rd_ack_r2<= `SMX_PD tohdl_xtb_rd_ack_r1;
355 tohdl_xtb_rd_ack_r3<= `SMX_PD tohdl_xtb_rd_ack_r2;
356 tohdl_xtb_rd_ack<= `SMX_PD tohdl_xtb_rd_ack_r3;
357 end
358end
359always @(posedge clk) begin
360// if(xtb_rd_ack_n | tohdl_xtb_rd_ack_n) sel_xtb_raddr_r1<= `SMX_PD sel_xtb_raddr;
361
362 xtb_rdata_r3<= `SMX_PD sel_xtb_rdata;
363
364 // wanna keep data constant after ack
365 if(xtb_rd_ack_r3) begin
366 xtb_rdata_r4<= `SMX_PD xtb_rdata_r3;
367 xtb_rdata_perr<= `SMX_PD xtb_rdata_perr_n;
368 end
369 if(tohdl_xtb_rd_ack_r3) begin
370 tohdl_xtb_rdata_r4<= `SMX_PD xtb_rdata_r3;
371 tohdl_xtb_rdata_perr<= `SMX_PD xtb_rdata_perr_n;
372 end
373end
374
375/*
376register implemented
377niu_smx_regfl #(144,6) xtb_regfl(
378 .clk (clk),
379 .reset_l (reset_l),
380 .wr (rdreq_xtb_wr | wreq_xtb_wr),
381 .addr_wr (sel_xtb_waddr[5:0]),
382 .data_wr ({16'h0, sel_xtb_wdata[127:0]}),
383 .rd (xtb_rd),
384 .addr_rd (xtb_raddr[5:0]),
385 .data_rd (sel_xtb_rdata[143:0])
386);
387*/
388
389/*
390 not use
391niu_smx_regfl #(144,5) xtb_wr_regfl(
392 .clk (clk),
393 .reset_l (reset_l),
394 .wr (wreq_xtb_wr),
395 .addr_wr (wreq_xtb_waddr[4:0]),
396 .data_wr ({16'h0, wreq_xtb_wdata[127:0]}),
397 .rd (wreq_xtb_rd),
398 .addr_rd (wreq_xtb_raddr[4:0]),
399 .data_rd (wreq_xtb_rdata[143:0])
400);
401*/
402
403
404/*
405wire[5:0] xtb_waddr= (wreq_xtb_wr)? {1'b1, wreq_xtb_waddr[4:0]} :
406 {1'b0, rdreq_xtb_waddr[4:0]};
407wire [9:0] rcvfile_rdata;
408wire [128:0] xtb_rdata= {rcvfile_rdata[9:0],sel_xtb_rdata[118:0]};
409wire xtb_wr= rdreq_xtb_wr | wreq_xtb_wr;
410*/
411 // ??? no parity yet
412 // ??? can more bits remove ?
413 // ??? rcvfile rdata truncate to 9bits
414
415// make 2 copies; one for rd, one for wr; ???
416// might need to add arb if combine both ????
417
418// wire [9:0] rdreq_rcvfile_rdata;
419// // // // // // // // wire [9:0] wreq_rcvfile_rdata;
420/*
421wire [9:0] sel_rcvfile_rdata= (xtb_raddr[5])?
422 wreq_rcvfile_rdata : rdreq_rcvfile_rdata;
423*/
424
425wire [9:0] rcvfile_rdata;
426wire [128:0] xtb_rdata= {rcvfile_rdata[9:0], xtb_rdata_r4[118:0]};
427
428wire [5:0] rcvfile_raddr_n= (xtb_rcvfile_update)?
429 xtb_rcvfile_update_addr : xtb_raddr;
430niu_smx_resp_rcvfile #(10,6) rdreq_resp_rcvfile(
431 .clk (clk),
432 .reset_l (reset_l),
433 .rd (xtb_rd_ack_n),
434 .rd_inc (xtb_rcvfile_update),
435 .raddr (rcvfile_raddr_n[5:0]),
436 .wr_rst (rdreq_xtb_wr | wreq_xtb_wr),
437 .waddr (sel_xtb_waddr[5:0]),
438 .rdata (rcvfile_rdata[9:0])
439);
440
441/*
442niu_smx_resp_rcvfile #(10,5) wreq_resp_rcvfile(
443 .clk (clk),
444 .reset_l (reset_l),
445 .rd (), // nc
446 .rd_inc (xtb_rd),
447 .raddr (xtb_raddr[4:0]),
448 .wr_rst (wreq_xtb_wr),
449 .waddr (wreq_xtb_waddr[4:0]),
450 .rdata (wreq_rcvfile_rdata[9:0])
451);
452*/
453
454// ??? add xtb_rd arb; rcvfile xtb_rd fix ?????
455
456// error inject
457reg one_pkt_flag;
458reg alt_pkt_flag;
459wire rd_ack_n= xtb_rd_ack_r3 | tohdl_xtb_rd_ack_r3;
460 // mux err-injected data occurs at r3
461
462always @(posedge clk) begin
463 if(!reset_l) begin
464 one_pkt_flag <= `SMX_PD 1'b0;
465 alt_pkt_flag <= `SMX_PD 1'b0;
466 end
467 else begin
468 if(rd_ack_n & ~one_pkt_flag & pio_xtb_err_inject_cfg[0])
469 one_pkt_flag <= `SMX_PD 1'b1; // set one_pkt flag
470 else if (~pio_xtb_err_inject_cfg[0]) one_pkt_flag <= `SMX_PD 1'b0;
471 // reset when cfg one_pkt unset
472
473 if(rd_ack_n & pio_xtb_err_inject_cfg[1]) // alternate each rd
474 alt_pkt_flag <= `SMX_PD ~alt_pkt_flag;
475
476 end
477end
478
479
480assign err_inject_enable_n= (~one_pkt_flag & pio_xtb_err_inject_cfg[0]) |
481 (alt_pkt_flag & pio_xtb_err_inject_cfg[1]) |
482 pio_xtb_err_inject_cfg[2];
483
484
485endmodule
486
487