Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / design / sys / iop / niu / rtl / niu_smx_sm_resp_dv.v
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: niu_smx_sm_resp_dv.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_sm_resp_dv(
37/*AUTOARG*/
38 // Outputs
39 smx_dmc_dv, smx_dmc_data, smx_dmc_byte_en, smx_dmc_status,
40 smx_dmc_resp_comp, smx_dmc_xcomp, smx_dmc_ack_comp,
41 smx_dmc_ack_xcomp, rst_dvflag, dv_idle, resp_dataff_rd, dv_cs,
42 // Inputs
43 clk, reset_l, dvflag, dvflag_with_data, dvflag_line_en,
44 dvflag_sop_pos, dvflag_eop_pos, dvflag_sop_byte_en,
45 dvflag_eop_byte_en, dvflag_client, dvflag_xcomp, dvflag_status,
46 early_dvflag, early_dvflag_with_data, early_dvflag_line_en,
47 early_dvflag_sop_pos, early_dvflag_eop_pos,
48 early_dvflag_sop_byte_en, early_dvflag_eop_byte_en,
49 early_dvflag_client, early_dvflag_xcomp, early_dvflag_status,
50 resp_dataff_empty, resp_dataff_rdata, pio_resp_err_inject_cfg
51 );
52
53input clk;
54input reset_l;
55 // dmc if
56output [7:0] smx_dmc_dv;
57output [127:0] smx_dmc_data;
58output [15:0] smx_dmc_byte_en;
59output [3:0] smx_dmc_status;
60output [7:0] smx_dmc_resp_comp;
61output [7:0] smx_dmc_xcomp;
62
63 // ack if
64output [7:0] smx_dmc_ack_comp;
65output [7:0] smx_dmc_ack_xcomp;
66
67 // cmdlaunch if
68input dvflag;
69input [1:0] dvflag_with_data; // b1: 1= rd (data,dv also sio dq) ,
70 // 0= wr/rderr (sio dq only)
71 // b0: 1= with data
72 // 0= without data
73input [3:0] dvflag_line_en;
74input [3:0] dvflag_sop_pos; // indicate first data line position
75input [3:0] dvflag_eop_pos; // indicate last data line position
76input [15:0] dvflag_sop_byte_en; // use this for 'first' data line
77input [15:0] dvflag_eop_byte_en; // use this for 'last' data line
78input [7:0] dvflag_client;
79input [3:0] dvflag_xcomp;
80input [3:0] dvflag_status;
81output rst_dvflag;
82
83output dv_idle; // dv in idle state
84input early_dvflag; // dv needs to be in idle to catch this pulse
85 // and dvflag not set
86input [1:0] early_dvflag_with_data;
87 // 1= rd (data,dv also sio dq)
88 // 0= wr/rderr (sio dq only)
89input [3:0] early_dvflag_line_en;
90input [3:0] early_dvflag_sop_pos; // indicate first data line position
91input [3:0] early_dvflag_eop_pos; // indicate last data line position
92input [15:0] early_dvflag_sop_byte_en; // use this for 'first' data line
93input [15:0] early_dvflag_eop_byte_en; // use this for 'last' data line
94input [7:0] early_dvflag_client;
95input [3:0] early_dvflag_xcomp;
96input [3:0] early_dvflag_status;
97
98// sio if
99// output niu_sio_dq;
100// move to cmdff rd; dataff have extra entries to handle
101// pending data from cmdff rd to dv's data read out
102// siu still handle 4 credits
103
104// resp dataff if
105input resp_dataff_empty; // not use ??
106input [143:0] resp_dataff_rdata;
107output resp_dataff_rd;
108
109// pio i/f
110input [2:0] pio_resp_err_inject_cfg; // [0] - one pkt
111 // [1] - alt pkt
112 // [2] - all pkt
113output [2:0] dv_cs;
114
115
116
117parameter dv_s0= 3'h0,
118 dv_s1= 3'h1,
119 dv_s2= 3'h2,
120 dv_s3= 3'h3,
121 dv_s4= 3'h4,
122 dv_s5= 3'h5;
123
124
125wire [1:0] with_data_n= (dvflag)? dvflag_with_data : early_dvflag_with_data;
126wire [3:0] line_en_n= (dvflag)? dvflag_line_en : early_dvflag_line_en;
127wire [3:0] sop_pos_n= (dvflag)? dvflag_sop_pos : early_dvflag_sop_pos;
128wire [3:0] eop_pos_n= (dvflag)? dvflag_eop_pos : early_dvflag_eop_pos;
129wire [15:0] sop_byte_en_n= (dvflag)? dvflag_sop_byte_en : early_dvflag_sop_byte_en;
130wire [15:0] eop_byte_en_n= (dvflag)? dvflag_eop_byte_en : early_dvflag_eop_byte_en;
131wire [7:0] client_n= (dvflag)? dvflag_client : early_dvflag_client;
132wire [3:0] xcomp_n= (dvflag)? dvflag_xcomp : early_dvflag_xcomp;
133wire [3:0] status_n= (dvflag)? dvflag_status : early_dvflag_status;
134
135wire [127:0] smx_dmc_data_n= resp_dataff_rdata [127:0];
136wire [7:0] smx_dmc_data_parity_n= resp_dataff_rdata [135:128];
137reg [127:0] smx_dmc_data;
138
139reg resp_dataff_rd_n;
140wire resp_dataff_rd= resp_dataff_rd_n;
141
142reg [2:0] dv_ns, dv_cs;
143wire dv_idle_n= (dv_cs==dv_s0);
144wire dv_idle= dv_idle_n;
145
146// parity support related
147// added r1 stage to flop in ram data to do parity chk
148reg [7:0] smx_dmc_dv_r1;
149reg [127:0] smx_dmc_data_r1;
150reg [7:0] smx_dmc_data_parity_r1;
151reg [15:0] smx_dmc_byte_en_r1;
152reg [3:0] smx_dmc_status_r1;
153reg [7:0] smx_dmc_resp_comp_r1;
154reg [7:0] smx_dmc_xcomp_r1;
155wire [7:0] gen_data_parity_n;
156wire data_parerr_n=
157 |(gen_data_parity_n ^ smx_dmc_data_parity_r1);
158
159
160reg smx_dmc_dv_n;
161reg smx_dmc_resp_comp_n;
162reg smx_dmc_xcomp_n;
163reg [15:0] smx_dmc_byte_en_n, smx_dmc_byte_en ;
164reg [3:0] smx_dmc_status_n, smx_dmc_status;
165// reg niu_sio_dq_n, niu_sio_dq;
166reg ld_dvflag_data_n;
167reg rst_dvflag_n;
168wire rst_dvflag= rst_dvflag_n;
169reg ld_dataff_rd_shift_n; // in err case, rd 4 lines;
170reg [3:0] dataff_rd_shift;
171
172 // ack if
173reg smx_dmc_ack_comp_n;
174reg smx_dmc_ack_xcomp_n;
175
176// reg [1:0] dvflag_with_data_r;
177reg [3:0] dvflag_line_en_r;
178reg [3:0] dvflag_sop_pos_r;
179reg [3:0] dvflag_eop_pos_r;
180reg [15:0] dvflag_sop_byte_en_r;
181reg [15:0] dvflag_eop_byte_en_r;
182reg [7:0] dvflag_client_r;
183reg [3:0] dvflag_xcomp_r;
184reg [3:0] dvflag_status_r;
185
186
187always @(/*AUTOSENSE*/dataff_rd_shift or dv_cs or dvflag
188 or dvflag_eop_byte_en_r or dvflag_eop_pos_r
189 or dvflag_line_en_r or dvflag_sop_byte_en_r
190 or dvflag_sop_pos_r or dvflag_status_r or dvflag_xcomp_r
191 or early_dvflag or eop_byte_en_n or eop_pos_n or line_en_n
192 or smx_dmc_status_r1 or sop_byte_en_n or sop_pos_n
193 or status_n or with_data_n or xcomp_n) begin
194 smx_dmc_dv_n= 1'b0;
195 smx_dmc_resp_comp_n= 1'b0;
196 smx_dmc_xcomp_n= 1'b0;
197 smx_dmc_byte_en_n= 16'h0;
198 smx_dmc_status_n= smx_dmc_status_r1;
199 smx_dmc_ack_comp_n= 1'b0;
200 smx_dmc_ack_xcomp_n= 1'b0;
201// niu_sio_dq_n= 1'b0;
202 resp_dataff_rd_n= 1'b0;
203 ld_dvflag_data_n= 1'b0;
204 rst_dvflag_n= 1'b0;
205 ld_dataff_rd_shift_n= 1'b0;
206 dv_ns= dv_cs;
207 case(dv_cs)
208 dv_s0: begin // wait dvflag or early dvflag
209 // check to see if with data
210 // deq if no data
211 // flop in working copy
212 if(dvflag||early_dvflag) begin
213 if(status_n[0]) begin // pkterr drop;
214 dv_ns= dv_s4;
215 end
216 else begin
217 if(with_data_n[0]) begin
218 smx_dmc_dv_n= line_en_n[0];
219 smx_dmc_resp_comp_n= line_en_n[3:0]==4'b0001;
220 smx_dmc_xcomp_n= xcomp_n[0];
221 smx_dmc_byte_en_n= sel_byte_en(sop_pos_n[0], eop_pos_n[0],
222 sop_byte_en_n, eop_byte_en_n);
223 smx_dmc_status_n= status_n; // or it with parity err ????
224 resp_dataff_rd_n= 1'b1;
225 ld_dvflag_data_n= 1'b1; // make own copy for s1-s3
226 rst_dvflag_n= dvflag; // make room for next
227 dv_ns= dv_s1;
228// niu_sio_dq_n= 1'b1; // put here to save cycles
229 end
230 else begin // no data; just deq
231 if(with_data_n[1]) begin // rd
232 smx_dmc_resp_comp_n= 1'b1;
233 smx_dmc_xcomp_n= xcomp_n[0];
234 end
235 else begin // wr
236 smx_dmc_ack_comp_n= 1'b1;
237 smx_dmc_ack_xcomp_n= xcomp_n[0];
238 end
239// niu_sio_dq_n= 1'b1;
240 rst_dvflag_n= dvflag;
241 dv_ns= dv_s0;
242 end
243 end // good pkt
244 end
245 end
246 dv_s1: begin
247 smx_dmc_dv_n= dvflag_line_en_r[1];
248 smx_dmc_resp_comp_n= dvflag_line_en_r[3:1]==3'b001;
249 smx_dmc_xcomp_n= dvflag_xcomp_r[1];
250 smx_dmc_byte_en_n= sel_byte_en(dvflag_sop_pos_r[1], dvflag_eop_pos_r[1],
251 dvflag_sop_byte_en_r, dvflag_eop_byte_en_r);
252 smx_dmc_status_n= dvflag_status_r; // or it with parity err ????
253 resp_dataff_rd_n= 1'b1;
254 dv_ns= dv_s2;
255 end
256 dv_s2: begin
257 smx_dmc_dv_n= dvflag_line_en_r[2];
258 smx_dmc_resp_comp_n= dvflag_line_en_r[3:2]==2'b01;
259 smx_dmc_xcomp_n= dvflag_xcomp_r[2];
260 smx_dmc_byte_en_n= sel_byte_en(dvflag_sop_pos_r[2], dvflag_eop_pos_r[2],
261 dvflag_sop_byte_en_r, dvflag_eop_byte_en_r);
262 smx_dmc_status_n= dvflag_status_r; // or it with parity err ????
263 resp_dataff_rd_n= 1'b1;
264 dv_ns= dv_s3;
265 end
266 dv_s3: begin
267 smx_dmc_dv_n= dvflag_line_en_r[3];
268 smx_dmc_resp_comp_n= dvflag_line_en_r[3];
269 // smx_dmc_resp_comp_n= (|dvflag_xcomp_r)? dvflag_xcomp_r[3] : 1'b1;
270 // if xcomp on any cycle, use xcomp; else force 1 (mid of pkt)
271 smx_dmc_xcomp_n= dvflag_xcomp_r[3];
272 smx_dmc_byte_en_n= sel_byte_en(dvflag_sop_pos_r[3], dvflag_eop_pos_r[3],
273 dvflag_sop_byte_en_r, dvflag_eop_byte_en_r);
274 smx_dmc_status_n= dvflag_status_r; // or it with parity err ????
275 resp_dataff_rd_n= 1'b1;
276 // niu_sio_dq_n= 1'b1;
277 dv_ns= dv_s0;
278 end
279 dv_s4: begin // pkt err handle
280 if(with_data_n[0]) begin
281 ld_dataff_rd_shift_n= 1'b1;
282 dv_ns= dv_s5;
283// niu_sio_dq_n= 1'b1; // save cycles
284 end
285 else begin // no data; just deq
286// niu_sio_dq_n= 1'b1;
287 rst_dvflag_n= dvflag;
288 dv_ns= dv_s0;
289 end
290 end
291 dv_s5: begin // pkterr read datafff
292 if(|dataff_rd_shift) resp_dataff_rd_n= 1'b1;
293 else begin // read dataff done; dq
294 // niu_sio_dq_n= 1'b1;
295 rst_dvflag_n= dvflag;
296 dv_ns= dv_s0;
297 end
298 end
299 endcase
300end
301
302
303always @(posedge clk) begin
304 if(!reset_l)
305 dataff_rd_shift<= `SMX_PD 4'h0;
306 else begin
307 if(ld_dataff_rd_shift_n)
308 dataff_rd_shift<= `SMX_PD 4'hf; // ld 4cy write
309 else
310 dataff_rd_shift<= `SMX_PD (dataff_rd_shift>>1);
311 end
312end
313
314
315
316always @ (posedge clk) begin
317 if(ld_dvflag_data_n) begin
318// dvflag_with_data_r<= `SMX_PD with_data_n;
319 dvflag_line_en_r<= `SMX_PD line_en_n;
320 dvflag_sop_pos_r<= `SMX_PD sop_pos_n;
321 dvflag_eop_pos_r<= `SMX_PD eop_pos_n;
322 dvflag_sop_byte_en_r<= `SMX_PD sop_byte_en_n;
323 dvflag_eop_byte_en_r<= `SMX_PD eop_byte_en_n;
324 dvflag_client_r<= `SMX_PD client_n;
325 dvflag_xcomp_r<= `SMX_PD xcomp_n;
326 dvflag_status_r<= `SMX_PD status_n;
327 end
328end
329
330wire [7:0] sel_client_n= (dv_idle_n)? client_n : dvflag_client_r;
331
332reg [7:0] smx_dmc_dv;
333reg [7:0] smx_dmc_resp_comp;
334reg [7:0] smx_dmc_xcomp;
335reg [7:0] smx_dmc_ack_comp;
336reg [7:0] smx_dmc_ack_xcomp;
337
338always @ (posedge clk) begin
339 if(!reset_l) begin
340// niu_sio_dq<= `SMX_PD 1'b0;
341 smx_dmc_dv<= `SMX_PD 8'h0;
342 smx_dmc_dv_r1<= `SMX_PD 8'h0;
343 smx_dmc_xcomp<= `SMX_PD 8'h0;
344 smx_dmc_xcomp_r1<= `SMX_PD 8'h0;
345 smx_dmc_resp_comp<= `SMX_PD 8'h0;
346 smx_dmc_resp_comp_r1<= `SMX_PD 8'h0;
347 smx_dmc_ack_xcomp<= `SMX_PD 8'h0;
348 smx_dmc_ack_comp<= `SMX_PD 8'h0;
349 dv_cs<= `SMX_PD dv_s0;
350 end
351 else begin
352// niu_sio_dq<= `SMX_PD niu_sio_dq_n;
353 smx_dmc_dv_r1<= `SMX_PD {8{smx_dmc_dv_n}} & sel_client_n ;
354 smx_dmc_xcomp_r1<= `SMX_PD {8{smx_dmc_xcomp_n}} & sel_client_n ;
355 smx_dmc_resp_comp_r1<= `SMX_PD {8{smx_dmc_resp_comp_n}} & sel_client_n ;
356
357 // one stage to allow ram data flop for parity check
358 smx_dmc_dv<= `SMX_PD smx_dmc_dv_r1;
359 smx_dmc_xcomp<= `SMX_PD smx_dmc_xcomp_r1;
360 smx_dmc_resp_comp<= `SMX_PD smx_dmc_resp_comp_r1;
361
362 smx_dmc_ack_xcomp<= `SMX_PD {8{smx_dmc_ack_xcomp_n}} & sel_client_n ;
363 smx_dmc_ack_comp<= `SMX_PD {8{smx_dmc_ack_comp_n}} & sel_client_n ;
364 dv_cs<= `SMX_PD dv_ns;
365 end
366end
367
368
369always @ (posedge clk) begin
370 smx_dmc_data_r1<= `SMX_PD smx_dmc_data_n;
371 smx_dmc_data_parity_r1<= `SMX_PD smx_dmc_data_parity_n[7:0];
372 smx_dmc_byte_en_r1<= `SMX_PD smx_dmc_byte_en_n;
373 smx_dmc_status_r1<= `SMX_PD smx_dmc_status_n;
374
375 smx_dmc_data<= `SMX_PD smx_dmc_data_r1;
376 smx_dmc_byte_en<= `SMX_PD smx_dmc_byte_en_r1;
377 smx_dmc_status<= `SMX_PD (smx_dmc_status_r1 | {3'h0, data_parerr_n});
378end
379
380wire err_inject_enable_n;
381wire [127:0] smx_dmc_data_r1_n= (err_inject_enable_n)?
382 {smx_dmc_data_r1[127:1], ~smx_dmc_data_r1[0]} :
383 smx_dmc_data_r1;
384
385niu_smx_gen_siudp genpar(
386 .data (smx_dmc_data_r1_n [127:0]),
387 .parity (gen_data_parity_n [7:0])
388 );
389
390
391// error injection
392reg one_pkt_flag;
393reg alt_pkt_flag;
394reg first_line_r1; // name _r1 to indicate align with data_r1
395
396always @(posedge clk) begin
397 if(!reset_l) begin
398 one_pkt_flag <= `SMX_PD 1'b0;
399 alt_pkt_flag <= `SMX_PD 1'b0;
400 first_line_r1 <= `SMX_PD 1'b0;
401 end
402 else begin
403 if(first_line_r1 & ~one_pkt_flag & pio_resp_err_inject_cfg[0])
404 one_pkt_flag <= `SMX_PD 1'b1; // set one_pkt flag
405 else if (~pio_resp_err_inject_cfg[0]) one_pkt_flag <= `SMX_PD 1'b0;
406 // reset when cfg one_pkt unset
407
408 if(first_line_r1 & pio_resp_err_inject_cfg[1]) // alternate each rd
409 alt_pkt_flag <= `SMX_PD ~alt_pkt_flag;
410
411 if(ld_dvflag_data_n) first_line_r1 <= `SMX_PD 1'b1; // set at dv_s0
412 else if(first_line_r1) first_line_r1 <= `SMX_PD 1'b0; // reset itself when set
413 end
414end
415
416
417assign err_inject_enable_n= ((~one_pkt_flag & pio_resp_err_inject_cfg[0]) |
418 (alt_pkt_flag & pio_resp_err_inject_cfg[1]) |
419 pio_resp_err_inject_cfg[2]) & first_line_r1;
420
421
422
423function [15:0] sel_byte_en;
424 input sop;
425 input eop;
426 input[15:0] sop_ben;
427 input[15:0] eop_ben;
428 begin
429 case({sop,eop})
430 2'b00: sel_byte_en= 16'hffff;
431 2'b01: sel_byte_en= eop_ben;
432 2'b10: sel_byte_en= sop_ben;
433 2'b11: sel_byte_en= (sop_ben & eop_ben);
434 endcase
435 end
436endfunction
437
438
439endmodule
440