| 1 |  | 
|---|
| 2 | /* -*- c++ -*- | 
|---|
| 3 | * | 
|---|
| 4 | * SOCLIB_LGPL_HEADER_BEGIN | 
|---|
| 5 | * | 
|---|
| 6 | * This file is part of SoCLib, GNU LGPLv2.1. | 
|---|
| 7 | * | 
|---|
| 8 | * SoCLib is free software; you can redistribute it and/or modify it | 
|---|
| 9 | * under the terms of the GNU Lesser General Public License as published | 
|---|
| 10 | * by the Free Software Foundation; version 2.1 of the License. | 
|---|
| 11 | * | 
|---|
| 12 | * SoCLib is distributed in the hope that it will be useful, but | 
|---|
| 13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | 
|---|
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU | 
|---|
| 15 | * Lesser General Public License for more details. | 
|---|
| 16 | * | 
|---|
| 17 | * You should have received a copy of the GNU Lesser General Public | 
|---|
| 18 | * License along with SoCLib; if not, write to the Free Software | 
|---|
| 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | 
|---|
| 20 | * 02110-1301 USA | 
|---|
| 21 | * | 
|---|
| 22 | * SOCLIB_LGPL_HEADER_END | 
|---|
| 23 | * | 
|---|
| 24 | * Copyright (c) UPMC, Lip6, SoC | 
|---|
| 25 | *         manuel.bouyer@lip6.fr october 2013 | 
|---|
| 26 | * | 
|---|
| 27 | * Maintainers: bouyer | 
|---|
| 28 | */ | 
|---|
| 29 |  | 
|---|
| 30 | ////////////////////////////////////////////////////////////////////////////////////// | 
|---|
| 31 | // This component is a SPI controller with a VCI interface | 
|---|
| 32 | // It supports only 32 or 64 bits VCI DATA width, but all addressable registers | 
|---|
| 33 | // contain 32 bits words. It supports VCI addresss lartger than 32 bits. | 
|---|
| 34 | // | 
|---|
| 35 | // This component can perform data transfers between one single file belonging | 
|---|
| 36 | // to the host system and a buffer in the memory of the virtual prototype. | 
|---|
| 37 | // The file name is an argument of the constructor. | 
|---|
| 38 | // This component has a DMA capability, and is both a target and an initiator. | 
|---|
| 39 | // The burst size (bytes) must be power of 2. | 
|---|
| 40 | // The burst size is typically a cache line. | 
|---|
| 41 | // The memory buffer must be aligned to a a burst boundary. | 
|---|
| 42 | // Both read and write transfers are supported. An IRQ is optionally | 
|---|
| 43 | // asserted when the transfer is completed. | 
|---|
| 44 | // | 
|---|
| 45 |  | 
|---|
| 46 | #ifndef SOCLIB_VCI_SPI_H | 
|---|
| 47 | #define SOCLIB_VCI_SPI_H | 
|---|
| 48 |  | 
|---|
| 49 | #include <stdint.h> | 
|---|
| 50 | #include <systemc> | 
|---|
| 51 | #include <unistd.h> | 
|---|
| 52 | #include "caba_base_module.h" | 
|---|
| 53 | #include "mapping_table.h" | 
|---|
| 54 | #include "vci_initiator.h" | 
|---|
| 55 | #include "vci_target.h" | 
|---|
| 56 | #include "generic_fifo.h" | 
|---|
| 57 |  | 
|---|
| 58 | namespace soclib { | 
|---|
| 59 | namespace caba { | 
|---|
| 60 |  | 
|---|
| 61 | using namespace sc_core; | 
|---|
| 62 |  | 
|---|
| 63 | template<typename vci_param> | 
|---|
| 64 | class VciSpi | 
|---|
| 65 | : public caba::BaseModule | 
|---|
| 66 | { | 
|---|
| 67 | private: | 
|---|
| 68 |  | 
|---|
| 69 | // Registers | 
|---|
| 70 | sc_signal<int>                     r_target_fsm;       // target fsm state register | 
|---|
| 71 | sc_signal<int>                     r_initiator_fsm;    // initiator fsm state register | 
|---|
| 72 | sc_signal<int>                     r_spi_fsm;          // spi engine state | 
|---|
| 73 | sc_signal<uint64_t>                r_txrx[2];          // data in/out | 
|---|
| 74 | sc_signal<uint32_t>                r_divider;          // SPI clk divider | 
|---|
| 75 | sc_signal<uint8_t>                 r_ss;               // SPI slave select | 
|---|
| 76 | sc_signal<bool>                    r_ctrl_cpol;     // clock polarity | 
|---|
| 77 | sc_signal<bool>                    r_ctrl_cpha;     // clock phase | 
|---|
| 78 | sc_signal<bool>                    r_ctrl_ie;       // interrupt enable | 
|---|
| 79 | sc_signal<uint8_t>                 r_ctrl_char_len; // number of bits in xfer | 
|---|
| 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 | 
|---|
| 88 | sc_signal<uint32_t>                r_spi_bit_count; | 
|---|
| 89 | sc_signal<uint32_t>                r_spi_word_count; | 
|---|
| 90 | sc_signal<uint32_t>                r_spi_clk_counter; | 
|---|
| 91 | sc_signal<bool>                    r_spi_clk; | 
|---|
| 92 | sc_signal<bool>                    r_spi_clk_previous; | 
|---|
| 93 | sc_signal<bool>                    r_spi_clk_ignore; | 
|---|
| 94 | sc_signal<bool>                    r_spi_out; | 
|---|
| 95 | sc_signal<bool>                    r_spi_done; | 
|---|
| 96 | sc_signal<bool>                    r_irq; | 
|---|
| 97 |  | 
|---|
| 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 | 
|---|
| 100 |  | 
|---|
| 101 | sc_signal<typename vci_param::srcid_t >     r_srcid;   // save srcid | 
|---|
| 102 | sc_signal<typename vci_param::trdid_t >     r_trdid;   // save trdid | 
|---|
| 103 | sc_signal<typename vci_param::pktid_t >     r_pktid;   // save pktid | 
|---|
| 104 |  | 
|---|
| 105 | sc_signal<typename vci_param::data_t >      r_rdata;   // save reply | 
|---|
| 106 |  | 
|---|
| 107 | // structural parameters | 
|---|
| 108 | std::list<soclib::common::Segment> m_seglist; | 
|---|
| 109 | uint32_t                           m_srcid;            // initiator index | 
|---|
| 110 | const uint32_t                     m_burst_size;       // number of words in a burst | 
|---|
| 111 | const uint32_t                     m_words_per_burst;  // number of words in a burst | 
|---|
| 112 | const uint32_t                     m_byte2burst_shift; // log2(burst_size) | 
|---|
| 113 |  | 
|---|
| 114 | // methods | 
|---|
| 115 | void transition(); | 
|---|
| 116 | void genMoore(); | 
|---|
| 117 |  | 
|---|
| 118 | //  Master FSM states | 
|---|
| 119 | enum { | 
|---|
| 120 | M_IDLE              = 0, | 
|---|
| 121 | M_READ_WAIT         = 1, | 
|---|
| 122 | M_READ_CMD          = 2, | 
|---|
| 123 | M_READ_RSP          = 3, | 
|---|
| 124 | M_INTR              = 4, | 
|---|
| 125 | M_WRITE_WAIT        = 5, | 
|---|
| 126 | M_WRITE_CMD         = 6, | 
|---|
| 127 | M_WRITE_RSP         = 7, | 
|---|
| 128 | M_WRITE_END         = 8 | 
|---|
| 129 | }; | 
|---|
| 130 |  | 
|---|
| 131 | // Target FSM states | 
|---|
| 132 | enum { | 
|---|
| 133 | T_IDLE              = 0, | 
|---|
| 134 | T_RSP_READ          = 1, | 
|---|
| 135 | T_RSP_WRITE         = 2, | 
|---|
| 136 | T_ERROR_READ        = 3, | 
|---|
| 137 | T_ERROR_WRITE       = 4 | 
|---|
| 138 | }; | 
|---|
| 139 |  | 
|---|
| 140 | // SPI FSM states | 
|---|
| 141 | enum { | 
|---|
| 142 | S_IDLE              = 0, | 
|---|
| 143 | S_DMA_RECEIVE       = 1, | 
|---|
| 144 | S_DMA_SEND_START    = 2, | 
|---|
| 145 | S_DMA_SEND          = 3, | 
|---|
| 146 | S_DMA_SEND_END      = 4, | 
|---|
| 147 | S_XMIT              = 5, | 
|---|
| 148 | }; | 
|---|
| 149 |  | 
|---|
| 150 | // Error codes values | 
|---|
| 151 | enum { | 
|---|
| 152 | VCI_READ_OK         = 0, | 
|---|
| 153 | VCI_READ_ERROR      = 1, | 
|---|
| 154 | VCI_WRITE_OK        = 2, | 
|---|
| 155 | VCI_WRITE_ERROR     = 3, | 
|---|
| 156 | }; | 
|---|
| 157 |  | 
|---|
| 158 | /* transaction type, pktid field */ | 
|---|
| 159 | enum transaction_type_e | 
|---|
| 160 | { | 
|---|
| 161 | // b3 unused | 
|---|
| 162 | // b2 READ / NOT READ | 
|---|
| 163 | // Si READ | 
|---|
| 164 | //  b1 DATA / INS | 
|---|
| 165 | //  b0 UNC / MISS | 
|---|
| 166 | // Si NOT READ | 
|---|
| 167 | //  b1 accÚs table llsc type SW / other | 
|---|
| 168 | //  b2 WRITE/CAS/LL/SC | 
|---|
| 169 | TYPE_READ_DATA_UNC          = 0x0, | 
|---|
| 170 | TYPE_READ_DATA_MISS         = 0x1, | 
|---|
| 171 | TYPE_READ_INS_UNC           = 0x2, | 
|---|
| 172 | TYPE_READ_INS_MISS          = 0x3, | 
|---|
| 173 | TYPE_WRITE                  = 0x4, | 
|---|
| 174 | TYPE_CAS                    = 0x5, | 
|---|
| 175 | TYPE_LL                     = 0x6, | 
|---|
| 176 | TYPE_SC                     = 0x7 | 
|---|
| 177 | }; | 
|---|
| 178 |  | 
|---|
| 179 | protected: | 
|---|
| 180 |  | 
|---|
| 181 | SC_HAS_PROCESS(VciSpi); | 
|---|
| 182 |  | 
|---|
| 183 | public: | 
|---|
| 184 |  | 
|---|
| 185 | // ports | 
|---|
| 186 | sc_in<bool>                                               p_clk; | 
|---|
| 187 | sc_in<bool>                                               p_resetn; | 
|---|
| 188 | sc_out<bool>                                              p_irq; | 
|---|
| 189 | soclib::caba::VciInitiator<vci_param> p_vci_initiator; | 
|---|
| 190 | soclib::caba::VciTarget<vci_param>    p_vci_target; | 
|---|
| 191 | sc_out<bool>                                              p_spi_ss; | 
|---|
| 192 | sc_out<bool>                                              p_spi_clk; | 
|---|
| 193 | sc_out<bool>                                              p_spi_mosi; | 
|---|
| 194 | sc_in<bool>                                               p_spi_miso; | 
|---|
| 195 |  | 
|---|
| 196 | void print_trace(); | 
|---|
| 197 |  | 
|---|
| 198 | // Constructor | 
|---|
| 199 | VciSpi( | 
|---|
| 200 | sc_module_name                      name, | 
|---|
| 201 | const soclib::common::MappingTable  &mt, | 
|---|
| 202 | const soclib::common::IntTab        &srcid, | 
|---|
| 203 | const soclib::common::IntTab        &tgtid, | 
|---|
| 204 | const uint32_t                      burst_size = 64); | 
|---|
| 205 |  | 
|---|
| 206 | ~VciSpi(); | 
|---|
| 207 |  | 
|---|
| 208 | }; | 
|---|
| 209 |  | 
|---|
| 210 | }} | 
|---|
| 211 |  | 
|---|
| 212 | #endif /* SOCLIB_VCI_SPI_H */ | 
|---|
| 213 |  | 
|---|
| 214 | // Local Variables: | 
|---|
| 215 | // tab-width: 4 | 
|---|
| 216 | // c-basic-offset: 4 | 
|---|
| 217 | // c-file-offsets:((innamespace . 0)(inline-open . 0)) | 
|---|
| 218 | // indent-tabs-mode: nil | 
|---|
| 219 | // End: | 
|---|
| 220 |  | 
|---|
| 221 | // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4 | 
|---|
| 222 |  | 
|---|