Initial commit of OpenSPARC T2 design and verification files.
[OpenSPARC-T2-DV] / design / sys / iop / niu / rtl / niu_smx_sm_req_cmdreq.v
CommitLineData
86530b38
AT
1// ========== Copyright Header Begin ==========================================
2//
3// OpenSPARC T2 Processor File: niu_smx_sm_req_cmdreq.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 ============================================
35module niu_smx_sm_req_cmdreq(
36/*AUTOARG*/
37 // Outputs
38 ack, cmdflag, cmdflag_data, early_cmdflag_n, early_cmdflag_data_n,
39 xtb_wr, xtb_waddr, xtb_wdata, ff_wr, ff_wdata, lnen_ff_wr,
40 lnen_ff_wdata, cmdreq_idle, cmd_cs,
41 // Inputs
42 clk, reset_l, req, req_cmd, req_addr, req_len, req_xid, req_port,
43 req_dma, req_client, rst_cmdflag, cfg_no_cmdflag,
44 cfg_no_sameclientck, datareq_idle, xfer_done, rst_xtb_wr, ff_full,
45 lnen_ff_full, stall_enable, tid_valid_rdata_bus
46 );
47
48input clk;
49input reset_l;
50 // dmc cmd req if
51input req;
52input [7:0] req_cmd;
53input [63:0] req_addr;
54input [13:0] req_len;
55input [5:0] req_xid;
56input [1:0] req_port;
57input [4:0] req_dma;
58input [7:0] req_client;
59output ack;
60
61 // datareq if
62output cmdflag;
63output [4:0] cmdflag_data;
64output early_cmdflag_n;
65output [4:0] early_cmdflag_data_n;
66input rst_cmdflag;
67input cfg_no_cmdflag;
68input cfg_no_sameclientck;
69input datareq_idle;
70
71 // datareq/dv if
72input xfer_done; // dmc_comp & nothing in datareq sm (ext logic)
73
74 // xtb if
75output xtb_wr; // this one also reset curnof64B cnt to 0
76output [5:0] xtb_waddr;
77output [127:0] xtb_wdata;
78input rst_xtb_wr;
79
80 // cmd ff if
81output ff_wr;
82output [65:0] ff_wdata;
83input ff_full;
84
85 // lnen_ff if
86output lnen_ff_wr;
87output [4:0] lnen_ff_wdata;
88input lnen_ff_full;
89
90 // stall_hdlr if
91input stall_enable;
92output cmdreq_idle;
93
94output [2:0] cmd_cs;
95
96// status
97// added 121405
98input [63:0] tid_valid_rdata_bus;
99
100/* generate line enable */
101
102function [3:0] gen_eop_line_en;
103 input[5:0] offset;
104
105 // bit0 - line0 (16B), bit1 - line1 (32B)
106 // bit2 - line2 (48B), bit3 - line3 (64B)
107 // 0 - no write; 1- write
108
109 reg [3:0] line_en;
110 reg anyone_16B;
111 begin
112 anyone_16B= |offset[3:0];
113 case({offset[5:4]})
114 2'b00: line_en= (anyone_16B)? 4'b0001 : 4'b1111;
115 2'b01: line_en= (anyone_16B)? 4'b0011 : 4'b0001;
116 2'b10: line_en= (anyone_16B)? 4'b0111 : 4'b0011;
117 2'b11: line_en= (anyone_16B)? 4'b1111 : 4'b0111;
118 endcase
119 gen_eop_line_en= line_en;
120 end
121endfunction
122
123function [3:0] gen_sop_line_en;
124 input[5:0] offset;
125
126 reg [3:0] line_en;
127 begin
128 case(offset[5:4])
129 2'b00: line_en= 4'b1111;
130 2'b01: line_en= 4'b1110;
131 2'b10: line_en= 4'b1100;
132 2'b11: line_en= 4'b1000;
133 endcase
134 gen_sop_line_en= line_en;
135 end
136endfunction
137
138/*
139function [15:0] decode_eop_16b_byte_en_little; // B15,B14..,B1,B0
140 input [3:0] offset;
141
142 reg [15:0] byte_en;
143 begin
144 case(offset)
145 4'h0: byte_en= 16'hffff;
146 4'h1: byte_en= 16'h1;
147 4'h2: byte_en= 16'h3;
148 4'h3: byte_en= 16'h7;
149 4'h4: byte_en= 16'hf;
150 4'h5: byte_en= 16'h1f;
151 4'h6: byte_en= 16'h3f;
152 4'h7: byte_en= 16'h7f;
153 4'h8: byte_en= 16'hff;
154 4'h9: byte_en= 16'h1ff;
155 4'ha: byte_en= 16'h3ff;
156 4'hb: byte_en= 16'h7ff;
157 4'hc: byte_en= 16'hfff;
158 4'hd: byte_en= 16'h1fff;
159 4'he: byte_en= 16'h3fff;
160 4'hf: byte_en= 16'h7fff;
161 endcase
162 decode_eop_16b_byte_en_little= byte_en;
163 end
164endfunction
165
166function [15:0] decode_eop_16b_byte_en_big; // B0,B1...,B14,B15
167 input [3:0] offset;
168
169 reg [15:0] byte_en;
170
171 begin
172 case(offset)
173 4'h0: byte_en= 16'hffff;
174 4'h1: byte_en= 16'h8000;
175 4'h2: byte_en= 16'hc000;
176 4'h3: byte_en= 16'he000;
177 4'h4: byte_en= 16'hf000;
178 4'h5: byte_en= 16'hf800;
179 4'h6: byte_en= 16'hfc00;
180 4'h7: byte_en= 16'hfe00;
181 4'h8: byte_en= 16'hff00;
182 4'h9: byte_en= 16'hff80;
183 4'ha: byte_en= 16'hffc0;
184 4'hb: byte_en= 16'hffe0;
185 4'hc: byte_en= 16'hfff0;
186 4'hd: byte_en= 16'hfff8;
187 4'he: byte_en= 16'hfffc;
188 4'hf: byte_en= 16'hfffe;
189 endcase
190 decode_eop_16b_byte_en_big= byte_en;
191 end
192endfunction
193
194function [15:0] decode_sop_16b_byte_en_big; // B0,B1...,B14,B15
195 input [3:0] offset;
196
197 reg [15:0] byte_en;
198
199 begin
200 case(offset)
201 4'h0: byte_en= 16'hffff;
202 4'h1: byte_en= 16'h7fff;
203 4'h2: byte_en= 16'h3fff;
204 4'h3: byte_en= 16'h1fff;
205 4'h4: byte_en= 16'h0fff;
206 4'h5: byte_en= 16'h07ff;
207 4'h6: byte_en= 16'h03ff;
208 4'h7: byte_en= 16'h01ff;
209 4'h8: byte_en= 16'h00ff;
210 4'h9: byte_en= 16'h007f;
211 4'ha: byte_en= 16'h003f;
212 4'hb: byte_en= 16'h001f;
213 4'hc: byte_en= 16'h000f;
214 4'hd: byte_en= 16'h0007;
215 4'he: byte_en= 16'h0003;
216 4'hf: byte_en= 16'h0001;
217 endcase
218 decode_sop_16b_byte_en_big= byte_en;
219 end
220endfunction
221*/
222
223function [6:0] xlate_cmd_meta_to_si;
224 input[7:0] cmd;
225
226 reg [6:0] new_cmd; // {err, si_cmd}
227
228 begin
229 case(cmd[`SMX_CMDPOS_CODE])
230 `SMX_CMD_MEMRD: new_cmd= {1'b0, `SMX_SICMD_RD};
231 `SMX_CMD_MEMWR: new_cmd= (cmd[`SMX_CMDPOS_POST]==`SMX_CMD_POST)?
232 {1'b0, `SMX_SICMD_WR_POST} : {1'b0, `SMX_SICMD_WR_NONPOST};
233 default: new_cmd= {1'b1, 6'h0}; // unrecognized cmd ??
234 endcase
235 xlate_cmd_meta_to_si= new_cmd;
236 end
237endfunction
238
239
240parameter s0= 3'h0,
241 s1= 3'h1,
242 s1_1= 3'h4,
243 s2= 3'h2,
244 s3= 3'h3;
245
246reg [63:0] req_addr_r;
247reg [13:0] req_len_r;
248reg [1:0] req_port_r;
249reg [4:0] req_dma_r;
250reg [7:0] req_cmd_r;
251reg [5:0] req_xid_r;
252reg [7:0] req_client_r;
253
254/* adjust to 64B aligned */
255// wire[14:0] adj_len_n= {9'h0, req_addr[5:0]} + {1'b0, req_len[13:0]}; // no reg in ??
256wire[14:0] adj_len_n= {9'h0, req_addr_r[5:0]} + {1'b0, req_len_r[13:0]};
257
258/* generate nof64B for rd/wr resp (store) */
259wire anyone_64B_adj_len_n= |adj_len_n[5:0];
260wire [9:0] nof64B_n= (anyone_64B_adj_len_n)?
261 ({1'b0, adj_len_n[14:6]} + 1'b1) : {1'b0, adj_len_n[14:6]};
262// + ((anyone_64B_adj_len_n)? 1'b1 : 1'b0);
263
264/* generate sop_line_en, eop_line_en for rd resp (store) */
265// wire [3:0] sop_line_en_n= gen_sop_line_en(req_addr[5:0]); // no reg in
266wire [3:0] sop_line_en_n= gen_sop_line_en(req_addr_r[5:0]);
267wire [3:0] eop_line_en_n= gen_eop_line_en(adj_len_n[5:0]);
268 // also use for line_en in wr side of data req
269
270/* generate sop_byte_en, eop_byte_en for rd resp (store) */
271// wire [3:0] ec_sop_byte_en_n= req_addr[3:0]; // encoded ; no reg in??
272wire [3:0] ec_sop_byte_en_n= req_addr_r[3:0]; // encoded
273wire [3:0] ec_eop_byte_en_n= adj_len_n[3:0];
274// wire [15:0] sop_byte_en_n= decode_sop_16b_byte_en_big(ec_sop_byte_en_n);
275// wire [15:0] eop_byte_en_n= decode_eop_16b_byte_en_big(ec_eop_byte_en_n);
276
277/*
278 no reg in ???
279wire [127:0] xtb_wdata_n= {10'h0,
280 req_addr, req_len, req_port, req_dma, req_client,
281 nof64B_n, sop_line_en_n, eop_line_en_n,
282 ec_sop_byte_en_n, ec_eop_byte_en_n};
283*/
284wire [127:0] xtb_wdata_n= {9'h0,
285 req_addr_r, req_len_r, req_port_r, req_dma_r, req_client_r,
286 nof64B_n, sop_line_en_n, eop_line_en_n,
287 ec_sop_byte_en_n, ec_eop_byte_en_n};
288 // 64, 14, 2, 5, 8,
289 // 10, 4, 4, 4, 4
290reg [127:0] xtb_wdata;
291
292// wire [5:0] xtb_waddr_n= req_xid; // no reg in ??
293wire [5:0] xtb_waddr_n= req_xid_r;
294reg [5:0] xtb_waddr;
295
296// wire is_nonpost_n= (req_cmd[`SMX_CMDPOS_POST] == `SMX_CMD_NONPOST)? 1'b1 : 1'b0; // no reg in
297wire is_nonpost_n= (req_cmd_r[`SMX_CMDPOS_POST] == `SMX_CMD_NONPOST)? 1'b1 : 1'b0;
298
299reg [63:0] curaddr;
300reg [9:0] cntof64B;
301reg [9:0] nof64B;
302
303// cmd data use in s1; xx_r avail at s1
304wire [15:0] si_id= {req_xid_r[5:0], cntof64B[9:0]};
305wire [39:0] si_addr= {curaddr[39:6], 6'h0};
306wire [2:0] si_err= {3'h0}; // ???
307wire si_order= req_cmd_r[`SMX_CMDPOS_ORDER];
308
309
310// translate meta cmd to sii cmd
311wire [6:0] xlate_cmd= xlate_cmd_meta_to_si(req_cmd_r); // ??? handle of non-existence cmd
312wire [5:0] si_cmd= xlate_cmd[5:0]; // bit6 is xlate error
313
314reg ff_wr_n;
315wire ff_wr= ff_wr_n;
316// ff cmd data
317wire [65:0] ff_wdata_n= {si_cmd[5:0], si_err[2:0], si_id[15:0], si_addr[39:0], si_order};
318 // 6, 3, 16, 40, 1
319wire [65:0] ff_wdata= ff_wdata_n;
320
321// inc sii start addr (by 64B) per send
322wire [57:0] msb_curaddr= curaddr[63:6];
323wire [57:0] new_msb_curaddr_n= msb_curaddr+1'b1; // use incrementor rather than add 64B
324
325// inc token LSB (by 1) per send
326wire [9:0] new_cntof64B_n= cntof64B + 1'b1;
327wire eop_n= (new_cntof64B_n==nof64B)? 1'b1: 1'b0;
328wire one64Blen= (nof64B==10'h1);
329
330 // assume wr always start at 64B aligned;
331 // at end of pkt, use eop_line_en, else read 4 lines
332reg [3:0] eop_line_en;
333wire [4:0] cmdflag_data_n= (eop_n)? {eop_n,eop_line_en} : {eop_n, 4'b1111};
334reg [4:0] cmdflag_data;
335
336wire same_client_n= (cfg_no_sameclientck)? 1'b1 : // always bogus same if disable
337 ((req_client_r==req_client)? 1'b1 : 1'b0);
338
339 // early version of cmdflag to save 1 cycle at start
340reg early_cmdflag_n;
341wire [4:0] early_cmdflag_data_n= cmdflag_data_n;
342
343reg ack_n, ack;
344reg set_xtb_wr_n, xtb_wr;
345reg ld_cdata_n; // flop in meta cmd
346reg ld_info_n; // flop in info for cmdflag proc use;
347 // ie eop_line_en, 64B cnt
348reg inc_cntof64B_n;
349reg inc_curaddr_n;
350reg set_cmdflag_n;
351reg cmdflag;
352reg [2:0] cmd_cs, cmd_ns;
353
354wire cmdreq_idle= (cmd_cs==s0);
355
356//
357// ??? need registered in ? migh have timing problem on xtb_wdata_n gen
358// xtb_wr need flag ??? rdreq and wreq arb if use one ram 64 entries;
359//
360reg lnen_ff_wr_n;
361wire lnen_ff_wr= lnen_ff_wr_n;
362wire [4:0] lnen_ff_wdata= {eop_n, cmdflag_data_n[3:0]};
363
364
365// added 121405 - begin
366wire tag_is_valid_n= ((cntof64B>10'h4) && cfg_no_cmdflag)?
367 tid_valid_rdata_bus[req_xid_r] : 1'b1;
368 // condition tag valid only if in rdreq case (cfg_no_cmdflag is 1)
369 // and at least 4 dispatched (this is to make time for xtb
370 // write to go thru since xtb_wr signal arb with wrreq
371
372always @(/*AUTOSENSE*/cmd_cs or cmdflag or datareq_idle or eop_n
373 or ff_full or is_nonpost_n or lnen_ff_full or one64Blen
374 or req or same_client_n or stall_enable or tag_is_valid_n
375 or xfer_done or xtb_wr) begin
376 ack_n= 1'b0;
377 set_xtb_wr_n= 1'b0;
378 ld_cdata_n= 1'b0;
379 ld_info_n= 1'b0;
380 inc_cntof64B_n= 1'b0;
381 inc_curaddr_n= 1'b0;
382 ff_wr_n= 1'b0;
383 lnen_ff_wr_n= 1'b0;
384 set_cmdflag_n= 1'b0;
385 early_cmdflag_n= 1'b0;
386 cmd_ns= cmd_cs;
387 case(cmd_cs)
388 s0: begin // idle; wait for dmc req
389 if(req && !stall_enable) begin
390 ack_n= 1'b1;
391 ld_cdata_n= 1'b1; // flop in meta cmd data; rst/init working copies
392 // curaddr init to startaddr, cntof64B rst to 0
393 // generate xtb_wdata_n, to be written at s1;
394 // gen nof64B_n, eop_line_en_n (to be used in s1)
395 // xtb_wr_n= is_nonpost_n; // no reg in ??
396 cmd_ns= s1;
397 end
398 end
399 s1: begin // cnt= 0; xtb wr; meta_cmd_data_r available;
400 // xx_r use in rest of state until ld_cdata_n= 1
401 // generate xtb_wdata_n, to be written at next state;
402 // gen nof64B_n, eop_line_en_n (to be used in next state)
403 ld_info_n= 1'b1; // always load info for proc/cmdflag use
404 if(is_nonpost_n) begin // xtb write only with non-post cmd
405 if(!xtb_wr) begin // wait till previous write go thru
406 set_xtb_wr_n= 1'b1;
407 cmd_ns= s1_1;
408 end
409 end else cmd_ns= s1_1;
410 end
411 s1_1: begin // cnt= 0; xtb wr; meta_cmd_data_r available;
412 // xx_r use in rest of state until ld_cdata_n= 1
413 // check ff_full, flag;
414 // wrff, wr flag_data; set flag
415 if(!ff_full && !cmdflag && !lnen_ff_full) begin
416 if(tag_is_valid_n) begin // added 121405
417 lnen_ff_wr_n= 1'b1; // line enable ff for dv sm
418 ff_wr_n= 1'b1; // cmdff
419 if(datareq_idle) begin // cmdflag
420 // datareq machine idle; kick it to work; save 1 cycle;
421 early_cmdflag_n= 1'b1;
422 end
423 else begin
424 set_cmdflag_n= 1'b1;
425 end
426 // eop check;
427 if(eop_n) begin
428 if(one64Blen) cmd_ns= s3; // req not ready on dmc
429 // wait one cycle
430 else begin
431 if(req && same_client_n && !stall_enable) begin
432 // cont' to next pkt; same client can burst in datareq
433 ack_n= 1'b1;
434 ld_cdata_n= 1'b1;
435 // xtb_wr_n= is_nonpost_n; // no reg in ??
436 cmd_ns= s1;
437 end
438 else begin // wait data complete before switch to next client
439 cmd_ns= s2;
440 end
441 end
442 end // eop
443 else begin
444 inc_cntof64B_n= 1'b1;
445 inc_curaddr_n= 1'b1;
446 cmd_ns= cmd_cs; // continue this pkt
447 end
448 end // added 121405
449 else begin // tag not valid (could be timeout in mid)
450 cmd_ns= s3; // cont' to next pkt
451 end
452 end
453 end
454 s2: begin // wait data complete
455 // xfer done is a pulse that align with dv of end of datareq;
456 // in wr, since it always has 4 cycles for data, and it takes
457 // less than 4 cycles from s1 to s2, s2 should be able to
458 // catch this pulse;
459 // in rd, xfer_done is hard wired to 1
460
461 // check if req with same client
462 // req can happen while waiting for complete
463 // try to burst out dv without waiting for
464 // previous pkt comp of same client
465 if(req && same_client_n && !stall_enable) begin
466 // new pkt; same client can burst in datareq
467 ack_n= 1'b1;
468 ld_cdata_n= 1'b1;
469 // xtb_wr_n= is_nonpost_n; // no reg in ?/
470 cmd_ns= s1;
471 end
472 else begin
473 if(xfer_done) begin
474 if(req && !stall_enable)begin
475 ack_n= 1'b1;
476 ld_cdata_n= 1'b1;
477 // xtb_wr_n= is_nonpost_n; // no reg in ?/
478 cmd_ns= s1; // continue to process
479 end
480 else
481 cmd_ns= s0; // no more req; go back to idle
482 end
483 end // not same client at req
484 end
485 s3: begin // dummy cycle to sample correct dmc_req
486 if(req && same_client_n && !stall_enable) begin
487 // new pkt; same client can burst in datareq
488 ack_n= 1'b1;
489 ld_cdata_n= 1'b1;
490 // xtb_wr_n= is_nonpost_n; // no reg in ?/
491 cmd_ns= s1;
492 end
493 else begin // wait data complete before switch to next client
494 cmd_ns= s2;
495 end
496 end
497 endcase
498end
499
500
501always @ (posedge clk) begin
502 if(ld_cdata_n) begin
503 req_cmd_r<= `SMX_PD req_cmd;
504 req_addr_r<= `SMX_PD req_addr;
505 req_len_r<= `SMX_PD req_len;
506 req_xid_r<= `SMX_PD req_xid;
507 req_port_r<= `SMX_PD req_port;
508 req_dma_r<= `SMX_PD req_dma;
509 req_client_r<= `SMX_PD req_client;
510 end
511
512 if(ld_cdata_n)
513 curaddr<= `SMX_PD {req_addr[63:6], 6'h0}; // always start at 64B boundary
514 else
515 if(inc_curaddr_n) curaddr<= `SMX_PD {new_msb_curaddr_n[57:0], 6'h0};
516
517 if(ld_cdata_n)
518 cntof64B<= `SMX_PD 10'h0;
519 else
520 if(inc_cntof64B_n) cntof64B<= `SMX_PD new_cntof64B_n;
521
522end
523
524always @ (posedge clk) begin
525 if(!reset_l)begin
526 xtb_wr<= `SMX_PD 1'b0;
527 ack<= `SMX_PD 1'b0;
528 cmd_cs<= `SMX_PD s0;
529 cmdflag<= `SMX_PD 1'b0;
530 end
531 else begin
532 if(set_xtb_wr_n)
533 xtb_wr<= `SMX_PD 1'b1;
534 else if(rst_xtb_wr)
535 xtb_wr<= `SMX_PD 1'b0;
536 ack<= `SMX_PD ack_n;
537 cmd_cs<= `SMX_PD cmd_ns;
538 if(cfg_no_cmdflag) begin
539 cmdflag<= `SMX_PD 1'b0;
540 end
541 else begin
542 if(set_cmdflag_n)
543 cmdflag<= `SMX_PD 1'b1;
544 else
545 if(rst_cmdflag) cmdflag<= `SMX_PD 1'b0;
546 end
547 end
548end
549
550always @ (posedge clk) begin
551 if(set_xtb_wr_n) begin
552 xtb_wdata<= `SMX_PD xtb_wdata_n;
553 xtb_waddr<= `SMX_PD xtb_waddr_n;
554 end
555 if(ld_info_n) begin
556 nof64B<= `SMX_PD nof64B_n;
557 eop_line_en<= `SMX_PD eop_line_en_n;
558 end
559 if(set_cmdflag_n) cmdflag_data<= `SMX_PD cmdflag_data_n;
560end
561
562
563
564endmodule