Changeset 579


Ignore:
Timestamp:
Nov 23, 2013, 1:25:13 AM (10 years ago)
Author:
bouyer
Message:

Add some basic DMA capabilities. Passes basic read/write tests.
Can only do line-aligned transfers which are multiple of a cache line in size,
but shouldn't be a strong limitation for real use.

Location:
trunk/modules/vci_spi
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/modules/vci_spi/caba/metadata/vci_spi.sd

    r551 r579  
    3535        uses = [
    3636                    Uses('caba:base_module'),
    37             Uses('common:mapping_table'),
     37                    Uses('common:mapping_table'),
     38                    Uses('caba:generic_fifo'),
    3839                ],
    3940
  • trunk/modules/vci_spi/caba/source/include/vci_spi.h

    r565 r579  
    5454#include "vci_initiator.h"
    5555#include "vci_target.h"
     56#include "generic_fifo.h"
    5657
    5758namespace soclib {
     
    7677    sc_signal<bool>                    r_ctrl_cpha;     // clock phase
    7778    sc_signal<bool>                    r_ctrl_ie;       // interrupt enable
    78     sc_signal<bool>                    r_ctrl_go_bsy;
    7979    sc_signal<uint8_t>                 r_ctrl_char_len; // number of bits in xfer
    80 
     80    sc_signal<uint64_t>                r_buf_address;  // memory buffer address
     81    sc_signal<uint32_t>                r_dma_count;   // DMA burst count
     82    sc_signal<bool>                    r_read;        // DMA read/write
     83
     84    sc_signal<uint32_t>                r_burst_word;  // DMA burst word count
     85    sc_signal<bool>                    r_dma_error;   // DMA error
     86
     87    sc_signal<bool>                    r_spi_bsy;    // SPI shifter busy
    8188    sc_signal<uint32_t>                r_spi_bit_count;
     89    sc_signal<uint32_t>                r_spi_word_count;
    8290    sc_signal<uint32_t>                r_spi_clk_counter;
    8391    sc_signal<bool>                    r_spi_clk;
     
    8896    sc_signal<bool>                    r_irq;
    8997
    90     sc_signal<bool>                    r_read;
    91     sc_signal<uint32_t>                r_nblocks;          // number of blocks in transfer
    92     sc_signal<uint64_t>                r_buf_address;      // memory buffer address
    93     sc_signal<uint32_t>                r_index;            // word index in local buffer
    94     sc_signal<uint32_t>                r_latency_count;    // latency counter
    95     sc_signal<uint32_t>                r_words_count;      // word counter (in a burst)
    96     sc_signal<uint32_t>                r_burst_count;      // burst counter (in a block)
    97     sc_signal<uint32_t>                r_block_count;      // block counter (in a transfer)
    98     sc_signal<uint32_t>                r_burst_offset;     // number of non aligned words
    99     sc_signal<uint32_t>                r_burst_nwords;     // number of words in a burst
    100     sc_signal<bool>                    r_go;               // command from T_FSM to M_FSM
     98    GenericFifo<typename vci_param::data_t> r_dma_fifo_read; // buffer data from SPI to network
     99    GenericFifo<typename vci_param::data_t> r_dma_fifo_write;// buffer data from network to SPI
    101100
    102101    sc_signal<typename vci_param::srcid_t >     r_srcid;   // save srcid
     
    106105    sc_signal<typename vci_param::data_t >      r_rdata;   // save reply
    107106
    108     uint32_t*                          r_local_buffer;     // capacity is one block
    109 
    110107    // structural parameters
    111108    std::list<soclib::common::Segment> m_seglist;
    112109    uint32_t                           m_srcid;            // initiator index
    113     const uint32_t                     m_words_per_block;  // block size
     110    const uint32_t                     m_burst_size;       // number of words in a burst
    114111    const uint32_t                     m_words_per_burst;  // number of words in a burst
    115     const uint32_t                     m_bursts_per_block; // number of bursts in a block
     112    const uint32_t                     m_byte2burst_shift; // log2(burst_size)
    116113
    117114    // methods
     
    122119    enum {
    123120    M_IDLE              = 0,
    124 
    125     M_READ_BLOCK        = 1,
    126     M_READ_BURST        = 2,
    127     M_READ_CMD          = 3,
    128     M_READ_RSP          = 4,
    129     M_READ_SUCCESS      = 5,
    130     M_READ_ERROR        = 6,
    131 
    132     M_WRITE_BURST       = 7,
    133     M_WRITE_CMD         = 8,
    134     M_WRITE_RSP         = 9,
    135     M_WRITE_BLOCK       = 10,
    136     M_WRITE_SUCCESS     = 11,
    137     M_WRITE_ERROR       = 12,
     121    M_READ_WAIT         = 1,
     122    M_READ_CMD          = 2,
     123    M_READ_RSP          = 3,
     124    M_WRITE_WAIT        = 4,
     125    M_WRITE_CMD         = 5,
     126    M_WRITE_RSP         = 6,
     127    M_WRITE_END         = 7
    138128    };
    139129
     
    150140    enum {
    151141    S_IDLE              = 0,
    152     S_XMIT              = 1,
     142    S_DMA_RECEIVE       = 1,
     143    S_DMA_SEND_START    = 2,
     144    S_DMA_SEND          = 3,
     145    S_DMA_SEND_END      = 4,
     146    S_XMIT              = 5,
    153147    };
    154148
  • trunk/modules/vci_spi/caba/source/src/vci_spi.cpp

    r576 r579  
    2929#include <stdint.h>
    3030#include <iostream>
     31#include <arithmetics.h>
    3132#include <fcntl.h>
    3233#include "vci_spi.h"
     
    4344tmpl(void)::transition()
    4445{
     46
     47    bool s_dma_bsy = (r_initiator_fsm != M_IDLE);
    4548    if(p_resetn.read() == false)
    4649    {
    4750        r_initiator_fsm   = M_IDLE;
    4851        r_target_fsm      = T_IDLE;
    49         r_spi_fsm        = S_IDLE;
    50         r_ss          = 0;
    51         r_divider        = 0xffff;
     52        r_spi_fsm         = S_IDLE;
     53        r_ss              = 0;
     54        r_divider         = 0xffff;
    5255        r_ctrl_char_len   = 0;
    53         r_ctrl_ie        = false;
     56        r_ctrl_ie         = false;
    5457        r_ctrl_cpol       = false;
    5558        r_ctrl_cpha       = false;
    56         r_ctrl_go_bsy     = false;
    57         r_spi_clk_counter     = 0xffff;
    58         r_spi_clk        = 0;
     59        r_spi_bsy         = false;
     60        r_dma_count       = 0;
     61        r_spi_clk_counter = 0xffff;
     62        r_spi_clk         = 0;
    5963        r_spi_done        = false;
    6064
    6165        r_irq             = false;
    6266        r_read            = false;
     67
     68        r_dma_fifo_read.init();
     69        r_dma_fifo_write.init();
    6370
    6471        return;
     
    7178
    7279    if (r_spi_done)
    73         r_ctrl_go_bsy = false;
     80        r_spi_bsy = false;
    7481
    7582    switch(r_target_fsm) {
     
    102109                r_target_fsm = T_ERROR_READ;
    103110            } else {
    104                 bool     write  = (p_vci_target.cmd.read() == vci_param::CMD_WRITE) & !r_ctrl_go_bsy;
     111                bool     write  = (p_vci_target.cmd.read() == vci_param::CMD_WRITE) & !r_spi_bsy &!s_dma_bsy;
    105112                uint32_t cell   = (uint32_t)((address & 0x3F)>>2);
    106113                switch(cell) {
     
    150157                    if (r_ctrl_ie.read())
    151158                        data |= SPI_CTRL_IE_EN;
    152                     if (r_ctrl_go_bsy.read())
     159                    if (r_spi_bsy.read())
    153160                        data |= SPI_CTRL_GO_BSY;
     161                    if (s_dma_bsy)
     162                        data |= SPI_CTRL_DMA_BSY;
    154163                    data |= (uint32_t)r_ctrl_char_len.read();
    155164                    r_rdata = data;
     
    159168                        r_ctrl_ie  = ((wdata & SPI_CTRL_IE_EN) != 0);
    160169                        if (wdata & SPI_CTRL_GO_BSY)
    161                                 r_ctrl_go_bsy = true;
     170                                r_spi_bsy = true;
    162171                        r_ctrl_char_len = (wdata & SPI_CTRL_CHAR_LEN_MASK);
    163172#ifdef SOCLIB_MODULE_DEBUG
     
    167176#endif
    168177                    } else {
    169                         r_irq = r_irq & r_ctrl_go_bsy;
     178                        r_irq = r_irq & r_spi_bsy;
    170179                    }
    171180                    r_target_fsm = (p_vci_target.cmd.read() == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ;
     
    186195                    if (write) {
    187196                        r_ss = wdata;
     197                    }
     198                    r_target_fsm = (p_vci_target.cmd.read() == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ;
     199                    break;
     200                case SPI_DMA_BASE:
     201                    r_rdata = r_buf_address.read();
     202                    if (write) {
     203                        r_buf_address = (r_buf_address & (uint64_t)0xffffffff00000000) | wdata;
     204                    }
     205                    r_target_fsm = (p_vci_target.cmd.read() == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ;
     206                    break;
     207                case SPI_DMA_BASEH:
     208                    r_rdata = r_buf_address >> 32;
     209                    if (write) {
     210                        r_buf_address = (r_buf_address & (uint64_t)0x00000000ffffffff) | ((uint64_t)wdata << 32);
     211                    }
     212                    r_target_fsm = (p_vci_target.cmd.read() == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ;
     213                    break;
     214                case SPI_DMA_COUNT:
     215                    r_rdata = (r_dma_count.read() << m_byte2burst_shift) |
     216                        r_read;
     217                    if (write) {
     218                        r_read = (wdata & 0x1);
     219                        r_dma_count = wdata >> m_byte2burst_shift;
     220                        r_ctrl_char_len = vci_param::B * 8;
    188221                    }
    189222                    r_target_fsm = (p_vci_target.cmd.read() == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ;
     
    214247    // the SPI FSM controls SPI signals
    215248    //////////////////////////////////////////////////////////////////////////////
    216     if (r_ctrl_go_bsy == false)
     249    if (r_spi_bsy == false)
    217250        r_spi_done = false;
    218251    switch (r_spi_fsm) {
     
    224257        r_spi_bit_count = r_ctrl_char_len;
    225258        r_spi_out = (r_txrx[(r_ctrl_char_len -1)/ 64] >> ((r_ctrl_char_len - 1) % 64)) & (uint64_t)0x0000000000000001ULL;
    226         if (r_ctrl_go_bsy.read() && !r_spi_done.read())
    227                 r_spi_fsm = S_XMIT;
     259        if (r_dma_count != 0) {
     260                if (r_read.read())
     261                        r_spi_fsm = S_DMA_SEND_START;
     262                else
     263                        r_spi_fsm = S_DMA_RECEIVE;
     264        } else if (r_spi_bsy.read() && !r_spi_done.read()) {
     265            r_spi_fsm = S_XMIT;
     266        }
     267        break;
     268    case S_DMA_RECEIVE:
     269    {
     270        r_spi_clk_counter = r_divider.read();
     271        r_spi_clk = 0;
     272        r_spi_clk_previous = r_ctrl_cpha;
     273        r_spi_clk_ignore = r_ctrl_cpha;
     274        r_spi_bit_count = r_ctrl_char_len;
     275        if (r_initiator_fsm != M_WRITE_RSP || !p_vci_initiator.rspval.read()) {
     276            if (r_dma_fifo_write.rok()) {
     277                typename vci_param::data_t v = r_dma_fifo_write.read();
     278                r_dma_fifo_write.simple_get();
     279                r_txrx[0] = v;
     280                r_spi_out = (v >> ((vci_param::B * 8) - 1)) & 0x1;
     281                r_spi_fsm = S_XMIT;
     282            } else if (r_initiator_fsm == M_WRITE_END) {
     283                r_spi_fsm = S_IDLE;
     284            }
     285        }
     286        break;
     287    }
     288    case S_DMA_SEND_START:
     289        r_spi_word_count = (r_dma_count << (m_byte2burst_shift - 2)) - 1;
     290        r_spi_out = 1;
     291        r_txrx[0] = 0xffffffff;
     292        r_spi_fsm = S_XMIT;
     293        break;
     294    case S_DMA_SEND:
     295        r_spi_out = 1;
     296        r_txrx[0] = 0xffffffff;
     297        r_spi_clk_counter = r_divider.read();
     298        r_spi_clk = 0;
     299        r_spi_clk_previous = r_ctrl_cpha;
     300        r_spi_clk_ignore = r_ctrl_cpha;
     301        r_spi_bit_count = r_ctrl_char_len;
     302        if (r_initiator_fsm != M_READ_CMD) {
     303            if (r_dma_fifo_read.wok()) {
     304                r_dma_fifo_read.simple_put(
     305                    (typename vci_param::data_t)r_txrx[0]);
     306                r_spi_word_count = r_spi_word_count - 1;
     307                if ( r_spi_word_count == 0 ) {
     308                    r_spi_fsm = S_DMA_SEND_END;
     309                } else {
     310                    r_spi_fsm = S_XMIT;
     311                }
     312            }
     313        }
     314        break;
     315    case S_DMA_SEND_END:
     316        if (r_initiator_fsm == M_IDLE)
     317                r_spi_fsm = S_IDLE;
    228318        break;
    229319    case S_XMIT:
     
    241331                // high to low transition: change output, or stop
    242332                if (r_spi_bit_count == 0) {
    243                     r_spi_fsm = S_IDLE;
    244                     r_irq = r_ctrl_ie;
    245                     r_spi_done = true;
     333                    if (r_initiator_fsm != M_IDLE) {
     334                        if (r_read)
     335                            r_spi_fsm = S_DMA_SEND;
     336                        else
     337                            r_spi_fsm = S_DMA_RECEIVE;
     338                    } else {
     339                        r_spi_fsm = S_IDLE;
     340                        r_irq = r_ctrl_ie;
     341                        r_spi_done = true;
     342                    }
    246343#ifdef SOCLIB_MODULE_DEBUG0
    247344                    std::cout << name() << " end xfer " << std::dec << (int)r_ctrl_char_len.read() << " data " << std::hex << r_txrx[1] << " " << r_txrx[0] << std::endl;
     
    265362    }
    266363    //////////////////////////////////////////////////////////////////////////////
    267     // The initiator FSM executes a loop, transfering one block per iteration.
    268     // Each block is split in bursts, and the number of bursts depends
    269     // on the memory buffer alignment on a burst boundary:
    270     // - If buffer aligned, all burst have the same length (m_words_per burst)
    271     //   and the number of bursts is (m_bursts_per_block).
    272     // - If buffer not aligned, the number of bursts is (m_bursts_per_block + 1)
    273     //   and first and last burst are shorter, because all words in a burst
    274     //   must be contained in a single cache line.
    275     //   first burst => nwords = m_words_per_burst - offset
    276     //   last  burst => nwords = offset
    277     //   other burst => nwords = m_words_per_burst
     364    // The initiator FSM executes a loop, transfering one burst per iteration.
     365    // data comes from or goes to fifos, the other end of the fifos is
     366    // feed by or eaten by the SPI fsm.
    278367    //////////////////////////////////////////////////////////////////////////////
    279368
     
    282371    case M_IDLE:        // check buffer alignment to compute the number of bursts
    283372    {
    284         if ( false )  // XXX
     373        if ( r_dma_count != 0 )
    285374        {
    286             r_index      = 0;
    287             r_block_count   = 0;
    288             r_burst_count   = 0;
    289             r_words_count   = 0;
    290 
    291             // compute r_burst_offset (zero when buffer aligned)
    292             r_burst_offset = (uint32_t)((r_buf_address.read()>>2) % m_words_per_burst);
    293 
    294             // start tranfer
    295             if ( r_read.read() )        r_initiator_fsm = M_READ_BLOCK;
    296             else                    r_initiator_fsm = M_WRITE_BURST;
    297         }
    298         break;
    299     }
    300     //////////////////
    301     case M_READ_BLOCK:  // read one block from disk after waiting m_latency cycles
    302     {
    303         r_burst_count   = 0;
    304         r_words_count    = 0;
    305         r_initiator_fsm = M_READ_BURST;
    306         break;
    307     }
    308     //////////////////
    309     case M_READ_BURST:  // Compute the number of words and the number of flits in the burst
    310                         // The number of flits can be smaller than the number of words
    311                         // in case of 8 bytes flits...
    312     {
    313         uint32_t nwords;
    314         uint32_t offset = r_burst_offset.read();
    315 
    316         if ( offset )             // buffer not aligned
    317         {
    318             if ( r_burst_count.read() == 0 ) nwords = m_words_per_burst - offset;
    319             else if ( r_burst_count.read() == m_bursts_per_block ) nwords = offset;
    320             else nwords = m_words_per_burst;
    321         }
    322         else                       // buffer aligned
    323         {
    324             nwords = m_words_per_burst;
    325         }
    326 
    327         r_burst_nwords  = nwords;
    328         r_initiator_fsm = M_READ_CMD;
    329         break;
    330     }
     375            // start transfer
     376            if ( r_read.read() )    r_initiator_fsm = M_READ_WAIT;
     377            else                    r_initiator_fsm = M_WRITE_WAIT;
     378        }
     379        break;
     380    }
     381    case M_READ_WAIT:  // wait for the FIFO to be full
     382        if (!r_dma_fifo_read.wok()) {
     383                r_burst_word = m_words_per_burst - 1;
     384                r_initiator_fsm = M_READ_CMD;
     385        }
     386        break;
    331387    ////////////////
    332388    case M_READ_CMD:    // Send a multi-flits VCI WRITE command
     
    334390        if ( p_vci_initiator.cmdack.read() )
    335391        {
    336             uint32_t nwords = r_burst_nwords.read() - r_words_count.read();
    337 
    338             if ( vci_param::B == 4 )    // one word per flit
    339             {
    340                 if ( nwords <= 1 )      // last flit
    341                 {
    342                     r_initiator_fsm = M_READ_RSP;
    343                     r_words_count = 0;
    344                 }
    345                 else                // not the last flit
    346                 {
    347                     r_words_count = r_words_count.read() + 1;
    348                 }
    349 
    350                 // compute next word address and next local buffer index
    351                 r_buf_address = r_buf_address.read() + 4;
    352                 r_index       = r_index.read() + 1;
    353             }
    354             else                        // 2 words per flit
    355             {
    356                 if ( nwords <= 2 )      // last flit
    357                 {
    358                     r_initiator_fsm = M_READ_RSP;
    359                     r_words_count = 0;
    360                 }
    361                 else                // not the last flit
    362                 {
    363                     r_words_count = r_words_count.read() + 2;
    364                 }
    365                    
    366                 // compute next word address and next local buffer index
    367                 if ( nwords == 1 )
    368                 {
    369                     r_buf_address = r_buf_address.read() + 4;
    370                     r_index       = r_index.read() + 1;
    371                 }
    372                 else
    373                 {
    374                     r_buf_address = r_buf_address.read() + 8;
    375                     r_index       = r_index.read() + 2;
    376                 }
    377             }
     392            if ( r_burst_word == 0 )      // last flit
     393            {
     394                r_initiator_fsm = M_READ_RSP;
     395            }
     396            else                    // not the last flit
     397            {
     398                r_burst_word = r_burst_word.read() - 1;
     399            }
     400
     401            r_dma_fifo_read.simple_get(); // consume one fifo word
     402            // compute next word address
     403            r_buf_address = r_buf_address.read() + vci_param::B;
    378404        }
    379405        break;
     
    384410        if ( p_vci_initiator.rspval.read() )
    385411        {
    386             bool aligned = (r_burst_offset.read() == 0);
    387 
    388412            if ( (p_vci_initiator.rerror.read()&0x1) != 0 )
    389413            {
    390                 r_initiator_fsm = M_READ_ERROR;
     414                r_burst_word = 0;
     415                r_dma_count = 0;
     416                r_dma_error = true;
     417                r_initiator_fsm = M_IDLE;
    391418#ifdef SOCLIB_MODULE_DEBUG
    392419                std::cout << "vci_bd M_READ_ERROR" << std::endl;
    393420#endif
    394421            }
    395             else if ( (not aligned and (r_burst_count.read() == m_bursts_per_block)) or
    396                       (aligned and (r_burst_count.read() == (m_bursts_per_block-1))) )
    397             {
    398                 if ( r_block_count.read() == (r_nblocks.read()-1) ) // last burst of last block
    399                 {
    400                     r_initiator_fsm = M_READ_SUCCESS;
     422            else if ( r_spi_fsm == S_DMA_SEND_END ) // last burst
     423            {
     424                r_dma_count = 0;
     425                r_initiator_fsm = M_IDLE;
     426                r_dma_error = false;
    401427#ifdef SOCLIB_MODULE_DEBUG
    402                     std::cout << "vci_bd M_READ_SUCCESS" << std::endl;
     428                std::cout << "vci_bd M_READ_SUCCESS" << std::endl;
    403429#endif
    404                 }
    405                 else                                          // last burst not last block
    406                 {
    407                     r_index       = 0;
    408                     r_burst_count    = 0;
    409                     r_block_count    = r_block_count.read() + 1;
    410                     r_initiator_fsm  = M_READ_BLOCK;
    411                 }
    412             }
    413             else                                                // not the last burst
    414             {
    415                 r_burst_count = r_burst_count.read() + 1;
    416                 r_initiator_fsm = M_READ_BURST;
     430            }
     431            else // keep on reading
     432            {
     433                r_dma_count = r_dma_count - 1;
     434                r_initiator_fsm  = M_READ_WAIT;
    417435            }
    418436        }
     
    420438    }
    421439    ///////////////////
    422     case M_READ_SUCCESS:
    423     case M_READ_ERROR:
    424     {
    425         if( !r_go ) r_initiator_fsm = M_IDLE;
    426         break;
    427     }
    428     ///////////////////
    429     case M_WRITE_BURST:  // Compute the number of words in the burst
    430     {
    431         uint32_t nwords;
    432         uint32_t offset = r_burst_offset.read();
    433 
    434         if ( offset )             // buffer not aligned
    435         {
    436             if ( r_burst_count.read() == 0 ) nwords = m_words_per_burst - offset;
    437             else if ( r_burst_count.read() == m_bursts_per_block ) nwords = offset;
    438             else nwords = m_words_per_burst;
    439         }
    440         else                       // buffer aligned
    441         {
    442             nwords = m_words_per_burst;
    443         }
    444 
    445         r_burst_nwords  = nwords;
    446         r_initiator_fsm =  M_WRITE_CMD;
    447         break;
    448     }
     440    case M_WRITE_WAIT:  // wait for the FIFO to be empty
     441        if (!r_dma_fifo_write.rok()) {
     442            r_burst_word = m_words_per_burst - 1;
     443            r_dma_count = r_dma_count - 1;
     444            r_initiator_fsm = M_WRITE_CMD;
     445        }
     446        break;
    449447    /////////////////
    450448    case M_WRITE_CMD:   // This is actually a single flit VCI READ command
    451449    {
    452             if ( p_vci_initiator.cmdack.read() ) r_initiator_fsm = M_WRITE_RSP;
     450        if ( p_vci_initiator.cmdack.read() ) r_initiator_fsm = M_WRITE_RSP;
    453451        break;
    454452    }
     
    458456        if ( p_vci_initiator.rspval.read() )
    459457        {
    460             bool aligned = (r_burst_offset.read() == 0);
    461 
    462             if ( (vci_param::B == 8) and (r_burst_nwords.read() > 1) )
    463             {
    464                 r_local_buffer[r_index.read()]   = (uint32_t)p_vci_initiator.rdata.read();
    465                 r_local_buffer[r_index.read()+1] = (uint32_t)(p_vci_initiator.rdata.read()>>32);
    466                 r_index = r_index.read() + 2;
    467             }
    468             else
    469             {
    470                 r_local_buffer[r_index.read()]   = (uint32_t)p_vci_initiator.rdata.read();
    471                 r_index = r_index.read() + 1;
    472             }
    473 
     458            typename vci_param::data_t v = p_vci_initiator.rdata.read();
     459            typename vci_param::data_t f = 0;
     460            // byte-swap
     461            for (int i = 0; i < (vci_param::B * 8); i += 8) {
     462                f |= ((v >> i) & 0xff) << ((vci_param::B * 8) - 8 - i);
     463            }
     464            r_dma_fifo_write.simple_put(f);
     465            r_burst_word = r_burst_word.read() - 1;
    474466            if ( p_vci_initiator.reop.read() )  // last flit of the burst
    475467            {
    476                     r_words_count  = 0;
    477                 r_buf_address = r_buf_address.read() + (r_burst_nwords.read()<<2);
    478 
    479                     if( (p_vci_initiator.rerror.read()&0x1) != 0 )
     468                r_buf_address = r_buf_address.read() + m_burst_size;
     469
     470                if( (p_vci_initiator.rerror.read()&0x1) != 0 )
    480471                {
    481                     r_initiator_fsm = M_WRITE_ERROR;
     472                    r_dma_count = 0;
     473                    r_dma_error = 1;
     474                    r_initiator_fsm = M_WRITE_END;
    482475#ifdef SOCLIB_MODULE_DEBUG
    483476                    std::cout << "vci_bd M_WRITE_ERROR" << std::endl;
    484477#endif
    485478                }
    486                 else if ( (not aligned and (r_burst_count.read() == m_bursts_per_block)) or
    487                      (aligned and (r_burst_count.read() == (m_bursts_per_block-1))) ) // last burst
     479                else if ( r_dma_count.read() == 0) // last burst
    488480                {
    489                     r_initiator_fsm  = M_WRITE_BLOCK;
     481                    r_dma_error = 0;
     482                    r_initiator_fsm  = M_WRITE_END;
    490483                }
    491484                else                                      // not the last burst
    492485                {
    493                     r_burst_count = r_burst_count.read() + 1;
    494                     r_initiator_fsm = M_WRITE_BURST;
     486                    r_initiator_fsm = M_WRITE_WAIT;
    495487                }
    496488            }
    497             else
    498             {
    499                     r_words_count = r_words_count.read() + 1;
    500             }
    501         }
    502         break;
    503     }
    504     ///////////////////
    505     case M_WRITE_BLOCK:         // write a block to disk after waiting m_latency cycles
    506     {
    507         if ( r_block_count.read() == r_nblocks.read() - 1 )
    508         {
    509             r_initiator_fsm = M_WRITE_SUCCESS;
    510 #ifdef SOCLIB_MODULE_DEBUG
    511             std::cout << "vci_bd M_WRITE_SUCCESS" << std::endl;
    512 #endif
    513         }
    514         else
    515         {
    516             r_burst_count    = 0;
    517             r_index       = 0;
    518             r_block_count    = r_block_count.read() + 1;
    519             r_initiator_fsm  = M_WRITE_BURST;
    520         }
    521         break;
    522     }
    523     /////////////////////
    524     case M_WRITE_SUCCESS:
    525     case M_WRITE_ERROR:
    526     {
    527         r_initiator_fsm = M_IDLE;
    528         break;
    529     }
    530     } // end switch r_initiator_fsm
     489        }
     490        break;
     491    }
     492    /////////////////
     493    case M_WRITE_END:   // wait for the write to be complete
     494    {
     495        if (r_spi_fsm == S_IDLE) { // write complete
     496            r_initiator_fsm  = M_IDLE;
     497        }
     498        break;
     499    }
     500  } // end switch r_initiator_fsm
    531501}  // end transition
    532502
     
    590560        p_vci_initiator.wdata   = 0;
    591561        p_vci_initiator.be      = 0;
    592         p_vci_initiator.plen    = (sc_dt::sc_uint<vci_param::K>)(r_burst_nwords.read()<<2);
     562        p_vci_initiator.plen    = (sc_dt::sc_uint<vci_param::K>)(m_burst_size);
    593563        p_vci_initiator.eop     = true;
    594564        break;
    595565    case M_READ_CMD:            // It is actually a multi-words VCI WRITE command
     566    {
     567        typename vci_param::data_t v = 0;
     568        typename vci_param::data_t f;
    596569        p_vci_initiator.rspack  = false;
    597570        p_vci_initiator.cmdval  = true;
    598         p_vci_initiator.address = (sc_dt::sc_uint<vci_param::N>)r_buf_address.read(); 
     571        p_vci_initiator.address = (sc_dt::sc_uint<vci_param::N>)r_buf_address.read();
    599572        p_vci_initiator.cmd     = vci_param::CMD_WRITE;
    600573        p_vci_initiator.pktid   = TYPE_WRITE;
    601         p_vci_initiator.plen    = (sc_dt::sc_uint<vci_param::K>)(r_burst_nwords.read()<<2);
    602         if ( (vci_param::B == 8) and ((r_burst_nwords.read() - r_words_count.read()) > 1) ) 
     574        p_vci_initiator.plen    = (sc_dt::sc_uint<vci_param::K>)(m_burst_size);
     575        f = r_dma_fifo_read.read();
     576        // byte-swap
     577        for (int i = 0; i < (vci_param::B * 8); i += 8) {
     578                v |= ((f >> i) & 0xff) << ((vci_param::B * 8) - 8 - i);
     579        }
     580        p_vci_initiator.wdata = v;
     581        p_vci_initiator.eop   = ( r_burst_word.read() == 0);
     582        if (vci_param::B == 8)
    603583        {
    604             p_vci_initiator.wdata = ((uint64_t)r_local_buffer[r_index.read()  ]) +
    605                                    (((uint64_t)r_local_buffer[r_index.read()+1]) << 32);
    606584            p_vci_initiator.be    = 0xFF;
    607             p_vci_initiator.eop   = ( (r_burst_nwords.read() - r_words_count.read()) <= 2 );
    608585        }
    609586        else
    610587        {
    611             p_vci_initiator.wdata = r_local_buffer[r_index.read()];
    612588            p_vci_initiator.be    = 0xF;
    613             p_vci_initiator.eop   = ( r_words_count.read() == (r_burst_nwords.read() - 1) );
    614         }
    615         break;
     589        }
     590        break;
     591    }
    616592    case M_READ_RSP:
    617593    case M_WRITE_RSP:
     
    628604    p_spi_ss = ((r_ss & 0x1) == 0);
    629605    switch(r_spi_fsm) {
    630     case S_IDLE:
     606    default:
    631607        p_spi_mosi = r_spi_out;
    632608        p_spi_clk = 0;
     
    663639        m_seglist(mt.getSegmentList(tgtid)),
    664640        m_srcid(mt.indexForId(srcid)),
    665         m_words_per_block(512/4),
    666         m_words_per_burst(burst_size/4),
    667         m_bursts_per_block(512/burst_size),
     641        m_burst_size(burst_size),
     642        m_words_per_burst(burst_size / vci_param::B),
     643        m_byte2burst_shift(soclib::common::uint32_log2(burst_size)),
    668644        p_clk("p_clk"),
    669645        p_resetn("p_resetn"),
     
    674650        p_spi_clk("p_spi_clk"),
    675651        p_spi_mosi("p_spi_mosi"),
    676         p_spi_miso("p_spi_miso")
     652        p_spi_miso("p_spi_miso"),
     653
     654        r_dma_fifo_read("r_dma_fifo_read", burst_size / vci_param::B), // one cache line
     655        r_dma_fifo_write("r_dma_fifo_read", burst_size / vci_param::B) // one cache line
    677656{
    678657    std::cout << "  - Building VciSpi " << name << std::endl;
     
    735714        }
    736715
    737         r_local_buffer = new uint32_t[m_words_per_block];
    738 
    739716} // end constructor
    740717
    741718tmpl(/**/)::~VciSpi()
    742719{
    743     delete [] r_local_buffer;
    744720}
    745721
     
    752728                "M_IDLE",
    753729
    754                 "M_READ_BLOCK",
    755                 "M_READ_BURST",
     730                "M_READ_WAIT",
    756731                "M_READ_CMD",
    757732                "M_READ_RSP",
    758                 "M_READ_SUCCESS",
    759                 "M_READ_ERROR",
    760 
    761                 "M_WRITE_BURST",
     733
     734                "M_WRITE_WAIT",
    762735                "M_WRITE_CMD",
    763736                "M_WRITE_RSP",
    764                 "M_WRITE_BLOCK",
    765                 "M_WRITE_SUCCESS",
    766                 "M_WRITE_ERROR",
     737                "M_WRITE_END",
    767738        };
    768739        const char* target_str[] =
     
    777748        {
    778749                "S_IDLE",
     750                "S_DMA_RECEIVE",
     751                "S_DMA_SEND_START",
     752                "S_DMA_SEND",
     753                "S_DMA_SEND_END",
    779754                "S_XMIT",
    780755        };
     
    785760            << " clk_counter " << r_spi_clk_counter.read()
    786761            << " r_spi_bit_count " << r_spi_bit_count.read()
    787             << " r_ctrl_go_bsy " << (int)r_ctrl_go_bsy.read() << std::endl;
     762            << " r_spi_bsy " << (int)r_spi_bsy.read() << std::endl;
    788763        std::cout << name() << " _SPI : "
    789764            << " r_spi_clk " << r_spi_clk.read()
     
    793768            << " r_txrx 0x" << std::hex
    794769            << r_txrx[1].read() << " " << r_txrx[0].read()
     770
    795771            << std::endl;
    796772        std::cout << name() << "  _INI : " << initiator_str[r_initiator_fsm.read()]
    797773          << "  buf = " << std::hex << r_buf_address.read()
    798           << "  block = " << std::dec << r_block_count.read()
    799           << "  burst = " << r_burst_count.read()
    800           << "  word  = " << r_words_count.read() <<std::endl;
     774          << "  burst = " << r_burst_word.read()
     775          << "  count = " << r_dma_count.read()
     776          << "  spi_count = " << r_spi_word_count.read()
     777          <<std::endl;
    801778}
    802779
  • trunk/modules/vci_spi/include/soclib/vcispi.h

    r573 r579  
    3535    SPI_CTRL,
    3636    SPI_DIVIDER,
    37     SPI_SS
     37    SPI_SS,
     38    SPI_DMA_BASE,
     39    SPI_DMA_BASEH,
     40    SPI_DMA_COUNT
    3841};
    3942
    40 #define SPI_CTRL_CPOL           (1 << 15) /* Clock polarity                */
    41 #define SPI_CTRL_CPHA           (1 << 14) /* Clock phase                   */
    42 #define SPI_CTRL_IE_EN          (1 << 12) /* Interrupt Enable              */
     43#define SPI_CTRL_DMA_BSY        (1 << 16) /* R   DMA in progress              */
     44#define SPI_CTRL_CPOL           (1 << 15) /* R/W Clock polarity               */
     45#define SPI_CTRL_CPHA           (1 << 14) /* R/W Clock phase                  */
     46#define SPI_CTRL_IE_EN          (1 << 12) /* R/W Interrupt Enable             */
    4347// 9-11 reserved
    44 #define SPI_CTRL_GO_BSY         (1 << 8 ) /* Start the transfer            */
    45 #define SPI_CTRL_CHAR_LEN_MASK  (0xFF   ) /* Bits transmited in 1 transfer */
     48#define SPI_CTRL_GO_BSY         (1 << 8 ) /* R/W Start the transfer           */
     49#define SPI_CTRL_CHAR_LEN_MASK  (0xFF   ) /* R/W Bits transmited in 1 transfer*/
     50
     51#define SPI_DMA_COUNT_READ      (1 << 0) /* operation is a read (else write) */
    4652
    4753#endif /* SPISD_H */
Note: See TracChangeset for help on using the changeset viewer.