Changeset 579 for trunk/modules/vci_spi
- Timestamp:
- Nov 23, 2013, 1:25:13 AM (11 years ago)
- Location:
- trunk/modules/vci_spi
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/modules/vci_spi/caba/metadata/vci_spi.sd
r551 r579 35 35 uses = [ 36 36 Uses('caba:base_module'), 37 Uses('common:mapping_table'), 37 Uses('common:mapping_table'), 38 Uses('caba:generic_fifo'), 38 39 ], 39 40 -
trunk/modules/vci_spi/caba/source/include/vci_spi.h
r565 r579 54 54 #include "vci_initiator.h" 55 55 #include "vci_target.h" 56 #include "generic_fifo.h" 56 57 57 58 namespace soclib { … … 76 77 sc_signal<bool> r_ctrl_cpha; // clock phase 77 78 sc_signal<bool> r_ctrl_ie; // interrupt enable 78 sc_signal<bool> r_ctrl_go_bsy;79 79 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 81 88 sc_signal<uint32_t> r_spi_bit_count; 89 sc_signal<uint32_t> r_spi_word_count; 82 90 sc_signal<uint32_t> r_spi_clk_counter; 83 91 sc_signal<bool> r_spi_clk; … … 88 96 sc_signal<bool> r_irq; 89 97 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 101 100 102 101 sc_signal<typename vci_param::srcid_t > r_srcid; // save srcid … … 106 105 sc_signal<typename vci_param::data_t > r_rdata; // save reply 107 106 108 uint32_t* r_local_buffer; // capacity is one block109 110 107 // structural parameters 111 108 std::list<soclib::common::Segment> m_seglist; 112 109 uint32_t m_srcid; // initiator index 113 const uint32_t m_words_per_block; // block size110 const uint32_t m_burst_size; // number of words in a burst 114 111 const uint32_t m_words_per_burst; // number of words in a burst 115 const uint32_t m_b ursts_per_block; // number of bursts in a block112 const uint32_t m_byte2burst_shift; // log2(burst_size) 116 113 117 114 // methods … … 122 119 enum { 123 120 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 138 128 }; 139 129 … … 150 140 enum { 151 141 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, 153 147 }; 154 148 -
trunk/modules/vci_spi/caba/source/src/vci_spi.cpp
r576 r579 29 29 #include <stdint.h> 30 30 #include <iostream> 31 #include <arithmetics.h> 31 32 #include <fcntl.h> 32 33 #include "vci_spi.h" … … 43 44 tmpl(void)::transition() 44 45 { 46 47 bool s_dma_bsy = (r_initiator_fsm != M_IDLE); 45 48 if(p_resetn.read() == false) 46 49 { 47 50 r_initiator_fsm = M_IDLE; 48 51 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; 52 55 r_ctrl_char_len = 0; 53 r_ctrl_ie = false;56 r_ctrl_ie = false; 54 57 r_ctrl_cpol = false; 55 58 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; 59 63 r_spi_done = false; 60 64 61 65 r_irq = false; 62 66 r_read = false; 67 68 r_dma_fifo_read.init(); 69 r_dma_fifo_write.init(); 63 70 64 71 return; … … 71 78 72 79 if (r_spi_done) 73 r_ ctrl_go_bsy = false;80 r_spi_bsy = false; 74 81 75 82 switch(r_target_fsm) { … … 102 109 r_target_fsm = T_ERROR_READ; 103 110 } 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; 105 112 uint32_t cell = (uint32_t)((address & 0x3F)>>2); 106 113 switch(cell) { … … 150 157 if (r_ctrl_ie.read()) 151 158 data |= SPI_CTRL_IE_EN; 152 if (r_ ctrl_go_bsy.read())159 if (r_spi_bsy.read()) 153 160 data |= SPI_CTRL_GO_BSY; 161 if (s_dma_bsy) 162 data |= SPI_CTRL_DMA_BSY; 154 163 data |= (uint32_t)r_ctrl_char_len.read(); 155 164 r_rdata = data; … … 159 168 r_ctrl_ie = ((wdata & SPI_CTRL_IE_EN) != 0); 160 169 if (wdata & SPI_CTRL_GO_BSY) 161 r_ ctrl_go_bsy = true;170 r_spi_bsy = true; 162 171 r_ctrl_char_len = (wdata & SPI_CTRL_CHAR_LEN_MASK); 163 172 #ifdef SOCLIB_MODULE_DEBUG … … 167 176 #endif 168 177 } else { 169 r_irq = r_irq & r_ ctrl_go_bsy;178 r_irq = r_irq & r_spi_bsy; 170 179 } 171 180 r_target_fsm = (p_vci_target.cmd.read() == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ; … … 186 195 if (write) { 187 196 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; 188 221 } 189 222 r_target_fsm = (p_vci_target.cmd.read() == vci_param::CMD_WRITE) ? T_RSP_WRITE : T_RSP_READ; … … 214 247 // the SPI FSM controls SPI signals 215 248 ////////////////////////////////////////////////////////////////////////////// 216 if (r_ ctrl_go_bsy == false)249 if (r_spi_bsy == false) 217 250 r_spi_done = false; 218 251 switch (r_spi_fsm) { … … 224 257 r_spi_bit_count = r_ctrl_char_len; 225 258 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; 228 318 break; 229 319 case S_XMIT: … … 241 331 // high to low transition: change output, or stop 242 332 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 } 246 343 #ifdef SOCLIB_MODULE_DEBUG0 247 344 std::cout << name() << " end xfer " << std::dec << (int)r_ctrl_char_len.read() << " data " << std::hex << r_txrx[1] << " " << r_txrx[0] << std::endl; … … 265 362 } 266 363 ////////////////////////////////////////////////////////////////////////////// 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. 278 367 ////////////////////////////////////////////////////////////////////////////// 279 368 … … 282 371 case M_IDLE: // check buffer alignment to compute the number of bursts 283 372 { 284 if ( false ) // XXX373 if ( r_dma_count != 0 ) 285 374 { 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; 331 387 //////////////// 332 388 case M_READ_CMD: // Send a multi-flits VCI WRITE command … … 334 390 if ( p_vci_initiator.cmdack.read() ) 335 391 { 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; 378 404 } 379 405 break; … … 384 410 if ( p_vci_initiator.rspval.read() ) 385 411 { 386 bool aligned = (r_burst_offset.read() == 0);387 388 412 if ( (p_vci_initiator.rerror.read()&0x1) != 0 ) 389 413 { 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; 391 418 #ifdef SOCLIB_MODULE_DEBUG 392 419 std::cout << "vci_bd M_READ_ERROR" << std::endl; 393 420 #endif 394 421 } 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; 401 427 #ifdef SOCLIB_MODULE_DEBUG 402 428 std::cout << "vci_bd M_READ_SUCCESS" << std::endl; 403 429 #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; 417 435 } 418 436 } … … 420 438 } 421 439 /////////////////// 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; 449 447 ///////////////// 450 448 case M_WRITE_CMD: // This is actually a single flit VCI READ command 451 449 { 452 450 if ( p_vci_initiator.cmdack.read() ) r_initiator_fsm = M_WRITE_RSP; 453 451 break; 454 452 } … … 458 456 if ( p_vci_initiator.rspval.read() ) 459 457 { 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; 474 466 if ( p_vci_initiator.reop.read() ) // last flit of the burst 475 467 { 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 ) 480 471 { 481 r_initiator_fsm = M_WRITE_ERROR; 472 r_dma_count = 0; 473 r_dma_error = 1; 474 r_initiator_fsm = M_WRITE_END; 482 475 #ifdef SOCLIB_MODULE_DEBUG 483 476 std::cout << "vci_bd M_WRITE_ERROR" << std::endl; 484 477 #endif 485 478 } 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 488 480 { 489 r_initiator_fsm = M_WRITE_BLOCK; 481 r_dma_error = 0; 482 r_initiator_fsm = M_WRITE_END; 490 483 } 491 484 else // not the last burst 492 485 { 493 r_burst_count = r_burst_count.read() + 1; 494 r_initiator_fsm = M_WRITE_BURST; 486 r_initiator_fsm = M_WRITE_WAIT; 495 487 } 496 488 } 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 531 501 } // end transition 532 502 … … 590 560 p_vci_initiator.wdata = 0; 591 561 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); 593 563 p_vci_initiator.eop = true; 594 564 break; 595 565 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; 596 569 p_vci_initiator.rspack = false; 597 570 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(); 599 572 p_vci_initiator.cmd = vci_param::CMD_WRITE; 600 573 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) 603 583 { 604 p_vci_initiator.wdata = ((uint64_t)r_local_buffer[r_index.read() ]) +605 (((uint64_t)r_local_buffer[r_index.read()+1]) << 32);606 584 p_vci_initiator.be = 0xFF; 607 p_vci_initiator.eop = ( (r_burst_nwords.read() - r_words_count.read()) <= 2 );608 585 } 609 586 else 610 587 { 611 p_vci_initiator.wdata = r_local_buffer[r_index.read()];612 588 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 } 616 592 case M_READ_RSP: 617 593 case M_WRITE_RSP: … … 628 604 p_spi_ss = ((r_ss & 0x1) == 0); 629 605 switch(r_spi_fsm) { 630 case S_IDLE:606 default: 631 607 p_spi_mosi = r_spi_out; 632 608 p_spi_clk = 0; … … 663 639 m_seglist(mt.getSegmentList(tgtid)), 664 640 m_srcid(mt.indexForId(srcid)), 665 m_ words_per_block(512/4),666 m_words_per_burst(burst_size /4),667 m_b ursts_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)), 668 644 p_clk("p_clk"), 669 645 p_resetn("p_resetn"), … … 674 650 p_spi_clk("p_spi_clk"), 675 651 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 677 656 { 678 657 std::cout << " - Building VciSpi " << name << std::endl; … … 735 714 } 736 715 737 r_local_buffer = new uint32_t[m_words_per_block];738 739 716 } // end constructor 740 717 741 718 tmpl(/**/)::~VciSpi() 742 719 { 743 delete [] r_local_buffer;744 720 } 745 721 … … 752 728 "M_IDLE", 753 729 754 "M_READ_BLOCK", 755 "M_READ_BURST", 730 "M_READ_WAIT", 756 731 "M_READ_CMD", 757 732 "M_READ_RSP", 758 "M_READ_SUCCESS", 759 "M_READ_ERROR", 760 761 "M_WRITE_BURST", 733 734 "M_WRITE_WAIT", 762 735 "M_WRITE_CMD", 763 736 "M_WRITE_RSP", 764 "M_WRITE_BLOCK", 765 "M_WRITE_SUCCESS", 766 "M_WRITE_ERROR", 737 "M_WRITE_END", 767 738 }; 768 739 const char* target_str[] = … … 777 748 { 778 749 "S_IDLE", 750 "S_DMA_RECEIVE", 751 "S_DMA_SEND_START", 752 "S_DMA_SEND", 753 "S_DMA_SEND_END", 779 754 "S_XMIT", 780 755 }; … … 785 760 << " clk_counter " << r_spi_clk_counter.read() 786 761 << " 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; 788 763 std::cout << name() << " _SPI : " 789 764 << " r_spi_clk " << r_spi_clk.read() … … 793 768 << " r_txrx 0x" << std::hex 794 769 << r_txrx[1].read() << " " << r_txrx[0].read() 770 795 771 << std::endl; 796 772 std::cout << name() << " _INI : " << initiator_str[r_initiator_fsm.read()] 797 773 << " 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; 801 778 } 802 779 -
trunk/modules/vci_spi/include/soclib/vcispi.h
r573 r579 35 35 SPI_CTRL, 36 36 SPI_DIVIDER, 37 SPI_SS 37 SPI_SS, 38 SPI_DMA_BASE, 39 SPI_DMA_BASEH, 40 SPI_DMA_COUNT 38 41 }; 39 42 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 */ 43 47 // 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) */ 46 52 47 53 #endif /* SPISD_H */
Note: See TracChangeset
for help on using the changeset viewer.