Ignore:
Timestamp:
Jun 21, 2017, 10:50:42 AM (7 years ago)
Author:
alain
Message:

few bugs

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/modules/vci_spi/caba/source/src/vci_spi.cpp

    r595 r1052  
    4646
    4747    bool s_dma_bsy = (r_initiator_fsm != M_IDLE);
     48
    4849    if(p_resetn.read() == false)
    4950    {
    50         r_initiator_fsm   = M_IDLE;
    51         r_target_fsm      = T_IDLE;
    52         r_spi_fsm         = S_IDLE;
    53         r_ss              = 0;
    54         r_divider         = 0xffff;
    55         r_ctrl_char_len   = 0;
    56         r_ctrl_ie         = false;
    57         r_ctrl_cpol       = false;
    58         r_ctrl_cpha       = false;
    59         r_spi_bsy         = false;
    60         r_dma_count       = 0;
    61         r_dma_error       = false;
    62         r_spi_clk_counter = 0xffff;
    63         r_spi_clk         = 0;
    64         r_spi_done        = false;
    65 
    66         r_irq             = false;
    67         r_read            = false;
    68 
    69         r_dma_fifo_read.init();
    70         r_dma_fifo_write.init();
    71 
    72         return;
     51            r_initiator_fsm   = M_IDLE;
     52            r_target_fsm      = T_IDLE;
     53            r_spi_fsm         = S_IDLE;
     54            r_ss                  = 0;
     55            r_divider         = 0xffff;
     56            r_ctrl_char_len   = 0;
     57            r_ctrl_ie         = false;
     58            r_ctrl_cpol       = false;
     59            r_ctrl_cpha       = false;
     60            r_spi_bsy         = false;
     61            r_dma_count       = 0;
     62            r_dma_error       = false;
     63            r_spi_clk_counter = 0xffff;
     64            r_spi_clk         = 0;
     65            r_spi_done        = false;
     66
     67            r_irq                     = false;
     68            r_read                    = false;
     69
     70            r_dma_fifo_read.init();
     71            r_dma_fifo_write.init();
     72
     73            return;
    7374    }
    7475
    7576    //////////////////////////////////////////////////////////////////////////////
    76     // The Target FSM controls the following registers:
    77     // r_target_fsm, r_irq_enable, r_nblocks, r_buf adress, r_lba, r_go, r_read
     77    // The Target FSM handles the software access to addressable registers
    7878    //////////////////////////////////////////////////////////////////////////////
    7979
     
    8181        r_spi_bsy = false;
    8282
    83     switch(r_target_fsm) {
     83    switch(r_target_fsm)
     84    {
    8485    ////////////
    8586    case T_IDLE:
    8687    {
    87         if ( p_vci_target.cmdval.read() )
    88         {
    89             r_srcid = p_vci_target.srcid.read();
    90             r_trdid = p_vci_target.trdid.read();
    91             r_pktid = p_vci_target.pktid.read();
    92             uint32_t wdata = p_vci_target.wdata.read();
    93             sc_dt::sc_uint<vci_param::N> address = p_vci_target.address.read();
    94 
    95             bool found = false;
    96             std::list<soclib::common::Segment>::iterator seg;
    97             for ( seg = m_seglist.begin() ; seg != m_seglist.end() ; seg++ )
    98             {
    99                 if ( seg->contains(address) ) found = true;
    100             }
     88        if ( p_vci_target.cmdval.read() )
     89        {
     90                r_srcid = p_vci_target.srcid.read();
     91                r_trdid = p_vci_target.trdid.read();
     92                r_pktid = p_vci_target.pktid.read();
     93                uint32_t wdata = p_vci_target.wdata.read();
     94                sc_dt::sc_uint<vci_param::N> address = p_vci_target.address.read();
     95
     96                bool found = false;
     97                std::list<soclib::common::Segment>::iterator seg;
     98                for ( seg = m_seglist.begin() ; seg != m_seglist.end() ; seg++ )
     99                {
     100                        if ( seg->contains(address) ) found = true;
     101                }
    101102 
    102 
    103             if (not found) {
    104                 if (p_vci_target.cmd.read() == vci_param::CMD_WRITE)
    105                     r_target_fsm = T_ERROR_WRITE;
    106                 else
     103                if (not found)
     104            {
     105                        if (p_vci_target.cmd.read() == vci_param::CMD_WRITE)
     106                    r_target_fsm = T_ERROR_WRITE;
     107                        else
     108                        r_target_fsm = T_ERROR_READ;
     109                }
     110            else if (p_vci_target.cmd.read() != vci_param::CMD_READ &&
     111                             p_vci_target.cmd.read() != vci_param::CMD_WRITE)
     112            {
    107113                    r_target_fsm = T_ERROR_READ;
    108             } else if (p_vci_target.cmd.read() != vci_param::CMD_READ &&
    109                        p_vci_target.cmd.read() != vci_param::CMD_WRITE) {
    110                 r_target_fsm = T_ERROR_READ;
    111             } else {
    112                 bool     write  = (p_vci_target.cmd.read() == vci_param::CMD_WRITE) & !r_spi_bsy &!s_dma_bsy;
    113                 uint32_t cell   = (uint32_t)((address & 0x3F)>>2);
    114                 switch(cell) {
    115                 case SPI_DATA_TXRX0:
    116                     r_rdata = r_txrx[0] & (uint64_t)0x00000000ffffffffULL;
    117                     if (write) {
    118                         r_txrx[0] =
    119                            (r_txrx[0] & (uint64_t)0xffffffff00000000ULL) |
    120                            ((uint64_t)wdata);
    121                     }
    122                     r_target_fsm = (p_vci_target.cmd.read() == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ;
    123                     break;
    124                 case SPI_DATA_TXRX1:
    125                     r_rdata = r_txrx[0] >> 32;
    126                     if (write) {
    127                         r_txrx[0] =
    128                             (r_txrx[0] & (uint64_t)0x00000000ffffffffULL) |
    129                             ((uint64_t)wdata << 32);
    130                     }
    131                     r_target_fsm = (p_vci_target.cmd.read() == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ;
    132                     break;
    133                 case SPI_DATA_TXRX2:
    134                     r_rdata = r_txrx[1] & (uint64_t)0x00000000ffffffffULL;
    135                     if (write) {
    136                         r_txrx[1] =
    137                            (r_txrx[1] & (uint64_t)0xffffffff00000000ULL) |
    138                            ((uint64_t)wdata);
    139                     }
    140                     r_target_fsm = (p_vci_target.cmd.read() == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ;
    141                     break;
    142                 case SPI_DATA_TXRX3:
    143                     r_rdata = r_txrx[1] >> 32;
    144                     if (write) {
    145                         r_txrx[1] =
    146                             (r_txrx[1] & (uint64_t)0x00000000ffffffffULL) |
    147                             ((uint64_t)wdata << 32);
    148                     }
    149                     r_target_fsm = (p_vci_target.cmd.read() == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ;
    150                     break;
    151                 case SPI_CTRL:
    152                 {
    153                     uint32_t data = 0;
    154                     if (r_ctrl_cpol.read())
    155                         data |= SPI_CTRL_CPOL;
    156                     if (r_ctrl_cpha.read())
    157                         data |= SPI_CTRL_CPHA;
    158                     if (r_ctrl_ie.read())
    159                         data |= SPI_CTRL_IE_EN;
    160                     if (r_spi_bsy.read())
    161                         data |= SPI_CTRL_GO_BSY;
    162                     if (s_dma_bsy)
    163                         data |= SPI_CTRL_DMA_BSY;
    164                     if (r_dma_error)
    165                         data |= SPI_CTRL_DMA_ERR;
    166                     data |= (uint32_t)r_ctrl_char_len.read();
    167                     r_rdata = data;
    168                     if (write) {
    169                         r_ctrl_cpol = ((wdata & SPI_CTRL_CPOL) != 0);
    170                         r_ctrl_cpha = ((wdata & SPI_CTRL_CPHA) != 0);
    171                         r_ctrl_ie  = ((wdata & SPI_CTRL_IE_EN) != 0);
    172                         if (wdata & SPI_CTRL_GO_BSY)
    173                                 r_spi_bsy = true;
    174                         r_ctrl_char_len = (wdata & SPI_CTRL_CHAR_LEN_MASK);
     114                }
     115            else
     116            {
     117                        bool     write  = (p_vci_target.cmd.read() == vci_param::CMD_WRITE)
     118                                   & !r_spi_bsy & !s_dma_bsy;
     119                uint32_t cell   = (uint32_t)((address & 0x3F)>>2);
     120                        switch(cell)
     121                {
     122                            case SPI_DATA_TXRX0:
     123                            r_rdata = r_txrx[0] & (uint64_t)0x00000000ffffffffULL;
     124                            if (write)
     125                    {
     126                                    r_txrx[0] = (r_txrx[0] & (uint64_t)0xffffffff00000000ULL) |
     127                                                ((uint64_t)wdata);
     128                            }
     129                            r_target_fsm = (p_vci_target.cmd.read()
     130                                     == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ;
     131                            break;
     132                            case SPI_DATA_TXRX1:
     133                            r_rdata = r_txrx[0] >> 32;
     134                            if (write)
     135                    {
     136                                    r_txrx[0] = (r_txrx[0] & (uint64_t)0x00000000ffffffffULL) |
     137                                                ((uint64_t)wdata << 32);
     138                            }
     139                            r_target_fsm = (p_vci_target.cmd.read()
     140                                    == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ;
     141                            break;
     142                            case SPI_DATA_TXRX2:
     143                            r_rdata = r_txrx[1] & (uint64_t)0x00000000ffffffffULL;
     144                            if (write)
     145                    {
     146                                    r_txrx[1] = (r_txrx[1] & (uint64_t)0xffffffff00000000ULL) |
     147                                                ((uint64_t)wdata);
     148                            }
     149                            r_target_fsm = (p_vci_target.cmd.read()
     150                                    == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ;
     151                            break;
     152                            case SPI_DATA_TXRX3:
     153                            r_rdata = r_txrx[1] >> 32;
     154                            if (write)
     155                    {
     156                                r_txrx[1] = (r_txrx[1] & (uint64_t)0x00000000ffffffffULL) |
     157                                                ((uint64_t)wdata << 32);
     158                            }
     159                            r_target_fsm = (p_vci_target.cmd.read()
     160                                    == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ;
     161                            break;
     162                            case SPI_CTRL:
     163                            uint32_t data = 0;
     164                            if (r_ctrl_cpol.read()) data |= SPI_CTRL_CPOL;
     165                            if (r_ctrl_cpha.read()) data |= SPI_CTRL_CPHA;
     166                            if (r_ctrl_ie.read())   data |= SPI_CTRL_IE_EN;
     167                            if (r_spi_bsy.read())   data |= SPI_CTRL_GO_BSY;
     168                            if (s_dma_bsy)          data |= SPI_CTRL_DMA_BSY;
     169                            if (r_dma_error)        data |= SPI_CTRL_DMA_ERR;
     170                            data |= (uint32_t)r_ctrl_char_len.read();
     171                            r_rdata = data;
     172                            if (write)
     173                    {
     174                        r_ctrl_cpol = ((wdata & SPI_CTRL_CPOL) != 0);
     175                        r_ctrl_cpha = ((wdata & SPI_CTRL_CPHA) != 0);
     176                        r_ctrl_ie  = ((wdata & SPI_CTRL_IE_EN) != 0);
     177                        if (wdata & SPI_CTRL_GO_BSY) r_spi_bsy = true;
     178                                    r_ctrl_char_len = (wdata & SPI_CTRL_CHAR_LEN_MASK);
     179
    175180#ifdef SOCLIB_MODULE_DEBUG
    176181                        if ((wdata & SPI_CTRL_GO_BSY) != 0) {
     
    178183                        }
    179184#endif
    180                     } else {
    181                         r_irq = false;
    182                     }
    183                     r_target_fsm = (p_vci_target.cmd.read() == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ;
    184                     break;
    185                 }
    186                 case SPI_DIVIDER:
    187                     r_rdata = r_divider.read();
    188                     if (write) {
     185                    }
     186                    else
     187                    {
     188                                    r_irq = false;
     189                            }
     190                            r_target_fsm = (p_vci_target.cmd.read()
     191                                    == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ;
     192                            break;
     193                            case SPI_DIVIDER:
     194                            r_rdata = r_divider.read();
     195                            if (write) r_divider = wdata;
     196
    189197#ifdef SOCLIB_MODULE_DEBUG
    190198                        std::cout << name() << " divider set to " << std::dec << wdata << std::endl;
    191199#endif
    192                         r_divider = wdata;
    193                     }
    194                     r_target_fsm = (p_vci_target.cmd.read() == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ;
    195                     break;
    196                 case SPI_SS:
    197                     r_rdata = r_ss.read();
    198                     if (write) {
    199                         r_ss = wdata;
    200                     }
    201                     r_target_fsm = (p_vci_target.cmd.read() == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ;
    202                     break;
    203                 case SPI_DMA_BASE:
    204                     r_rdata = r_buf_address.read();
    205                     if (write) {
    206                         r_buf_address = (r_buf_address & (uint64_t)0xffffffff00000000) | wdata;
    207                     }
    208                     r_target_fsm = (p_vci_target.cmd.read() == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ;
    209                     break;
    210                 case SPI_DMA_BASEH:
    211                     r_rdata = r_buf_address >> 32;
    212                     if (write) {
    213                         r_buf_address = (r_buf_address & (uint64_t)0x00000000ffffffff) | ((uint64_t)wdata << 32);
    214                     }
    215                     r_target_fsm = (p_vci_target.cmd.read() == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ;
    216                     break;
    217                 case SPI_DMA_COUNT:
    218                     r_rdata = (r_dma_count.read() << m_byte2burst_shift) |
    219                         r_read;
    220                     if (write) {
    221                         r_read = (wdata & 0x1);
    222                         r_dma_count = wdata >> m_byte2burst_shift;
    223                         r_ctrl_char_len = vci_param::B * 8;
    224                     }
    225                     r_target_fsm = (p_vci_target.cmd.read() == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ;
    226                     break;
    227                 default:
    228                     r_target_fsm = (p_vci_target.cmd.read() == vci_param::CMD_WRITE) ? T_ERROR_WRITE : T_ERROR_READ;
    229                     break;
    230                 }
    231             }
    232         }
    233         break;
     200                            r_target_fsm = (p_vci_target.cmd.read()
     201                                    == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ;
     202                            break;
     203                            case SPI_SS:
     204                            r_rdata = r_ss.read();
     205                            if (write) r_ss = wdata;
     206                            r_target_fsm = (p_vci_target.cmd.read()
     207                                    == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ;
     208                            break;
     209                            case SPI_DMA_BASE:
     210                            r_rdata = r_buf_address.read();
     211                            if (write) r_buf_address = (r_buf_address.read &
     212                                    (uint64_t)0xffffffff00000000) | wdata;
     213                            r_target_fsm = (p_vci_target.cmd.read()
     214                                    == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ;
     215                            break;
     216                    case SPI_DMA_BASEH:
     217                            r_rdata = r_buf_address >> 32;
     218                            if (write) r_buf_address = (r_buf_address &
     219                                    (uint64_t)0x00000000ffffffff) | ((uint64_t)wdata << 32);
     220                            r_target_fsm = (p_vci_target.cmd.read()
     221                                    == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ;
     222                            break;
     223                            case SPI_DMA_COUNT:
     224                            r_rdata = (r_dma_count.read() << m_byte2burst_shift) | r_read;
     225                            if (write)
     226                    {
     227                                    r_read = (wdata & 0x1);
     228                        r_dma_count = wdata >> m_byte2burst_shift;
     229                                    r_ctrl_char_len = vci_param::B * 8;
     230                            }
     231                            r_target_fsm = (p_vci_target.cmd.read()
     232                                    == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ;
     233                            break;
     234                            default:
     235                            r_target_fsm = (p_vci_target.cmd.read()
     236                                  == vci_param::CMD_WRITE) ? T_ERROR_WRITE : T_ERROR_READ;
     237                            break;
     238                        }
     239                }
     240            }
     241            break;
    234242    }
    235243    ////////////////////
     
    238246    case T_ERROR_READ:
    239247    case T_ERROR_WRITE:
    240         if (p_vci_target.rspack.read() ) {
    241             r_target_fsm  = T_IDLE;
    242         }
    243         break;
     248    {
     249            if (p_vci_target.rspack.read() ) r_target_fsm  = T_IDLE;
     250            break;
     251    }
    244252    } // end switch target fsm
    245253
     
    252260    if (r_spi_bsy == false)
    253261        r_spi_done = false;
    254     switch (r_spi_fsm) {
    255     case S_IDLE:
    256         r_spi_clk_counter = r_divider.read();
    257         r_spi_clk = 0;
    258         r_spi_clk_previous = r_ctrl_cpha;
    259         r_spi_clk_ignore = r_ctrl_cpha;
    260         r_spi_bit_count = r_ctrl_char_len;
    261         if (r_dma_count != 0) {
    262                 if (r_read.read())
    263                         r_spi_fsm = S_DMA_SEND_START;
    264                 else
    265                         r_spi_fsm = S_DMA_RECEIVE;
    266         } else if (r_spi_bsy.read() && !r_spi_done.read()) {
     262 
     263    switch (r_spi_fsm)
     264    {
     265    ////////////
     266    case S_IDLE:   // polling the (r_dma_count/r_read) registers for dma request
     267                   // polling the r_spi_bsy register for config request
     268    {
     269        r_spi_clk_counter = r_divider.read();
     270        r_spi_clk = 0;
     271        r_spi_clk_previous = r_ctrl_cpha;
     272        r_spi_clk_ignore = r_ctrl_cpha;
     273            r_spi_bit_count = r_ctrl_char_len;
     274        if (r_dma_count != 0)
     275        {
     276                    if (r_read.read()) r_spi_fsm = S_DMA_SEND_START;
     277                    else               r_spi_fsm = S_DMA_RECEIVE;
     278            }
     279        else if (r_spi_bsy.read() && !r_spi_done.read())
     280        {
     281                r_spi_fsm = S_XMIT;
     282                r_spi_out = (r_txrx[(r_ctrl_char_len -1)/ 64] >> ((r_ctrl_char_len - 1) % 64))
     283                          & (uint64_t)0x0000000000000001ULL;
     284            }
     285            break;
     286    }
     287    ///////////////////
     288    case S_DMA_RECEIVE:  // copy one word from fifo_write to shift register
     289    {
     290            r_spi_clk_counter = r_divider.read();
     291            r_spi_clk = 0;
     292            r_spi_clk_previous = r_ctrl_cpha;
     293            r_spi_clk_ignore = r_ctrl_cpha;
     294            r_spi_bit_count = r_ctrl_char_len;
     295            if (r_initiator_fsm != M_WRITE_RSP || !p_vci_initiator.rspval.read())
     296        {
     297                if (r_dma_fifo_write.rok())
     298            {
     299                    typename vci_param::data_t v = r_dma_fifo_write.read();
     300                    r_dma_fifo_write.simple_get();
     301                    r_txrx[0] = v;
     302                    r_spi_out = (v >> ((vci_param::B * 8) - 1)) & 0x1;
     303                    r_spi_fsm = S_XMIT;
     304                }
     305            else if (r_initiator_fsm == M_WRITE_END)
     306            {
     307                    r_spi_fsm = S_IDLE;
     308                }
     309            }
     310            break;
     311    }
     312    //////////////////////
     313    case S_DMA_SEND_START:
     314    {
     315            r_spi_word_count = (r_dma_count << (m_byte2burst_shift - 2)) - 1;
     316            r_spi_out = 1;
     317            r_txrx[0] = 0xffffffff;
    267318            r_spi_fsm = S_XMIT;
    268             r_spi_out = (r_txrx[(r_ctrl_char_len -1)/ 64] >> ((r_ctrl_char_len - 1) % 64)) & (uint64_t)0x0000000000000001ULL;
    269         }
    270         break;
    271     case S_DMA_RECEIVE:
    272     {
    273         r_spi_clk_counter = r_divider.read();
    274         r_spi_clk = 0;
    275         r_spi_clk_previous = r_ctrl_cpha;
    276         r_spi_clk_ignore = r_ctrl_cpha;
    277         r_spi_bit_count = r_ctrl_char_len;
    278         if (r_initiator_fsm != M_WRITE_RSP || !p_vci_initiator.rspval.read()) {
    279             if (r_dma_fifo_write.rok()) {
    280                 typename vci_param::data_t v = r_dma_fifo_write.read();
    281                 r_dma_fifo_write.simple_get();
    282                 r_txrx[0] = v;
    283                 r_spi_out = (v >> ((vci_param::B * 8) - 1)) & 0x1;
    284                 r_spi_fsm = S_XMIT;
    285             } else if (r_initiator_fsm == M_WRITE_END) {
    286                 r_spi_fsm = S_IDLE;
    287             }
    288         }
    289         break;
    290     }
    291     case S_DMA_SEND_START:
    292         r_spi_word_count = (r_dma_count << (m_byte2burst_shift - 2)) - 1;
    293         r_spi_out = 1;
    294         r_txrx[0] = 0xffffffff;
    295         r_spi_fsm = S_XMIT;
    296         break;
     319            break;
     320    }
     321    ////////////////
    297322    case S_DMA_SEND:
    298         r_spi_out = 1;
    299         r_spi_clk_counter = r_divider.read();
    300         r_spi_clk = 0;
    301         r_spi_clk_previous = r_ctrl_cpha;
    302         r_spi_clk_ignore = r_ctrl_cpha;
    303         r_spi_bit_count = r_ctrl_char_len;
    304         if (r_initiator_fsm != M_READ_CMD) {
    305             if (r_dma_fifo_read.wok()) {
    306                 r_dma_fifo_read.simple_put(
    307                     (typename vci_param::data_t)r_txrx[0]);
    308                 r_spi_word_count = r_spi_word_count - 1;
    309                 r_txrx[0] = 0xffffffff;
    310                 if ( r_spi_word_count == 0 ) {
    311                     r_spi_fsm = S_DMA_SEND_END;
    312                 } else {
    313                     r_spi_fsm = S_XMIT;
    314                 }
    315             }
    316         }
    317         break;
    318     case S_DMA_SEND_END:
    319         if (r_initiator_fsm == M_IDLE)
    320                 r_spi_fsm = S_IDLE;
    321         break;
    322     case S_XMIT:
    323       {
    324         bool s_clk_sample;
    325         // on clock transition, sample input line, and shift data
    326         s_clk_sample = r_spi_clk ^ r_ctrl_cpha;
    327         if (!r_spi_clk_ignore) {
    328             if (r_spi_clk_previous == 0 && s_clk_sample == 1) {
    329                 // low to high transition: shift and sample
    330                 r_txrx[1] = (r_txrx[1] << 1) | (r_txrx[0] >> 63);
    331                 r_txrx[0] = (r_txrx[0] << 1) | p_spi_miso;
    332                 r_spi_bit_count = r_spi_bit_count - 1;
    333             } else if (r_spi_clk_previous == 1 && s_clk_sample == 0) {
    334                 // high to low transition: change output, or stop
    335                 if (r_spi_bit_count == 0) {
    336                     if (r_initiator_fsm != M_IDLE) {
    337                         if (r_read)
    338                             r_spi_fsm = S_DMA_SEND;
    339                         else
    340                             r_spi_fsm = S_DMA_RECEIVE;
    341                     } else {
    342                         r_spi_fsm = S_IDLE;
    343                         r_irq = r_ctrl_ie;
    344                         r_spi_done = true;
    345                     }
     323        {
     324        r_spi_out = 1;
     325            r_spi_clk_counter = r_divider.read();
     326            r_spi_clk = 0;
     327            r_spi_clk_previous = r_ctrl_cpha;
     328            r_spi_clk_ignore = r_ctrl_cpha;
     329            r_spi_bit_count = r_ctrl_char_len;
     330            if (r_initiator_fsm != M_READ_CMD)
     331        {
     332                if (r_dma_fifo_read.wok())
     333            {
     334                    r_dma_fifo_read.simple_put( (typename vci_param::data_t)r_txrx[0] );
     335                    r_spi_word_count = r_spi_word_count - 1;
     336                        r_txrx[0] = 0xffffffff;
     337                    if ( r_spi_word_count == 0 ) r_spi_fsm = S_DMA_SEND_END;
     338                else                         r_spi_fsm = S_XMIT;
     339                }
     340            }
     341            break;
     342    }
     343    ////////////////////
     344    case S_DMA_SEND_END:
     345    {
     346            if (r_initiator_fsm == M_IDLE) r_spi_fsm = S_IDLE;
     347            break;
     348    }
     349    ////////////
     350    case S_XMIT:   // on SPI clock transitions, sample input line, and shift data
     351    {
     352        bool s_clk_sample;
     353            // on clock transition, sample input line, and shift data
     354            s_clk_sample = r_spi_clk ^ r_ctrl_cpha;
     355
     356            if ( !r_spi_clk_ignore )
     357        {
     358                if (r_spi_clk_previous == 0 && s_clk_sample == 1)
     359            {
     360                        // low to high transition: shift and sample
     361                        r_txrx[1] = (r_txrx[1] << 1) | (r_txrx[0] >> 63);
     362                        r_txrx[0] = (r_txrx[0] << 1) | p_spi_miso;
     363                        r_spi_bit_count = r_spi_bit_count - 1;
     364                }
     365            else if (r_spi_clk_previous == 1 && s_clk_sample == 0)
     366            {
     367                        // high to low transition: change output, or stop
     368                        if (r_spi_bit_count == 0)
     369                {
     370                            if (r_initiator_fsm != M_IDLE)
     371                    {
     372                                    if (r_read) r_spi_fsm = S_DMA_SEND;
     373                                    else        r_spi_fsm = S_DMA_RECEIVE;
     374                            }
     375                    else
     376                    {
     377                                r_spi_fsm = S_IDLE;
     378                                r_irq = r_ctrl_ie;
     379                                r_spi_done = true;
     380                            }
    346381#ifdef SOCLIB_MODULE_DEBUG0
    347382                    std::cout << name() << " end xfer " << std::dec << (int)r_ctrl_char_len.read() << " data " << std::hex << r_txrx[1] << " " << r_txrx[0] << std::endl;
    348383#endif
    349                 } else {
    350                     r_spi_out = (r_txrx[(r_ctrl_char_len -1)/ 64] >> ((r_ctrl_char_len - 1) % 64)) & (uint64_t)0x0000000000000001ULL;
    351                 }
    352             }
    353         }
    354         r_spi_clk_previous = s_clk_sample;
    355         // generate the SPI clock
    356         if (r_spi_clk_counter.read() == 0) {
    357             r_spi_clk_counter = r_divider.read();
    358             r_spi_clk = !r_spi_clk.read();
    359             r_spi_clk_ignore = false;
    360         } else {
    361             r_spi_clk_counter = r_spi_clk_counter.read() - 1;
    362         }
    363         break;
    364       }
    365     }
     384                        }
     385                else
     386                {
     387                            r_spi_out = (r_txrx[(r_ctrl_char_len -1)/ 64] >> ((r_ctrl_char_len - 1) % 64))
     388                                 & (uint64_t)0x0000000000000001ULL;
     389                        }
     390                }
     391            }
     392            r_spi_clk_previous = s_clk_sample;
     393
     394            // generate the SPI clock
     395        if (r_spi_clk_counter.read() == 0)
     396        {
     397                r_spi_clk_counter = r_divider.read();
     398                r_spi_clk = !r_spi_clk.read();
     399                r_spi_clk_ignore = false;
     400            }
     401        else
     402        {
     403                r_spi_clk_counter = r_spi_clk_counter.read() - 1;
     404        }
     405            break;
     406    }
     407    }  // end r_spi_fsm
     408
    366409    //////////////////////////////////////////////////////////////////////////////
    367410    // The initiator FSM executes a loop, transfering one burst per iteration.
     
    370413    //////////////////////////////////////////////////////////////////////////////
    371414
    372     switch( r_initiator_fsm.read() ) {
     415    switch( r_initiator_fsm.read() )
     416    {
    373417    ////////////
    374     case M_IDLE:        // check buffer alignment to compute the number of bursts
    375     {
    376         if ( r_dma_count != 0 )
    377         {
    378             // start transfer
    379             if ( r_read.read() )    r_initiator_fsm = M_READ_WAIT;
    380             else                    r_initiator_fsm = M_WRITE_WAIT;
    381         }
    382         break;
    383     }
     418    case M_IDLE:        // poll the r_dma_count and r_read registers
     419    {
     420            if ( r_dma_count != 0 )
     421            {
     422                // start transfer
     423                if ( r_read.read() )    r_initiator_fsm = M_READ_WAIT;
     424                else                        r_initiator_fsm = M_WRITE_WAIT;
     425            }
     426            break;
     427    }
     428    /////////////////
    384429    case M_READ_WAIT:  // wait for the FIFO to be full
    385         if (!r_dma_fifo_read.wok()) {
    386                 r_burst_word = m_words_per_burst - 1;
    387                 r_initiator_fsm = M_READ_CMD;
    388         }
    389         break;
     430    {
     431            if (!r_dma_fifo_read.wok())
     432        {
     433                    r_burst_word = m_words_per_burst - 1;
     434                    r_initiator_fsm = M_READ_CMD;
     435            }
     436            break;
     437    }
    390438    ////////////////
    391     case M_READ_CMD:    // Send a multi-flits VCI WRITE command
    392     {
    393         if ( p_vci_initiator.cmdack.read() )
    394         {
    395             if ( r_burst_word == 0 )      // last flit
     439    case M_READ_CMD:    // multi-flits VCI WRITE command for one burst
     440    {
     441            if ( p_vci_initiator.cmdack.read() )
    396442            {
    397                 r_initiator_fsm = M_READ_RSP;
    398             }
    399             else                    // not the last flit
    400             {
    401                 r_burst_word = r_burst_word.read() - 1;
    402             }
    403 
    404             r_dma_fifo_read.simple_get(); // consume one fifo word
    405             // compute next word address
    406             r_buf_address = r_buf_address.read() + vci_param::B;
    407         }
    408         break;
     443                if ( r_burst_word == 0 )      // last flit
     444                {
     445                        r_initiator_fsm = M_READ_RSP;
     446                }
     447                else                // not the last flit
     448                {
     449                        r_burst_word = r_burst_word.read() - 1;
     450                }
     451
     452                r_dma_fifo_read.simple_get(); // consume one fifo word
     453                // compute next word address
     454                r_buf_address = r_buf_address.read() + vci_param::B;
     455            }
     456            break;
    409457    }
    410458    ////////////////
    411459    case M_READ_RSP:    // Wait a single flit VCI WRITE response
    412460    {
    413         if ( p_vci_initiator.rspval.read() )
    414         {
    415             if ( (p_vci_initiator.rerror.read()&0x1) != 0 )
     461            if ( p_vci_initiator.rspval.read() )
    416462            {
    417                 r_burst_word = 0;
    418                 r_dma_count = 0;
    419                 r_dma_error = true;
    420                 r_initiator_fsm = M_INTR;
     463                if ( (p_vci_initiator.rerror.read()&0x1) != 0 )
     464                {
     465                    r_burst_word = 0;
     466                r_dma_count = 0;
     467                r_dma_error = true;
     468                    r_initiator_fsm = M_INTR;
     469
    421470#ifdef SOCLIB_MODULE_DEBUG
    422471                std::cout << "vci_bd M_READ_ERROR" << std::endl;
    423472#endif
    424             }
    425             else if ( r_spi_fsm == S_DMA_SEND_END ) // last burst
    426             {
    427                 r_dma_count = 0;
    428                 r_initiator_fsm = M_INTR;
    429                 r_dma_error = false;
     473
     474                }
     475                else if ( r_spi_fsm == S_DMA_SEND_END ) // last burst
     476                {
     477                r_dma_count = 0;
     478                r_initiator_fsm = M_INTR;
     479                    r_dma_error = false;
     480
    430481#ifdef SOCLIB_MODULE_DEBUG
    431482                std::cout << "vci_bd M_READ_SUCCESS" << std::endl;
    432483#endif
    433             }
    434             else // keep on reading
    435             {
    436                 r_dma_count = r_dma_count - 1;
    437                 r_initiator_fsm  = M_READ_WAIT;
    438             }
    439         }
    440         break;
     484
     485                }
     486                else // keep on reading
     487                {
     488                r_dma_count = r_dma_count - 1;
     489                        r_initiator_fsm  = M_READ_WAIT;
     490                }
     491            }
     492            break;
    441493    }
    442494    ///////////////////
    443495    case M_INTR:
    444         r_initiator_fsm = M_IDLE;
    445         r_irq = true;
    446         break;
     496    {
     497            r_initiator_fsm = M_IDLE;
     498            r_irq = true;
     499            break;
     500    }
    447501    ///////////////////
    448502    case M_WRITE_WAIT:  // wait for the FIFO to be empty
    449         if (!r_dma_fifo_write.rok()) {
    450             r_burst_word = m_words_per_burst - 1;
    451             r_dma_count = r_dma_count - 1;
    452             r_initiator_fsm = M_WRITE_CMD;
    453         }
    454         break;
     503        {
     504        if (!r_dma_fifo_write.rok())
     505        {
     506                r_burst_word = m_words_per_burst - 1;
     507                r_dma_count = r_dma_count - 1;
     508                r_initiator_fsm = M_WRITE_CMD;
     509            }
     510            break;
     511    }
    455512    /////////////////
    456     case M_WRITE_CMD:   // This is actually a single flit VCI READ command
    457     {
    458         if ( p_vci_initiator.cmdack.read() ) r_initiator_fsm = M_WRITE_RSP;
    459         break;
     513    case M_WRITE_CMD:   // single flit VCI READ command for one burst
     514    {
     515            if ( p_vci_initiator.cmdack.read() ) r_initiator_fsm = M_WRITE_RSP;
     516            break;
    460517    }
    461518    /////////////////
    462     case M_WRITE_RSP:   // This is actually a multi-words VCI READ response
    463     {
    464         if ( p_vci_initiator.rspval.read() )
    465         {
    466             typename vci_param::data_t v = p_vci_initiator.rdata.read();
    467             typename vci_param::data_t f = 0;
    468             // byte-swap
    469             for (int i = 0; i < (vci_param::B * 8); i += 8) {
    470                 f |= ((v >> i) & 0xff) << ((vci_param::B * 8) - 8 - i);
    471             }
    472             r_dma_fifo_write.simple_put(f);
    473             r_burst_word = r_burst_word.read() - 1;
    474             if ( p_vci_initiator.reop.read() )  // last flit of the burst
     519    case M_WRITE_RSP:   // wait multi-words VCI READ response
     520    {
     521            if ( p_vci_initiator.rspval.read() )
    475522            {
    476                 r_buf_address = r_buf_address.read() + m_burst_size;
    477 
    478                 if( (p_vci_initiator.rerror.read()&0x1) != 0 )
    479                 {
    480                     r_dma_count = 0;
    481                     r_dma_error = 1;
    482                     r_initiator_fsm = M_WRITE_END;
     523                typename vci_param::data_t v = p_vci_initiator.rdata.read();
     524                typename vci_param::data_t f = 0;
     525                // byte-swap
     526                for (int i = 0; i < (vci_param::B * 8); i += 8)
     527            {
     528                        f |= ((v >> i) & 0xff) << ((vci_param::B * 8) - 8 - i);
     529                }
     530                r_dma_fifo_write.simple_put(f);
     531                r_burst_word = r_burst_word.read() - 1;
     532                if ( p_vci_initiator.reop.read() )  // last flit of the burst
     533                {
     534                        r_buf_address = r_buf_address.read() + m_burst_size;
     535
     536                        if( (p_vci_initiator.rerror.read()&0x1) != 0 )
     537                        {
     538                            r_dma_count = 0;
     539                            r_dma_error = 1;
     540                            r_initiator_fsm = M_WRITE_END;
     541
    483542#ifdef SOCLIB_MODULE_DEBUG
    484                     std::cout << "vci_bd M_WRITE_ERROR" << std::endl;
     543                    std::cout << "vci_spi M_WRITE_ERROR" << std::endl;
    485544#endif
    486                 }
    487                 else if ( r_dma_count.read() == 0) // last burst
    488                 {
    489                     r_dma_error = 0;
    490                     r_initiator_fsm  = M_WRITE_END;
    491                 }
    492                 else                                      // not the last burst
    493                 {
    494                     r_initiator_fsm = M_WRITE_WAIT;
    495                 }
    496             }
    497         }
    498         break;
     545                }
     546                        else if ( r_dma_count.read() == 0) // last burst
     547                {
     548                            r_dma_error = 0;
     549                            r_initiator_fsm  = M_WRITE_END;
     550                        }
     551                else                                      // not the last burst
     552                {
     553                            r_initiator_fsm = M_WRITE_WAIT;
     554                        }
     555                }
     556            }
     557            break;
    499558    }
    500559    /////////////////
    501     case M_WRITE_END:   // wait for the write to be complete
    502     {
    503         if (r_spi_fsm == S_IDLE) { // write complete
    504             r_initiator_fsm  = M_INTR;
    505         }
    506         break;
    507     }
    508   } // end switch r_initiator_fsm
     560    case M_WRITE_END:   // wait for the write to be completed by SPI FSM
     561    {
     562            if (r_spi_fsm == S_IDLE)  r_initiator_fsm  = M_INTR;
     563            break;
     564    }
     565    } // end switch r_initiator_fsm
    509566}  // end transition
    510567
     
    609666    }
    610667
    611     // SPI signals
     668    ////////////// SPI signals
    612669    p_spi_ss = ((r_ss & 0x1) == 0);
    613     switch(r_spi_fsm) {
     670
     671    switch(r_spi_fsm)
     672    {
    614673    default:
    615         p_spi_mosi = r_spi_out;
    616         p_spi_clk = 0;
    617         break;
     674            p_spi_mosi = r_spi_out;
     675            p_spi_clk = 0;
     676            break;
    618677    case S_XMIT:
    619       {
    620         bool s_clk_sample = r_spi_clk ^ r_ctrl_cpha;
    621         p_spi_clk = r_spi_clk ^ r_ctrl_cpol;
    622         if (s_clk_sample == 0) {
    623             // clock low: get data directly from shift register
    624             // as r_spi_out may be delayed by one clock cycle
    625             p_spi_mosi = (r_txrx[(r_ctrl_char_len -1)/ 64] >> ((r_ctrl_char_len - 1) % 64)) & (uint64_t)0x0000000000000001ULL;
    626         } else {
    627             // clock high: get data from saved value, as the shift register
    628             // may have changed
    629             p_spi_mosi = r_spi_out;
    630         }
    631         break;
    632       }
     678    {
     679            bool s_clk_sample = r_spi_clk ^ r_ctrl_cpha;
     680            p_spi_clk = r_spi_clk ^ r_ctrl_cpol;
     681            if (s_clk_sample == 0)
     682        {
     683                // clock low: get data directly from shift register
     684                // as r_spi_out may be delayed by one clock cycle
     685                p_spi_mosi = (r_txrx[(r_ctrl_char_len -1)/ 64] >> ((r_ctrl_char_len - 1) % 64)) & (uint64_t)0x0000000000000001ULL;
     686            }
     687        else
     688        {
     689                // clock high: get data from saved value, as the shift register
     690                // may have changed
     691                p_spi_mosi = r_spi_out;
     692            }
     693            break;
     694    }
    633695    }
    634696
     
    638700
    639701//////////////////////////////////////////////////////////////////////////////
    640 tmpl(/**/)::VciSpi( sc_core::sc_module_name           name,
     702tmpl(/**/)::VciSpi( sc_core::sc_module_name              name,
    641703                                const soclib::common::MappingTable   &mt,
    642                                 const soclib::common::IntTab    &srcid,
    643                                 const soclib::common::IntTab    &tgtid,
    644                                 const uint32_t                 burst_size)
     704                                const soclib::common::IntTab        &srcid,
     705                                const soclib::common::IntTab        &tgtid,
     706                                const uint32_t                           burst_size)
    645707
    646708: caba::BaseModule(name),
Note: See TracChangeset for help on using the changeset viewer.