| 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 ============================================ |
| 35 | module 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 | |
| 48 | input clk; |
| 49 | input reset_l; |
| 50 | // dmc cmd req if |
| 51 | input req; |
| 52 | input [7:0] req_cmd; |
| 53 | input [63:0] req_addr; |
| 54 | input [13:0] req_len; |
| 55 | input [5:0] req_xid; |
| 56 | input [1:0] req_port; |
| 57 | input [4:0] req_dma; |
| 58 | input [7:0] req_client; |
| 59 | output ack; |
| 60 | |
| 61 | // datareq if |
| 62 | output cmdflag; |
| 63 | output [4:0] cmdflag_data; |
| 64 | output early_cmdflag_n; |
| 65 | output [4:0] early_cmdflag_data_n; |
| 66 | input rst_cmdflag; |
| 67 | input cfg_no_cmdflag; |
| 68 | input cfg_no_sameclientck; |
| 69 | input datareq_idle; |
| 70 | |
| 71 | // datareq/dv if |
| 72 | input xfer_done; // dmc_comp & nothing in datareq sm (ext logic) |
| 73 | |
| 74 | // xtb if |
| 75 | output xtb_wr; // this one also reset curnof64B cnt to 0 |
| 76 | output [5:0] xtb_waddr; |
| 77 | output [127:0] xtb_wdata; |
| 78 | input rst_xtb_wr; |
| 79 | |
| 80 | // cmd ff if |
| 81 | output ff_wr; |
| 82 | output [65:0] ff_wdata; |
| 83 | input ff_full; |
| 84 | |
| 85 | // lnen_ff if |
| 86 | output lnen_ff_wr; |
| 87 | output [4:0] lnen_ff_wdata; |
| 88 | input lnen_ff_full; |
| 89 | |
| 90 | // stall_hdlr if |
| 91 | input stall_enable; |
| 92 | output cmdreq_idle; |
| 93 | |
| 94 | output [2:0] cmd_cs; |
| 95 | |
| 96 | // status |
| 97 | // added 121405 |
| 98 | input [63:0] tid_valid_rdata_bus; |
| 99 | |
| 100 | /* generate line enable */ |
| 101 | |
| 102 | function [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 |
| 121 | endfunction |
| 122 | |
| 123 | function [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 |
| 136 | endfunction |
| 137 | |
| 138 | /* |
| 139 | function [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 |
| 164 | endfunction |
| 165 | |
| 166 | function [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 |
| 192 | endfunction |
| 193 | |
| 194 | function [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 |
| 220 | endfunction |
| 221 | */ |
| 222 | |
| 223 | function [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 |
| 237 | endfunction |
| 238 | |
| 239 | |
| 240 | parameter s0= 3'h0, |
| 241 | s1= 3'h1, |
| 242 | s1_1= 3'h4, |
| 243 | s2= 3'h2, |
| 244 | s3= 3'h3; |
| 245 | |
| 246 | reg [63:0] req_addr_r; |
| 247 | reg [13:0] req_len_r; |
| 248 | reg [1:0] req_port_r; |
| 249 | reg [4:0] req_dma_r; |
| 250 | reg [7:0] req_cmd_r; |
| 251 | reg [5:0] req_xid_r; |
| 252 | reg [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 ?? |
| 256 | wire[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) */ |
| 259 | wire anyone_64B_adj_len_n= |adj_len_n[5:0]; |
| 260 | wire [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 |
| 266 | wire [3:0] sop_line_en_n= gen_sop_line_en(req_addr_r[5:0]); |
| 267 | wire [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?? |
| 272 | wire [3:0] ec_sop_byte_en_n= req_addr_r[3:0]; // encoded |
| 273 | wire [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 ??? |
| 279 | wire [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 | */ |
| 284 | wire [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 |
| 290 | reg [127:0] xtb_wdata; |
| 291 | |
| 292 | // wire [5:0] xtb_waddr_n= req_xid; // no reg in ?? |
| 293 | wire [5:0] xtb_waddr_n= req_xid_r; |
| 294 | reg [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 |
| 297 | wire is_nonpost_n= (req_cmd_r[`SMX_CMDPOS_POST] == `SMX_CMD_NONPOST)? 1'b1 : 1'b0; |
| 298 | |
| 299 | reg [63:0] curaddr; |
| 300 | reg [9:0] cntof64B; |
| 301 | reg [9:0] nof64B; |
| 302 | |
| 303 | // cmd data use in s1; xx_r avail at s1 |
| 304 | wire [15:0] si_id= {req_xid_r[5:0], cntof64B[9:0]}; |
| 305 | wire [39:0] si_addr= {curaddr[39:6], 6'h0}; |
| 306 | wire [2:0] si_err= {3'h0}; // ??? |
| 307 | wire si_order= req_cmd_r[`SMX_CMDPOS_ORDER]; |
| 308 | |
| 309 | |
| 310 | // translate meta cmd to sii cmd |
| 311 | wire [6:0] xlate_cmd= xlate_cmd_meta_to_si(req_cmd_r); // ??? handle of non-existence cmd |
| 312 | wire [5:0] si_cmd= xlate_cmd[5:0]; // bit6 is xlate error |
| 313 | |
| 314 | reg ff_wr_n; |
| 315 | wire ff_wr= ff_wr_n; |
| 316 | // ff cmd data |
| 317 | wire [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 |
| 319 | wire [65:0] ff_wdata= ff_wdata_n; |
| 320 | |
| 321 | // inc sii start addr (by 64B) per send |
| 322 | wire [57:0] msb_curaddr= curaddr[63:6]; |
| 323 | wire [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 |
| 326 | wire [9:0] new_cntof64B_n= cntof64B + 1'b1; |
| 327 | wire eop_n= (new_cntof64B_n==nof64B)? 1'b1: 1'b0; |
| 328 | wire 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 |
| 332 | reg [3:0] eop_line_en; |
| 333 | wire [4:0] cmdflag_data_n= (eop_n)? {eop_n,eop_line_en} : {eop_n, 4'b1111}; |
| 334 | reg [4:0] cmdflag_data; |
| 335 | |
| 336 | wire 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 |
| 340 | reg early_cmdflag_n; |
| 341 | wire [4:0] early_cmdflag_data_n= cmdflag_data_n; |
| 342 | |
| 343 | reg ack_n, ack; |
| 344 | reg set_xtb_wr_n, xtb_wr; |
| 345 | reg ld_cdata_n; // flop in meta cmd |
| 346 | reg ld_info_n; // flop in info for cmdflag proc use; |
| 347 | // ie eop_line_en, 64B cnt |
| 348 | reg inc_cntof64B_n; |
| 349 | reg inc_curaddr_n; |
| 350 | reg set_cmdflag_n; |
| 351 | reg cmdflag; |
| 352 | reg [2:0] cmd_cs, cmd_ns; |
| 353 | |
| 354 | wire 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 | // |
| 360 | reg lnen_ff_wr_n; |
| 361 | wire lnen_ff_wr= lnen_ff_wr_n; |
| 362 | wire [4:0] lnen_ff_wdata= {eop_n, cmdflag_data_n[3:0]}; |
| 363 | |
| 364 | |
| 365 | // added 121405 - begin |
| 366 | wire 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 | |
| 372 | always @(/*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 |
| 498 | end |
| 499 | |
| 500 | |
| 501 | always @ (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 | |
| 522 | end |
| 523 | |
| 524 | always @ (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 |
| 548 | end |
| 549 | |
| 550 | always @ (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; |
| 560 | end |
| 561 | |
| 562 | |
| 563 | |
| 564 | endmodule |