Changeset 400 for trunk/modules/vci_block_device_tsar
- Timestamp:
- Jun 3, 2013, 10:25:33 AM (11 years ago)
- Location:
- trunk/modules/vci_block_device_tsar/caba/source
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/modules/vci_block_device_tsar/caba/source/include/vci_block_device_tsar.h
r392 r400 30 30 ////////////////////////////////////////////////////////////////////////////////////// 31 31 // This component is a simplified disk controller with a VCI interface. 32 // It supports only 32 or 64 bits VCI DATA width, but all addressable registers 33 // contain 32 bits words. It supports VCI addresss lartger than 32 bits. 34 // 32 35 // This component can perform data transfers between one single file belonging 33 36 // to the host system and a buffer in the memory of the virtual prototype. … … 36 39 // The block size (bytes), and the burst size (bytes) must be power of 2. 37 40 // The burst size is typically a cache line. 38 // If the memory buffer is not constrained to be aligned on a burst boundary. 41 // The memory buffer is not constrained to be aligned on a burst boundary, 42 // but must be aligned on a 32 bits word boundary. 39 43 // Both read and write transfers are supported. An IRQ is optionally 40 44 // asserted when the transfer is completed. 41 45 // 42 // As a target this block device controler contains 9 memory mapped registers,46 // As a target this block device controler contains 9 32 bits memory mapped registers, 43 47 // taking 36 bytes in the address space. 44 // - BLOCK_DEVICE_BUFFER 0x00 (read/write) Memory buffer base address (32LSB bits)45 // - BLOCK_DEVICE_COUNT 0x04 (read/write) 46 // - BLOCK_DEVICE_LBA 0x08 (read/write) 47 // - BLOCK_DEVICE_OP 0x0C (write-only) 48 // - BLOCK_DEVICE_STATUS 0x10 (read-only) 49 // - BLOCK_DEVICE_IRQ_ENABLE 0x14 (read/write) 50 // - BLOCK_DEVICE_SIZE 0x18 (read-only) 51 // - BLOCK_DEVICE_BLOCK_SIZE 0x1C (read_only) 52 // - BLOCK_DEVICE_BUFFER_EXT 0x20 (read_only) Memory buffer base address (32MSB bits)48 // - BLOCK_DEVICE_BUFFER 0x00 (read/write) Memory buffer base address (LSB bits) 49 // - BLOCK_DEVICE_COUNT 0x04 (read/write) Number of blocks to be transfered. 50 // - BLOCK_DEVICE_LBA 0x08 (read/write) Index of first block in the file. 51 // - BLOCK_DEVICE_OP 0x0C (write-only) Writing here starts the operation. 52 // - BLOCK_DEVICE_STATUS 0x10 (read-only) Block Device status. 53 // - BLOCK_DEVICE_IRQ_ENABLE 0x14 (read/write) IRQ enabled if non zero. 54 // - BLOCK_DEVICE_SIZE 0x18 (read-only) Number of addressable blocks. 55 // - BLOCK_DEVICE_BLOCK_SIZE 0x1C (read_only) Block size in bytes. 56 // - BLOCK_DEVICE_BUFFER_EXT 0x20 (read_only) Memory buffer base address (MSB bits) 53 57 // 54 58 // The following operations codes are supported: … … 104 108 sc_signal<uint32_t> r_lba; // first block index 105 109 sc_signal<bool> r_read; // requested operation 106 sc_signal<uint32_t> r_index; // flitindex in local buffer110 sc_signal<uint32_t> r_index; // word index in local buffer 107 111 sc_signal<uint32_t> r_latency_count; // latency counter 108 sc_signal<uint32_t> r_ flit_count; // flitcounter (in a burst)112 sc_signal<uint32_t> r_words_count; // word counter (in a burst) 109 113 sc_signal<uint32_t> r_burst_count; // burst counter (in a block) 110 114 sc_signal<uint32_t> r_block_count; // block counter (in a transfer) 111 sc_signal<uint32_t> r_burst_offset; // number of non aligned flits112 sc_signal<uint32_t> r_burst_n flits; // number of flits in a burst115 sc_signal<uint32_t> r_burst_offset; // number of non aligned words 116 sc_signal<uint32_t> r_burst_nwords; // number of words in a burst 113 117 sc_signal<bool> r_go; // command from T_FSM to M_FSM 114 118 … … 124 128 int m_fd; // File descriptor 125 129 uint64_t m_device_size; // Total number of blocks 126 const uint32_t m_ flits_per_block; // number of flits in a block127 const uint32_t m_ flits_per_burst; // number of flits in a burst130 const uint32_t m_words_per_block; // number of words in a block 131 const uint32_t m_words_per_burst; // number of words in a burst 128 132 const uint32_t m_bursts_per_block; // number of bursts in a block 129 133 const uint32_t m_latency; // device latency -
trunk/modules/vci_block_device_tsar/caba/source/src/vci_block_device_tsar.cpp
r392 r400 199 199 // Each block is split in bursts, and the number of bursts depends 200 200 // on the memory buffer alignment on a burst boundary: 201 // - If buffer aligned, all burst have the same length (m_ flits_per burst)201 // - If buffer aligned, all burst have the same length (m_words_per burst) 202 202 // and the number of bursts is (m_bursts_per_block). 203 203 // - If buffer not aligned, the number of bursts is (m_bursts_per_block + 1) 204 // and first and last burst are shorter, because all flits in a burst204 // and first and last burst are shorter, because all words in a burst 205 205 // must be contained in a single cache line. 206 // first burst => n flits = m_flits_per_burst - offset207 // last burst => n flits = offset208 // other burst => n flits = m_flits_per_burst206 // first burst => nwords = m_words_per_burst - offset 207 // last burst => nwords = offset 208 // other burst => nwords = m_words_per_burst 209 209 ////////////////////////////////////////////////////////////////////////////// 210 210 … … 218 218 r_block_count = 0; 219 219 r_burst_count = 0; 220 r_ flit_count = 0;220 r_words_count = 0; 221 221 r_latency_count = m_latency; 222 222 223 223 // compute r_burst_offset (zero when buffer aligned) 224 r_burst_offset = (uint32_t)((r_buf_address.read()>>2) % m_ flits_per_burst);224 r_burst_offset = (uint32_t)((r_buf_address.read()>>2) % m_words_per_burst); 225 225 226 226 // start tranfer … … 236 236 { 237 237 r_latency_count = m_latency; 238 ::lseek(m_fd, (r_lba + r_block_count)*m_ flits_per_block*4, SEEK_SET);239 if( ::read(m_fd, r_local_buffer, m_ flits_per_block*4) < 0 )238 ::lseek(m_fd, (r_lba + r_block_count)*m_words_per_block*4, SEEK_SET); 239 if( ::read(m_fd, r_local_buffer, m_words_per_block*4) < 0 ) 240 240 { 241 241 r_initiator_fsm = M_READ_ERROR; … … 244 244 { 245 245 r_burst_count = 0; 246 r_ flit_count = 0;246 r_words_count = 0; 247 247 r_initiator_fsm = M_READ_BURST; 248 248 } … … 255 255 } 256 256 ////////////////// 257 case M_READ_BURST: // Compute the number of flits in the burst 258 { 257 case M_READ_BURST: // Compute the number of words and the number of flits in the burst 258 // The number of flits can be smaller than the number of words 259 // in case of 8 bytes flits... 260 { 261 uint32_t nwords; 259 262 uint32_t offset = r_burst_offset.read(); 260 263 261 264 if ( offset ) // buffer not aligned 262 265 { 263 if ( r_burst_count.read() == 0 ) r_burst_nflits = m_flits_per_burst - offset;264 else if ( r_burst_count.read() == m_bursts_per_block ) r_burst_nflits = offset;265 else r_burst_nflits = m_flits_per_burst;266 if ( r_burst_count.read() == 0 ) nwords = m_words_per_burst - offset; 267 else if ( r_burst_count.read() == m_bursts_per_block ) nwords = offset; 268 else nwords = m_words_per_burst; 266 269 } 267 270 else // buffer aligned 268 271 { 269 r_burst_nflits = m_flits_per_burst; 270 } 271 r_initiator_fsm = M_READ_CMD; 272 nwords = m_words_per_burst; 273 } 274 275 r_burst_nwords = nwords; 276 r_initiator_fsm = M_READ_CMD; 272 277 break; 273 278 } … … 277 282 if ( p_vci_initiator.cmdack.read() ) 278 283 { 279 if ( r_flit_count == (r_burst_nflits.read() - 1) ) // last flit in a burst 280 { 281 r_initiator_fsm = M_READ_RSP; 282 r_flit_count = 0; 283 } 284 else // not the last flit 285 { 286 r_flit_count = r_flit_count.read() + 1; 287 } 288 289 // compute next flit address and next local buffer index 290 r_buf_address = r_buf_address.read() + 4; 291 r_index = r_index.read() + 1; 284 uint32_t nwords = r_burst_nwords.read() - r_words_count.read(); 285 286 if ( vci_param::B == 4 ) // one word per flit 287 { 288 if ( nwords <= 1 ) // last flit 289 { 290 r_initiator_fsm = M_READ_RSP; 291 r_words_count = 0; 292 } 293 else // not the last flit 294 { 295 r_words_count = r_words_count.read() + 1; 296 } 297 298 // compute next word address and next local buffer index 299 r_buf_address = r_buf_address.read() + 4; 300 r_index = r_index.read() + 1; 301 } 302 else // 2 words per flit 303 { 304 if ( nwords <= 2 ) // last flit 305 { 306 r_initiator_fsm = M_READ_RSP; 307 r_words_count = 0; 308 } 309 else // not the last flit 310 { 311 r_words_count = r_words_count.read() + 2; 312 } 313 314 // compute next word address and next local buffer index 315 if ( nwords == 1 ) 316 { 317 r_buf_address = r_buf_address.read() + 4; 318 r_index = r_index.read() + 1; 319 } 320 else 321 { 322 r_buf_address = r_buf_address.read() + 8; 323 r_index = r_index.read() + 2; 324 } 325 } 292 326 } 293 327 break; … … 335 369 } 336 370 /////////////////// 337 case M_WRITE_BURST: // Compute the number of flits in the burst 338 { 371 case M_WRITE_BURST: // Compute the number of words in the burst 372 { 373 uint32_t nwords; 339 374 uint32_t offset = r_burst_offset.read(); 340 375 341 376 if ( offset ) // buffer not aligned 342 377 { 343 if ( r_burst_count.read() == 0 ) r_burst_nflits = m_flits_per_burst - offset;344 else if ( r_burst_count.read() == m_bursts_per_block ) r_burst_nflits = offset;345 else r_burst_nflits = m_flits_per_burst;378 if ( r_burst_count.read() == 0 ) nwords = m_words_per_burst - offset; 379 else if ( r_burst_count.read() == m_bursts_per_block ) nwords = offset; 380 else nwords = m_words_per_burst; 346 381 } 347 382 else // buffer aligned 348 383 { 349 r_burst_nflits = m_flits_per_burst; 350 } 384 nwords = m_words_per_burst; 385 } 386 387 r_burst_nwords = nwords; 351 388 r_initiator_fsm = M_WRITE_CMD; 352 389 break; … … 359 396 } 360 397 ///////////////// 361 case M_WRITE_RSP: // This is actually a multi-flits VCI READ response 362 { 363 bool aligned = (r_burst_offset.read() == 0); 364 398 case M_WRITE_RSP: // This is actually a multi-words VCI READ response 399 { 365 400 if ( p_vci_initiator.rspval.read() ) 366 401 { 367 r_local_buffer[r_index.read()] = (uint32_t)p_vci_initiator.rdata.read(); 368 r_index = r_index.read() + 1; 402 bool aligned = (r_burst_offset.read() == 0); 403 404 if ( (vci_param::B == 8) and (r_burst_nwords.read() > 1) ) 405 { 406 r_local_buffer[r_index.read()] = (uint32_t)p_vci_initiator.rdata.read(); 407 r_local_buffer[r_index.read()+1] = (uint32_t)(p_vci_initiator.rdata.read()>>32); 408 r_index = r_index.read() + 2; 409 } 410 else 411 { 412 r_local_buffer[r_index.read()] = (uint32_t)p_vci_initiator.rdata.read(); 413 r_index = r_index.read() + 1; 414 } 369 415 370 416 if ( p_vci_initiator.reop.read() ) // last flit of the burst 371 417 { 372 r_ flit_count = 0;373 r_buf_address = r_buf_address.read() + (r_burst_n flits.read()<<2);418 r_words_count = 0; 419 r_buf_address = r_buf_address.read() + (r_burst_nwords.read()<<2); 374 420 375 421 if( (p_vci_initiator.rerror.read()&0x1) != 0 ) … … 378 424 } 379 425 else if ( (not aligned and (r_burst_count.read() == m_bursts_per_block)) or 380 426 (aligned and (r_burst_count.read() == (m_bursts_per_block-1))) ) // last burst 381 427 { 382 428 r_initiator_fsm = M_WRITE_BLOCK; … … 390 436 else 391 437 { 392 r_ flit_count = r_flit_count.read() + 1;438 r_words_count = r_words_count.read() + 1; 393 439 } 394 440 } … … 401 447 { 402 448 r_latency_count = m_latency; 403 ::lseek(m_fd, (r_lba + r_block_count)*m_ flits_per_block*vci_param::B, SEEK_SET);404 if( ::write(m_fd, r_local_buffer, m_ flits_per_block*vci_param::B) < 0 )449 ::lseek(m_fd, (r_lba + r_block_count)*m_words_per_block*vci_param::B, SEEK_SET); 450 if( ::write(m_fd, r_local_buffer, m_words_per_block*vci_param::B) < 0 ) 405 451 { 406 452 r_initiator_fsm = M_WRITE_ERROR; … … 413 459 { 414 460 r_burst_count = 0; 415 461 r_index = 0; 416 462 r_block_count = r_block_count.read() + 1; 417 r_initiator_fsm = M_WRITE_BURST;463 r_initiator_fsm = M_WRITE_BURST; 418 464 } 419 465 } … … 474 520 p_vci_target.cmdack = false; 475 521 p_vci_target.rspval = true; 476 p_vci_target.rdata = (uint32_t)r_nblocks.read();522 p_vci_target.rdata = r_nblocks.read(); 477 523 p_vci_target.rerror = VCI_READ_OK; 478 524 break; … … 480 526 p_vci_target.cmdack = false; 481 527 p_vci_target.rspval = true; 482 p_vci_target.rdata = (uint32_t)r_lba.read();528 p_vci_target.rdata = r_lba.read(); 483 529 p_vci_target.rerror = VCI_READ_OK; 484 530 break; … … 486 532 p_vci_target.cmdack = false; 487 533 p_vci_target.rspval = true; 488 p_vci_target.rdata = (uint32_t)r_irq_enable.read();534 p_vci_target.rdata = r_irq_enable.read(); 489 535 p_vci_target.rerror = VCI_READ_OK; 490 536 break; … … 492 538 p_vci_target.cmdack = false; 493 539 p_vci_target.rspval = true; 494 p_vci_target.rdata = (uint32_t)m_device_size;540 p_vci_target.rdata = m_device_size; 495 541 p_vci_target.rerror = VCI_READ_OK; 496 542 break; … … 498 544 p_vci_target.cmdack = false; 499 545 p_vci_target.rspval = true; 500 p_vci_target.rdata = (uint32_t)m_flits_per_block*vci_param::B;546 p_vci_target.rdata = m_words_per_block*vci_param::B; 501 547 p_vci_target.rerror = VCI_READ_OK; 502 548 break; … … 504 550 p_vci_target.cmdack = false; 505 551 p_vci_target.rspval = true; 506 p_vci_target.rdata = 0;552 p_vci_target.rdata = 0; 507 553 p_vci_target.rerror = VCI_READ_ERROR; 508 554 break; … … 510 556 p_vci_target.cmdack = false; 511 557 p_vci_target.rspval = true; 512 p_vci_target.rdata = 0;558 p_vci_target.rdata = 0; 513 559 p_vci_target.rerror = VCI_WRITE_ERROR; 514 560 break; … … 516 562 p_vci_target.cmdack = false; 517 563 p_vci_target.rspval = true; 518 p_vci_target.rdata = 0;564 p_vci_target.rdata = 0; 519 565 p_vci_target.rerror = VCI_WRITE_OK; 520 566 break; … … 531 577 532 578 switch (r_initiator_fsm) { 533 case M_WRITE_CMD: // It is actually a single flitVCI read command579 case M_WRITE_CMD: // It is actually a single word VCI read command 534 580 p_vci_initiator.rspack = false; 535 581 p_vci_initiator.cmdval = true; … … 539 585 p_vci_initiator.wdata = 0; 540 586 p_vci_initiator.be = (uint32_t)0xF; 541 p_vci_initiator.plen = (sc_dt::sc_uint<vci_param::K>)(r_burst_n flits.read()<<2);587 p_vci_initiator.plen = (sc_dt::sc_uint<vci_param::K>)(r_burst_nwords.read()<<2); 542 588 p_vci_initiator.eop = true; 543 589 break; 544 case M_READ_CMD: // It is actually a multi- flits VCI WRITE command590 case M_READ_CMD: // It is actually a multi-words VCI WRITE command 545 591 p_vci_initiator.rspack = false; 546 592 p_vci_initiator.cmdval = true; … … 548 594 p_vci_initiator.cmd = vci_param::CMD_WRITE; 549 595 p_vci_initiator.pktid = TYPE_WRITE; 550 p_vci_initiator.wdata = (uint32_t)r_local_buffer[r_index.read()];551 596 p_vci_initiator.be = 0xF; 552 p_vci_initiator.plen = (sc_dt::sc_uint<vci_param::K>)(r_burst_nflits.read()<<2); 553 p_vci_initiator.eop = ( r_flit_count.read() == (r_burst_nflits.read() - 1) ); 597 p_vci_initiator.plen = (sc_dt::sc_uint<vci_param::K>)(r_burst_nwords.read()<<2); 598 p_vci_initiator.eop = ( r_words_count.read() == (r_burst_nwords.read() - 1) ); 599 if (vci_param::B == 4) p_vci_initiator.wdata = r_local_buffer[r_index.read()]; 600 else p_vci_initiator.wdata = (uint64_t)r_local_buffer[r_index.read()] + 601 ((uint64_t)r_local_buffer[r_index.read()+1])<<32; 554 602 break; 555 603 case M_READ_RSP: … … 574 622 ////////////////////////////////////////////////////////////////////////////// 575 623 tmpl(/**/)::VciBlockDeviceTsar( sc_core::sc_module_name name, 576 577 578 579 580 581 582 624 const soclib::common::MappingTable &mt, 625 const soclib::common::IntTab &srcid, 626 const soclib::common::IntTab &tgtid, 627 const std::string &filename, 628 const uint32_t block_size, 629 const uint32_t burst_size, 630 const uint32_t latency) 583 631 584 632 : caba::BaseModule(name), 585 633 m_segment(mt.getSegment(tgtid)), 586 634 m_srcid(mt.indexForId(srcid)), 587 m_ flits_per_block(block_size/vci_param::B),588 m_ flits_per_burst(burst_size/vci_param::B),635 m_words_per_block(block_size/4), 636 m_words_per_burst(burst_size/4), 589 637 m_bursts_per_block(block_size/burst_size), 590 638 m_latency(latency), … … 603 651 sensitive << p_clk.neg(); 604 652 605 if( (block_size != 64 ) && 606 (block_size != 128) && 653 if( (block_size != 128) && 607 654 (block_size != 256) && 608 655 (block_size != 512) && … … 615 662 exit(1); 616 663 } 617 if( (burst_size != 1 ) && 618 (burst_size != 2 ) && 619 (burst_size != 4 ) && 664 if( (burst_size != 4 ) && 620 665 (burst_size != 8 ) && 621 666 (burst_size != 16) && … … 624 669 { 625 670 std::cout << "Error in component VciBlockDeviceTsar : " << name << std::endl; 626 std::cout << "The burst size must be 1, 2,4, 8, 16, 32 or 64 bytes" << std::endl;671 std::cout << "The burst size must be 4, 8, 16, 32 or 64 bytes" << std::endl; 627 672 exit(1); 628 673 } 629 if ( m_segment.size() < 32)674 if ( m_segment.size() < 64 ) 630 675 { 631 676 std::cout << "Error in component VciBlockDeviceTsar : " << name << std::endl; 632 std::cout << "The size of the segment cannot be smaller than 32bytes" << std::endl;677 std::cout << "The size of the segment cannot be smaller than 64 bytes" << std::endl; 633 678 exit(1); 634 679 } 635 if ( (m_segment.baseAddress() & 0x000000 1F) != 0 )680 if ( (m_segment.baseAddress() & 0x0000003F) != 0 ) 636 681 { 637 682 std::cout << "Error in component VciBlockDeviceTsar : " << name << std::endl; 638 std::cout << "The base address of the segment must be multiple of 32bytes" << std::endl;683 std::cout << "The base address of the segment must be multiple of 64 bytes" << std::endl; 639 684 exit(1); 640 685 } 641 if ( vci_param::B != 4)686 if ( (vci_param::B != 4) and (vci_param::B != 8) ) 642 687 { 643 688 std::cout << "Error in component VciBlockDeviceTsar : " << name << std::endl; 644 std::cout << "The VCI data fields must have 32 bits " << std::endl;689 std::cout << "The VCI data fields must have 32 bits or 64 bits" << std::endl; 645 690 exit(1); 646 691 } … … 661 706 } 662 707 663 r_local_buffer = new uint32_t[m_ flits_per_block];708 r_local_buffer = new uint32_t[m_words_per_block]; 664 709 665 710 } // end constructor … … 711 756 << " block = " << std::dec << r_block_count.read() 712 757 << " burst = " << r_burst_count.read() 713 << " flit = " << r_flit_count.read() <<std::endl;758 << " word = " << r_words_count.read() <<std::endl; 714 759 } 715 760
Note: See TracChangeset
for help on using the changeset viewer.