Changeset 558
- Timestamp:
- Oct 25, 2013, 5:35:50 PM (11 years ago)
- Location:
- trunk/modules/vci_spi/caba/source
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/modules/vci_spi/caba/source/include/vci_spi.h
r551 r558 80 80 sc_signal<uint8_t> r_ctrl_char_len; // number of bits in xfer 81 81 82 sc_signal<uint8_t> r_txrx_addr;83 84 82 sc_signal<uint32_t> r_bit_count; 85 83 sc_signal<uint32_t> r_clk_counter; … … 105 103 sc_signal<typename vci_param::trdid_t > r_trdid; // save trdid 106 104 sc_signal<typename vci_param::pktid_t > r_pktid; // save pktid 107 sc_signal<typename vci_param::data_t > r_tdata; // save wdata 105 106 sc_signal<typename vci_param::data_t > r_rdata; // save reply 108 107 109 108 uint32_t* r_local_buffer; // capacity is one block … … 142 141 enum { 143 142 T_IDLE = 0, 144 T_WRITE_TXRX = 1, 145 T_READ_TXRX = 2, 146 T_WRITE_CTRL = 3, 147 T_READ_CTRL = 4, 148 T_WRITE_DIVIDER = 5, 149 T_READ_DIVIDER = 6, 150 T_WRITE_SS = 7, 151 T_READ_SS = 8, 152 T_WRITE_ERROR = 9, 153 T_READ_ERROR = 10, 143 T_RSP_READ = 1, 144 T_RSP_WRITE = 2, 145 T_ERROR_READ = 3, 146 T_ERROR_WRITE = 4 154 147 }; 155 148 -
trunk/modules/vci_spi/caba/source/src/vci_spi.cpp
r553 r558 22 22 * 23 23 * Copyright (c) UPMC, Lip6, SoC 24 * 24 * manuel.bouyer@lip6.fr october 2013 25 25 * 26 26 * Maintainers: bouyer … … 45 45 if(p_resetn.read() == false) 46 46 { 47 48 49 r_spi_fsm 50 r_ss= 0;51 r_divider= 0xffff;52 53 r_ctrl_ass= false;54 r_ctrl_ie= false;55 56 57 47 r_initiator_fsm = M_IDLE; 48 r_target_fsm = T_IDLE; 49 r_spi_fsm = S_IDLE; 50 r_ss = 0; 51 r_divider = 0xffff; 52 r_ctrl_char_len = 0; 53 r_ctrl_ass = false; 54 r_ctrl_ie = false; 55 r_ctrl_cpol = false; 56 r_ctrl_cpha = false; 57 r_ctrl_go_bsy = false; 58 58 r_clk_counter = 0xffff; 59 r_spi_clk 59 r_spi_clk = 0; 60 60 61 61 r_irq = false; 62 62 r_read = false; 63 63 64 64 return; 65 65 } 66 66 … … 74 74 case T_IDLE: 75 75 { 76 77 78 79 80 81 r_tdata = p_vci_target.wdata.read();82 83 84 85 86 87 88 89 76 if ( p_vci_target.cmdval.read() ) 77 { 78 r_srcid = p_vci_target.srcid.read(); 79 r_trdid = p_vci_target.trdid.read(); 80 r_pktid = p_vci_target.pktid.read(); 81 uint32_t wdata = p_vci_target.wdata.read(); 82 sc_dt::sc_uint<vci_param::N> address = p_vci_target.address.read(); 83 84 bool found = false; 85 std::list<soclib::common::Segment>::iterator seg; 86 for ( seg = m_seglist.begin() ; seg != m_seglist.end() ; seg++ ) 87 { 88 if ( seg->contains(address) ) found = true; 89 } 90 90 91 bool read = (p_vci_target.cmd.read() == vci_param::CMD_READ); 92 uint32_t cell = (uint32_t)((address & 0x3F)>>2); 93 94 if (read) { 95 if (not found) { 96 r_target_fsm = T_READ_ERROR; 97 } else { 98 switch(cell) { 99 case SPI_DATA_TXRX0: 100 case SPI_DATA_TXRX1: 101 case SPI_DATA_TXRX2: 102 case SPI_DATA_TXRX3: 103 r_target_fsm = T_READ_TXRX; 104 r_txrx_addr = cell; 105 break; 106 case SPI_CTRL: 107 r_target_fsm = T_READ_CTRL; 108 break; 109 case SPI_DIVIDER: 110 r_target_fsm = T_READ_DIVIDER; 111 break; 112 case SPI_SS: 113 r_target_fsm = T_READ_SS; 114 break; 115 default: 116 r_target_fsm = T_READ_ERROR; 117 break; 91 92 if (not found) { 93 if (p_vci_target.cmd.read() == vci_param::CMD_WRITE) 94 r_target_fsm = T_ERROR_WRITE; 95 else 96 r_target_fsm = T_ERROR_READ; 97 } else if (p_vci_target.cmd.read() != vci_param::CMD_READ && 98 p_vci_target.cmd.read() != vci_param::CMD_WRITE) { 99 r_target_fsm = T_ERROR_READ; 100 } else { 101 bool write = (p_vci_target.cmd.read() == vci_param::CMD_WRITE) & !r_ctrl_go_bsy; 102 uint32_t cell = (uint32_t)((address & 0x3F)>>2); 103 switch(cell) { 104 case SPI_DATA_TXRX0: 105 r_rdata = r_txrx[0] & (uint64_t)0x00000000ffffffffULL; 106 if (write) { 107 r_txrx[0] = 108 (r_txrx[0] & (uint64_t)0xffffffff00000000ULL) | 109 ((uint64_t)wdata); 110 } 111 r_target_fsm = (p_vci_target.cmd.read() == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ; 112 break; 113 case SPI_DATA_TXRX1: 114 r_rdata = r_txrx[0] >> 32; 115 if (write) { 116 r_txrx[0] = 117 (r_txrx[0] & (uint64_t)0x00000000ffffffffULL) | 118 ((uint64_t)wdata << 32); 119 } 120 r_target_fsm = (p_vci_target.cmd.read() == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ; 121 break; 122 case SPI_DATA_TXRX2: 123 r_rdata = r_txrx[1] & (uint64_t)0x00000000ffffffffULL; 124 if (write) { 125 r_txrx[1] = 126 (r_txrx[1] & (uint64_t)0xffffffff00000000ULL) | 127 ((uint64_t)wdata); 128 } 129 r_target_fsm = (p_vci_target.cmd.read() == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ; 130 break; 131 case SPI_DATA_TXRX3: 132 r_rdata = r_txrx[1] >> 32; 133 if (write) { 134 r_txrx[1] = 135 (r_txrx[1] & (uint64_t)0x00000000ffffffffULL) | 136 ((uint64_t)wdata << 32); 137 } 138 r_target_fsm = (p_vci_target.cmd.read() == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ; 139 break; 140 case SPI_CTRL: 141 { 142 uint32_t data = 0; 143 if (r_ctrl_cpol.read()) 144 data |= SPI_CTRL_CPOL; 145 if (r_ctrl_cpha.read()) 146 data |= SPI_CTRL_CPHA; 147 if (r_ctrl_ass.read()) 148 data |= SPI_CTRL_ASS_EN; 149 if (r_ctrl_ie.read()) 150 data |= SPI_CTRL_IE_EN; 151 if (r_ctrl_go_bsy.read()) 152 data |= SPI_CTRL_GO_BSY; 153 data |= (uint32_t)r_ctrl_char_len.read(); 154 r_rdata = data; 155 if (write) { 156 r_ctrl_cpol = ((wdata & SPI_CTRL_CPOL) != 0); 157 r_ctrl_cpha = ((wdata & SPI_CTRL_CPHA) != 0); 158 r_ctrl_ass = ((wdata & SPI_CTRL_ASS_EN) != 0); 159 r_ctrl_ie = ((wdata & SPI_CTRL_IE_EN) != 0); 160 r_ctrl_go_bsy = ((wdata & SPI_CTRL_GO_BSY) != 0); 161 r_ctrl_char_len = (wdata & SPI_CTRL_CHAR_LEN_MASK); 162 #ifdef SOCLIB_MODULE_DEBUG 163 if ((wdata & SPI_CTRL_GO_BSY) != 0) { 164 std::cout << name() << " start xfer " << std::dec << (int)r_ctrl_char_len.read() << " data " << std::hex << r_txrx[1] << " " << r_txrx[0] << std::endl; 118 165 } 119 } 120 } else { // write121 if (not found) {122 r_target_fsm = T_WRITE_ERROR; 123 } else {124 switch(cell) {125 case SPI_DATA_TXRX0:126 case SPI_DATA_TXRX1:127 case SPI_DATA_TXRX2:128 case SPI_DATA_TXRX3:129 r_target_fsm = T_WRITE_TXRX; 130 r_txrx_addr = cell;131 break; 132 case SPI_CTRL:133 r_target_fsm = T_WRITE_CTRL;134 break;135 case SPI_DIVIDER:136 r_target_fsm = T_WRITE_DIVIDER;137 break;138 case SPI_SS:139 r_target_fsm = T_WRITE_SS;140 break;141 default:142 r_target_fsm = T_WRITE_ERROR;143 break;144 }145 }146 147 148 149 166 #endif 167 } else { 168 r_irq = r_irq & r_ctrl_go_bsy; 169 } 170 r_target_fsm = (p_vci_target.cmd.read() == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ; 171 break; 172 } 173 case SPI_DIVIDER: 174 r_rdata = r_divider.read(); 175 if (write) { 176 #ifdef SOCLIB_MODULE_DEBUG 177 std::cout << name() << " divider set to " << std::dec << wdata << std::endl; 178 #endif 179 r_divider = wdata; 180 } 181 r_target_fsm = (p_vci_target.cmd.read() == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ; 182 break; 183 case SPI_SS: 184 r_rdata = r_ss.read(); 185 if (write) { 186 r_ss = wdata; 187 } 188 r_target_fsm = (p_vci_target.cmd.read() == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ; 189 break; 190 default: 191 r_target_fsm = (p_vci_target.cmd.read() == vci_param::CMD_WRITE) ? T_ERROR_WRITE : T_ERROR_READ; 192 break; 193 } 194 } 195 } 196 break; 150 197 } 151 198 //////////////////// 152 case T_WRITE_TXRX: 153 { 199 case T_RSP_READ: 200 case T_RSP_WRITE: 201 case T_ERROR_READ: 202 case T_ERROR_WRITE: 154 203 if (p_vci_target.rspack.read() ) { 155 if (r_ctrl_go_bsy.read() == false) 156 { 157 switch(r_txrx_addr.read()) { 158 case 0: 159 r_txrx[0] = (r_txrx[0] & (uint64_t)0xffffffff00000000ULL) | 160 ((uint64_t)r_tdata.read() & (uint64_t)0x00000000ffffffffULL); 161 break; 162 case 1: 163 r_txrx[0] = (r_txrx[0] & (uint64_t)0x00000000ffffffffULL) | 164 ((uint64_t)r_tdata.read() << 32); 165 break; 166 case 2: 167 r_txrx[1] = (r_txrx[1] & (uint64_t)0xffffffff00000000ULL) | 168 ((uint64_t)r_tdata.read() & (uint64_t)0x00000000ffffffffULL); 169 break; 170 case 3: 171 r_txrx[1] = (r_txrx[1] & (uint64_t)0x00000000ffffffffULL) | 172 ((uint64_t)r_tdata.read() << 32); 173 break; 174 } 175 r_target_fsm = T_IDLE; 176 } 177 break; 178 } 179 //////////////////////// 180 case T_WRITE_CTRL: 181 { 182 if (p_vci_target.rspack.read() ) { 183 if (r_ctrl_go_bsy.read() == false) 184 { 185 r_ctrl_cpol = ((r_tdata.read() & SPI_CTRL_CPOL) != 0); 186 r_ctrl_cpha = ((r_tdata.read() & SPI_CTRL_CPHA) != 0); 187 r_ctrl_ass = ((r_tdata.read() & SPI_CTRL_ASS_EN) != 0); 188 r_ctrl_ie = ((r_tdata.read() & SPI_CTRL_IE_EN) != 0); 189 r_ctrl_go_bsy = ((r_tdata.read() & SPI_CTRL_GO_BSY) != 0); 190 r_ctrl_char_len = (r_tdata.read() & SPI_CTRL_CHAR_LEN_MASK); 191 #ifdef SOCLIB_MODULE_DEBUG 192 if ((r_tdata.read() & SPI_CTRL_GO_BSY) != 0) { 193 std::cout << name() << " start xfer " << std::dec << (int)r_ctrl_char_len.read() << " data " << std::hex << r_txrx[1] << " " << r_txrx[0] << std::endl; 194 } 195 #endif 196 } 197 r_target_fsm = T_IDLE; 198 } 199 break; 200 } 201 /////////////////// 202 case T_WRITE_DIVIDER: 203 { 204 if (p_vci_target.rspack.read() ) { 205 if (r_ctrl_go_bsy.read() == false) 206 { 207 r_divider = (uint32_t)r_tdata.read(); 208 #ifdef SOCLIB_MODULE_DEBUG 209 std::cout << name() << " divider set to " << std::dec << (uint32_t)r_tdata.read() << std::endl; 210 #endif 211 } 212 r_target_fsm = T_IDLE; 213 } 214 break; 215 } 216 ///////////////// 217 case T_WRITE_SS: 218 { 219 if (p_vci_target.rspack.read() ) { 220 if (r_ctrl_go_bsy.read() == false) 221 r_ss = (uint32_t)r_tdata.read(); 222 } 223 r_target_fsm = T_IDLE; 224 } 225 break; 226 } 227 /////////////////// 228 case T_READ_TXRX: 229 case T_READ_DIVIDER: 230 case T_READ_SS: 231 case T_WRITE_ERROR: 232 case T_READ_ERROR: 233 { 234 if ( p_vci_target.rspack.read() ) r_target_fsm = T_IDLE; 235 break; 236 } 237 /////////////////// 238 case T_READ_CTRL: 239 { 240 if ( p_vci_target.rspack.read() ) 241 { 242 r_target_fsm = T_IDLE; 243 r_irq = r_irq & r_ctrl_go_bsy; 244 } 245 break; 246 } 204 r_target_fsm = T_IDLE; 205 } 206 break; 247 207 } // end switch target fsm 248 208 … … 271 231 if (!r_spi_clk_ignore) { 272 232 if (r_spi_clk_previous == 0 && s_clk_sample == 1) { 273 274 275 276 233 // low to high transition: shift and sample 234 r_txrx[1] = (r_txrx[1] << 1) | (r_txrx[0] >> 63); 235 r_txrx[0] = (r_txrx[0] << 1) | p_spi_miso; 236 r_bit_count = r_bit_count - 1; 277 237 } else if (r_spi_clk_previous == 1 && s_clk_sample == 0) { 278 279 238 // high to low transition: change output, or stop 239 if (r_bit_count == 0) { 280 240 r_spi_fsm = S_IDLE; 281 241 r_irq = r_ctrl_ie; 282 242 r_ctrl_go_bsy = false; 283 #ifdef SOCLIB_MODULE_DEBUG 243 #ifdef SOCLIB_MODULE_DEBUG0 284 244 std::cout << name() << " end xfer " << std::dec << (int)r_ctrl_char_len.read() << " data " << std::hex << r_txrx[1] << " " << r_txrx[0] << std::endl; 285 245 #endif … … 290 250 } 291 251 r_spi_clk_previous = s_clk_sample; 292 252 // generate the SPI clock 293 253 if (r_clk_counter.read() == 0) { 294 254 r_clk_counter = r_divider.read(); … … 319 279 case M_IDLE: // check buffer alignment to compute the number of bursts 320 280 { 321 322 323 r_index= 0;324 325 326 327 328 329 330 331 332 333 elser_initiator_fsm = M_WRITE_BURST;334 335 281 if ( false ) // XXX 282 { 283 r_index = 0; 284 r_block_count = 0; 285 r_burst_count = 0; 286 r_words_count = 0; 287 288 // compute r_burst_offset (zero when buffer aligned) 289 r_burst_offset = (uint32_t)((r_buf_address.read()>>2) % m_words_per_burst); 290 291 // start tranfer 292 if ( r_read.read() ) r_initiator_fsm = M_READ_BLOCK; 293 else r_initiator_fsm = M_WRITE_BURST; 294 } 295 break; 336 296 } 337 297 ////////////////// 338 298 case M_READ_BLOCK: // read one block from disk after waiting m_latency cycles 339 299 { 340 341 342 343 300 r_burst_count = 0; 301 r_words_count = 0; 302 r_initiator_fsm = M_READ_BURST; 303 break; 344 304 } 345 305 ////////////////// 346 306 case M_READ_BURST: // Compute the number of words and the number of flits in the burst 347 348 349 { 350 351 352 353 if ( offset )// buffer not aligned354 355 356 357 358 359 else// buffer aligned360 361 362 363 364 365 366 307 // The number of flits can be smaller than the number of words 308 // in case of 8 bytes flits... 309 { 310 uint32_t nwords; 311 uint32_t offset = r_burst_offset.read(); 312 313 if ( offset ) // buffer not aligned 314 { 315 if ( r_burst_count.read() == 0 ) nwords = m_words_per_burst - offset; 316 else if ( r_burst_count.read() == m_bursts_per_block ) nwords = offset; 317 else nwords = m_words_per_burst; 318 } 319 else // buffer aligned 320 { 321 nwords = m_words_per_burst; 322 } 323 324 r_burst_nwords = nwords; 325 r_initiator_fsm = M_READ_CMD; 326 break; 367 327 } 368 328 //////////////// 369 329 case M_READ_CMD: // Send a multi-flits VCI WRITE command 370 330 { 371 372 373 374 375 376 377 378 379 380 381 382 else// not the last flit383 384 385 386 387 388 389 390 391 else// 2 words per flit392 393 394 395 396 397 398 else// not the last flit399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 331 if ( p_vci_initiator.cmdack.read() ) 332 { 333 uint32_t nwords = r_burst_nwords.read() - r_words_count.read(); 334 335 if ( vci_param::B == 4 ) // one word per flit 336 { 337 if ( nwords <= 1 ) // last flit 338 { 339 r_initiator_fsm = M_READ_RSP; 340 r_words_count = 0; 341 } 342 else // not the last flit 343 { 344 r_words_count = r_words_count.read() + 1; 345 } 346 347 // compute next word address and next local buffer index 348 r_buf_address = r_buf_address.read() + 4; 349 r_index = r_index.read() + 1; 350 } 351 else // 2 words per flit 352 { 353 if ( nwords <= 2 ) // last flit 354 { 355 r_initiator_fsm = M_READ_RSP; 356 r_words_count = 0; 357 } 358 else // not the last flit 359 { 360 r_words_count = r_words_count.read() + 2; 361 } 362 363 // compute next word address and next local buffer index 364 if ( nwords == 1 ) 365 { 366 r_buf_address = r_buf_address.read() + 4; 367 r_index = r_index.read() + 1; 368 } 369 else 370 { 371 r_buf_address = r_buf_address.read() + 8; 372 r_index = r_index.read() + 2; 373 } 374 } 375 } 376 break; 417 377 } 418 378 //////////////// 419 379 case M_READ_RSP: // Wait a single flit VCI WRITE response 420 380 { 421 422 423 424 425 426 427 381 if ( p_vci_initiator.rspval.read() ) 382 { 383 bool aligned = (r_burst_offset.read() == 0); 384 385 if ( (p_vci_initiator.rerror.read()&0x1) != 0 ) 386 { 387 r_initiator_fsm = M_READ_ERROR; 428 388 #ifdef SOCLIB_MODULE_DEBUG 429 389 std::cout << "vci_bd M_READ_ERROR" << std::endl; 430 390 #endif 431 432 433 434 435 436 437 391 } 392 else if ( (not aligned and (r_burst_count.read() == m_bursts_per_block)) or 393 (aligned and (r_burst_count.read() == (m_bursts_per_block-1))) ) 394 { 395 if ( r_block_count.read() == (r_nblocks.read()-1) ) // last burst of last block 396 { 397 r_initiator_fsm = M_READ_SUCCESS; 438 398 #ifdef SOCLIB_MODULE_DEBUG 439 399 std::cout << "vci_bd M_READ_SUCCESS" << std::endl; 440 400 #endif 441 442 else// last burst not last block443 444 r_index= 0;445 446 447 448 449 450 else// not the last burst451 452 453 454 455 456 401 } 402 else // last burst not last block 403 { 404 r_index = 0; 405 r_burst_count = 0; 406 r_block_count = r_block_count.read() + 1; 407 r_initiator_fsm = M_READ_BLOCK; 408 } 409 } 410 else // not the last burst 411 { 412 r_burst_count = r_burst_count.read() + 1; 413 r_initiator_fsm = M_READ_BURST; 414 } 415 } 416 break; 457 417 } 458 418 /////////////////// … … 460 420 case M_READ_ERROR: 461 421 { 462 463 422 if( !r_go ) r_initiator_fsm = M_IDLE; 423 break; 464 424 } 465 425 /////////////////// 466 426 case M_WRITE_BURST: // Compute the number of words in the burst 467 427 { 468 469 470 471 if ( offset )// buffer not aligned472 473 474 475 476 477 else// buffer aligned478 479 480 481 482 483 484 428 uint32_t nwords; 429 uint32_t offset = r_burst_offset.read(); 430 431 if ( offset ) // buffer not aligned 432 { 433 if ( r_burst_count.read() == 0 ) nwords = m_words_per_burst - offset; 434 else if ( r_burst_count.read() == m_bursts_per_block ) nwords = offset; 435 else nwords = m_words_per_burst; 436 } 437 else // buffer aligned 438 { 439 nwords = m_words_per_burst; 440 } 441 442 r_burst_nwords = nwords; 443 r_initiator_fsm = M_WRITE_CMD; 444 break; 485 445 } 486 446 ///////////////// … … 488 448 { 489 449 if ( p_vci_initiator.cmdack.read() ) r_initiator_fsm = M_WRITE_RSP; 490 450 break; 491 451 } 492 452 ///////////////// 493 453 case M_WRITE_RSP: // This is actually a multi-words VCI READ response 494 454 { 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 455 if ( p_vci_initiator.rspval.read() ) 456 { 457 bool aligned = (r_burst_offset.read() == 0); 458 459 if ( (vci_param::B == 8) and (r_burst_nwords.read() > 1) ) 460 { 461 r_local_buffer[r_index.read()] = (uint32_t)p_vci_initiator.rdata.read(); 462 r_local_buffer[r_index.read()+1] = (uint32_t)(p_vci_initiator.rdata.read()>>32); 463 r_index = r_index.read() + 2; 464 } 465 else 466 { 467 r_local_buffer[r_index.read()] = (uint32_t)p_vci_initiator.rdata.read(); 468 r_index = r_index.read() + 1; 469 } 470 471 if ( p_vci_initiator.reop.read() ) // last flit of the burst 472 { 473 r_words_count = 0; 474 r_buf_address = r_buf_address.read() + (r_burst_nwords.read()<<2); 475 476 if( (p_vci_initiator.rerror.read()&0x1) != 0 ) 477 { 478 r_initiator_fsm = M_WRITE_ERROR; 519 479 #ifdef SOCLIB_MODULE_DEBUG 520 480 std::cout << "vci_bd M_WRITE_ERROR" << std::endl; 521 481 #endif 522 523 524 525 526 527 528 else// not the last burst529 530 531 532 533 534 535 536 537 538 539 482 } 483 else if ( (not aligned and (r_burst_count.read() == m_bursts_per_block)) or 484 (aligned and (r_burst_count.read() == (m_bursts_per_block-1))) ) // last burst 485 { 486 r_initiator_fsm = M_WRITE_BLOCK; 487 } 488 else // not the last burst 489 { 490 r_burst_count = r_burst_count.read() + 1; 491 r_initiator_fsm = M_WRITE_BURST; 492 } 493 } 494 else 495 { 496 r_words_count = r_words_count.read() + 1; 497 } 498 } 499 break; 540 500 } 541 501 /////////////////// 542 502 case M_WRITE_BLOCK: // write a block to disk after waiting m_latency cycles 543 503 { 544 545 546 504 if ( r_block_count.read() == r_nblocks.read() - 1 ) 505 { 506 r_initiator_fsm = M_WRITE_SUCCESS; 547 507 #ifdef SOCLIB_MODULE_DEBUG 548 508 std::cout << "vci_bd M_WRITE_SUCCESS" << std::endl; 549 509 #endif 550 551 552 553 554 r_index= 0;555 556 557 558 510 } 511 else 512 { 513 r_burst_count = 0; 514 r_index = 0; 515 r_block_count = r_block_count.read() + 1; 516 r_initiator_fsm = M_WRITE_BURST; 517 } 518 break; 559 519 } 560 520 ///////////////////// … … 562 522 case M_WRITE_ERROR: 563 523 { 564 565 524 r_initiator_fsm = M_IDLE; 525 break; 566 526 } 567 527 } // end switch r_initiator_fsm … … 579 539 switch(r_target_fsm) { 580 540 case T_IDLE: 581 p_vci_target.cmdack = true; 582 p_vci_target.rspval = false; 583 p_vci_target.rdata = 0; 584 break; 585 case T_READ_TXRX: 586 p_vci_target.cmdack = false; 587 p_vci_target.rspval = true; 588 switch(r_txrx_addr.read()) { 589 case 0: 590 p_vci_target.rdata = r_txrx[0] & (uint64_t)0x00000000ffffffffULL; 591 break; 592 case 1: 593 p_vci_target.rdata = r_txrx[0] >> 32; 594 break; 595 case 2: 596 p_vci_target.rdata = r_txrx[1] & (uint64_t)0x00000000ffffffffULL; 597 break; 598 case 3: 599 p_vci_target.rdata = r_txrx[1] >> 32; 600 break; 601 } 602 p_vci_target.rerror = VCI_READ_OK; 603 break; 604 case T_READ_CTRL: 605 { 606 uint32_t data = 0; 607 if (r_ctrl_cpol.read()) 608 data |= SPI_CTRL_CPOL; 609 if (r_ctrl_cpha.read()) 610 data |= SPI_CTRL_CPHA; 611 if (r_ctrl_ass.read()) 612 data |= SPI_CTRL_ASS_EN; 613 if (r_ctrl_ie.read()) 614 data |= SPI_CTRL_IE_EN; 615 if (r_ctrl_go_bsy.read()) 616 data |= SPI_CTRL_GO_BSY; 617 data |= (uint32_t)r_ctrl_char_len.read(); 618 619 p_vci_target.cmdack = false; 620 p_vci_target.rspval = true; 621 p_vci_target.rdata = data; 622 p_vci_target.rerror = VCI_READ_OK; 623 break; 624 } 625 case T_READ_DIVIDER: 626 p_vci_target.cmdack = false; 627 p_vci_target.rspval = true; 628 p_vci_target.rdata = r_divider.read(); 629 p_vci_target.rerror = VCI_READ_OK; 630 break; 631 case T_READ_SS: 632 p_vci_target.cmdack = false; 633 p_vci_target.rspval = true; 634 p_vci_target.rdata = r_ss.read(); 635 p_vci_target.rerror = VCI_READ_OK; 636 break; 637 case T_READ_ERROR: 638 p_vci_target.cmdack = false; 639 p_vci_target.rspval = true; 640 p_vci_target.rdata = 0; 641 p_vci_target.rerror = VCI_READ_ERROR; 642 break; 643 case T_WRITE_ERROR: 644 p_vci_target.cmdack = false; 645 p_vci_target.rspval = true; 646 p_vci_target.rdata = 0; 647 p_vci_target.rerror = VCI_WRITE_ERROR; 648 break; 649 default: 650 p_vci_target.cmdack = false; 651 p_vci_target.rspval = true; 652 p_vci_target.rdata = 0; 653 p_vci_target.rerror = VCI_WRITE_OK; 654 break; 541 p_vci_target.cmdack = true; 542 p_vci_target.rspval = false; 543 p_vci_target.rdata = 0; 544 break; 545 case T_RSP_READ: 546 p_vci_target.cmdack = false; 547 p_vci_target.rspval = true; 548 p_vci_target.rdata = r_rdata; 549 p_vci_target.rerror = VCI_READ_OK; 550 break; 551 case T_RSP_WRITE: 552 p_vci_target.cmdack = false; 553 p_vci_target.rspval = true; 554 p_vci_target.rdata = 0; 555 p_vci_target.rerror = VCI_WRITE_OK; 556 break; 557 case T_ERROR_READ: 558 p_vci_target.cmdack = false; 559 p_vci_target.rspval = true; 560 p_vci_target.rdata = 0; 561 p_vci_target.rerror = VCI_READ_ERROR; 562 break; 563 case T_ERROR_WRITE: 564 p_vci_target.cmdack = false; 565 p_vci_target.rspval = true; 566 p_vci_target.rdata = 0; 567 p_vci_target.rerror = VCI_WRITE_ERROR; 568 break; 655 569 } // end switch target fsm 656 570 … … 666 580 switch (r_initiator_fsm) { 667 581 case M_WRITE_CMD: // It is actually a single flit VCI read command 668 669 670 671 672 673 674 675 676 677 582 p_vci_initiator.rspack = false; 583 p_vci_initiator.cmdval = true; 584 p_vci_initiator.address = (sc_dt::sc_uint<vci_param::N>)r_buf_address.read(); 585 p_vci_initiator.cmd = vci_param::CMD_READ; 586 p_vci_initiator.pktid = TYPE_READ_DATA_UNC; 587 p_vci_initiator.wdata = 0; 588 p_vci_initiator.be = 0; 589 p_vci_initiator.plen = (sc_dt::sc_uint<vci_param::K>)(r_burst_nwords.read()<<2); 590 p_vci_initiator.eop = true; 591 break; 678 592 case M_READ_CMD: // It is actually a multi-words VCI WRITE command 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 593 p_vci_initiator.rspack = false; 594 p_vci_initiator.cmdval = true; 595 p_vci_initiator.address = (sc_dt::sc_uint<vci_param::N>)r_buf_address.read(); 596 p_vci_initiator.cmd = vci_param::CMD_WRITE; 597 p_vci_initiator.pktid = TYPE_WRITE; 598 p_vci_initiator.plen = (sc_dt::sc_uint<vci_param::K>)(r_burst_nwords.read()<<2); 599 if ( (vci_param::B == 8) and ((r_burst_nwords.read() - r_words_count.read()) > 1) ) 600 { 601 p_vci_initiator.wdata = ((uint64_t)r_local_buffer[r_index.read() ]) + 602 (((uint64_t)r_local_buffer[r_index.read()+1]) << 32); 603 p_vci_initiator.be = 0xFF; 604 p_vci_initiator.eop = ( (r_burst_nwords.read() - r_words_count.read()) <= 2 ); 605 } 606 else 607 { 608 p_vci_initiator.wdata = r_local_buffer[r_index.read()]; 609 p_vci_initiator.be = 0xF; 610 p_vci_initiator.eop = ( r_words_count.read() == (r_burst_nwords.read() - 1) ); 611 } 612 break; 699 613 case M_READ_RSP: 700 614 case M_WRITE_RSP: 701 702 703 615 p_vci_initiator.rspack = true; 616 p_vci_initiator.cmdval = false; 617 break; 704 618 default: 705 706 707 619 p_vci_initiator.rspack = false; 620 p_vci_initiator.cmdval = false; 621 break; 708 622 } 709 623 … … 726 640 727 641 ////////////////////////////////////////////////////////////////////////////// 728 tmpl(/**/)::VciSpi( sc_core::sc_module_name 729 730 const soclib::common::IntTab&srcid,731 const soclib::common::IntTab&tgtid,732 const uint32_tburst_size)642 tmpl(/**/)::VciSpi( sc_core::sc_module_name name, 643 const soclib::common::MappingTable &mt, 644 const soclib::common::IntTab &srcid, 645 const soclib::common::IntTab &tgtid, 646 const uint32_t burst_size) 733 647 734 648 : caba::BaseModule(name), … … 762 676 for ( seg = m_seglist.begin() ; seg != m_seglist.end() ; seg++ ) 763 677 { 764 765 678 nbsegs++; 679 766 680 if ( (seg->baseAddress() & 0x0000003F) != 0 ) 767 681 { 768 682 std::cout << "Error in component VciSpi : " << name 769 770 683 << "The base address of segment " << seg->name() 684 << " must be multiple of 64 bytes" << std::endl; 771 685 exit(1); 772 686 } … … 774 688 { 775 689 std::cout << "Error in component VciSpi : " << name 776 777 690 << "The size of segment " << seg->name() 691 << " cannot be smaller than 64 bytes" << std::endl; 778 692 exit(1); 779 693 } 780 781 782 694 std::cout << " => segment " << seg->name() 695 << " / base = " << std::hex << seg->baseAddress() 696 << " / size = " << seg->size() << std::endl; 783 697 } 784 698 … … 786 700 { 787 701 std::cout << "Error in component VciSpi : " << name 788 702 << " No segment allocated" << std::endl; 789 703 exit(1); 790 704 } … … 796 710 { 797 711 std::cout << "Error in component VciSpi : " << name 798 712 << " The burst size must be 8, 16, 32 or 64 bytes" << std::endl; 799 713 exit(1); 800 714 } … … 802 716 if ( (vci_param::B != 4) and (vci_param::B != 8) ) 803 717 { 804 std::cout << "Error in component VciSpi : " << name 805 718 std::cout << "Error in component VciSpi : " << name 719 << " The VCI data fields must have 32 bits or 64 bits" << std::endl; 806 720 exit(1); 807 721 } … … 839 753 }; 840 754 const char* target_str[] = 841 {755 { 842 756 "T_IDLE", 843 "T_WRITE_TXRX", 844 "T_READ_TXRX", 845 "T_WRITE_CTRL", 846 "T_READ_CTRL", 847 "T_WRITE_DIVIDER", 848 "T_READ_DIVIDER", 849 "T_WRITE_SS", 850 "T_READ_SS", 851 "T_WRITE_ERROR", 852 "T_READ_ERROR", 757 "T_RSP_READ", 758 "T_RSP_WRITE", 759 "T_ERROR_READ", 760 "T_ERROR_WRITE", 853 761 }; 854 762 const char* spi_str[] = 855 {763 { 856 764 "S_IDLE", 857 765 "S_XMIT", … … 872 780 << std::endl; 873 781 std::cout << name() << " _INI : " << initiator_str[r_initiator_fsm.read()] 874 782 << " buf = " << std::hex << r_buf_address.read() 875 783 << " block = " << std::dec << r_block_count.read() 876 784 << " burst = " << r_burst_count.read()
Note: See TracChangeset
for help on using the changeset viewer.