Changeset 558


Ignore:
Timestamp:
Oct 25, 2013, 5:35:50 PM (10 years ago)
Author:
bouyer
Message:

Simplify target FSM by doing register read and write in IDLE state,
when we read the request from the VCI port.

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  
    8080    sc_signal<uint8_t>                 r_ctrl_char_len; // number of bits in xfer
    8181
    82     sc_signal<uint8_t>                 r_txrx_addr;
    83 
    8482    sc_signal<uint32_t>                r_bit_count;
    8583    sc_signal<uint32_t>                r_clk_counter;
     
    105103    sc_signal<typename vci_param::trdid_t >     r_trdid;   // save trdid
    106104    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
    108107
    109108    uint32_t*                          r_local_buffer;     // capacity is one block
     
    142141    enum {
    143142    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
    154147    };
    155148
  • trunk/modules/vci_spi/caba/source/src/vci_spi.cpp

    r553 r558  
    2222 *
    2323 * Copyright (c) UPMC, Lip6, SoC
    24  *        manuel.bouyer@lip6.fr october 2013
     24 *      manuel.bouyer@lip6.fr october 2013
    2525 *
    2626 * Maintainers: bouyer
     
    4545    if(p_resetn.read() == false)
    4646    {
    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;
     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;
    5858        r_clk_counter     = 0xffff;
    59         r_spi_clk        = 0;
     59        r_spi_clk        = 0;
    6060
    6161        r_irq             = false;
    6262        r_read            = false;
    6363
    64         return;
     64        return;
    6565    }
    6666
     
    7474    case T_IDLE:
    7575    {
    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             r_tdata = 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             }
     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            }
    9090 
    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;
    118165                        }
    119                 }
    120             } else { // write
    121                 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         break;
     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;
    150197    }
    151198    ////////////////////
    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:
    154203        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;
    247207    } // end switch target fsm
    248208
     
    271231        if (!r_spi_clk_ignore) {
    272232            if (r_spi_clk_previous == 0 && s_clk_sample == 1) {
    273                 // low to high transition: shift and sample
    274                 r_txrx[1] = (r_txrx[1] << 1) | (r_txrx[0] >> 63);
    275                 r_txrx[0] = (r_txrx[0] << 1) | p_spi_miso;
    276                 r_bit_count = r_bit_count - 1;
     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;
    277237            } else if (r_spi_clk_previous == 1 && s_clk_sample == 0) {
    278                 // high to low transition: change output, or stop
    279                 if (r_bit_count == 0) {
     238                // high to low transition: change output, or stop
     239                if (r_bit_count == 0) {
    280240                    r_spi_fsm = S_IDLE;
    281241                    r_irq = r_ctrl_ie;
    282242                    r_ctrl_go_bsy = false;
    283 #ifdef SOCLIB_MODULE_DEBUG
     243#ifdef SOCLIB_MODULE_DEBUG0
    284244                    std::cout << name() << " end xfer " << std::dec << (int)r_ctrl_char_len.read() << " data " << std::hex << r_txrx[1] << " " << r_txrx[0] << std::endl;
    285245#endif
     
    290250        }
    291251        r_spi_clk_previous = s_clk_sample;
    292         // generate the SPI clock
     252        // generate the SPI clock
    293253        if (r_clk_counter.read() == 0) {
    294254            r_clk_counter = r_divider.read();
     
    319279    case M_IDLE:        // check buffer alignment to compute the number of bursts
    320280    {
    321         if ( false )  // XXX
    322         {
    323             r_index        = 0;
    324             r_block_count   = 0;
    325             r_burst_count   = 0;
    326             r_words_count   = 0;
    327 
    328             // compute r_burst_offset (zero when buffer aligned)
    329             r_burst_offset = (uint32_t)((r_buf_address.read()>>2) % m_words_per_burst);
    330 
    331             // start tranfer
    332             if ( r_read.read() )        r_initiator_fsm = M_READ_BLOCK;
    333             else                    r_initiator_fsm = M_WRITE_BURST;
    334         }
    335         break;
     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;
    336296    }
    337297    //////////////////
    338298    case M_READ_BLOCK:  // read one block from disk after waiting m_latency cycles
    339299    {
    340         r_burst_count   = 0;
    341         r_words_count    = 0;
    342         r_initiator_fsm = M_READ_BURST;
    343         break;
     300        r_burst_count   = 0;
     301        r_words_count    = 0;
     302        r_initiator_fsm = M_READ_BURST;
     303        break;
    344304    }
    345305    //////////////////
    346306    case M_READ_BURST:  // Compute the number of words and the number of flits in the burst
    347                         // The number of flits can be smaller than the number of words
    348                         // in case of 8 bytes flits...
    349     {
    350         uint32_t nwords;
    351         uint32_t offset = r_burst_offset.read();
    352 
    353         if ( offset )                  // buffer not aligned
    354         {
    355             if ( r_burst_count.read() == 0 ) nwords = m_words_per_burst - offset;
    356             else if ( r_burst_count.read() == m_bursts_per_block ) nwords = offset;
    357             else nwords = m_words_per_burst;
    358         }
    359         else                           // buffer aligned
    360         {
    361             nwords = m_words_per_burst;
    362         }
    363 
    364         r_burst_nwords  = nwords;
    365         r_initiator_fsm = M_READ_CMD;
    366         break;
     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;
    367327    }
    368328    ////////////////
    369329    case M_READ_CMD:    // Send a multi-flits VCI WRITE command
    370330    {
    371         if ( p_vci_initiator.cmdack.read() )
    372         {
    373             uint32_t nwords = r_burst_nwords.read() - r_words_count.read();
    374 
    375             if ( vci_param::B == 4 )    // one word per flit
    376             {
    377                 if ( nwords <= 1 )      // last flit
    378                 {
    379                     r_initiator_fsm = M_READ_RSP;
    380                     r_words_count = 0;
    381                 }
    382                 else                    // not the last flit
    383                 {
    384                     r_words_count = r_words_count.read() + 1;
    385                 }
    386 
    387                 // compute next word address and next local buffer index
    388                 r_buf_address = r_buf_address.read() + 4;
    389                 r_index       = r_index.read() + 1;
    390             }
    391             else                        // 2 words per flit
    392             {
    393                 if ( nwords <= 2 )      // last flit
    394                 {
    395                     r_initiator_fsm = M_READ_RSP;
    396                     r_words_count = 0;
    397                 }
    398                 else                    // not the last flit
    399                 {
    400                     r_words_count = r_words_count.read() + 2;
    401                 }
    402                    
    403                 // compute next word address and next local buffer index
    404                 if ( nwords == 1 )
    405                 {
    406                     r_buf_address = r_buf_address.read() + 4;
    407                     r_index       = r_index.read() + 1;
    408                 }
    409                 else
    410                 {
    411                     r_buf_address = r_buf_address.read() + 8;
    412                     r_index       = r_index.read() + 2;
    413                 }
    414             }
    415         }
    416         break;
     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;
    417377    }
    418378    ////////////////
    419379    case M_READ_RSP:    // Wait a single flit VCI WRITE response
    420380    {
    421         if ( p_vci_initiator.rspval.read() )
    422         {
    423             bool aligned = (r_burst_offset.read() == 0);
    424 
    425             if ( (p_vci_initiator.rerror.read()&0x1) != 0 )
    426             {
    427                 r_initiator_fsm = M_READ_ERROR;
     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;
    428388#ifdef SOCLIB_MODULE_DEBUG
    429389                std::cout << "vci_bd M_READ_ERROR" << std::endl;
    430390#endif
    431             }
    432             else if ( (not aligned and (r_burst_count.read() == m_bursts_per_block)) or
    433                       (aligned and (r_burst_count.read() == (m_bursts_per_block-1))) )
    434             {
    435                 if ( r_block_count.read() == (r_nblocks.read()-1) ) // last burst of last block
    436                 {
    437                     r_initiator_fsm = M_READ_SUCCESS;
     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;
    438398#ifdef SOCLIB_MODULE_DEBUG
    439399                    std::cout << "vci_bd M_READ_SUCCESS" << std::endl;
    440400#endif
    441                 }
    442                 else                                              // last burst not last block
    443                 {
    444                     r_index          = 0;
    445                     r_burst_count    = 0;
    446                     r_block_count    = r_block_count.read() + 1;
    447                     r_initiator_fsm  = M_READ_BLOCK;
    448                 }
    449             }
    450             else                                                // not the last burst
    451             {
    452                 r_burst_count = r_burst_count.read() + 1;
    453                 r_initiator_fsm = M_READ_BURST;
    454             }
    455         }
    456         break;
     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;
    457417    }
    458418    ///////////////////
     
    460420    case M_READ_ERROR:
    461421    {
    462         if( !r_go ) r_initiator_fsm = M_IDLE;
    463         break;
     422        if( !r_go ) r_initiator_fsm = M_IDLE;
     423        break;
    464424    }
    465425    ///////////////////
    466426    case M_WRITE_BURST:  // Compute the number of words in the burst
    467427    {
    468         uint32_t nwords;
    469         uint32_t offset = r_burst_offset.read();
    470 
    471         if ( offset )                  // buffer not aligned
    472         {
    473             if ( r_burst_count.read() == 0 ) nwords = m_words_per_burst - offset;
    474             else if ( r_burst_count.read() == m_bursts_per_block ) nwords = offset;
    475             else nwords = m_words_per_burst;
    476         }
    477         else                           // buffer aligned
    478         {
    479             nwords = m_words_per_burst;
    480         }
    481 
    482         r_burst_nwords  = nwords;
    483         r_initiator_fsm =  M_WRITE_CMD;
    484         break;
     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;
    485445    }
    486446    /////////////////
     
    488448    {
    489449            if ( p_vci_initiator.cmdack.read() ) r_initiator_fsm = M_WRITE_RSP;
    490         break;
     450        break;
    491451    }
    492452    /////////////////
    493453    case M_WRITE_RSP:   // This is actually a multi-words VCI READ response
    494454    {
    495         if ( p_vci_initiator.rspval.read() )
    496         {
    497             bool aligned = (r_burst_offset.read() == 0);
    498 
    499             if ( (vci_param::B == 8) and (r_burst_nwords.read() > 1) )
    500             {
    501                 r_local_buffer[r_index.read()]   = (uint32_t)p_vci_initiator.rdata.read();
    502                 r_local_buffer[r_index.read()+1] = (uint32_t)(p_vci_initiator.rdata.read()>>32);
    503                 r_index = r_index.read() + 2;
    504             }
    505             else
    506             {
    507                 r_local_buffer[r_index.read()]   = (uint32_t)p_vci_initiator.rdata.read();
    508                 r_index = r_index.read() + 1;
    509             }
    510 
    511             if ( p_vci_initiator.reop.read() )  // last flit of the burst
    512             {
    513                     r_words_count  = 0;
    514                 r_buf_address = r_buf_address.read() + (r_burst_nwords.read()<<2);
    515 
    516                     if( (p_vci_initiator.rerror.read()&0x1) != 0 )
    517                 {
    518                     r_initiator_fsm = M_WRITE_ERROR;
     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;
    519479#ifdef SOCLIB_MODULE_DEBUG
    520480                    std::cout << "vci_bd M_WRITE_ERROR" << std::endl;
    521481#endif
    522                 }
    523                 else if ( (not aligned and (r_burst_count.read() == m_bursts_per_block)) or
    524                      (aligned and (r_burst_count.read() == (m_bursts_per_block-1))) ) // last burst
    525                 {
    526                     r_initiator_fsm  = M_WRITE_BLOCK;
    527                 }
    528                 else                                          // not the last burst
    529                 {
    530                     r_burst_count = r_burst_count.read() + 1;
    531                     r_initiator_fsm = M_WRITE_BURST;
    532                 }
    533             }
    534             else
    535             {
    536                     r_words_count = r_words_count.read() + 1;
    537             }
    538         }
    539         break;
     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;
    540500    }
    541501    ///////////////////
    542502    case M_WRITE_BLOCK:         // write a block to disk after waiting m_latency cycles
    543503    {
    544         if ( r_block_count.read() == r_nblocks.read() - 1 )
    545         {
    546             r_initiator_fsm = M_WRITE_SUCCESS;
     504        if ( r_block_count.read() == r_nblocks.read() - 1 )
     505        {
     506            r_initiator_fsm = M_WRITE_SUCCESS;
    547507#ifdef SOCLIB_MODULE_DEBUG
    548508            std::cout << "vci_bd M_WRITE_SUCCESS" << std::endl;
    549509#endif
    550         }
    551         else
    552         {
    553             r_burst_count    = 0;
    554             r_index          = 0;
    555             r_block_count    = r_block_count.read() + 1;
    556             r_initiator_fsm  = M_WRITE_BURST;
    557         }
    558         break;
     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;
    559519    }
    560520    /////////////////////
     
    562522    case M_WRITE_ERROR:
    563523    {
    564         r_initiator_fsm = M_IDLE;
    565         break;
     524        r_initiator_fsm = M_IDLE;
     525        break;
    566526    }
    567527    } // end switch r_initiator_fsm
     
    579539    switch(r_target_fsm) {
    580540    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;
    655569    } // end switch target fsm
    656570
     
    666580    switch (r_initiator_fsm) {
    667581    case M_WRITE_CMD:           // It is actually a single flit VCI read command
    668         p_vci_initiator.rspack  = false;
    669         p_vci_initiator.cmdval  = true;
    670         p_vci_initiator.address = (sc_dt::sc_uint<vci_param::N>)r_buf_address.read();
    671         p_vci_initiator.cmd     = vci_param::CMD_READ;
    672         p_vci_initiator.pktid   = TYPE_READ_DATA_UNC;
    673         p_vci_initiator.wdata   = 0;
    674         p_vci_initiator.be      = 0;
    675         p_vci_initiator.plen    = (sc_dt::sc_uint<vci_param::K>)(r_burst_nwords.read()<<2);
    676         p_vci_initiator.eop     = true;
    677         break;
     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;
    678592    case M_READ_CMD:            // It is actually a multi-words VCI WRITE command
    679         p_vci_initiator.rspack  = false;
    680         p_vci_initiator.cmdval  = true;
    681         p_vci_initiator.address = (sc_dt::sc_uint<vci_param::N>)r_buf_address.read();
    682         p_vci_initiator.cmd     = vci_param::CMD_WRITE;
    683         p_vci_initiator.pktid   = TYPE_WRITE;
    684         p_vci_initiator.plen    = (sc_dt::sc_uint<vci_param::K>)(r_burst_nwords.read()<<2);
    685         if ( (vci_param::B == 8) and ((r_burst_nwords.read() - r_words_count.read()) > 1) ) 
    686         {
    687             p_vci_initiator.wdata = ((uint64_t)r_local_buffer[r_index.read()  ]) +
    688                                    (((uint64_t)r_local_buffer[r_index.read()+1]) << 32);
    689             p_vci_initiator.be    = 0xFF;
    690             p_vci_initiator.eop   = ( (r_burst_nwords.read() - r_words_count.read()) <= 2 );
    691         }
    692         else
    693         {
    694             p_vci_initiator.wdata = r_local_buffer[r_index.read()];
    695             p_vci_initiator.be    = 0xF;
    696             p_vci_initiator.eop   = ( r_words_count.read() == (r_burst_nwords.read() - 1) );
    697         }
    698         break;
     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;
    699613    case M_READ_RSP:
    700614    case M_WRITE_RSP:
    701         p_vci_initiator.rspack  = true;
    702         p_vci_initiator.cmdval  = false;
    703         break;
     615        p_vci_initiator.rspack  = true;
     616        p_vci_initiator.cmdval  = false;
     617        break;
    704618    default:
    705         p_vci_initiator.rspack  = false;
    706         p_vci_initiator.cmdval  = false;
    707         break;
     619        p_vci_initiator.rspack  = false;
     620        p_vci_initiator.cmdval  = false;
     621        break;
    708622    }
    709623
     
    726640
    727641//////////////////////////////////////////////////////////////////////////////
    728 tmpl(/**/)::VciSpi( sc_core::sc_module_name              name,
    729                                 const soclib::common::MappingTable   &mt,
    730                                 const soclib::common::IntTab        &srcid,
    731                                 const soclib::common::IntTab        &tgtid,
    732                                 const uint32_t                       burst_size)
     642tmpl(/**/)::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)
    733647
    734648: caba::BaseModule(name),
     
    762676    for ( seg = m_seglist.begin() ; seg != m_seglist.end() ; seg++ )
    763677    {
    764         nbsegs++;
    765        
     678        nbsegs++;
     679       
    766680            if ( (seg->baseAddress() & 0x0000003F) != 0 )
    767681            {
    768682                    std::cout << "Error in component VciSpi : " << name
    769                               << "The base address of segment " << seg->name()
    770                       << " must be multiple of 64 bytes" << std::endl;
     683                              << "The base address of segment " << seg->name()
     684                      << " must be multiple of 64 bytes" << std::endl;
    771685                    exit(1);
    772686            }
     
    774688            {
    775689                    std::cout << "Error in component VciSpi : " << name
    776                           << "The size of segment " << seg->name()
    777                       << " cannot be smaller than 64 bytes" << std::endl;
     690                          << "The size of segment " << seg->name()
     691                      << " cannot be smaller than 64 bytes" << std::endl;
    778692                    exit(1);
    779693            }
    780         std::cout << "    => segment " << seg->name()
    781                   << " / base = " << std::hex << seg->baseAddress()
    782                   << " / size = " << seg->size() << std::endl;
     694        std::cout << "    => segment " << seg->name()
     695                  << " / base = " << std::hex << seg->baseAddress()
     696                  << " / size = " << seg->size() << std::endl;
    783697    }
    784698
     
    786700    {
    787701                std::cout << "Error in component VciSpi : " << name
    788                           << " No segment allocated" << std::endl;
     702                          << " No segment allocated" << std::endl;
    789703                exit(1);
    790704    }
     
    796710        {
    797711                std::cout << "Error in component VciSpi : " << name
    798                           << " The burst size must be 8, 16, 32 or 64 bytes" << std::endl;
     712                          << " The burst size must be 8, 16, 32 or 64 bytes" << std::endl;
    799713                exit(1);
    800714        }
     
    802716        if ( (vci_param::B != 4) and (vci_param::B != 8) )
    803717        {
    804                 std::cout << "Error in component VciSpi : " << name             
    805                           << " The VCI data fields must have 32 bits or 64 bits" << std::endl;
     718                std::cout << "Error in component VciSpi : " << name          
     719                          << " The VCI data fields must have 32 bits or 64 bits" << std::endl;
    806720                exit(1);
    807721        }
     
    839753        };
    840754        const char* target_str[] =
    841     {
     755        {
    842756                "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",
    853761        };
    854762        const char* spi_str[] =
    855     {
     763        {
    856764                "S_IDLE",
    857765                "S_XMIT",
     
    872780            << std::endl;
    873781        std::cout << name() << "  _INI : " << initiator_str[r_initiator_fsm.read()]
    874           << "  buf = " << std::hex << r_buf_address.read()
     782          << "  buf = " << std::hex << r_buf_address.read()
    875783          << "  block = " << std::dec << r_block_count.read()
    876784          << "  burst = " << r_burst_count.read()
Note: See TracChangeset for help on using the changeset viewer.