Changeset 400 for trunk/modules


Ignore:
Timestamp:
Jun 3, 2013, 10:25:33 AM (12 years ago)
Author:
alain
Message:

Introducing support for VCI DATA 64 bits.

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  
    3030//////////////////////////////////////////////////////////////////////////////////////
    3131// 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//
    3235// This component can perform data transfers between one single file belonging
    3336// to the host system and a buffer in the memory of the virtual prototype.
     
    3639// The block size (bytes), and the burst size (bytes) must be power of 2.
    3740// 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.
    3943// Both read and write transfers are supported. An IRQ is optionally
    4044// asserted when the transfer is completed.
    4145//
    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,
    4347// taking 36 bytes in the address space.
    44 // - BLOCK_DEVICE_BUFFER        0x00 (read/write)    Memory buffer base address (32 LSB bits)
    45 // - BLOCK_DEVICE_COUNT         0x04 (read/write)    Number of blocks to be transfered.
    46 // - BLOCK_DEVICE_LBA           0x08 (read/write)    Index of first block in the file.
    47 // - BLOCK_DEVICE_OP            0x0C (write-only)    Writing here starts the operation.
    48 // - BLOCK_DEVICE_STATUS        0x10 (read-only)     Block Device status.
    49 // - BLOCK_DEVICE_IRQ_ENABLE    0x14 (read/write)    IRQ enabled if non zero.
    50 // - BLOCK_DEVICE_SIZE          0x18 (read-only)     Number of addressable blocks.
    51 // - BLOCK_DEVICE_BLOCK_SIZE    0x1C (read_only)     Block size in bytes.
    52 // - BLOCK_DEVICE_BUFFER_EXT    0x20 (read_only)     Memory buffer base address (32 MSB 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)
    5357//
    5458// The following operations codes are supported:
     
    104108    sc_signal<uint32_t>               r_lba;              // first block index
    105109    sc_signal<bool>                   r_read;             // requested operation
    106     sc_signal<uint32_t>               r_index;            // flit index in local buffer
     110    sc_signal<uint32_t>               r_index;            // word index in local buffer
    107111    sc_signal<uint32_t>               r_latency_count;    // latency counter
    108     sc_signal<uint32_t>               r_flit_count;       // flit counter (in a burst)
     112    sc_signal<uint32_t>               r_words_count;      // word counter (in a burst)
    109113    sc_signal<uint32_t>               r_burst_count;      // burst counter (in a block)
    110114    sc_signal<uint32_t>               r_block_count;      // block counter (in a transfer)
    111     sc_signal<uint32_t>               r_burst_offset;     // number of non aligned flits
    112     sc_signal<uint32_t>               r_burst_nflits;     // number of flits in a burst
     115    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
    113117    sc_signal<bool>                   r_go;               // command from T_FSM to M_FSM
    114118
     
    124128    int                               m_fd;               // File descriptor
    125129    uint64_t                          m_device_size;      // Total number of blocks
    126     const uint32_t                    m_flits_per_block;  // number of flits in a block
    127     const uint32_t                    m_flits_per_burst;  // number of flits in a burst
     130    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
    128132    const uint32_t                    m_bursts_per_block; // number of bursts in a block
    129133    const uint32_t                    m_latency;          // device latency
  • trunk/modules/vci_block_device_tsar/caba/source/src/vci_block_device_tsar.cpp

    r392 r400  
    199199    // Each block is split in bursts, and the number of bursts depends
    200200    // 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)
    202202    //   and the number of bursts is (m_bursts_per_block).
    203203    // - 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 burst
     204    //   and first and last burst are shorter, because all words in a burst
    205205    //   must be contained in a single cache line.
    206     //   first burst => nflits = m_flits_per_burst - offset
    207     //   last  burst => nflits = offset
    208     //   other burst => nflits = m_flits_per_burst
     206    //   first burst => nwords = m_words_per_burst - offset
     207    //   last  burst => nwords = offset
     208    //   other burst => nwords = m_words_per_burst
    209209    //////////////////////////////////////////////////////////////////////////////
    210210
     
    218218            r_block_count   = 0;
    219219            r_burst_count   = 0;
    220             r_flit_count    = 0;
     220            r_words_count    = 0;
    221221            r_latency_count = m_latency;
    222222
    223223            // 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);
    225225
    226226            // start tranfer
     
    236236        {
    237237            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 ) 
    240240            {
    241241                r_initiator_fsm = M_READ_ERROR;
     
    244244            {
    245245                r_burst_count   = 0;
    246                 r_flit_count    = 0;
     246                r_words_count    = 0;
    247247                r_initiator_fsm = M_READ_BURST;
    248248            }
     
    255255    }
    256256    //////////////////
    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;
    259262        uint32_t offset = r_burst_offset.read();
    260263
    261264        if ( offset )                  // buffer not aligned
    262265        {
    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;
    266269        }
    267270        else                           // buffer aligned
    268271        {
    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;
    272277        break;
    273278    }
     
    277282        if ( p_vci_initiator.cmdack.read() )
    278283        {
    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            }
    292326        }
    293327        break;
     
    335369    }
    336370    ///////////////////
    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;
    339374        uint32_t offset = r_burst_offset.read();
    340375
    341376        if ( offset )                  // buffer not aligned
    342377        {
    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;
    346381        }
    347382        else                           // buffer aligned
    348383        {
    349             r_burst_nflits = m_flits_per_burst;
    350         }
     384            nwords = m_words_per_burst;
     385        }
     386
     387        r_burst_nwords  = nwords;
    351388        r_initiator_fsm =  M_WRITE_CMD;
    352389        break;
     
    359396    }
    360397    /////////////////
    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    {
    365400        if ( p_vci_initiator.rspval.read() )
    366401        {
    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            }
    369415
    370416            if ( p_vci_initiator.reop.read() )  // last flit of the burst
    371417            {
    372                     r_flit_count  = 0;
    373                 r_buf_address = r_buf_address.read() + (r_burst_nflits.read()<<2);
     418                    r_words_count  = 0;
     419                r_buf_address = r_buf_address.read() + (r_burst_nwords.read()<<2);
    374420
    375421                    if( (p_vci_initiator.rerror.read()&0x1) != 0 )
     
    378424                }
    379425                else if ( (not aligned and (r_burst_count.read() == m_bursts_per_block)) or
    380                           (aligned and (r_burst_count.read() == (m_bursts_per_block-1))) ) // last burst
     426                     (aligned and (r_burst_count.read() == (m_bursts_per_block-1))) ) // last burst
    381427                {
    382428                    r_initiator_fsm  = M_WRITE_BLOCK;
     
    390436            else
    391437            {
    392                     r_flit_count = r_flit_count.read() + 1;
     438                    r_words_count = r_words_count.read() + 1;
    393439            }
    394440        }
     
    401447        {
    402448            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 )
    405451            {
    406452                r_initiator_fsm = M_WRITE_ERROR;
     
    413459            {
    414460                r_burst_count    = 0;
    415                 r_index          = 0;
     461                r_index          = 0;
    416462                r_block_count    = r_block_count.read() + 1;
    417                 r_initiator_fsm = M_WRITE_BURST;
     463                r_initiator_fsm  = M_WRITE_BURST;
    418464            }
    419465        }
     
    474520        p_vci_target.cmdack = false;
    475521        p_vci_target.rspval = true;
    476         p_vci_target.rdata = (uint32_t)r_nblocks.read();
     522        p_vci_target.rdata  = r_nblocks.read();
    477523        p_vci_target.rerror = VCI_READ_OK;
    478524        break;
     
    480526        p_vci_target.cmdack = false;
    481527        p_vci_target.rspval = true;
    482         p_vci_target.rdata = (uint32_t)r_lba.read();
     528        p_vci_target.rdata  = r_lba.read();
    483529        p_vci_target.rerror = VCI_READ_OK;
    484530        break;
     
    486532        p_vci_target.cmdack = false;
    487533        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();
    489535        p_vci_target.rerror = VCI_READ_OK;
    490536        break;
     
    492538        p_vci_target.cmdack = false;
    493539        p_vci_target.rspval = true;
    494         p_vci_target.rdata = (uint32_t)m_device_size;
     540        p_vci_target.rdata  = m_device_size;
    495541        p_vci_target.rerror = VCI_READ_OK;
    496542        break;
     
    498544        p_vci_target.cmdack = false;
    499545        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;
    501547        p_vci_target.rerror = VCI_READ_OK;
    502548        break;
     
    504550        p_vci_target.cmdack = false;
    505551        p_vci_target.rspval = true;
    506         p_vci_target.rdata = 0;
     552        p_vci_target.rdata  = 0;
    507553        p_vci_target.rerror = VCI_READ_ERROR;
    508554        break;
     
    510556        p_vci_target.cmdack = false;
    511557        p_vci_target.rspval = true;
    512         p_vci_target.rdata = 0;
     558        p_vci_target.rdata  = 0;
    513559        p_vci_target.rerror = VCI_WRITE_ERROR;
    514560        break;
     
    516562        p_vci_target.cmdack = false;
    517563        p_vci_target.rspval = true;
    518         p_vci_target.rdata = 0;
     564        p_vci_target.rdata  = 0;
    519565        p_vci_target.rerror = VCI_WRITE_OK;
    520566        break;
     
    531577
    532578    switch (r_initiator_fsm) {
    533     case M_WRITE_CMD:           // It is actually a single flit VCI read command
     579    case M_WRITE_CMD:           // It is actually a single word VCI read command
    534580        p_vci_initiator.rspack  = false;
    535581        p_vci_initiator.cmdval  = true;
     
    539585        p_vci_initiator.wdata   = 0;
    540586        p_vci_initiator.be      = (uint32_t)0xF;
    541         p_vci_initiator.plen    = (sc_dt::sc_uint<vci_param::K>)(r_burst_nflits.read()<<2);
     587        p_vci_initiator.plen    = (sc_dt::sc_uint<vci_param::K>)(r_burst_nwords.read()<<2);
    542588        p_vci_initiator.eop     = true;
    543589        break;
    544     case M_READ_CMD:            // It is actually a multi-flits VCI WRITE command
     590    case M_READ_CMD:            // It is actually a multi-words VCI WRITE command
    545591        p_vci_initiator.rspack  = false;
    546592        p_vci_initiator.cmdval  = true;
     
    548594        p_vci_initiator.cmd     = vci_param::CMD_WRITE;
    549595        p_vci_initiator.pktid   = TYPE_WRITE;
    550         p_vci_initiator.wdata   = (uint32_t)r_local_buffer[r_index.read()];
    551596        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;
    554602        break;
    555603    case M_READ_RSP:
     
    574622//////////////////////////////////////////////////////////////////////////////
    575623tmpl(/**/)::VciBlockDeviceTsar( sc_core::sc_module_name              name,
    576                                   const soclib::common::MappingTable   &mt,
    577                                   const soclib::common::IntTab         &srcid,
    578                                   const soclib::common::IntTab         &tgtid,
    579                                   const std::string                    &filename,
    580                                   const uint32_t                       block_size,
    581                                   const uint32_t                       burst_size,
    582                                   const uint32_t                       latency)
     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)
    583631
    584632: caba::BaseModule(name),
    585633        m_segment(mt.getSegment(tgtid)),
    586634        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),
    589637        m_bursts_per_block(block_size/burst_size),
    590638        m_latency(latency),
     
    603651    sensitive << p_clk.neg();
    604652
    605         if( (block_size != 64 )  &&
    606         (block_size != 128)  &&
     653    if( (block_size != 128)  &&
    607654        (block_size != 256)  &&
    608655        (block_size != 512)  &&
     
    615662                exit(1);
    616663        }
    617         if( (burst_size != 1 ) &&
    618                 (burst_size != 2 ) &&
    619                 (burst_size != 4 ) &&
     664    if( (burst_size != 4 ) &&
    620665                (burst_size != 8 ) &&
    621666                (burst_size != 16) &&
     
    624669        {
    625670                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;
    627672                exit(1);
    628673        }
    629         if ( m_segment.size() < 32 )
     674        if ( m_segment.size() < 64 )
    630675        {
    631676                std::cout << "Error in component VciBlockDeviceTsar : " << name << std::endl;
    632                 std::cout << "The size of the segment cannot be smaller than 32 bytes" << std::endl;
     677                std::cout << "The size of the segment cannot be smaller than 64 bytes" << std::endl;
    633678                exit(1);
    634679        }
    635         if ( (m_segment.baseAddress() & 0x0000001F) != 0 )
     680        if ( (m_segment.baseAddress() & 0x0000003F) != 0 )
    636681        {
    637682                std::cout << "Error in component VciBlockDeviceTsar : " << name << std::endl;
    638                 std::cout << "The base address of the segment must be multiple of 32 bytes" << std::endl;
     683                std::cout << "The base address of the segment must be multiple of 64 bytes" << std::endl;
    639684                exit(1);
    640685        }
    641         if ( vci_param::B != 4 )
     686        if ( (vci_param::B != 4) and (vci_param::B != 8) )
    642687        {
    643688                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;
    645690                exit(1);
    646691        }
     
    661706        }
    662707
    663         r_local_buffer = new uint32_t[m_flits_per_block];
     708        r_local_buffer = new uint32_t[m_words_per_block];
    664709
    665710} // end constructor
     
    711756                  << "  block = " << std::dec << r_block_count.read()
    712757                  << "  burst = " << r_burst_count.read()
    713                   << "  flit  = " << r_flit_count.read() <<std::endl;
     758                  << "  word  = " << r_words_count.read() <<std::endl;
    714759}
    715760
Note: See TracChangeset for help on using the changeset viewer.