| 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 | |