Changeset 1052 for trunk/modules/vci_spi/caba/source
- Timestamp:
- Jun 21, 2017, 10:50:42 AM (7 years ago)
- Location:
- trunk/modules/vci_spi/caba/source
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/modules/vci_spi/caba/source/include/vci_spi.h
r595 r1052 68 68 69 69 // Registers 70 sc_signal<int> 71 sc_signal<int> 72 sc_signal<int> r_spi_fsm; // spi engine state73 sc_signal<uint64_t> 74 sc_signal<uint32_t> 75 sc_signal<uint8_t> r_ss;// SPI slave select76 sc_signal<bool> r_ctrl_cpol;// clock polarity77 sc_signal<bool> r_ctrl_cpha;// clock phase78 sc_signal<bool> r_ctrl_ie;// interrupt enable79 sc_signal<uint8_t> r_ctrl_char_len;// number of bits in xfer80 sc_signal<uint64_t> r_buf_address;// memory buffer address81 sc_signal<uint32_t> r_dma_count;// DMA burst count82 sc_signal<bool> r_read; // DMA read/write83 84 sc_signal<uint32_t> r_burst_word;// DMA burst word count85 sc_signal<bool> r_dma_error;// DMA error86 87 sc_signal<bool> r_spi_bsy;// SPI shifter busy88 sc_signal<uint32_t> 89 sc_signal<uint32_t> 90 sc_signal<uint32_t> 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 91 sc_signal<bool> r_spi_clk; 92 92 sc_signal<bool> r_spi_clk_previous; … … 189 189 soclib::caba::VciInitiator<vci_param> p_vci_initiator; 190 190 soclib::caba::VciTarget<vci_param> p_vci_target; 191 191 192 sc_out<bool> p_spi_ss; 192 193 sc_out<bool> p_spi_clk; -
trunk/modules/vci_spi/caba/source/src/vci_spi.cpp
r595 r1052 46 46 47 47 bool s_dma_bsy = (r_initiator_fsm != M_IDLE); 48 48 49 if(p_resetn.read() == false) 49 50 { 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; 73 74 } 74 75 75 76 ////////////////////////////////////////////////////////////////////////////// 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 78 78 ////////////////////////////////////////////////////////////////////////////// 79 79 … … 81 81 r_spi_bsy = false; 82 82 83 switch(r_target_fsm) { 83 switch(r_target_fsm) 84 { 84 85 //////////// 85 86 case T_IDLE: 86 87 { 87 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 } 101 102 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 { 107 113 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 175 180 #ifdef SOCLIB_MODULE_DEBUG 176 181 if ((wdata & SPI_CTRL_GO_BSY) != 0) { … … 178 183 } 179 184 #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 189 197 #ifdef SOCLIB_MODULE_DEBUG 190 198 std::cout << name() << " divider set to " << std::dec << wdata << std::endl; 191 199 #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; 234 242 } 235 243 //////////////////// … … 238 246 case T_ERROR_READ: 239 247 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 } 244 252 } // end switch target fsm 245 253 … … 252 260 if (r_spi_bsy == false) 253 261 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; 267 318 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 //////////////// 297 322 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 } 346 381 #ifdef SOCLIB_MODULE_DEBUG0 347 382 std::cout << name() << " end xfer " << std::dec << (int)r_ctrl_char_len.read() << " data " << std::hex << r_txrx[1] << " " << r_txrx[0] << std::endl; 348 383 #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 366 409 ////////////////////////////////////////////////////////////////////////////// 367 410 // The initiator FSM executes a loop, transfering one burst per iteration. … … 370 413 ////////////////////////////////////////////////////////////////////////////// 371 414 372 switch( r_initiator_fsm.read() ) { 415 switch( r_initiator_fsm.read() ) 416 { 373 417 //////////// 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 ///////////////// 384 429 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 } 390 438 //////////////// 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() ) 396 442 { 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; 409 457 } 410 458 //////////////// 411 459 case M_READ_RSP: // Wait a single flit VCI WRITE response 412 460 { 413 if ( p_vci_initiator.rspval.read() ) 414 { 415 if ( (p_vci_initiator.rerror.read()&0x1) != 0 ) 461 if ( p_vci_initiator.rspval.read() ) 416 462 { 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 421 470 #ifdef SOCLIB_MODULE_DEBUG 422 471 std::cout << "vci_bd M_READ_ERROR" << std::endl; 423 472 #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 430 481 #ifdef SOCLIB_MODULE_DEBUG 431 482 std::cout << "vci_bd M_READ_SUCCESS" << std::endl; 432 483 #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; 441 493 } 442 494 /////////////////// 443 495 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 } 447 501 /////////////////// 448 502 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 } 455 512 ///////////////// 456 case M_WRITE_CMD: // This is actually a single flit VCI READ command457 { 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; 460 517 } 461 518 ///////////////// 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() ) 475 522 { 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 483 542 #ifdef SOCLIB_MODULE_DEBUG 484 std::cout << "vci_ bdM_WRITE_ERROR" << std::endl;543 std::cout << "vci_spi M_WRITE_ERROR" << std::endl; 485 544 #endif 486 487 else if ( r_dma_count.read() == 0) // last burst488 489 r_dma_error = 0;490 r_initiator_fsm = M_WRITE_END;491 }492 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; 499 558 } 500 559 ///////////////// 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 509 566 } // end transition 510 567 … … 609 666 } 610 667 611 // SPI signals668 ////////////// SPI signals 612 669 p_spi_ss = ((r_ss & 0x1) == 0); 613 switch(r_spi_fsm) { 670 671 switch(r_spi_fsm) 672 { 614 673 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; 618 677 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 } 633 695 } 634 696 … … 638 700 639 701 ////////////////////////////////////////////////////////////////////////////// 640 tmpl(/**/)::VciSpi( sc_core::sc_module_name name,702 tmpl(/**/)::VciSpi( sc_core::sc_module_name name, 641 703 const soclib::common::MappingTable &mt, 642 const soclib::common::IntTab 643 const soclib::common::IntTab 644 const uint32_t burst_size)704 const soclib::common::IntTab &srcid, 705 const soclib::common::IntTab &tgtid, 706 const uint32_t burst_size) 645 707 646 708 : caba::BaseModule(name),
Note: See TracChangeset
for help on using the changeset viewer.