Commit | Line | Data |
---|---|---|
86530b38 AT |
1 | // ========== Copyright Header Begin ========================================== |
2 | // | |
3 | // OpenSPARC T2 Processor File: niu_smx_sm_resp_cmdproc.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 | module niu_smx_sm_resp_cmdproc( | |
37 | /*AUTOARG*/ | |
38 | // Outputs | |
39 | resp_cmdff_rd, xtb_rd, xtb_raddr, xtb_rcvfile_update, | |
40 | xtb_rcvfile_update_addr, tid_valid_rst0, tid_valid_rst_addr0, | |
41 | tid_valid_rd, tid_valid_raddr, resp_rcv_set, resp_rcv_set_addr, | |
42 | procflag, procflag_cmd, procflag_addr, procflag_xid, | |
43 | procflag_port, procflag_dma, procflag_client, | |
44 | procflag_sop_line_en, procflag_eop_line_en, procflag_sop_byte_en, | |
45 | procflag_eop_byte_en, procflag_err, procflag_rd, | |
46 | procflag_with_data, procflag_sop, procflag_eop, procflag_xcomp, | |
47 | niu_sio_dq, proc_cs, | |
48 | // Inputs | |
49 | clk, reset_l, resp_cmdff_empty, resp_cmdff_rdata, xtb_rdata, | |
50 | xtb_rd_ack, xtb_rdata_err, tid_valid_rdata, rst_procflag | |
51 | ); | |
52 | ||
53 | input clk; | |
54 | input reset_l; | |
55 | ||
56 | // resp cmdff if | |
57 | input resp_cmdff_empty; | |
58 | input [21:0] resp_cmdff_rdata; | |
59 | output resp_cmdff_rd; | |
60 | ||
61 | ||
62 | // xtb if | |
63 | output xtb_rd; | |
64 | output [5:0] xtb_raddr; | |
65 | input [128:0] xtb_rdata; | |
66 | input xtb_rd_ack; | |
67 | input xtb_rdata_err; | |
68 | output xtb_rcvfile_update; | |
69 | output [5:0] xtb_rcvfile_update_addr; | |
70 | ||
71 | // status if | |
72 | output tid_valid_rst0; | |
73 | output [5:0] tid_valid_rst_addr0; | |
74 | ||
75 | output tid_valid_rd; | |
76 | output [5:0] tid_valid_raddr; | |
77 | input tid_valid_rdata; | |
78 | ||
79 | output resp_rcv_set; | |
80 | output [5:0] resp_rcv_set_addr; | |
81 | ||
82 | ||
83 | ||
84 | // resp cmdlaunch if | |
85 | output procflag; | |
86 | output [7:0] procflag_cmd; | |
87 | output [63:0] procflag_addr; | |
88 | // output [13:0] procflag_len; | |
89 | output [5:0] procflag_xid; | |
90 | output [1:0] procflag_port; | |
91 | output [4:0] procflag_dma; | |
92 | output [7:0] procflag_client; | |
93 | output [3:0] procflag_sop_line_en; | |
94 | output [3:0] procflag_eop_line_en; | |
95 | output [3:0] procflag_sop_byte_en; | |
96 | output [3:0] procflag_eop_byte_en; | |
97 | output [2:0] procflag_err; // [0] - pkterr; pkt drop | |
98 | // [2:1] - reserved | |
99 | output procflag_rd; // rd= 1, wr= 0 | |
100 | output procflag_with_data; // 1- data, 0- no data (payload) | |
101 | output procflag_sop; // sop portion rcving | |
102 | output procflag_eop; // eop portion rcving | |
103 | output procflag_xcomp; // all rcv'd | |
104 | input rst_procflag; | |
105 | ||
106 | // input cmdlaunch_idle; // in case need save 1 cycle at start | |
107 | // output early_procflag; // not use for now ??? | |
108 | // output [150:0] early_procflag_data; // not use for now ??? | |
109 | ||
110 | // sio if | |
111 | output niu_sio_dq; | |
112 | ||
113 | ||
114 | output [1:0] proc_cs; | |
115 | ||
116 | parameter proc_s0= 2'h0, | |
117 | proc_s1= 2'h1, | |
118 | proc_s2= 2'h2, | |
119 | proc_s3= 2'h3; | |
120 | ||
121 | ||
122 | /* | |
123 | xlate to meta cmd | |
124 | rd xtb | |
125 | rd/wr lineen, sop_be, eop_be, xtb_data, xcomp | |
126 | (if wr, dq, no dv) | |
127 | */ | |
128 | ||
129 | wire [5:0] xtb_raddr_n= resp_cmdff_rdata[`SMX_RESP_CMDFF_POS_ID_META]; | |
130 | wire [5:0] xtb_raddr= xtb_raddr_n; | |
131 | // made xtb_raddr one cycle earlier | |
132 | // reg [5:0] xtb_raddr; // flop in at set_xtb_rd_n | |
133 | ||
134 | ||
135 | reg [21:0] resp_cmdff_rdata_r; | |
136 | reg xtb_rcvfile_update_n; | |
137 | wire xtb_rcvfile_update= xtb_rcvfile_update_n ; | |
138 | wire [5:0] xtb_rcvfile_update_addr= resp_cmdff_rdata_r[`SMX_RESP_CMDFF_POS_ID_META]; | |
139 | ||
140 | reg resp_cmdff_rd_n; | |
141 | wire resp_cmdff_rd= resp_cmdff_rd_n; | |
142 | ||
143 | reg tid_valid_rd_n; | |
144 | wire tid_valid_rd= tid_valid_rd_n; | |
145 | wire [5:0] tid_valid_raddr= resp_cmdff_rdata[`SMX_RESP_CMDFF_POS_ID_META]; | |
146 | ||
147 | reg resp_rcv_set_n; | |
148 | wire resp_rcv_set= resp_rcv_set_n; | |
149 | wire [5:0] resp_rcv_set_addr= resp_cmdff_rdata_r[`SMX_RESP_CMDFF_POS_ID_META]; | |
150 | ||
151 | reg tid_valid_rst0_n; | |
152 | wire tid_valid_rst0= tid_valid_rst0_n; | |
153 | wire [5:0] tid_valid_rst_addr0= resp_cmdff_rdata_r[`SMX_RESP_CMDFF_POS_ID_META]; | |
154 | ||
155 | reg ld_cmdff_r_n; | |
156 | reg set_procflag_n; | |
157 | reg procflag; | |
158 | reg ld_procflag_data_n; | |
159 | reg [1:0] proc_ns, proc_cs; | |
160 | reg set_xtb_rd_n; // rst by xtb_rd_ack | |
161 | reg pktdrop_n; | |
162 | ||
163 | wire pkterr= resp_cmdff_rdata[`SMX_RESP_CMDFF_POS_PKTERR]; | |
164 | wire xtb_err_n= (tid_valid_rdata & xtb_rdata_err) | ~tid_valid_rdata; | |
165 | wire procflag_xcomp_n; | |
166 | wire xid_comp_n= procflag_xcomp_n & ~xtb_err_n; | |
167 | ||
168 | always @(/*AUTOSENSE*/pkterr or proc_cs or procflag | |
169 | or resp_cmdff_empty or xid_comp_n or xtb_err_n or xtb_rd_ack) begin | |
170 | ld_cmdff_r_n= 1'b0; | |
171 | resp_cmdff_rd_n= 1'b0; | |
172 | set_procflag_n= 1'b0; | |
173 | ld_procflag_data_n= 1'b0; | |
174 | set_xtb_rd_n= 1'b0; // set xtb rd; | |
175 | tid_valid_rd_n= 1'b0; // rd tid_valid flag file | |
176 | resp_rcv_set_n= 1'b0; // set resp_rcv flag | |
177 | tid_valid_rst0_n= 1'b0; // rst tid_valid flag; | |
178 | xtb_rcvfile_update_n= 1'b0; // inc rcvcnt | |
179 | pktdrop_n= 1'b0; | |
180 | proc_ns= proc_cs; | |
181 | case(proc_cs) | |
182 | proc_s0: begin // wait for cmdff | |
183 | if(!resp_cmdff_empty) begin | |
184 | ld_cmdff_r_n= 1'b1; | |
185 | resp_cmdff_rd_n= 1'b1; | |
186 | if(pkterr) begin | |
187 | proc_ns= proc_s2; | |
188 | end | |
189 | else begin // rd xtb only if no pkterr | |
190 | set_xtb_rd_n= 1'b1; | |
191 | tid_valid_rd_n= 1'b1; | |
192 | proc_ns= proc_s1; | |
193 | end | |
194 | end | |
195 | end | |
196 | proc_s1: begin // xtb data avail | |
197 | // in case need multiple cycle for xtb data (ecc gen) | |
198 | // also arb with TO handler | |
199 | if(xtb_rd_ack) begin | |
200 | set_xtb_rd_n= 1'b0; // rst xtb_rd | |
201 | // set flag only if procflag ready | |
202 | if(!procflag) begin | |
203 | set_procflag_n= 1'b1; | |
204 | ld_procflag_data_n= 1'b1; | |
205 | pktdrop_n= xtb_err_n; | |
206 | xtb_rcvfile_update_n= ~xtb_err_n; //inc rcvcnt only if no err | |
207 | resp_rcv_set_n= xid_comp_n; // set resp rcv flag on each resp | |
208 | tid_valid_rst0_n= xid_comp_n; // rst tid_valid at xcomp | |
209 | proc_ns= proc_s0; | |
210 | end | |
211 | else proc_ns= proc_s3; | |
212 | // wait procflag if not ready | |
213 | end | |
214 | else begin // keep xtb_rd '1' until rd ack | |
215 | set_xtb_rd_n= 1'b1; | |
216 | proc_ns= proc_cs; | |
217 | end | |
218 | end | |
219 | proc_s2: begin // wait procflag empty; pkterr; propagate err | |
220 | if(!procflag) begin | |
221 | set_procflag_n= 1'b1; | |
222 | ld_procflag_data_n= 1'b1; // need this to load pktdrop status | |
223 | pktdrop_n= 1'b1; | |
224 | proc_ns= proc_s0; | |
225 | end | |
226 | end | |
227 | proc_s3: begin // wait procflag empty; note xtb_rdata | |
228 | // (and rcvfile_rdata) needs to stag unchanged from proc_s1; | |
229 | // in xtb.v, rdata flopped on each ack; | |
230 | if(!procflag) begin | |
231 | set_procflag_n= 1'b1; | |
232 | ld_procflag_data_n= 1'b1; | |
233 | pktdrop_n= xtb_err_n; | |
234 | xtb_rcvfile_update_n= ~xtb_err_n; //inc rcvcnt only if no err | |
235 | resp_rcv_set_n= xid_comp_n; // set resp rcv flag on each resp | |
236 | tid_valid_rst0_n= xid_comp_n; // rst tid_valid at xcomp | |
237 | proc_ns= proc_s0; | |
238 | end | |
239 | end | |
240 | endcase | |
241 | end | |
242 | ||
243 | // assemble procflag data | |
244 | wire procflag_sop_n= (resp_cmdff_rdata_r[`SMX_RESP_CMDFF_POS_SEQ]==10'h0); | |
245 | reg procflag_sop; | |
246 | ||
247 | wire [9:0] eop_index_n= xtb_rdata[`SMX_XTB_POS_NOF64B]-1'b1; | |
248 | wire procflag_eop_n= (resp_cmdff_rdata_r[`SMX_RESP_CMDFF_POS_SEQ]==eop_index_n); | |
249 | reg procflag_eop; | |
250 | ||
251 | assign procflag_xcomp_n= (xtb_rdata[`SMX_XTB_POS_RCVCNT]==xtb_rdata[`SMX_XTB_POS_NOF64B]); | |
252 | reg procflag_xcomp; | |
253 | ||
254 | wire [2:0] resp_code= (resp_cmdff_rdata_r[`SMX_RESP_CMDFF_POS_RD])? | |
255 | `SMX_CMD_COMP_WITH_DATA : `SMX_CMD_COMP_WITHOUT_DATA; | |
256 | ||
257 | wire [7:0] procflag_cmd_n= { // si->meta cmd xlated | |
258 | 2'h0, // rsv | |
259 | 1'b0, // resp always non-posted | |
260 | 1'b0, // is wr completion ordered? | |
261 | // put 0 for resp | |
262 | 1'b0, // rsv | |
263 | resp_code | |
264 | }; | |
265 | /* | |
266 | 2'b10, // resp code | |
267 | ~resp_cmdff_rdata_r[`SMX_RESP_CMDFF_POS_RD] | |
268 | // si rd= 1, meta rd= 0 | |
269 | // si wr= 0, meta wr= 1 | |
270 | */ | |
271 | // | |
272 | // not sure resp code; | |
273 | // descrepancy between peu and smx spec ??? | |
274 | // peu[4:3] error type ??? | |
275 | // for now , implement smx's | |
276 | // | |
277 | reg [7:0] procflag_cmd; | |
278 | ||
279 | wire [63:0] xtb_data_addr= xtb_rdata[`SMX_XTB_POS_ADDR]; | |
280 | wire [9:0] resp_seq= resp_cmdff_rdata_r[`SMX_RESP_CMDFF_POS_SEQ]; | |
281 | // wire [57:0] msb_new_addr_n= xtb_data_addr[63:6] + {48'h0, resp_seq}; | |
282 | wire [63:0] adder_msb_addr_out; | |
283 | wire [57:0] msb_new_addr_n= adder_msb_addr_out[57:0]; | |
284 | ||
285 | wire [63:0] procflag_addr_n= (resp_seq==10'h0)? | |
286 | {xtb_data_addr[63:4], xtb_data_addr[3:0] & 4'h0} : // xtb_data_addr : cc 071105 orignal start addr | |
287 | // orignal start addr (16B aligned) | |
288 | // if first seq | |
289 | {msb_new_addr_n, 6'h0}; | |
290 | // always at 64B boundary | |
291 | // in subsequent seq | |
292 | cl_a1_add64_8x adder_msb_addr( | |
293 | .cin (1'b0), | |
294 | .in0 ({6'h0, xtb_data_addr[63:6]}), | |
295 | .in1 ({54'h0, resp_seq}), | |
296 | .out (adder_msb_addr_out[63:0]), | |
297 | .cout () | |
298 | ); | |
299 | ||
300 | reg [63:0] procflag_addr; | |
301 | ||
302 | // reg [13:0] procflag_len; | |
303 | reg [1:0] procflag_port; | |
304 | reg [4:0] procflag_dma; | |
305 | reg [7:0] procflag_client; | |
306 | reg [3:0] procflag_sop_line_en; | |
307 | reg [3:0] procflag_eop_line_en; | |
308 | reg [3:0] procflag_sop_byte_en; | |
309 | reg [3:0] procflag_eop_byte_en; | |
310 | reg [5:0] procflag_xid; | |
311 | reg [2:0] procflag_err; | |
312 | reg procflag_rd; | |
313 | reg procflag_with_data; | |
314 | ||
315 | always @(posedge clk) begin | |
316 | if(ld_cmdff_r_n) resp_cmdff_rdata_r<= `SMX_PD resp_cmdff_rdata; // flop in for s1 use | |
317 | if(ld_procflag_data_n) begin // sample at s1 | |
318 | // derive from xtb, cmdff_r | |
319 | procflag_cmd<= `SMX_PD procflag_cmd_n; // cmdff_r | |
320 | procflag_addr<= `SMX_PD procflag_addr_n; | |
321 | procflag_xcomp<= `SMX_PD procflag_xcomp_n; | |
322 | procflag_sop<= `SMX_PD procflag_sop_n; // cmdff_r | |
323 | procflag_eop<= `SMX_PD procflag_eop_n; | |
324 | // extract from xtb | |
325 | // procflag_len<= `SMX_PD xtb_rdata[`SMX_XTB_POS_LEN]; | |
326 | procflag_port<= `SMX_PD xtb_rdata[`SMX_XTB_POS_PORT]; | |
327 | procflag_dma<= `SMX_PD xtb_rdata[`SMX_XTB_POS_DMA]; | |
328 | procflag_client<= `SMX_PD xtb_rdata[`SMX_XTB_POS_CLIENT]; | |
329 | procflag_sop_line_en<= `SMX_PD xtb_rdata[`SMX_XTB_POS_SOP_LINE_EN]; | |
330 | procflag_eop_line_en<= `SMX_PD xtb_rdata[`SMX_XTB_POS_EOP_LINE_EN]; | |
331 | procflag_sop_byte_en<= `SMX_PD xtb_rdata[`SMX_XTB_POS_SOP_BYTE_EN]; | |
332 | procflag_eop_byte_en<= `SMX_PD xtb_rdata[`SMX_XTB_POS_EOP_BYTE_EN]; | |
333 | // extract from cmdff_r | |
334 | procflag_xid<= `SMX_PD resp_cmdff_rdata_r[`SMX_RESP_CMDFF_POS_ID_META]; | |
335 | procflag_err<= `SMX_PD {2'h0, pktdrop_n}; | |
336 | procflag_rd<= `SMX_PD resp_cmdff_rdata_r[`SMX_RESP_CMDFF_POS_RD]; | |
337 | procflag_with_data<= `SMX_PD resp_cmdff_rdata_r[`SMX_RESP_CMDFF_POS_WITH_DATA]; | |
338 | end | |
339 | end | |
340 | ||
341 | always @(posedge clk) begin | |
342 | if(!reset_l) begin | |
343 | procflag<= `SMX_PD 1'b0; | |
344 | proc_cs<= `SMX_PD proc_s0; | |
345 | ||
346 | // xtb_rd<= `SMX_PD 1'b0; | |
347 | end | |
348 | else begin | |
349 | if(set_procflag_n) procflag<= `SMX_PD 1'b1; | |
350 | else if (rst_procflag) procflag<= `SMX_PD 1'b0; | |
351 | proc_cs<= `SMX_PD proc_ns; | |
352 | ||
353 | /* | |
354 | made xtb_rd one cycle earlier | |
355 | if(set_xtb_rd_n) xtb_rd<= `SMX_PD 1'b1; | |
356 | else if (xtb_rd_ack) xtb_rd<= `SMX_PD 1'b0; | |
357 | */ | |
358 | end | |
359 | end | |
360 | ||
361 | // made xtb_raddr one cycle earlier | |
362 | // reg xtb_rd; // level signal | |
363 | wire xtb_rd= set_xtb_rd_n; | |
364 | ||
365 | /* | |
366 | made xtb_rd one cycle earlier | |
367 | always @ (posedge clk) begin | |
368 | if(set_xtb_rd_n) xtb_raddr<= `SMX_PD xtb_raddr_n; | |
369 | end | |
370 | */ | |
371 | ||
372 | wire niu_sio_dq_n= resp_cmdff_rd; | |
373 | reg niu_sio_dq; | |
374 | always @ (posedge clk) begin | |
375 | if(!reset_l) begin | |
376 | niu_sio_dq<= `SMX_PD 1'b0; | |
377 | end | |
378 | else begin | |
379 | niu_sio_dq<= `SMX_PD niu_sio_dq_n; | |
380 | end | |
381 | end | |
382 | ||
383 | endmodule | |
384 | ||
385 |