Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / design / sys / iop / niu / rtl / niu_smx_sm_resp_cmdlaunch.v
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: niu_smx_sm_resp_cmdlaunch.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_cmdlaunch(
37/*AUTOARG*/
38 // Outputs
39 smx_dmc_rdy, smx_dmc_cmd, smx_dmc_cmd_status, smx_dmc_addr,
40 smx_dmc_len, smx_dmc_xid, smx_dmc_port, smx_dmc_dma,
41 smx_dmc_client, smx_dmc_ack_rdy, smx_dmc_ack_cmd,
42 smx_dmc_ack_cmd_status,
43 smx_dmc_ack_xid,
44 smx_dmc_ack_dma,
45 smx_dmc_ack_client, rst_procflag, dvflag,
46 dvflag_with_data, dvflag_line_en, dvflag_sop_pos, dvflag_eop_pos,
47 dvflag_sop_byte_en, dvflag_eop_byte_en, dvflag_client,
48 dvflag_xcomp, dvflag_status, early_dvflag, early_dvflag_with_data,
49 early_dvflag_line_en, early_dvflag_sop_pos, early_dvflag_eop_pos,
50 early_dvflag_sop_byte_en, early_dvflag_eop_byte_en,
51 early_dvflag_client, early_dvflag_xcomp, early_dvflag_status,
52 cmdl_tohdl_ack, cmdl_cs,
53 // Inputs
54 clk, reset_l, dmc_smx_accept, dmc_smx_ack_accept, procflag,
55 procflag_cmd, procflag_addr, procflag_xid,
56 procflag_port, procflag_dma, procflag_client,
57 procflag_sop_line_en, procflag_eop_line_en, procflag_sop_byte_en,
58 procflag_eop_byte_en, procflag_err, procflag_rd,
59 procflag_with_data, procflag_xcomp, procflag_sop, procflag_eop,
60 rst_dvflag, dv_idle, tohdl_cmdl_req, tohdl_cmdl_cmd,
61 tohdl_cmdl_addr, tohdl_cmdl_len, tohdl_cmdl_xid, tohdl_cmdl_port,
62 tohdl_cmdl_dma, tohdl_cmdl_client, tid_dirty_rdata_bus
63 );
64
65input clk;
66input reset_l;
67
68 // dmc if
69output smx_dmc_rdy;
70output [7:0] smx_dmc_cmd;
71output [3:0] smx_dmc_cmd_status;
72output [63:0] smx_dmc_addr;
73output [13:0] smx_dmc_len;
74output [5:0] smx_dmc_xid;
75output [1:0] smx_dmc_port;
76output [4:0] smx_dmc_dma;
77output [7:0] smx_dmc_client;
78input [7:0] dmc_smx_accept;
79
80 // ack if
81output smx_dmc_ack_rdy;
82output [7:0] smx_dmc_ack_cmd;
83output [3:0] smx_dmc_ack_cmd_status;
84// output [63:0] smx_dmc_ack_addr;
85// output [13:0] smx_dmc_ack_len;
86output [5:0] smx_dmc_ack_xid;
87// output [1:0] smx_dmc_ack_port;
88output [4:0] smx_dmc_ack_dma;
89output [7:0] smx_dmc_ack_client;
90input [7:0] dmc_smx_ack_accept;
91
92 // cmdproc if
93input procflag;
94input [7:0] procflag_cmd;
95input [63:0] procflag_addr;
96input [5:0] procflag_xid;
97input [1:0] procflag_port;
98input [4:0] procflag_dma;
99input [7:0] procflag_client;
100input [3:0] procflag_sop_line_en;
101input [3:0] procflag_eop_line_en;
102input [3:0] procflag_sop_byte_en;
103input [3:0] procflag_eop_byte_en;
104input [2:0] procflag_err;
105input procflag_rd; // rd= 1, wr= 0
106input procflag_with_data; //1- data, 0- no data
107input procflag_xcomp;
108input procflag_sop;
109input procflag_eop;
110output rst_procflag;
111
112// output cmdlaunch_idle; // in case need save 1 cycle at start
113// input early_procflag;
114// input [150:0] early_procflag_data; // not use for now
115
116
117// dv if
118output dvflag;
119output [1:0] dvflag_with_data; // 1= rd (data,dv also sio dq) ,
120 // 0= wr/rderr (sio dq only)
121output [3:0] dvflag_line_en;
122output [3:0] dvflag_sop_pos; // indicate first data line position
123output [3:0] dvflag_eop_pos; // indicate last data line position
124output [15:0] dvflag_sop_byte_en; // use this for 'first' data line
125output [15:0] dvflag_eop_byte_en; // use this for 'last' data line
126output [7:0] dvflag_client;
127output [3:0] dvflag_xcomp;
128output [3:0] dvflag_status;
129input rst_dvflag;
130
131input dv_idle; // dv in idle state
132output early_dvflag; // dv needs to be in idle to catch this pulse
133 // and dvflag not set
134output [1:0] early_dvflag_with_data; // 1= rd (data,dv also sio dq) ,
135 // 0= wr/rderr (sio dq only)
136output [3:0] early_dvflag_line_en;
137output [3:0] early_dvflag_sop_pos; // indicate first data line position
138output [3:0] early_dvflag_eop_pos; // indicate last data line position
139output [15:0] early_dvflag_sop_byte_en; // use this for 'first' data line
140output [15:0] early_dvflag_eop_byte_en; // use this for 'last' data line
141output [7:0] early_dvflag_client;
142output [3:0] early_dvflag_xcomp;
143output [3:0] early_dvflag_status;
144
145 // TO handler if
146input tohdl_cmdl_req;
147input [7:0] tohdl_cmdl_cmd;
148input [63:0] tohdl_cmdl_addr;
149input [13:0] tohdl_cmdl_len;
150input [5:0] tohdl_cmdl_xid;
151input [1:0] tohdl_cmdl_port;
152input [4:0] tohdl_cmdl_dma;
153input [7:0] tohdl_cmdl_client;
154output cmdl_tohdl_ack;
155
156output [2:0] cmdl_cs;
157
158 // status i/f
159input [63:0] tid_dirty_rdata_bus;
160
161function [15:0] decode_eop_16b_byte_en_little; // B15,B14..,B1,B0
162 input [3:0] offset;
163
164 reg [15:0] byte_en;
165 begin
166 case(offset)
167 4'h0: byte_en= 16'hffff;
168 4'h1: byte_en= 16'h1;
169 4'h2: byte_en= 16'h3;
170 4'h3: byte_en= 16'h7;
171 4'h4: byte_en= 16'hf;
172 4'h5: byte_en= 16'h1f;
173 4'h6: byte_en= 16'h3f;
174 4'h7: byte_en= 16'h7f;
175 4'h8: byte_en= 16'hff;
176 4'h9: byte_en= 16'h1ff;
177 4'ha: byte_en= 16'h3ff;
178 4'hb: byte_en= 16'h7ff;
179 4'hc: byte_en= 16'hfff;
180 4'hd: byte_en= 16'h1fff;
181 4'he: byte_en= 16'h3fff;
182 4'hf: byte_en= 16'h7fff;
183 endcase
184 decode_eop_16b_byte_en_little= byte_en;
185 end
186endfunction
187
188function [15:0] decode_sop_16b_byte_en_little; // B15,B14..,B1,B0
189 input [3:0] offset;
190
191 reg [15:0] byte_en;
192 begin
193 case(offset)
194 4'h0: byte_en= 16'hffff;
195 4'h1: byte_en= 16'hfffe;
196 4'h2: byte_en= 16'hfffc;
197 4'h3: byte_en= 16'hfff8;
198 4'h4: byte_en= 16'hfff0;
199 4'h5: byte_en= 16'hffe0;
200 4'h6: byte_en= 16'hffc0;
201 4'h7: byte_en= 16'hff80;
202 4'h8: byte_en= 16'hff00;
203 4'h9: byte_en= 16'hfe00;
204 4'ha: byte_en= 16'hfc00;
205 4'hb: byte_en= 16'hf800;
206 4'hc: byte_en= 16'hf000;
207 4'hd: byte_en= 16'he000;
208 4'he: byte_en= 16'hc000;
209 4'hf: byte_en= 16'h8000;
210 endcase
211 decode_sop_16b_byte_en_little= byte_en;
212 end
213endfunction
214
215
216/*
217function [15:0] decode_eop_16b_byte_en_big; // B0,B1...,B14,B15
218 input [3:0] offset;
219
220 reg [15:0] byte_en;
221
222 begin
223 case(offset)
224 4'h0: byte_en= 16'hffff;
225 4'h1: byte_en= 16'h8000;
226 4'h2: byte_en= 16'hc000;
227 4'h3: byte_en= 16'he000;
228 4'h4: byte_en= 16'hf000;
229 4'h5: byte_en= 16'hf800;
230 4'h6: byte_en= 16'hfc00;
231 4'h7: byte_en= 16'hfe00;
232 4'h8: byte_en= 16'hff00;
233 4'h9: byte_en= 16'hff80;
234 4'ha: byte_en= 16'hffc0;
235 4'hb: byte_en= 16'hffe0;
236 4'hc: byte_en= 16'hfff0;
237 4'hd: byte_en= 16'hfff8;
238 4'he: byte_en= 16'hfffc;
239 4'hf: byte_en= 16'hfffe;
240 endcase
241 decode_eop_16b_byte_en_big= byte_en;
242 end
243endfunction
244
245function [15:0] decode_sop_16b_byte_en_big; // B0,B1...,B14,B15
246 input [3:0] offset;
247
248 reg [15:0] byte_en;
249
250 begin
251 case(offset)
252 4'h0: byte_en= 16'hffff;
253 4'h1: byte_en= 16'h7fff;
254 4'h2: byte_en= 16'h3fff;
255 4'h3: byte_en= 16'h1fff;
256 4'h4: byte_en= 16'h0fff;
257 4'h5: byte_en= 16'h07ff;
258 4'h6: byte_en= 16'h03ff;
259 4'h7: byte_en= 16'h01ff;
260 4'h8: byte_en= 16'h00ff;
261 4'h9: byte_en= 16'h007f;
262 4'ha: byte_en= 16'h003f;
263 4'hb: byte_en= 16'h001f;
264 4'hc: byte_en= 16'h000f;
265 4'hd: byte_en= 16'h0007;
266 4'he: byte_en= 16'h0003;
267 4'hf: byte_en= 16'h0001;
268 endcase
269 decode_sop_16b_byte_en_big= byte_en;
270 end
271endfunction
272*/
273
274parameter cmdl_s0= 3'h0,
275 cmdl_s1= 3'h1,
276 cmdl_s2= 3'h2,
277 cmdl_s3= 3'h3,
278 cmdl_s4= 3'h4;
279
280
281wire client_accept_n= (|(dmc_smx_accept & smx_dmc_client)) |
282 (|(dmc_smx_ack_accept & smx_dmc_ack_client));
283
284reg early_dvflag_n;
285wire early_dvflag= early_dvflag_n;
286
287reg rst_procflag_n;
288wire rst_procflag= rst_procflag_n;
289
290
291reg smx_dmc_rdy_n, smx_dmc_rdy ;
292reg smx_dmc_ack_rdy_n, smx_dmc_ack_rdy ;
293reg ld_dmc_n;
294reg set_dvflag_n;
295reg dvflag;
296reg [2:0] cmdl_ns, cmdl_cs;
297wire cmdl_req_n= procflag && !dvflag;
298reg rst_serve_tohdl_n;
299reg cmdl_tohdl_ack_n;
300wire cmdl_tohdl_ack= cmdl_tohdl_ack_n;
301reg serve_tohdl;
302
303wire proc_tid_is_dirty= tid_dirty_rdata_bus[procflag_xid];
304
305always @(/*AUTOSENSE*/client_accept_n or cmdl_cs or cmdl_req_n
306 or dv_idle or dvflag or procflag or procflag_err
307 or procflag_rd or serve_tohdl or smx_dmc_ack_rdy
308 or smx_dmc_rdy or tohdl_cmdl_req or tohdl_cmdl_xid
309 or proc_tid_is_dirty) begin
310 smx_dmc_rdy_n= smx_dmc_rdy;
311 smx_dmc_ack_rdy_n= smx_dmc_ack_rdy;
312 ld_dmc_n= 1'b0; // pulse to flop out smx_dmc cmd bus
313 set_dvflag_n= 1'b0; // also set dvflag_data
314 early_dvflag_n= 1'b0;
315 rst_procflag_n= 1'b0;
316 rst_serve_tohdl_n= 1'b0;
317 cmdl_tohdl_ack_n= 1'b0;
318 cmdl_ns= cmdl_cs;
319 case(cmdl_cs)
320 cmdl_s0: begin // wait procflag & !dvflag
321 // gen early_dvflag_xx using procflag_xx
322
323 // err ??? time share this with
324 // err handle;
325 // if both arb: serve_errhdl_first & lauch_err, cmdl_s3 (errhdl state)
326 // set served errhdl_first= each regular served
327 // rst each errhdl served
328 //
329 if(tohdl_cmdl_req & (serve_tohdl | (~serve_tohdl & ~cmdl_req_n))) begin
330 if(!dvflag) cmdl_ns= cmdl_s3;
331 end
332 else begin
333 if(procflag && !dvflag) begin
334 // flop in procflag_xx (->early_dvflag_xx)
335 rst_procflag_n= 1'b1;
336 if(procflag_err[0] | proc_tid_is_dirty) begin // pkterr; drop pkt
337 cmdl_ns= cmdl_s2;
338 end
339 else begin // launch cmd
340 if(procflag_rd) // rd
341 smx_dmc_rdy_n= 1'b1;
342 else // wr
343 smx_dmc_ack_rdy_n= 1'b1;
344 ld_dmc_n= 1'b1; // flop out dmc cmd bus
345 cmdl_ns= cmdl_s1;
346 end
347 end
348 end
349 end
350 cmdl_s1: begin // wait dmc client accept
351 // use procflag_xx_r to derive dvflag_xx_n
352 if(client_accept_n) begin
353 if(dv_idle) // kick dv earlier; save one cycle at start
354 early_dvflag_n= 1'b1; // early_dvflag_xx available
355 else
356 set_dvflag_n= 1'b1;
357 smx_dmc_rdy_n= 1'b0; // put all rdy to 0
358 smx_dmc_ack_rdy_n= 1'b0;
359 cmdl_ns= cmdl_s0;
360 end
361 end
362 cmdl_s2: begin // pkterr; drop pkt
363 set_dvflag_n= 1'b1;
364 cmdl_ns= cmdl_s0;
365 end
366 cmdl_s3: begin // TO hdlr
367 rst_serve_tohdl_n= 1'b1;
368 ld_dmc_n= 1'b1;
369 if(tohdl_cmdl_xid[5]) // wr
370 smx_dmc_ack_rdy_n= 1'b1;
371 else
372 smx_dmc_rdy_n= 1'b1;
373 cmdl_ns= cmdl_s4;
374 end
375 cmdl_s4: begin
376 if(client_accept_n) begin
377 set_dvflag_n= 1'b1;
378 smx_dmc_rdy_n= 1'b0; // put all rdy to 0
379 smx_dmc_ack_rdy_n= 1'b0;
380 cmdl_tohdl_ack_n= 1'b1;
381 cmdl_ns= cmdl_s0;
382 end
383 end
384 endcase
385end
386
387always @(posedge clk) begin
388 if(!reset_l) begin
389 cmdl_cs<= `SMX_PD cmdl_s0;
390 smx_dmc_rdy<= `SMX_PD 1'b0;
391 smx_dmc_ack_rdy<= `SMX_PD 1'b0;
392 dvflag<= `SMX_PD 1'b0;
393 serve_tohdl<= `SMX_PD 1'b0;
394 end
395 else begin
396 cmdl_cs<= `SMX_PD cmdl_ns;
397 smx_dmc_rdy<= `SMX_PD smx_dmc_rdy_n;
398 smx_dmc_ack_rdy<= `SMX_PD smx_dmc_ack_rdy_n;
399 if(set_dvflag_n) dvflag<= `SMX_PD 1'b1;
400 else if(rst_dvflag) dvflag<= `SMX_PD 1'b0;
401 if(rst_procflag_n) serve_tohdl<= `SMX_PD 1'b1;
402 else if(rst_serve_tohdl_n) serve_tohdl<= `SMX_PD 1'b0;
403 end
404end
405
406// wire cmdlaunch_idle= (cmdl_cs==cmdl_s0);
407
408// reg [3:0] procflag_sop_line_en_r;
409// reg [3:0] procflag_eop_line_en_r;
410// reg [3:0] procflag_sop_byte_en_r;
411// reg [3:0] procflag_eop_byte_en_r;
412// reg [2:0] procflag_err_r;
413// reg procflag_rd_r;
414// reg procflag_with_data_r;
415// reg procflag_xcomp_r;
416// reg procflag_sop_r;
417// reg procflag_eop_r;
418
419reg [7:0] smx_dmc_cmd;
420reg [3:0] smx_dmc_cmd_status;
421reg [63:0] smx_dmc_addr;
422reg [13:0] smx_dmc_len;
423reg [5:0] smx_dmc_xid;
424reg [1:0] smx_dmc_port;
425reg [4:0] smx_dmc_dma;
426reg [7:0] smx_dmc_client;
427
428// wire [63:0] smx_dmc_ack_addr= smx_dmc_addr;
429// wire [13:0] smx_dmc_ack_len= smx_dmc_len;
430// wire [1:0] smx_dmc_ack_port= smx_dmc_port;
431
432// cc registered to prevent ghosting effect with response bus 062905
433// wire [7:0] smx_dmc_ack_cmd= smx_dmc_cmd;
434// wire [3:0] smx_dmc_ack_cmd_status= smx_dmc_cmd_status;
435// wire [5:0] smx_dmc_ack_xid= smx_dmc_xid;
436// wire [4:0] smx_dmc_ack_dma= smx_dmc_dma;
437// wire [7:0] smx_dmc_ack_client= smx_dmc_client;
438
439reg [6:0] resp_len_n;
440
441reg [7:0] smx_dmc_ack_cmd;
442reg [3:0] smx_dmc_ack_cmd_status;
443reg [5:0] smx_dmc_ack_xid;
444reg [4:0] smx_dmc_ack_dma;
445reg [7:0] smx_dmc_ack_client;
446
447always @(posedge clk) begin
448 if(ld_dmc_n & smx_dmc_ack_rdy_n) begin // cc qualify to smx_dmc_ack_rdy_n 062905
449 smx_dmc_ack_cmd <= `SMX_PD (rst_serve_tohdl_n)? tohdl_cmdl_cmd : procflag_cmd;
450 smx_dmc_ack_cmd_status <= `SMX_PD (rst_serve_tohdl_n)? 4'hf : 4'h0;
451 smx_dmc_ack_xid <= `SMX_PD (rst_serve_tohdl_n)? tohdl_cmdl_xid : procflag_xid;
452 smx_dmc_ack_dma <= `SMX_PD (rst_serve_tohdl_n)? tohdl_cmdl_dma : procflag_dma;
453 smx_dmc_ack_client <= `SMX_PD (rst_serve_tohdl_n)? tohdl_cmdl_client : procflag_client;
454 end
455end
456
457always @(posedge clk) begin
458 if(ld_dmc_n & smx_dmc_rdy_n) begin // cc qualify to smx_dmc_rdy_n 062905
459 smx_dmc_cmd <= `SMX_PD (rst_serve_tohdl_n)? tohdl_cmdl_cmd : procflag_cmd;
460 smx_dmc_cmd_status <= `SMX_PD (rst_serve_tohdl_n)? 4'hf : 4'h0;
461 smx_dmc_addr <= `SMX_PD (rst_serve_tohdl_n)? tohdl_cmdl_addr : procflag_addr;
462 smx_dmc_len <= `SMX_PD (rst_serve_tohdl_n)? tohdl_cmdl_len : {7'h0, resp_len_n};
463 smx_dmc_xid <= `SMX_PD (rst_serve_tohdl_n)? tohdl_cmdl_xid : procflag_xid;
464 smx_dmc_port <= `SMX_PD (rst_serve_tohdl_n)? tohdl_cmdl_port : procflag_port;
465 smx_dmc_dma <= `SMX_PD (rst_serve_tohdl_n)? tohdl_cmdl_dma : procflag_dma;
466 smx_dmc_client <= `SMX_PD (rst_serve_tohdl_n)? tohdl_cmdl_client : procflag_client;
467
468 // also make own copy of non dmc
469 // make not need this copy ???
470 // procflag_sop_line_en_r<= `SMX_PD procflag_sop_line_en;
471 // procflag_eop_line_en_r<= `SMX_PD procflag_eop_line_en;
472// procflag_sop_byte_en_r<= `SMX_PD procflag_sop_byte_en;
473// procflag_eop_byte_en_r<= `SMX_PD procflag_eop_byte_en;
474// procflag_err_r<= `SMX_PD procflag_err;
475// procflag_rd_r<= `SMX_PD procflag_rd;
476// procflag_with_data_r<= `SMX_PD procflag_with_data;
477 // procflag_xcomp_r<= `SMX_PD procflag_xcomp;
478 // procflag_sop_r<= `SMX_PD procflag_sop;
479 // procflag_eop_r<= `SMX_PD procflag_eop;
480 end
481end
482
483reg [3:0] dvflag_line_en_n;
484always @ (/*AUTOSENSE*/procflag_eop or procflag_eop_line_en
485 or procflag_sop or procflag_sop_line_en) begin
486 case({procflag_sop, procflag_eop})
487 2'b00: dvflag_line_en_n= 4'hf; // mid of pkt
488 2'b01: dvflag_line_en_n= procflag_eop_line_en; // rcving eop
489 2'b10: dvflag_line_en_n= procflag_sop_line_en; // rcving sop
490 2'b11: dvflag_line_en_n= (procflag_sop_line_en & procflag_eop_line_en); // single 64B
491 endcase
492end
493
494reg [3:0] dvflag_sop_pos_n;
495always @ (/*AUTOSENSE*/procflag_sop_line_en) begin
496 dvflag_sop_pos_n= 4'h0;
497 case(procflag_sop_line_en)
498 4'b1111: dvflag_sop_pos_n= 4'b0001;
499 4'b1110: dvflag_sop_pos_n= 4'b0010;
500 4'b1100: dvflag_sop_pos_n= 4'b0100;
501 4'b1000: dvflag_sop_pos_n= 4'b1000;
502 default: dvflag_sop_pos_n= 4'b0000;
503 endcase
504end
505
506reg [3:0] dvflag_eop_pos_n;
507always @ (/*AUTOSENSE*/procflag_eop_line_en) begin
508 dvflag_eop_pos_n= 4'h0;
509 case(procflag_eop_line_en)
510 4'b1111: dvflag_eop_pos_n= 4'b1000;
511 4'b0111: dvflag_eop_pos_n= 4'b0100;
512 4'b0011: dvflag_eop_pos_n= 4'b0010;
513 4'b0001: dvflag_eop_pos_n= 4'b0001;
514 default: dvflag_eop_pos_n= 4'b0000;
515 endcase
516end
517
518wire [3:0] dvflag_xcomp_n;
519assign dvflag_xcomp_n[3]= procflag_xcomp & dvflag_line_en_n[3];
520assign dvflag_xcomp_n[2]= procflag_xcomp && (dvflag_line_en_n[3:2]==2'b01);
521assign dvflag_xcomp_n[1]= procflag_xcomp && (dvflag_line_en_n[3:1]==3'b001);
522assign dvflag_xcomp_n[0]= (procflag_xcomp && (dvflag_line_en_n[3:0]==4'b0001)) || // rd
523 (~procflag_rd && procflag_xcomp); // wr
524
525reg [1:0] dvflag_with_data;
526reg [3:0] dvflag_line_en;
527reg [3:0] dvflag_sop_pos; // indicate first data line position
528reg [3:0] dvflag_eop_pos; // indicate last data line position
529reg [15:0] dvflag_sop_byte_en; // use this for 'first' data line
530reg [15:0] dvflag_eop_byte_en; // use this for 'last' data line
531reg [7:0] dvflag_client;
532reg [3:0] dvflag_xcomp;
533reg [3:0] dvflag_status;
534
535reg [1:0] early_dvflag_with_data; // 1= rd (data,dv also sio dq) ,
536 // 0= wr/rderr (sio dq only)
537reg [3:0] early_dvflag_line_en;
538reg [3:0] early_dvflag_sop_pos; // indicate first data line position
539reg [3:0] early_dvflag_eop_pos; // indicate last data line position
540reg [15:0] early_dvflag_sop_byte_en; // use this for 'first' data line
541reg [15:0] early_dvflag_eop_byte_en; // use this for 'last' data line
542reg [7:0] early_dvflag_client;
543reg [3:0] early_dvflag_xcomp;
544reg [3:0] early_dvflag_status;
545
546
547wire procflag_err_0_cond= proc_tid_is_dirty? 1'b1 : procflag_err[0];
548
549always @(posedge clk) begin
550 if(rst_procflag_n) begin // make early dvflag_xxx
551 early_dvflag_with_data<= `SMX_PD {procflag_rd, procflag_with_data};
552 early_dvflag_line_en<= `SMX_PD dvflag_line_en_n;
553 // if rcving sop, sop at line X, else 0
554 early_dvflag_sop_pos<= `SMX_PD (procflag_sop)? dvflag_sop_pos_n : 4'h0;
555 // if rcving eop, eop at line X, else 0
556 early_dvflag_eop_pos<= `SMX_PD (procflag_eop)? dvflag_eop_pos_n : 4'h0;
557 // if 1 in sop/eop_pos , use sop/eop_byte_en
558 early_dvflag_sop_byte_en<= `SMX_PD decode_sop_16b_byte_en_little(procflag_sop_byte_en);
559 early_dvflag_eop_byte_en<= `SMX_PD decode_eop_16b_byte_en_little(procflag_eop_byte_en);
560 early_dvflag_xcomp<= `SMX_PD dvflag_xcomp_n;
561 early_dvflag_status<= `SMX_PD {1'b0, procflag_err[2:1],procflag_err_0_cond}; // extract from procflag_err
562 early_dvflag_client<= `SMX_PD procflag_client;
563 end
564 if(set_dvflag_n) begin
565 dvflag_with_data<= `SMX_PD (cmdl_tohdl_ack_n)? {~tohdl_cmdl_xid[5], 1'b0} :
566 early_dvflag_with_data;
567 dvflag_line_en<= `SMX_PD (cmdl_tohdl_ack_n)? 4'h0 : early_dvflag_line_en;
568 dvflag_sop_pos<= `SMX_PD (cmdl_tohdl_ack_n)? 4'h0: early_dvflag_sop_pos;
569 dvflag_eop_pos<= `SMX_PD (cmdl_tohdl_ack_n)? 4'h0: early_dvflag_eop_pos;
570 dvflag_sop_byte_en<= `SMX_PD (cmdl_tohdl_ack_n)? 16'h0: early_dvflag_sop_byte_en;
571 dvflag_eop_byte_en<= `SMX_PD (cmdl_tohdl_ack_n)? 16'h0: early_dvflag_eop_byte_en;
572 dvflag_xcomp<= `SMX_PD (cmdl_tohdl_ack_n)? 4'h1 : early_dvflag_xcomp;
573 dvflag_status<= `SMX_PD (cmdl_tohdl_ack_n)? 4'h0 : early_dvflag_status;
574 dvflag_client<= `SMX_PD (cmdl_tohdl_ack_n)? tohdl_cmdl_client : early_dvflag_client;
575 end
576/*
577 ??? note if need to have bubble between accept and dv,
578 need to put this back; right now, dv assert immediate
579 after accpet ???
580 or simply hard code dv_idle to 0;
581
582 if(set_dvflag_n) begin // right hand side all xx_r; gen dvflag_xx late
583 // important!!
584 // remember to chg dvflag_xx_n above to use _r if wanna use this
585 // line_en_n, eop/sop_pos_n....
586 // important!!
587 dvflag_with_data<= `SMX_PD procflag_with_data_r;
588 dvflag_line_en<= `SMX_PD dvflag_line_en_n;
589 dvflag_sop_pos<= `SMX_PD (procflag_sop_r)? dvflag_sop_pos_n : 4'h0;
590 dvflag_eop_pos<= `SMX_PD (procflag_eop_r)? dvflag_eop_pos_n : 4'h0;
591 dvflag_sop_byte_en<= `SMX_PD decode_sop_16b_byte_en_big(procflag_sop_byte_en_r);
592 dvflag_eop_byte_en<= `SMX_PD decode_eop_16b_byte_en_big(procflag_eop_byte_en_r);
593 dvflag_xcomp<= `SMX_PD procflag_xcomp_r;
594 dvflag_status<= `SMX_PD 4'h0; // extract from procflag_err ???;
595 dvflag_client<= `SMX_PD smx_dmc_client;
596 end
597*/
598end
599
600// adj resp_len to be actual len
601// not sure if timing can be a problem ??
602
603wire [1:0] sum_line_en_n= {1'b0, dvflag_line_en_n[0]} +
604 {1'b0, dvflag_line_en_n[1]} +
605 {1'b0, dvflag_line_en_n[2]} +
606 {1'b0, dvflag_line_en_n[3]};
607reg [6:0] sum_line_en_in_byte_n; // line_en in bytes
608
609always @(/*AUTOSENSE*/sum_line_en_n) begin
610 case(sum_line_en_n)
611 2'h0: sum_line_en_in_byte_n= 7'd64;
612 2'h1: sum_line_en_in_byte_n= 7'd16;
613 2'h2: sum_line_en_in_byte_n= 7'd32;
614 2'h3: sum_line_en_in_byte_n= 7'd48;
615 default: sum_line_en_in_byte_n= 7'd64;
616 endcase
617end
618
619//wire [4:0] sop_firstline_in_byte_n= 5'd16 - {1'b0, procflag_sop_byte_en};
620wire [4:0] sop_firstline_notuse_in_byte_n= {1'b0, procflag_sop_byte_en};
621wire [4:0] eop_lastline_in_byte_n= (|procflag_eop_byte_en)?
622 {1'b0, procflag_eop_byte_en} : 5'd16;
623wire [4:0] eop_lastline_notuse_in_byte_n= 5'd16 - eop_lastline_in_byte_n;
624
625always @(/*AUTOSENSE*/eop_lastline_notuse_in_byte_n or procflag_eop
626 or procflag_sop or sop_firstline_notuse_in_byte_n
627 or sum_line_en_in_byte_n) begin
628 case({procflag_sop, procflag_eop})
629 2'h0: resp_len_n= sum_line_en_in_byte_n; // mid resp
630 2'h1: resp_len_n= sum_line_en_in_byte_n - {2'h0, eop_lastline_notuse_in_byte_n}; // eop
631 2'h2: resp_len_n= sum_line_en_in_byte_n - {2'h0, sop_firstline_notuse_in_byte_n}; // sop
632 2'h3: resp_len_n= sum_line_en_in_byte_n - {2'h0, sop_firstline_notuse_in_byte_n}
633 - {2'h0, eop_lastline_notuse_in_byte_n};
634 // sop/eop in this resp chunk
635 default: resp_len_n= 7'd64;
636 endcase
637end
638
639endmodule
640
641
642
643
644