Changeset 260 for trunk/modules


Ignore:
Timestamp:
Sep 4, 2012, 6:47:24 PM (12 years ago)
Author:
alain
Message:

The vci_block_device_tsar_v4 component has been modified to support bursts
even when the memory buffer is not aligned on a cache line boundary.

Location:
trunk/modules/vci_block_device_tsar_v4/caba/source
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/modules/vci_block_device_tsar_v4/caba/source/include/vci_block_device_tsar_v4.h

    r187 r260  
    3232// This component can perform data transfers between one single file belonging
    3333// to the host system and a buffer in the memory of the virtual prototype.
    34 // The file name is an argument of the constructor,
    35 // as well as the block size (bytes), and the burst size (bytes).
     34// The file name is an argument of the constructor.
    3635// This component has a DMA capability, and is both a target and an initiator.
     36// The block size (bytes), and the burst size (bytes) must be power of 2.
     37// The burst size is typically a cache line.
     38// If the memory buffer is not constrained to be aligned on a burst boundary.
    3739// Both read and write transfers are supported. An IRQ is optionally
    3840// asserted when the transfer is completed.
     
    9294
    9395    // Registers
    94     sc_signal<int>                              r_target_fsm;           // target fsm state register
    95     sc_signal<int>                              r_initiator_fsm;        // initiator fsm state register
    96     sc_signal<bool>                             r_irq_enable;           // default value is true
    97     sc_signal<uint32_t>                         r_nblocks;              // number of blocks to be transfered
    98     sc_signal<uint32_t>                         r_buf_address;          // memory buffer address
    99     sc_signal<uint32_t>                         r_lba;                  // first block index
    100     sc_signal<bool>                             r_read;                 // requested operation
    101     sc_signal<uint32_t>                         r_flit_count;           // flit counter (in a burst)
    102     sc_signal<uint32_t>                         r_burst_count;          // burst counter (in a block)
    103     sc_signal<uint32_t>                         r_block_count;          // block counter (in a transfer)
    104     sc_signal<uint32_t>                         r_latency_count;        // latency access (for each block)
    105     sc_signal<bool>                             r_go;                   // transmit command from T_FSM to M_FSM
     96    sc_signal<int>               r_target_fsm;           // target fsm state register
     97    sc_signal<int>               r_initiator_fsm;    // initiator fsm state register
     98    sc_signal<bool>              r_irq_enable;           // default value is true
     99    sc_signal<uint32_t>          r_nblocks;              // number of blocks in transfer
     100    sc_signal<uint32_t>          r_buf_address;          // memory buffer address
     101    sc_signal<uint32_t>          r_lba;                  // first block index
     102    sc_signal<bool>              r_read;                 // requested operation
     103    sc_signal<uint32_t>          r_index;                // flit index in local buffer
     104    sc_signal<uint32_t>          r_latency_count;    // latency counter
     105    sc_signal<uint32_t>          r_flit_count;           // flit counter (in a burst)
     106    sc_signal<uint32_t>          r_burst_count;          // burst counter (in a block)
     107    sc_signal<uint32_t>          r_block_count;          // block counter (in a transfer)
     108    sc_signal<uint32_t>          r_burst_offset;     // number of non aligned flits
     109    sc_signal<uint32_t>          r_burst_nflits;     // number of flits in a burst
     110    sc_signal<bool>              r_go;                   // command from T_FSM to M_FSM
     111
    106112    sc_signal<sc_dt::sc_uint<vci_param::S> >    r_srcid;                // save srcid
    107113    sc_signal<sc_dt::sc_uint<vci_param::T> >    r_trdid;                // save trdid
    108114    sc_signal<sc_dt::sc_uint<vci_param::P> >    r_pktid;                // save pktid
    109115
    110     uint32_t*                                   m_local_buffer;         // capacity is one block (block_size bytes)
     116    uint32_t*                    r_local_buffer;         // capacity is one block
    111117
    112118    // structural parameters
    113     soclib::common::Segment                     m_segment;              // segment associated to target
    114     uint32_t                                    m_srcid;                // initiator index
    115     int                                         m_fd;                   // File descriptor
    116     uint64_t                                    m_device_size;          // Total number of blocks
    117     const uint32_t                              m_flits_per_block;      // number of flits in a block
    118     const uint32_t                              m_flits_per_burst;      // number of flits in a burst
    119     const uint32_t                              m_bursts_per_block;     // number of bursts in a block
    120     const uint32_t                              m_latency;              // device latency
     119    soclib::common::Segment      m_segment;              // segment associated to target
     120    uint32_t                     m_srcid;                // initiator index
     121    int                          m_fd;                   // File descriptor
     122    uint64_t                     m_device_size;          // Total number of blocks
     123    const uint32_t               m_flits_per_block;      // number of flits in a block
     124    const uint32_t               m_flits_per_burst;      // number of flits in a burst
     125    const uint32_t               m_bursts_per_block; // number of bursts in a block
     126    const uint32_t               m_latency;              // device latency
    121127
    122128    // methods
     
    127133    enum {
    128134    M_IDLE              = 0,
     135
    129136    M_READ_BLOCK        = 1,
    130     M_READ_CMD          = 2,
    131     M_READ_RSP          = 3,
    132     M_READ_TEST         = 4,
     137    M_READ_BURST        = 2,
     138    M_READ_CMD          = 3,
     139    M_READ_RSP          = 4,
    133140    M_READ_SUCCESS      = 5,
    134141    M_READ_ERROR        = 6,
    135     M_WRITE_BLOCK       = 7,
     142
     143    M_WRITE_BURST       = 7,
    136144    M_WRITE_CMD         = 8,
    137145    M_WRITE_RSP         = 9,
    138     M_WRITE_TEST        = 10,
     146    M_WRITE_BLOCK       = 10,
    139147    M_WRITE_SUCCESS     = 11,
    140148    M_WRITE_ERROR       = 12,
     
    185193    // Constructor   
    186194    VciBlockDeviceTsarV4(
    187                 sc_module_name                          name,
     195                sc_module_name                      name,
    188196                const soclib::common::MappingTable      &mt,
    189197                const soclib::common::IntTab            &srcid,
    190198                const soclib::common::IntTab            &tgtid,
    191                 const std::string                       &filename,
    192                 const uint32_t                          block_size = 512,
    193                 const uint32_t                          burst_size = 64,
    194                 const uint32_t                          latency = 0);
     199        const std::string                   &filename,
     200        const uint32_t                      block_size = 512,
     201        const uint32_t                      burst_size = 64,
     202        const uint32_t                      latency = 0);
    195203};
    196204
  • trunk/modules/vci_block_device_tsar_v4/caba/source/src/vci_block_device_tsar_v4.cpp

    r256 r260  
    4545    {
    4646        r_initiator_fsm = M_IDLE;
    47         r_target_fsm = T_IDLE;
    48         r_irq_enable = true;
    49         r_go         = false;
    50         return;
     47        r_target_fsm    = T_IDLE;
     48        r_irq_enable    = true;
     49        r_go            = false;
     50        return;
    5151    }
    5252
     
    5757
    5858    switch(r_target_fsm) {
     59    ////////////
    5960    case T_IDLE:
    6061    {
     
    6465            r_trdid = p_vci_target.trdid.read();
    6566            r_pktid = p_vci_target.pktid.read();
    66             sc_dt::sc_uint<vci_param::N> address = p_vci_target.address.read();
     67            sc_dt::sc_uint<vci_param::N> address = p_vci_target.address.read();
    6768            bool                  read    = (p_vci_target.cmd.read() == vci_param::CMD_READ);
    6869            uint32_t              cell    = (uint32_t)((address & 0x1F)>>2);
    6970
    70             if     ( !read && !m_segment.contains(address) )            r_target_fsm = T_WRITE_ERROR;
    71             else if(  read && !m_segment.contains(address) )            r_target_fsm = T_READ_ERROR;
    72             else if( !read && !p_vci_target.eop.read() )                r_target_fsm = T_WRITE_ERROR;
    73             else if(  read && !p_vci_target.eop.read() )                r_target_fsm = T_READ_ERROR;
    74             else if( !read && (cell == BLOCK_DEVICE_BUFFER) )           r_target_fsm = T_WRITE_BUFFER;
    75             else if(  read && (cell == BLOCK_DEVICE_BUFFER) )           r_target_fsm = T_READ_BUFFER;
    76             else if( !read && (cell == BLOCK_DEVICE_COUNT) )            r_target_fsm = T_WRITE_COUNT;
    77             else if(  read && (cell == BLOCK_DEVICE_COUNT) )            r_target_fsm = T_READ_COUNT;
    78             else if( !read && (cell == BLOCK_DEVICE_LBA) )              r_target_fsm = T_WRITE_LBA;
    79             else if(  read && (cell == BLOCK_DEVICE_LBA) )              r_target_fsm = T_READ_LBA;
    80             else if( !read && (cell == BLOCK_DEVICE_OP) )               r_target_fsm = T_WRITE_OP;
    81             else if(  read && (cell == BLOCK_DEVICE_STATUS) )           r_target_fsm = T_READ_STATUS;
    82             else if( !read && (cell == BLOCK_DEVICE_IRQ_ENABLE) )       r_target_fsm = T_WRITE_IRQEN;
    83             else if(  read && (cell == BLOCK_DEVICE_IRQ_ENABLE) )       r_target_fsm = T_READ_IRQEN;
    84             else if(  read && (cell == BLOCK_DEVICE_SIZE) )             r_target_fsm = T_READ_SIZE;
    85             else if(  read && (cell == BLOCK_DEVICE_BLOCK_SIZE) )       r_target_fsm = T_READ_BLOCK;
    86         }
    87         break;
    88     }
     71            if     ( !read && !m_segment.contains(address) )      r_target_fsm = T_WRITE_ERROR;
     72            else if(  read && !m_segment.contains(address) )      r_target_fsm = T_READ_ERROR;
     73            else if( !read && !p_vci_target.eop.read() )          r_target_fsm = T_WRITE_ERROR;
     74            else if(  read && !p_vci_target.eop.read() )          r_target_fsm = T_READ_ERROR;
     75            else if( !read && (cell == BLOCK_DEVICE_BUFFER) )     r_target_fsm = T_WRITE_BUFFER;
     76            else if(  read && (cell == BLOCK_DEVICE_BUFFER) )     r_target_fsm = T_READ_BUFFER;
     77            else if( !read && (cell == BLOCK_DEVICE_COUNT) )      r_target_fsm = T_WRITE_COUNT;
     78            else if(  read && (cell == BLOCK_DEVICE_COUNT) )      r_target_fsm = T_READ_COUNT;
     79            else if( !read && (cell == BLOCK_DEVICE_LBA) )        r_target_fsm = T_WRITE_LBA;
     80            else if(  read && (cell == BLOCK_DEVICE_LBA) )        r_target_fsm = T_READ_LBA;
     81            else if( !read && (cell == BLOCK_DEVICE_OP) )         r_target_fsm = T_WRITE_OP;
     82            else if(  read && (cell == BLOCK_DEVICE_STATUS) )     r_target_fsm = T_READ_STATUS;
     83            else if( !read && (cell == BLOCK_DEVICE_IRQ_ENABLE) ) r_target_fsm = T_WRITE_IRQEN;
     84            else if(  read && (cell == BLOCK_DEVICE_IRQ_ENABLE) ) r_target_fsm = T_READ_IRQEN;
     85            else if(  read && (cell == BLOCK_DEVICE_SIZE) )       r_target_fsm = T_READ_SIZE;
     86            else if(  read && (cell == BLOCK_DEVICE_BLOCK_SIZE) ) r_target_fsm = T_READ_BLOCK;
     87        }
     88        break;
     89    }
     90    ////////////////////
    8991    case T_WRITE_BUFFER:
    9092    {
     
    9395        break;
    9496    }
     97    ///////////////////
    9598    case T_WRITE_COUNT:
    9699    {
     
    99102        break;
    100103    }
     104    /////////////////
    101105    case T_WRITE_LBA:
    102106    {
     
    105109        break;
    106110    }
     111    ////////////////
    107112    case T_WRITE_OP:
    108113    {
     
    123128        break;
    124129    }
     130    ///////////////////
    125131    case T_WRITE_IRQEN:
    126132    {
     
    129135        break;
    130136    }
     137    ///////////////////
    131138    case T_READ_BUFFER:
    132139    case T_READ_COUNT:
     
    141148        break;
    142149    }
     150    ///////////////////
    143151    case T_READ_STATUS:
    144152    {
     
    155163    } // end switch target fsm
    156164       
    157     /////////////////////////////////////////////////////////////////////////
    158     // The initiator FSM controls the following registers :
    159     // r_initiator_fsm, r_flit_count, r_block_count, m_local_buffer
    160     /////////////////////////////////////////////////////////////////////////
    161     switch(r_initiator_fsm) {
    162     case M_IDLE :       // waiting for activation
    163     {
    164         if ( r_go )
    165         {
     165    //////////////////////////////////////////////////////////////////////////////
     166    // The initiator FSM executes a loop, transfering one block per iteration.
     167    // Each block is split in bursts, and the number of bursts depends
     168    // on the memory buffer alignment on a burst boundary:
     169    // - If buffer aligned, all burst have the same length (m_flits_per burst)
     170    //   and the number of bursts is (m_bursts_per_block).
     171    // - If buffer not aligned, the number of bursts is (m_bursts_per_block + 1)
     172    //   and first and last burst are shorter, because all flits in a burst
     173    //   must be contained in a single cache line.
     174    //   first burst => nflits = m_flits_per_burst - offset
     175    //   last  burst => nflits = offset
     176    //   other burst => nflits = m_flits_per_burst
     177    //////////////////////////////////////////////////////////////////////////////
     178
     179    switch( r_initiator_fsm.read() ) {
     180    ////////////
     181    case M_IDLE:        // check buffer alignment to compute the number of bursts
     182    {
     183        if ( r_go.read() )
     184        {
     185            r_index         = 0;
    166186            r_block_count   = 0;
    167187            r_burst_count   = 0;
     
    169189            r_latency_count = m_latency;
    170190
    171             if ( r_read )       r_initiator_fsm = M_READ_BLOCK;
    172             else            r_initiator_fsm = M_WRITE_CMD;
    173         }
    174         break;
    175     }
     191            // compute r_burst_offset (zero when buffer aligned)
     192            r_burst_offset = (r_buf_address.read()>>2) % m_flits_per_burst;
     193
     194            // start tranfer
     195            if ( r_read.read() )        r_initiator_fsm = M_READ_BLOCK;
     196            else                    r_initiator_fsm = M_WRITE_BURST;
     197        }
     198        break;
     199    }
     200    //////////////////
    176201    case M_READ_BLOCK:  // read one block from disk after waiting m_latency cycles
     202    {
     203        if ( r_latency_count.read() == 0 )
     204        {
     205            r_latency_count = m_latency;
     206            ::lseek(m_fd, (r_lba + r_block_count)*m_flits_per_block*4, SEEK_SET);
     207            if( ::read(m_fd, r_local_buffer, m_flits_per_block*4) < 0 ) 
     208            {
     209                r_initiator_fsm = M_READ_ERROR;
     210            }
     211            else   
     212            {
     213                r_burst_count   = 0;
     214                r_flit_count    = 0;
     215                r_initiator_fsm = M_READ_BURST;
     216            }
     217        }
     218        else
     219        {
     220            r_latency_count = r_latency_count.read() - 1;
     221        }
     222        break;
     223    }
     224    //////////////////
     225    case M_READ_BURST:  // Compute the number of flits in the burst
     226    {
     227        uint32_t offset = r_burst_offset.read();
     228
     229        if ( offset )                  // buffer not aligned
     230        {
     231            if ( r_burst_count.read() == 0 ) r_burst_nflits = m_flits_per_burst - offset;
     232            else if ( r_burst_count.read() == m_bursts_per_block ) r_burst_nflits = offset;
     233            else r_burst_nflits = m_flits_per_burst;
     234        }
     235        else                           // buffer aligned
     236        {
     237            r_burst_nflits = m_flits_per_burst;
     238        }
     239        r_initiator_fsm =  M_READ_CMD;
     240        break;
     241    }
     242    ////////////////
     243    case M_READ_CMD:    // Send a multi-flits VCI WRITE command
     244    {
     245        if ( p_vci_initiator.cmdack.read() )
     246        {
     247            if ( r_flit_count == (r_burst_nflits.read() - 1) ) // last flit in a burst
     248            {
     249                r_initiator_fsm = M_READ_RSP;
     250                r_flit_count = 0;
     251            }
     252            else                                               // not the last flit
     253            {
     254                r_flit_count = r_flit_count.read() + 1;
     255            }
     256
     257            // compute next flit address and next local buffer index
     258            r_buf_address = r_buf_address.read() + 4;
     259            r_index       = r_index.read() + 1;
     260        }
     261        break;
     262    }
     263    ////////////////
     264    case M_READ_RSP:    // Wait a single flit VCI WRITE response
     265    {
     266        if ( p_vci_initiator.rspval.read() )
     267        {
     268            bool aligned = (r_burst_offset.read() == 0);
     269
     270            if ( (p_vci_initiator.rerror.read()&0x1) != 0 )
     271            {
     272                r_initiator_fsm = M_READ_ERROR;
     273            }
     274            else if ( (not aligned and (r_burst_count.read() == m_bursts_per_block)) or
     275                      (aligned and (r_burst_count.read() == (m_bursts_per_block-1))) )
     276            {
     277                if ( r_block_count.read() == (r_nblocks.read()-1) ) // last burst of last block
     278                {
     279                    r_initiator_fsm = M_READ_SUCCESS;
     280                }
     281                else                                              // last burst not last block
     282                {
     283                    r_index          = 0;
     284                    r_burst_count    = 0;
     285                    r_block_count    = r_block_count.read() + 1;
     286                    r_initiator_fsm  = M_READ_BLOCK;
     287                }
     288            }
     289            else                                                // not the last burst
     290            {
     291                r_burst_count = r_burst_count.read() + 1;
     292                r_initiator_fsm = M_READ_BURST;
     293            }
     294        }
     295        break;
     296    }
     297    ///////////////////
     298    case M_READ_SUCCESS:
     299    case M_READ_ERROR:
     300    {
     301        if( !r_go ) r_initiator_fsm = M_IDLE;
     302        break;
     303    }
     304    ///////////////////
     305    case M_WRITE_BURST:  // Compute the number of flits in the burst
     306    {
     307        uint32_t offset = r_burst_offset.read();
     308
     309        if ( offset )                  // buffer not aligned
     310        {
     311            if ( r_burst_count.read() == 0 ) r_burst_nflits = m_flits_per_burst - offset;
     312            else if ( r_burst_count.read() == m_bursts_per_block ) r_burst_nflits = offset;
     313            else r_burst_nflits = m_flits_per_burst;
     314        }
     315        else                           // buffer aligned
     316        {
     317            r_burst_nflits = m_flits_per_burst;
     318        }
     319        r_initiator_fsm =  M_WRITE_CMD;
     320        break;
     321    }
     322    /////////////////
     323    case M_WRITE_CMD:   // This is actually a single flit VCI READ command
     324    {
     325            if ( p_vci_initiator.cmdack.read() ) r_initiator_fsm = M_WRITE_RSP;
     326        break;
     327    }
     328    /////////////////
     329    case M_WRITE_RSP:   // This is actually a multi-flits VCI READ response
     330    {
     331        bool aligned = (r_burst_offset.read() == 0);
     332
     333        if ( p_vci_initiator.rspval.read() )
     334        {
     335            r_local_buffer[r_index.read()] = (uint32_t)p_vci_initiator.rdata.read();
     336            r_index = r_index.read() + 1;
     337
     338            if ( p_vci_initiator.reop.read() )  // last flit of the burst
     339            {
     340                    r_flit_count  = 0;
     341                r_buf_address = r_buf_address.read() + r_burst_nflits.read()<<2;
     342
     343                        if( (p_vci_initiator.rerror.read()&0x1) != 0 )
     344                {
     345                    r_initiator_fsm = M_WRITE_ERROR;
     346                }
     347                else if ( (not aligned and (r_burst_count.read() == m_bursts_per_block)) or
     348                          (aligned and (r_burst_count.read() == (m_bursts_per_block-1))) ) // last burst
     349                {
     350                    r_burst_count    = 0;
     351                    r_block_count    = r_block_count.read() + 1;
     352                    r_initiator_fsm  = M_WRITE_BLOCK;
     353                }
     354                else                                          // not the last burst
     355                {
     356                    r_burst_count = r_burst_count.read() + 1;
     357                    r_initiator_fsm = M_WRITE_BURST;
     358                }
     359            }
     360            else
     361            {
     362                    r_flit_count = r_flit_count.read() + 1;
     363            }
     364        }
     365        break;
     366    }
     367    ///////////////////
     368    case M_WRITE_BLOCK:         // write a block to disk after waiting m_latency cycles
    177369    {
    178370        if ( r_latency_count == 0 )
     
    180372            r_latency_count = m_latency;
    181373            ::lseek(m_fd, (r_lba + r_block_count)*m_flits_per_block*vci_param::B, SEEK_SET);
    182             if( ::read(m_fd, m_local_buffer, m_flits_per_block*vci_param::B) < 0 ) 
    183             {
    184                  r_initiator_fsm = M_READ_ERROR;
    185             }
    186             else   
    187             {
    188                  r_initiator_fsm = M_READ_CMD;
    189             }
    190         }
    191         else
    192         {
    193             r_latency_count = r_latency_count - 1;
    194         }
    195         break;
    196     }
    197     case M_READ_CMD:    // This is actually a multi-flits VCI WRITE command
    198     {
    199         if ( p_vci_initiator.cmdack.read() )
    200         {
    201             if ( r_flit_count == (m_flits_per_burst - 1) )
    202             {
    203                 r_initiator_fsm = M_READ_RSP;
    204                 r_flit_count = 0;
     374            if( ::write(m_fd, r_local_buffer, m_flits_per_block*vci_param::B) < 0 )
     375            {
     376                r_initiator_fsm = M_WRITE_ERROR;
     377            }
     378            else if ( r_block_count.read() == r_nblocks.read() )
     379            {
     380                r_initiator_fsm = M_WRITE_SUCCESS;
    205381            }
    206382            else
    207383            {
    208                 r_flit_count = r_flit_count + 1;
    209             }
    210         }
    211         break;
    212     }
    213     case M_READ_RSP:    // This is actually a single flit VCI WRITE response
    214     {
    215         if ( p_vci_initiator.rspval.read() )
    216         {
    217             if ( (p_vci_initiator.rerror.read()&0x1) == 0 ) r_initiator_fsm = M_READ_TEST;
    218             else                                            r_initiator_fsm = M_READ_ERROR;
    219         }
    220         break;
    221     }
    222     case M_READ_TEST:
    223     {
    224         if ( r_burst_count.read() == (m_bursts_per_block - 1) )
    225         {
    226             if ( r_block_count.read() == (r_nblocks.read() - 1) ) // last burst of the last block
    227             {
    228                 r_burst_count = 0;
    229                 r_block_count = 0;
    230                 r_initiator_fsm = M_READ_SUCCESS;
    231             }
    232             else        // last burst but not last block
    233             {
    234                 r_burst_count = 0;
    235                 r_block_count = r_block_count.read() + 1;
    236                 r_initiator_fsm  = M_READ_BLOCK;
    237             }
    238         }
    239         else  // not the last burst of the block
    240         {
    241             r_burst_count = r_burst_count.read() + 1;
    242             r_initiator_fsm = M_READ_CMD;
    243         }
    244         break;
    245     }
    246     case M_READ_SUCCESS:
    247     {
    248         if( !r_go ) r_initiator_fsm = M_IDLE;
    249         break;
    250     }
    251     case M_READ_ERROR:
    252     {
    253         if( !r_go ) r_initiator_fsm = M_IDLE;
    254         break;
    255     }
    256     case M_WRITE_CMD:   // This is actually a single flit VCI READ command
    257     {
    258             if ( p_vci_initiator.cmdack.read() ) r_initiator_fsm = M_WRITE_RSP;
    259         break;
    260     }
    261     case M_WRITE_RSP:   // This is actually a multi-flits VCI READ response
    262     {
    263         if ( p_vci_initiator.rspval.read() )
    264         {
    265             uint32_t index = (r_burst_count.read()*m_flits_per_burst) + r_flit_count.read();
    266             m_local_buffer[index] = (uint32_t)p_vci_initiator.rdata.read();
    267             if ( p_vci_initiator.reop.read() )
    268             {
    269                     r_flit_count = 0;
    270                         if( (p_vci_initiator.rerror.read()&0x1) == 0 ) r_initiator_fsm = M_WRITE_TEST;
    271                 else                                           r_initiator_fsm = M_WRITE_ERROR;
    272             }
    273             else
    274             {
    275                     r_flit_count = r_flit_count.read() + 1;
    276             }
    277         }
    278         break;
    279     }
    280     case M_WRITE_TEST:
    281     {
    282         if ( r_burst_count.read() == (m_bursts_per_block - 1) ) // last burst of the block
    283         {
    284             r_burst_count = 0;
    285             r_block_count = r_block_count.read() + 1;
    286             r_initiator_fsm = M_WRITE_BLOCK;
    287         }                                       
    288         else                                                    // not the last burst
    289         {
    290             r_burst_count = r_burst_count.read() + 1;
    291             r_initiator_fsm = M_WRITE_CMD;
    292         }
    293         break;
    294     }
    295     case M_WRITE_BLOCK:         // write a block to disk after waiting m_latency cycles
    296     {
    297         if ( r_latency_count == 0 )
    298         {
    299             r_latency_count = m_latency;
    300             ::lseek(m_fd, (r_lba + r_block_count)*m_flits_per_block*vci_param::B, SEEK_SET);
    301             if( ::write(m_fd, m_local_buffer, m_flits_per_block*vci_param::B) < 0 )
    302             {
    303                 r_initiator_fsm = M_WRITE_ERROR;
    304             }
    305             else if ( r_block_count.read() == r_nblocks.read() )
    306             {
    307                 r_initiator_fsm = M_WRITE_SUCCESS;
    308             }
    309             else
    310             {
    311                 r_initiator_fsm = M_WRITE_CMD;
     384                r_initiator_fsm = M_WRITE_BURST;
    312385            }
    313386        }
     
    318391        break;
    319392    }
     393    /////////////////////
    320394    case M_WRITE_SUCCESS:
    321     {
    322         if( !r_go ) r_initiator_fsm = M_IDLE;
    323         break;
    324     }
    325395    case M_WRITE_ERROR:
    326396    {
     
    334404tmpl(void)::genMoore()
    335405{
    336     sc_dt::sc_uint<vci_param::N>        offset;
    337     uint32_t                    index;
    338 
    339406    // p_vci_target port   
    340407    p_vci_target.rsrcid = (sc_dt::sc_uint<vci_param::S>)r_srcid.read();
     
    346413    case T_IDLE:
    347414        p_vci_target.cmdack = true;
    348         p_vci_target.rspval = false;
     415        p_vci_target.rspval = false;
    349416        break;
    350417    case T_READ_STATUS:
    351418        p_vci_target.cmdack = false;
    352         p_vci_target.rspval = true;
    353         if     (r_initiator_fsm == M_IDLE)              p_vci_target.rdata = BLOCK_DEVICE_IDLE;
    354         else if(r_initiator_fsm == M_READ_SUCCESS)      p_vci_target.rdata = BLOCK_DEVICE_READ_SUCCESS;
    355         else if(r_initiator_fsm == M_WRITE_SUCCESS)     p_vci_target.rdata = BLOCK_DEVICE_WRITE_SUCCESS;
     419        p_vci_target.rspval = true;
     420        if     (r_initiator_fsm == M_IDLE)          p_vci_target.rdata = BLOCK_DEVICE_IDLE;
     421        else if(r_initiator_fsm == M_READ_SUCCESS)  p_vci_target.rdata = BLOCK_DEVICE_READ_SUCCESS;
     422        else if(r_initiator_fsm == M_WRITE_SUCCESS) p_vci_target.rdata = BLOCK_DEVICE_WRITE_SUCCESS;
    356423        else if(r_initiator_fsm == M_READ_ERROR)        p_vci_target.rdata = BLOCK_DEVICE_READ_ERROR;
    357424        else if(r_initiator_fsm == M_WRITE_ERROR)       p_vci_target.rdata = BLOCK_DEVICE_WRITE_ERROR;
     
    361428    case T_READ_BUFFER:
    362429        p_vci_target.cmdack = false;
    363         p_vci_target.rspval = true;
    364         p_vci_target.rdata  = (uint32_t)r_buf_address;
     430        p_vci_target.rspval = true;
     431        p_vci_target.rdata  = (uint32_t)r_buf_address.read();
    365432        p_vci_target.rerror = VCI_READ_OK;
    366433        break;
    367434    case T_READ_COUNT:
    368435        p_vci_target.cmdack = false;
    369         p_vci_target.rspval = true;
    370         p_vci_target.rdata = (uint32_t)r_nblocks;
     436        p_vci_target.rspval = true;
     437        p_vci_target.rdata = (uint32_t)r_nblocks.read();
    371438        p_vci_target.rerror = VCI_READ_OK;
    372439        break;
    373440    case T_READ_LBA:
    374441        p_vci_target.cmdack = false;
    375         p_vci_target.rspval = true;
    376         p_vci_target.rdata = (uint32_t)r_lba;
     442        p_vci_target.rspval = true;
     443        p_vci_target.rdata = (uint32_t)r_lba.read();
    377444        p_vci_target.rerror = VCI_READ_OK;
    378445        break;
    379446    case T_READ_IRQEN:
    380447        p_vci_target.cmdack = false;
    381         p_vci_target.rspval = true;
    382         p_vci_target.rdata = (uint32_t)r_irq_enable;
     448        p_vci_target.rspval = true;
     449        p_vci_target.rdata = (uint32_t)r_irq_enable.read();
    383450        p_vci_target.rerror = VCI_READ_OK;
    384451        break;
    385452    case T_READ_SIZE:
    386453        p_vci_target.cmdack = false;
    387         p_vci_target.rspval = true;
     454        p_vci_target.rspval = true;
    388455        p_vci_target.rdata = (uint32_t)m_device_size;
    389456        p_vci_target.rerror = VCI_READ_OK;
     
    391458    case T_READ_BLOCK:
    392459        p_vci_target.cmdack = false;
    393         p_vci_target.rspval = true;
     460        p_vci_target.rspval = true;
    394461        p_vci_target.rdata = (uint32_t)m_flits_per_block*vci_param::B;
    395462        p_vci_target.rerror = VCI_READ_OK;
     
    397464    case T_READ_ERROR:
    398465        p_vci_target.cmdack = false;
    399         p_vci_target.rspval = true;
     466        p_vci_target.rspval = true;
    400467        p_vci_target.rdata = 0;
    401468        p_vci_target.rerror = VCI_READ_ERROR;
     
    403470    case T_WRITE_ERROR:
    404471        p_vci_target.cmdack = false;
    405         p_vci_target.rspval = true;
     472        p_vci_target.rspval = true;
    406473        p_vci_target.rdata = 0;
    407474        p_vci_target.rerror = VCI_WRITE_ERROR;
     
    427494    switch (r_initiator_fsm) {
    428495    case M_WRITE_CMD:           // It is actually a single flit VCI read command
    429         offset = (r_block_count.read()*m_flits_per_block +
    430                   r_burst_count.read()*m_flits_per_burst) * vci_param::B;
    431496        p_vci_initiator.rspack  = false;
    432497        p_vci_initiator.cmdval  = true;
    433         p_vci_initiator.address = (sc_dt::sc_uint<vci_param::N>)r_buf_address.read() + offset;
     498        p_vci_initiator.address = (sc_dt::sc_uint<vci_param::N>)r_buf_address.read();
    434499        p_vci_initiator.cmd     = vci_param::CMD_READ;
    435500        p_vci_initiator.wdata   = 0;
    436501        p_vci_initiator.be      = (uint32_t)0xF;
    437         p_vci_initiator.plen    = (sc_dt::sc_uint<vci_param::K>)m_flits_per_burst*vci_param::B;
     502        p_vci_initiator.plen    = (sc_dt::sc_uint<vci_param::K>)(r_burst_nflits.read()<<2);
    438503        p_vci_initiator.eop     = true;
    439504        break;
    440505    case M_READ_CMD:            // It is actually a multi-flits VCI WRITE command
    441         offset = ( r_block_count.read()*m_flits_per_block +
    442                    r_burst_count.read()*m_flits_per_burst +
    443                    r_flit_count.read() ) * vci_param::B;
    444         index  = (r_burst_count.read()*m_flits_per_burst) + r_flit_count.read();
    445506        p_vci_initiator.rspack  = false;
    446507        p_vci_initiator.cmdval  = true;
    447         p_vci_initiator.address = (sc_dt::sc_uint<vci_param::N>)r_buf_address.read() + offset;
     508        p_vci_initiator.address = (sc_dt::sc_uint<vci_param::N>)r_buf_address.read();
    448509        p_vci_initiator.cmd     = vci_param::CMD_WRITE;
    449         p_vci_initiator.wdata   = (uint32_t)m_local_buffer[index];
     510        p_vci_initiator.wdata   = (uint32_t)r_local_buffer[r_index.read()];
    450511        p_vci_initiator.be      = 0xF;
    451         p_vci_initiator.plen    = (sc_dt::sc_uint<vci_param::K>)m_flits_per_burst*vci_param::B;
    452         p_vci_initiator.eop     = ( r_flit_count.read() == (m_flits_per_burst - 1) );
     512        p_vci_initiator.plen    = (sc_dt::sc_uint<vci_param::K>)(r_burst_nflits.read()<<2);
     513        p_vci_initiator.eop     = ( r_flit_count.read() == (r_burst_nflits.read() - 1) );
    453514        break;
    454515    case M_READ_RSP:
     
    456517        p_vci_initiator.rspack  = true;
    457518        p_vci_initiator.cmdval  = false;
    458         break;
     519        break;
    459520    default:
    460         p_vci_initiator.rspack  = false;
    461         p_vci_initiator.cmdval  = false;
    462         break;
     521        p_vci_initiator.rspack  = false;
     522        p_vci_initiator.cmdval  = false;
     523        break;
    463524    }
    464525
     
    472533
    473534//////////////////////////////////////////////////////////////////////////////
    474 tmpl(/**/)::VciBlockDeviceTsarV4(   sc_core::sc_module_name             name,
    475                 const soclib::common::MappingTable      &mt,
    476                 const soclib::common::IntTab    &srcid,
    477                 const soclib::common::IntTab    &tgtid,
    478                 const std::string               &filename,
    479                 const uint32_t                  block_size,
    480                 const uint32_t                  burst_size,
    481                 const uint32_t                          latency)
     535tmpl(/**/)::VciBlockDeviceTsarV4( sc_core::sc_module_name              name,
     536                                  const soclib::common::MappingTable   &mt,
     537                                  const soclib::common::IntTab         &srcid,
     538                                  const soclib::common::IntTab         &tgtid,
     539                                  const std::string                    &filename,
     540                                  const uint32_t                       block_size,
     541                                  const uint32_t                       burst_size,
     542                                  const uint32_t                       latency)
    482543
    483544: caba::BaseModule(name),
     
    512573                exit(1);
    513574        }
     575        if( (burst_size != 1 ) &&
     576                (burst_size != 2 ) &&
     577                (burst_size != 4 ) &&
     578                (burst_size != 8 ) &&
     579                (burst_size != 16) &&
     580                (burst_size != 32) &&
     581                (burst_size != 64) )
     582        {
     583                std::cout << "Error in component VciBlockDeviceTsarV4 : " << name << std::endl;
     584                std::cout << "The burst size must be 1, 2, 4, 8, 16, 32 or 64 bytes" << std::endl;
     585                exit(1);
     586        }
    514587        if ( m_segment.size() < 32 )
    515588        {
     
    522595                std::cout << "Error in component VciBlockDeviceTsarV4 : " << name << std::endl;
    523596                std::cout << "The base address of the segment must be multiple of 32 bytes" << std::endl;
    524                 exit(1);
    525         }
    526         if ( block_size%burst_size != 0 )
    527         {
    528                 std::cout << "Error in component VciBlockDeviceTsarV4 : " << name << std::endl;
    529                 std::cout << "The block_size parameter must be a multiple of the burst_size" << std::endl;
    530597                exit(1);
    531598        }
     
    552619        }
    553620
    554         m_local_buffer = new uint32_t[m_flits_per_block];
    555 /*
    556         std::cout << std::endl << "Instanciation of VciBlockDeviceTsarV4 : " << name << std::endl;
    557         std::cout << "    file_name  = " << filename << std::endl;
    558         std::cout << "    burst_size = " << std::dec << m_flits_per_burst*vci_param::B << std::endl;
    559         std::cout << "    block_size = " << std::dec << m_flits_per_block*vci_param::B << std::endl;
    560         std::cout << "    latency    = " << std::dec << m_latency << std::endl;
    561         std::cout << "    segment " << m_segment.name()
    562                 << " | base = 0x" << std::hex << m_segment.baseAddress()
    563                 << " | size = "   << std::dec << m_segment.size() << std::endl;
    564 */
     621        r_local_buffer = new uint32_t[m_flits_per_block];
     622
    565623} // end constructor
    566624
     
    569627{
    570628        const char* initiator_str[] = {
    571                 "IDLE         ",
    572                 "READ_BLOCK   ",
    573                 "READ_CMD     ",
    574                 "READ_RSP     ",
    575                 "READ_TEST    ",
    576                 "READ_SUCCESS ",
    577                 "READ_ERROR   ",
    578                 "WRITE_BLOCK  ",
    579                 "WRITE_CMD    ",
    580                 "WRITE_RSP    ",
    581                 "WRITE_TEST   ",
     629                "IDLE",
     630
     631                "READ_BLOCK",
     632                "READ_BURST",
     633                "READ_CMD",
     634                "READ_RSP",
     635                "READ_TEST",
     636                "READ_SUCCESS",
     637                "READ_ERROR",
     638
     639                "WRITE_BURST",
     640                "WRITE_CMD",
     641                "WRITE_RSP",
     642                "WRITE_BLOCK",
    582643                "WRITE_SUCCESS",
    583                 "WRITE_ERROR  ",
     644                "WRITE_ERROR",
    584645        };
    585646        const char* target_str[] = {
Note: See TracChangeset for help on using the changeset viewer.