source: trunk/modules/vci_block_device_tsar/caba/source/src/vci_block_device_tsar.cpp @ 400

Last change on this file since 400 was 400, checked in by alain, 11 years ago

Introducing support for VCI DATA 64 bits.

File size: 26.5 KB
Line 
1/* -*- c++ -*-
2 *
3 * SOCLIB_LGPL_HEADER_BEGIN
4 *
5 * This file is part of SoCLib, GNU LGPLv2.1.
6 *
7 * SoCLib is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as published
9 * by the Free Software Foundation; version 2.1 of the License.
10 *
11 * SoCLib is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with SoCLib; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 * 02110-1301 USA
20 *
21 * SOCLIB_LGPL_HEADER_END
22 *
23 * Copyright (c) UPMC, Lip6, Asim
24 *         alain.greiner@lip6.fr april 2011
25 *
26 * Maintainers: alain
27 */
28
29#include <stdint.h>
30#include <iostream>
31#include <fcntl.h>
32#include "vci_block_device_tsar.h"
33
34namespace soclib { namespace caba {
35
36#define tmpl(t) template<typename vci_param> t VciBlockDeviceTsar<vci_param>
37
38using namespace soclib::caba;
39using namespace soclib::common;
40
41////////////////////////
42tmpl(void)::transition()
43{
44    if(p_resetn.read() == false) 
45    {
46        r_initiator_fsm   = M_IDLE;
47        r_target_fsm      = T_IDLE;
48        r_irq_enable      = true;
49        r_go              = false;
50        return;
51    } 
52
53    //////////////////////////////////////////////////////////////////////////////
54    // The Target FSM controls the following registers:
55    // r_target_fsm, r_irq_enable, r_nblocks, r_buf adress, r_lba, r_go, r_read
56    //////////////////////////////////////////////////////////////////////////////
57
58    switch(r_target_fsm) {
59    ////////////
60    case T_IDLE:
61    {
62        if ( p_vci_target.cmdval.read() ) 
63        { 
64            r_srcid = p_vci_target.srcid.read();
65            r_trdid = p_vci_target.trdid.read();
66            r_pktid = p_vci_target.pktid.read();
67            sc_dt::sc_uint<vci_param::N> address = p_vci_target.address.read();
68            bool                  read    = (p_vci_target.cmd.read() == vci_param::CMD_READ);
69            uint32_t              cell    = (uint32_t)((address & 0x3F)>>2);
70
71            if     ( !read && !m_segment.contains(address) )      r_target_fsm = T_WRITE_ERROR;
72            else if(  read && !m_segment.contains(address) )      r_target_fsm = T_READ_ERROR;
73            else if( !read && !p_vci_target.eop.read() )          r_target_fsm = T_WRITE_ERROR;
74            else if(  read && !p_vci_target.eop.read() )          r_target_fsm = T_READ_ERROR;
75            else if( !read && (cell == BLOCK_DEVICE_BUFFER) )     r_target_fsm = T_WRITE_BUFFER;
76            else if(  read && (cell == BLOCK_DEVICE_BUFFER) )     r_target_fsm = T_READ_BUFFER;
77            else if( !read && (cell == BLOCK_DEVICE_BUFFER_EXT) ) r_target_fsm = T_WRITE_BUFFER_EXT;
78            else if(  read && (cell == BLOCK_DEVICE_BUFFER_EXT) ) r_target_fsm = T_READ_BUFFER_EXT;
79            else if( !read && (cell == BLOCK_DEVICE_COUNT) )      r_target_fsm = T_WRITE_COUNT;
80            else if(  read && (cell == BLOCK_DEVICE_COUNT) )      r_target_fsm = T_READ_COUNT;
81            else if( !read && (cell == BLOCK_DEVICE_LBA) )        r_target_fsm = T_WRITE_LBA;
82            else if(  read && (cell == BLOCK_DEVICE_LBA) )        r_target_fsm = T_READ_LBA;
83            else if( !read && (cell == BLOCK_DEVICE_OP) )         r_target_fsm = T_WRITE_OP;
84            else if(  read && (cell == BLOCK_DEVICE_STATUS) )     r_target_fsm = T_READ_STATUS;
85            else if( !read && (cell == BLOCK_DEVICE_IRQ_ENABLE) ) r_target_fsm = T_WRITE_IRQEN;
86            else if(  read && (cell == BLOCK_DEVICE_IRQ_ENABLE) ) r_target_fsm = T_READ_IRQEN;
87            else if(  read && (cell == BLOCK_DEVICE_SIZE) )       r_target_fsm = T_READ_SIZE;
88            else if(  read && (cell == BLOCK_DEVICE_BLOCK_SIZE) ) r_target_fsm = T_READ_BLOCK;
89        }
90        break;
91    }
92    ////////////////////
93    case T_WRITE_BUFFER:
94    {
95        if ( (r_initiator_fsm.read() == M_IDLE) and p_vci_target.rspack.read() ) 
96        {
97            r_buf_address = (uint64_t)p_vci_target.wdata.read();
98            r_target_fsm  = T_IDLE;
99        }
100        break;
101    }
102    ////////////////////////
103    case T_WRITE_BUFFER_EXT:
104    {
105        if ( (r_initiator_fsm.read() == M_IDLE) and p_vci_target.rspack.read() ) 
106        {
107            r_buf_address = r_buf_address.read() + 
108                            (((uint64_t)p_vci_target.wdata.read())<<32);
109            r_target_fsm  = T_IDLE;
110        }
111        break;
112    }
113    ///////////////////
114    case T_WRITE_COUNT:
115    {
116        if ( (r_initiator_fsm.read() == M_IDLE) and p_vci_target.rspack.read() ) 
117        {
118            r_nblocks    = (uint32_t)p_vci_target.wdata.read();
119            r_target_fsm = T_IDLE;
120        }
121        break;
122    }
123    /////////////////
124    case T_WRITE_LBA:
125    {
126        if ( (r_initiator_fsm.read() == M_IDLE) and p_vci_target.rspack.read() ) 
127        {
128            r_lba        = (uint32_t)p_vci_target.wdata.read();
129            r_target_fsm = T_IDLE;
130        }
131        break;
132    }
133    ////////////////
134    case T_WRITE_OP:
135    {
136        if ( p_vci_target.rspack.read() ) 
137        {
138            if ( ((uint32_t)p_vci_target.wdata.read() == BLOCK_DEVICE_READ) and
139                 (r_initiator_fsm.read() == M_IDLE) )
140            {
141                r_read = true;
142                r_go   = true;
143            }
144            else if ( ((uint32_t)p_vci_target.wdata.read() == BLOCK_DEVICE_WRITE) and
145                      (r_initiator_fsm.read() == M_IDLE) )
146            {
147                r_read = false;
148                r_go   = true;
149            }
150            else
151            {
152                r_go   = false;
153            }
154            r_target_fsm = T_IDLE;
155        }
156        break;
157    }
158    ///////////////////
159    case T_WRITE_IRQEN:
160    {
161        if ( p_vci_target.rspack.read() ) 
162        {
163            r_target_fsm = T_IDLE;
164            r_irq_enable = (p_vci_target.wdata.read() != 0);
165        }
166        break;
167    }
168    ///////////////////
169    case T_READ_BUFFER:
170    case T_READ_BUFFER_EXT:
171    case T_READ_COUNT:
172    case T_READ_LBA:
173    case T_READ_IRQEN:
174    case T_READ_SIZE:
175    case T_READ_BLOCK:
176    case T_READ_ERROR:
177    case T_WRITE_ERROR:
178    {
179        if ( p_vci_target.rspack.read() ) r_target_fsm = T_IDLE;
180        break;
181    }
182    ///////////////////
183    case T_READ_STATUS:
184    {
185        if ( p_vci_target.rspack.read() ) 
186        {
187            r_target_fsm = T_IDLE;
188            if( (r_initiator_fsm == M_READ_SUCCESS ) ||
189                (r_initiator_fsm == M_READ_ERROR   ) ||
190                (r_initiator_fsm == M_WRITE_SUCCESS) ||
191                (r_initiator_fsm == M_WRITE_ERROR  ) ) r_go = false;
192        }
193        break;
194    }
195    } // end switch target fsm
196       
197    //////////////////////////////////////////////////////////////////////////////
198    // The initiator FSM executes a loop, transfering one block per iteration.
199    // Each block is split in bursts, and the number of bursts depends
200    // on the memory buffer alignment on a burst boundary:
201    // - If buffer aligned, all burst have the same length (m_words_per burst)
202    //   and the number of bursts is (m_bursts_per_block).
203    // - If buffer not aligned, the number of bursts is (m_bursts_per_block + 1)
204    //   and first and last burst are shorter, because all words in a burst
205    //   must be contained in a single cache line.
206    //   first burst => nwords = m_words_per_burst - offset
207    //   last  burst => nwords = offset
208    //   other burst => nwords = m_words_per_burst
209    //////////////////////////////////////////////////////////////////////////////
210
211    switch( r_initiator_fsm.read() ) {
212    ////////////
213    case M_IDLE:        // check buffer alignment to compute the number of bursts
214    {
215        if ( r_go.read() ) 
216        {
217            r_index         = 0;
218            r_block_count   = 0;
219            r_burst_count   = 0;
220            r_words_count    = 0;
221            r_latency_count = m_latency;
222
223            // compute r_burst_offset (zero when buffer aligned)
224            r_burst_offset = (uint32_t)((r_buf_address.read()>>2) % m_words_per_burst);
225
226            // start tranfer
227            if ( r_read.read() )        r_initiator_fsm = M_READ_BLOCK;
228            else                    r_initiator_fsm = M_WRITE_BURST;
229        }
230        break;
231    } 
232    //////////////////
233    case M_READ_BLOCK:  // read one block from disk after waiting m_latency cycles
234    {
235        if ( r_latency_count.read() == 0 )
236        {
237            r_latency_count = m_latency;
238            ::lseek(m_fd, (r_lba + r_block_count)*m_words_per_block*4, SEEK_SET);
239            if( ::read(m_fd, r_local_buffer, m_words_per_block*4) < 0 ) 
240            {
241                r_initiator_fsm = M_READ_ERROR;
242            }
243            else   
244            {
245                r_burst_count   = 0;
246                r_words_count    = 0;
247                r_initiator_fsm = M_READ_BURST;
248            }
249        }
250        else
251        {
252            r_latency_count = r_latency_count.read() - 1;
253        }
254        break;
255    }
256    //////////////////
257    case M_READ_BURST:  // Compute the number of words and the number of flits in the burst
258                        // The number of flits can be smaller than the number of words
259                        // in case of 8 bytes flits...
260    {
261        uint32_t nwords;
262        uint32_t offset = r_burst_offset.read();
263
264        if ( offset )                  // buffer not aligned
265        {
266            if ( r_burst_count.read() == 0 ) nwords = m_words_per_burst - offset;
267            else if ( r_burst_count.read() == m_bursts_per_block ) nwords = offset;
268            else nwords = m_words_per_burst;
269        }
270        else                           // buffer aligned
271        {
272            nwords = m_words_per_burst;
273        }
274
275        r_burst_nwords  = nwords;
276        r_initiator_fsm = M_READ_CMD;
277        break;
278    }
279    ////////////////
280    case M_READ_CMD:    // Send a multi-flits VCI WRITE command
281    {
282        if ( p_vci_initiator.cmdack.read() )
283        {
284            uint32_t nwords = r_burst_nwords.read() - r_words_count.read();
285
286            if ( vci_param::B == 4 )    // one word per flit
287            {
288                if ( nwords <= 1 )      // last flit
289                {
290                    r_initiator_fsm = M_READ_RSP;
291                    r_words_count = 0;
292                }
293                else                    // not the last flit
294                {
295                    r_words_count = r_words_count.read() + 1;
296                }
297
298                // compute next word address and next local buffer index
299                r_buf_address = r_buf_address.read() + 4;
300                r_index       = r_index.read() + 1;
301            }
302            else                        // 2 words per flit
303            {
304                if ( nwords <= 2 )      // last flit
305                {
306                    r_initiator_fsm = M_READ_RSP;
307                    r_words_count = 0;
308                }
309                else                    // not the last flit
310                {
311                    r_words_count = r_words_count.read() + 2;
312                }
313                   
314                // compute next word address and next local buffer index
315                if ( nwords == 1 )
316                {
317                    r_buf_address = r_buf_address.read() + 4;
318                    r_index       = r_index.read() + 1;
319                }
320                else
321                {
322                    r_buf_address = r_buf_address.read() + 8;
323                    r_index       = r_index.read() + 2;
324                }
325            }
326        }
327        break;
328    }
329    ////////////////
330    case M_READ_RSP:    // Wait a single flit VCI WRITE response
331    {
332        if ( p_vci_initiator.rspval.read() )
333        {
334            bool aligned = (r_burst_offset.read() == 0);
335
336            if ( (p_vci_initiator.rerror.read()&0x1) != 0 ) 
337            {
338                r_initiator_fsm = M_READ_ERROR;
339            }
340            else if ( (not aligned and (r_burst_count.read() == m_bursts_per_block)) or
341                      (aligned and (r_burst_count.read() == (m_bursts_per_block-1))) )
342            {
343                if ( r_block_count.read() == (r_nblocks.read()-1) ) // last burst of last block
344                {
345                    r_initiator_fsm = M_READ_SUCCESS;
346                }
347                else                                              // last burst not last block
348                {
349                    r_index          = 0;
350                    r_burst_count    = 0;
351                    r_block_count    = r_block_count.read() + 1;
352                    r_initiator_fsm  = M_READ_BLOCK;
353                }
354            }
355            else                                                // not the last burst
356            {
357                r_burst_count = r_burst_count.read() + 1;
358                r_initiator_fsm = M_READ_BURST;
359            }
360        }
361        break;
362    }
363    ///////////////////
364    case M_READ_SUCCESS:
365    case M_READ_ERROR:
366    {
367        if( !r_go ) r_initiator_fsm = M_IDLE;
368        break;
369    }
370    ///////////////////
371    case M_WRITE_BURST:  // Compute the number of words in the burst
372    {
373        uint32_t nwords;
374        uint32_t offset = r_burst_offset.read();
375
376        if ( offset )                  // buffer not aligned
377        {
378            if ( r_burst_count.read() == 0 ) nwords = m_words_per_burst - offset;
379            else if ( r_burst_count.read() == m_bursts_per_block ) nwords = offset;
380            else nwords = m_words_per_burst;
381        }
382        else                           // buffer aligned
383        {
384            nwords = m_words_per_burst;
385        }
386
387        r_burst_nwords  = nwords;
388        r_initiator_fsm =  M_WRITE_CMD;
389        break;
390    }
391    /////////////////
392    case M_WRITE_CMD:   // This is actually a single flit VCI READ command
393    {
394            if ( p_vci_initiator.cmdack.read() ) r_initiator_fsm = M_WRITE_RSP;
395        break;
396    }
397    /////////////////
398    case M_WRITE_RSP:   // This is actually a multi-words VCI READ response
399    {
400        if ( p_vci_initiator.rspval.read() )
401        {
402            bool aligned = (r_burst_offset.read() == 0);
403
404            if ( (vci_param::B == 8) and (r_burst_nwords.read() > 1) )
405            {
406                r_local_buffer[r_index.read()]   = (uint32_t)p_vci_initiator.rdata.read();
407                r_local_buffer[r_index.read()+1] = (uint32_t)(p_vci_initiator.rdata.read()>>32);
408                r_index = r_index.read() + 2;
409            }
410            else
411            {
412                r_local_buffer[r_index.read()]   = (uint32_t)p_vci_initiator.rdata.read();
413                r_index = r_index.read() + 1;
414            }
415
416            if ( p_vci_initiator.reop.read() )  // last flit of the burst
417            {
418                    r_words_count  = 0;
419                r_buf_address = r_buf_address.read() + (r_burst_nwords.read()<<2); 
420
421                    if( (p_vci_initiator.rerror.read()&0x1) != 0 ) 
422                {
423                    r_initiator_fsm = M_WRITE_ERROR;
424                }
425                else if ( (not aligned and (r_burst_count.read() == m_bursts_per_block)) or
426                     (aligned and (r_burst_count.read() == (m_bursts_per_block-1))) ) // last burst
427                {
428                    r_initiator_fsm  = M_WRITE_BLOCK;
429                }
430                else                                          // not the last burst
431                {
432                    r_burst_count = r_burst_count.read() + 1;
433                    r_initiator_fsm = M_WRITE_BURST;
434                }
435            }
436            else
437            {
438                    r_words_count = r_words_count.read() + 1;
439            }
440        }
441        break;
442    }
443    ///////////////////
444    case M_WRITE_BLOCK:         // write a block to disk after waiting m_latency cycles
445    {
446        if ( r_latency_count == 0 )
447        {
448            r_latency_count = m_latency;
449            ::lseek(m_fd, (r_lba + r_block_count)*m_words_per_block*vci_param::B, SEEK_SET);
450            if( ::write(m_fd, r_local_buffer, m_words_per_block*vci_param::B) < 0 )
451            {
452                r_initiator_fsm = M_WRITE_ERROR; 
453            }
454            else if ( r_block_count.read() == r_nblocks.read() - 1 ) 
455            {
456                r_initiator_fsm = M_WRITE_SUCCESS; 
457            }
458            else
459            {
460                r_burst_count    = 0;
461                r_index          = 0;
462                r_block_count    = r_block_count.read() + 1;
463                r_initiator_fsm  = M_WRITE_BURST;
464            }
465        } 
466        else
467        {
468            r_latency_count = r_latency_count - 1;
469        }
470        break;
471    }
472    /////////////////////
473    case M_WRITE_SUCCESS:
474    case M_WRITE_ERROR:
475    {
476        if( !r_go ) r_initiator_fsm = M_IDLE;
477        break;
478    }
479    } // end switch r_initiator_fsm
480}  // end transition
481
482//////////////////////
483tmpl(void)::genMoore()
484{
485    // p_vci_target port   
486    p_vci_target.rsrcid = (sc_dt::sc_uint<vci_param::S>)r_srcid.read();
487    p_vci_target.rtrdid = (sc_dt::sc_uint<vci_param::T>)r_trdid.read();
488    p_vci_target.rpktid = (sc_dt::sc_uint<vci_param::P>)r_pktid.read();
489    p_vci_target.reop   = true;
490
491    switch(r_target_fsm) {
492    case T_IDLE:
493        p_vci_target.cmdack = true;
494        p_vci_target.rspval = false;
495        break;
496    case T_READ_STATUS:
497        p_vci_target.cmdack = false;
498        p_vci_target.rspval = true;
499        if     (r_initiator_fsm == M_IDLE)          p_vci_target.rdata = BLOCK_DEVICE_IDLE;
500        else if(r_initiator_fsm == M_READ_SUCCESS)  p_vci_target.rdata = BLOCK_DEVICE_READ_SUCCESS;
501        else if(r_initiator_fsm == M_WRITE_SUCCESS) p_vci_target.rdata = BLOCK_DEVICE_WRITE_SUCCESS;
502        else if(r_initiator_fsm == M_READ_ERROR)        p_vci_target.rdata = BLOCK_DEVICE_READ_ERROR;
503        else if(r_initiator_fsm == M_WRITE_ERROR)       p_vci_target.rdata = BLOCK_DEVICE_WRITE_ERROR;
504        else                                            p_vci_target.rdata = BLOCK_DEVICE_BUSY;
505        p_vci_target.rerror = VCI_READ_OK;
506        break;
507    case T_READ_BUFFER:
508        p_vci_target.cmdack = false;
509        p_vci_target.rspval = true;
510        p_vci_target.rdata  = (uint32_t)r_buf_address.read();
511        p_vci_target.rerror = VCI_READ_OK;
512        break;
513    case T_READ_BUFFER_EXT:
514        p_vci_target.cmdack = false;
515        p_vci_target.rspval = true;
516        p_vci_target.rdata  = (uint32_t)(r_buf_address.read()>>32);
517        p_vci_target.rerror = VCI_READ_OK;
518        break;
519    case T_READ_COUNT:
520        p_vci_target.cmdack = false;
521        p_vci_target.rspval = true;
522        p_vci_target.rdata  = r_nblocks.read();
523        p_vci_target.rerror = VCI_READ_OK;
524        break;
525    case T_READ_LBA:
526        p_vci_target.cmdack = false;
527        p_vci_target.rspval = true;
528        p_vci_target.rdata  = r_lba.read();
529        p_vci_target.rerror = VCI_READ_OK;
530        break;
531    case T_READ_IRQEN:
532        p_vci_target.cmdack = false;
533        p_vci_target.rspval = true;
534        p_vci_target.rdata  = r_irq_enable.read();
535        p_vci_target.rerror = VCI_READ_OK;
536        break;
537    case T_READ_SIZE:
538        p_vci_target.cmdack = false;
539        p_vci_target.rspval = true;
540        p_vci_target.rdata  = m_device_size;
541        p_vci_target.rerror = VCI_READ_OK;
542        break;
543    case T_READ_BLOCK:
544        p_vci_target.cmdack = false;
545        p_vci_target.rspval = true;
546        p_vci_target.rdata  = m_words_per_block*vci_param::B;
547        p_vci_target.rerror = VCI_READ_OK;
548        break;
549    case T_READ_ERROR:
550        p_vci_target.cmdack = false;
551        p_vci_target.rspval = true;
552        p_vci_target.rdata  = 0;
553        p_vci_target.rerror = VCI_READ_ERROR;
554        break;
555    case T_WRITE_ERROR:
556        p_vci_target.cmdack = false;
557        p_vci_target.rspval = true;
558        p_vci_target.rdata  = 0;
559        p_vci_target.rerror = VCI_WRITE_ERROR;
560        break;
561    default:
562        p_vci_target.cmdack = false;
563        p_vci_target.rspval = true;
564        p_vci_target.rdata  = 0;
565        p_vci_target.rerror = VCI_WRITE_OK;
566        break;
567    } // end switch target fsm
568
569    // p_vci_initiator port
570    p_vci_initiator.srcid  = (sc_dt::sc_uint<vci_param::S>)m_srcid;
571    p_vci_initiator.trdid  = 0;
572    p_vci_initiator.contig = true;
573    p_vci_initiator.cons   = false;
574    p_vci_initiator.wrap   = false;
575    p_vci_initiator.cfixed = false;
576    p_vci_initiator.clen   = 0;
577
578    switch (r_initiator_fsm) {
579    case M_WRITE_CMD:           // It is actually a single word VCI read command
580        p_vci_initiator.rspack  = false;
581        p_vci_initiator.cmdval  = true;
582        p_vci_initiator.address = (sc_dt::sc_uint<vci_param::N>)r_buf_address.read();
583        p_vci_initiator.cmd     = vci_param::CMD_READ;
584        p_vci_initiator.pktid   = TYPE_READ_DATA_UNC; // or _MISS ?
585        p_vci_initiator.wdata   = 0;
586        p_vci_initiator.be      = (uint32_t)0xF;
587        p_vci_initiator.plen    = (sc_dt::sc_uint<vci_param::K>)(r_burst_nwords.read()<<2);
588        p_vci_initiator.eop     = true;
589        break;
590    case M_READ_CMD:            // It is actually a multi-words VCI WRITE command
591        p_vci_initiator.rspack  = false;
592        p_vci_initiator.cmdval  = true;
593        p_vci_initiator.address = (sc_dt::sc_uint<vci_param::N>)r_buf_address.read(); 
594        p_vci_initiator.cmd     = vci_param::CMD_WRITE;
595        p_vci_initiator.pktid   = TYPE_WRITE;
596        p_vci_initiator.be      = 0xF;
597        p_vci_initiator.plen    = (sc_dt::sc_uint<vci_param::K>)(r_burst_nwords.read()<<2);
598        p_vci_initiator.eop     = ( r_words_count.read() == (r_burst_nwords.read() - 1) );
599        if (vci_param::B == 4)  p_vci_initiator.wdata = r_local_buffer[r_index.read()];
600        else                    p_vci_initiator.wdata = (uint64_t)r_local_buffer[r_index.read()] +
601                                   ((uint64_t)r_local_buffer[r_index.read()+1])<<32; 
602        break;
603    case M_READ_RSP:
604    case M_WRITE_RSP:
605        p_vci_initiator.rspack  = true;
606        p_vci_initiator.cmdval  = false;
607        break;
608    default:
609        p_vci_initiator.rspack  = false;
610        p_vci_initiator.cmdval  = false;
611        break;
612    }
613
614    // IRQ signal
615    if(((r_initiator_fsm == M_READ_SUCCESS)    ||
616                            (r_initiator_fsm == M_WRITE_SUCCESS)   ||
617                            (r_initiator_fsm == M_READ_ERROR)      ||
618                            (r_initiator_fsm == M_WRITE_ERROR) ) &&  r_irq_enable) p_irq = true;
619    else                                                       p_irq = false;
620} // end GenMoore()
621
622//////////////////////////////////////////////////////////////////////////////
623tmpl(/**/)::VciBlockDeviceTsar( sc_core::sc_module_name              name, 
624                                const soclib::common::MappingTable   &mt,
625                                const soclib::common::IntTab         &srcid,
626                                const soclib::common::IntTab         &tgtid,
627                                const std::string                    &filename,
628                                const uint32_t                       block_size,
629                                const uint32_t                       burst_size,
630                                const uint32_t                       latency)
631
632: caba::BaseModule(name),
633        m_segment(mt.getSegment(tgtid)),
634        m_srcid(mt.indexForId(srcid)),
635        m_words_per_block(block_size/4),
636        m_words_per_burst(burst_size/4),
637        m_bursts_per_block(block_size/burst_size),
638        m_latency(latency),
639        p_clk("p_clk"),
640        p_resetn("p_resetn"),
641        p_vci_initiator("p_vci_initiator"),
642        p_vci_target("p_vci_target"),
643        p_irq("p_irq") 
644{
645        SC_METHOD(transition);
646    dont_initialize();
647    sensitive << p_clk.pos();
648
649        SC_METHOD(genMoore);
650    dont_initialize();
651    sensitive << p_clk.neg();
652
653    if( (block_size != 128)  && 
654        (block_size != 256)  && 
655        (block_size != 512)  && 
656        (block_size != 1024) &&
657        (block_size != 2048) && 
658        (block_size != 4096) )
659        {
660                std::cout << "Error in component VciBlockDeviceTsar : " << name << std::endl;
661                std::cout << "The block size must be 128, 256, 512, 1024, 2048 or 4096 bytes" << std::endl;
662                exit(1);
663        }
664    if( (burst_size != 4 ) && 
665                (burst_size != 8 ) && 
666                (burst_size != 16) && 
667                (burst_size != 32) && 
668                (burst_size != 64) )
669        {
670                std::cout << "Error in component VciBlockDeviceTsar : " << name << std::endl;
671                std::cout << "The burst size must be 4, 8, 16, 32 or 64 bytes" << std::endl;
672                exit(1);
673        }
674        if ( m_segment.size() < 64 ) 
675        {
676                std::cout << "Error in component VciBlockDeviceTsar : " << name << std::endl;
677                std::cout << "The size of the segment cannot be smaller than 64 bytes" << std::endl;
678                exit(1);
679        }
680        if ( (m_segment.baseAddress() & 0x0000003F) != 0 ) 
681        {
682                std::cout << "Error in component VciBlockDeviceTsar : " << name << std::endl;
683                std::cout << "The base address of the segment must be multiple of 64 bytes" << std::endl;
684                exit(1);
685        }
686        if ( (vci_param::B != 4) and (vci_param::B != 8) )
687        {
688                std::cout << "Error in component VciBlockDeviceTsar : " << name << std::endl;
689                std::cout << "The VCI data fields must have 32 bits or 64 bits" << std::endl;
690                exit(1);
691        }
692        m_fd = ::open(filename.c_str(), O_RDWR);
693        if ( m_fd < 0 ) 
694        {
695                std::cout << "Error in component VciBlockDeviceTsar : " << name << std::endl;
696                std::cout << "Unable to open file " << filename << std::endl;
697                exit(1);
698        }
699        m_device_size = lseek(m_fd, 0, SEEK_END) / block_size;
700        if ( m_device_size > ((uint64_t)1<<32) ) 
701        {
702                std::cout << "Warning: block device " << name << std::endl;
703                std::cout << "The file " << filename << std::endl;
704                std::cout << "has more blocks than addressable with the 32 bits PIBUS address" << std::endl;
705                m_device_size = ((uint64_t)1<<32);
706        }
707
708        r_local_buffer = new uint32_t[m_words_per_block];
709
710} // end constructor
711
712//////////////////////////
713tmpl(void)::print_trace()
714{
715        const char* initiator_str[] = {
716                "IDLE",
717
718                "READ_BLOCK",
719                "READ_BURST",
720                "READ_CMD",
721                "READ_RSP",
722                "READ_TEST",
723                "READ_SUCCESS",
724                "READ_ERROR",
725
726                "WRITE_BURST",
727                "WRITE_CMD",
728                "WRITE_RSP",
729                "WRITE_BLOCK",
730                "WRITE_SUCCESS",
731                "WRITE_ERROR",
732        };
733        const char* target_str[] = {
734                "IDLE",
735                "WRITE_BUFFER",
736                "READ_BUFFER",
737                "WRITE_BUFFER_EXT",
738                "READ_BUFFER_EXT",
739                "WRITE_COUNT",
740                "READ_COUNT",
741                "WRITE_LBA",
742                "READ_LBA",
743                "WRITE_OP",
744                "READ_STATUS",
745                "WRITE_IRQEN",
746                "READ_IRQEN",
747                "READ_SIZE",
748                "READ_BLOCK",
749                "READ_ERROR",
750                "WRITE_ERROR ",
751        };
752
753        std::cout << "BDEV_TGT : " << target_str[r_target_fsm.read()] 
754                  << "  BDEV_INI : " << initiator_str[r_initiator_fsm.read()] 
755          << "  buf = " << std::hex << r_buf_address.read()
756                  << "  block = " << std::dec << r_block_count.read() 
757                  << "  burst = " << r_burst_count.read() 
758                  << "  word  = " << r_words_count.read() <<std::endl; 
759}
760
761
762}} // end namespace
763
764// Local Variables:
765// tab-width: 4
766// c-basic-offset: 4
767// c-file-offsets:((innamespace . 0)(inline-open . 0))
768// indent-tabs-mode: nil
769// End:
770
771// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
772
Note: See TracBrowser for help on using the repository browser.