source: trunk/modules/vci_block_device_tsar_v4/caba/source/src/vci_block_device_tsar_v4.cpp @ 272

Last change on this file since 272 was 272, checked in by bouyer, 11 years ago

Fix writes:

  • properly compute r_buf_address, + has highter priority than <<
  • compute r_block_count after writing the block to file, not before. Also, don't forget to reset r_index.
File size: 23.4 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_v4.h"
33
34namespace soclib { namespace caba {
35
36#define tmpl(t) template<typename vci_param> t VciBlockDeviceTsarV4<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 & 0x1F)>>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_COUNT) )      r_target_fsm = T_WRITE_COUNT;
78            else if(  read && (cell == BLOCK_DEVICE_COUNT) )      r_target_fsm = T_READ_COUNT;
79            else if( !read && (cell == BLOCK_DEVICE_LBA) )        r_target_fsm = T_WRITE_LBA;
80            else if(  read && (cell == BLOCK_DEVICE_LBA) )        r_target_fsm = T_READ_LBA;
81            else if( !read && (cell == BLOCK_DEVICE_OP) )         r_target_fsm = T_WRITE_OP;
82            else if(  read && (cell == BLOCK_DEVICE_STATUS) )     r_target_fsm = T_READ_STATUS;
83            else if( !read && (cell == BLOCK_DEVICE_IRQ_ENABLE) ) r_target_fsm = T_WRITE_IRQEN;
84            else if(  read && (cell == BLOCK_DEVICE_IRQ_ENABLE) ) r_target_fsm = T_READ_IRQEN;
85            else if(  read && (cell == BLOCK_DEVICE_SIZE) )       r_target_fsm = T_READ_SIZE;
86            else if(  read && (cell == BLOCK_DEVICE_BLOCK_SIZE) ) r_target_fsm = T_READ_BLOCK;
87        }
88        break;
89    }
90    ////////////////////
91    case T_WRITE_BUFFER:
92    {
93        if ( r_initiator_fsm == M_IDLE )  r_buf_address = (uint32_t)p_vci_target.wdata.read();
94        if ( p_vci_target.rspack.read() ) r_target_fsm = T_IDLE;
95        break;
96    }
97    ///////////////////
98    case T_WRITE_COUNT:
99    {
100        if ( r_initiator_fsm == M_IDLE )  r_nblocks = (uint32_t)p_vci_target.wdata.read();
101        if ( p_vci_target.rspack.read() ) r_target_fsm = T_IDLE;
102        break;
103    }
104    /////////////////
105    case T_WRITE_LBA:
106    {
107        if ( r_initiator_fsm == M_IDLE )  r_lba = (uint32_t)p_vci_target.wdata.read();
108        if ( p_vci_target.rspack.read() ) r_target_fsm = T_IDLE;
109        break;
110    }
111    ////////////////
112    case T_WRITE_OP:
113    {
114        if ( r_initiator_fsm == M_IDLE ) 
115        {
116            if ( (uint32_t)p_vci_target.wdata.read() == BLOCK_DEVICE_READ )
117            {
118                r_read = true;
119                r_go = true;
120            }
121            else if ( (uint32_t)p_vci_target.wdata.read() == BLOCK_DEVICE_WRITE)
122            {
123                r_read = false;
124                r_go = true;
125            }
126        }
127        if ( p_vci_target.rspack.read() ) r_target_fsm = T_IDLE;
128        break;
129    }
130    ///////////////////
131    case T_WRITE_IRQEN:
132    {
133        r_irq_enable = (p_vci_target.wdata.read() != 0);
134        if ( p_vci_target.rspack.read() ) r_target_fsm = T_IDLE;
135        break;
136    }
137    ///////////////////
138    case T_READ_BUFFER:
139    case T_READ_COUNT:
140    case T_READ_LBA:
141    case T_READ_IRQEN:
142    case T_READ_SIZE:
143    case T_READ_BLOCK:
144    case T_READ_ERROR:
145    case T_WRITE_ERROR:
146    {
147        if ( p_vci_target.rspack.read() ) r_target_fsm = T_IDLE;
148        break;
149    }
150    ///////////////////
151    case T_READ_STATUS:
152    {
153        if ( p_vci_target.rspack.read() ) 
154        {
155            r_target_fsm = T_IDLE;
156            if( (r_initiator_fsm == M_READ_SUCCESS ) ||
157                (r_initiator_fsm == M_READ_ERROR   ) ||
158                (r_initiator_fsm == M_WRITE_SUCCESS) ||
159                (r_initiator_fsm == M_WRITE_ERROR  ) ) r_go = false;
160        }
161        break;
162    }
163    } // end switch target fsm
164       
165    //////////////////////////////////////////////////////////////////////////////
166    // The initiator FSM executes a loop, transfering one block per iteration.
167    // Each block is split in bursts, and the number of bursts depends
168    // on the memory buffer alignment on a burst boundary:
169    // - If buffer aligned, all burst have the same length (m_flits_per burst)
170    //   and the number of bursts is (m_bursts_per_block).
171    // - If buffer not aligned, the number of bursts is (m_bursts_per_block + 1)
172    //   and first and last burst are shorter, because all flits in a burst
173    //   must be contained in a single cache line.
174    //   first burst => nflits = m_flits_per_burst - offset
175    //   last  burst => nflits = offset
176    //   other burst => nflits = m_flits_per_burst
177    //////////////////////////////////////////////////////////////////////////////
178
179    switch( r_initiator_fsm.read() ) {
180    ////////////
181    case M_IDLE:        // check buffer alignment to compute the number of bursts
182    {
183        if ( r_go.read() ) 
184        {
185            r_index         = 0;
186            r_block_count   = 0;
187            r_burst_count   = 0;
188            r_flit_count    = 0;
189            r_latency_count = m_latency;
190
191            // compute r_burst_offset (zero when buffer aligned)
192            r_burst_offset = (r_buf_address.read()>>2) % m_flits_per_burst;
193
194            // start tranfer
195            if ( r_read.read() )        r_initiator_fsm = M_READ_BLOCK;
196            else                    r_initiator_fsm = M_WRITE_BURST;
197        }
198        break;
199    } 
200    //////////////////
201    case M_READ_BLOCK:  // read one block from disk after waiting m_latency cycles
202    {
203        if ( r_latency_count.read() == 0 )
204        {
205            r_latency_count = m_latency;
206            ::lseek(m_fd, (r_lba + r_block_count)*m_flits_per_block*4, SEEK_SET);
207            if( ::read(m_fd, r_local_buffer, m_flits_per_block*4) < 0 ) 
208            {
209                r_initiator_fsm = M_READ_ERROR;
210            }
211            else   
212            {
213                r_burst_count   = 0;
214                r_flit_count    = 0;
215                r_initiator_fsm = M_READ_BURST;
216            }
217        }
218        else
219        {
220            r_latency_count = r_latency_count.read() - 1;
221        }
222        break;
223    }
224    //////////////////
225    case M_READ_BURST:  // Compute the number of flits in the burst
226    {
227        uint32_t offset = r_burst_offset.read();
228
229        if ( offset )                  // buffer not aligned
230        {
231            if ( r_burst_count.read() == 0 ) r_burst_nflits = m_flits_per_burst - offset;
232            else if ( r_burst_count.read() == m_bursts_per_block ) r_burst_nflits = offset;
233            else r_burst_nflits = m_flits_per_burst;
234        }
235        else                           // buffer aligned
236        {
237            r_burst_nflits = m_flits_per_burst;
238        }
239        r_initiator_fsm =  M_READ_CMD;
240        break;
241    }
242    ////////////////
243    case M_READ_CMD:    // Send a multi-flits VCI WRITE command
244    {
245        if ( p_vci_initiator.cmdack.read() )
246        {
247            if ( r_flit_count == (r_burst_nflits.read() - 1) ) // last flit in a burst
248            {
249                r_initiator_fsm = M_READ_RSP;
250                r_flit_count = 0;
251            }
252            else                                               // not the last flit
253            {
254                r_flit_count = r_flit_count.read() + 1;
255            }
256
257            // compute next flit address and next local buffer index
258            r_buf_address = r_buf_address.read() + 4;
259            r_index       = r_index.read() + 1;
260        }
261        break;
262    }
263    ////////////////
264    case M_READ_RSP:    // Wait a single flit VCI WRITE response
265    {
266        if ( p_vci_initiator.rspval.read() )
267        {
268            bool aligned = (r_burst_offset.read() == 0);
269
270            if ( (p_vci_initiator.rerror.read()&0x1) != 0 ) 
271            {
272                r_initiator_fsm = M_READ_ERROR;
273            }
274            else if ( (not aligned and (r_burst_count.read() == m_bursts_per_block)) or
275                      (aligned and (r_burst_count.read() == (m_bursts_per_block-1))) )
276            {
277                if ( r_block_count.read() == (r_nblocks.read()-1) ) // last burst of last block
278                {
279                    r_initiator_fsm = M_READ_SUCCESS;
280                }
281                else                                              // last burst not last block
282                {
283                    r_index          = 0;
284                    r_burst_count    = 0;
285                    r_block_count    = r_block_count.read() + 1;
286                    r_initiator_fsm  = M_READ_BLOCK;
287                }
288            }
289            else                                                // not the last burst
290            {
291                r_burst_count = r_burst_count.read() + 1;
292                r_initiator_fsm = M_READ_BURST;
293            }
294        }
295        break;
296    }
297    ///////////////////
298    case M_READ_SUCCESS:
299    case M_READ_ERROR:
300    {
301        if( !r_go ) r_initiator_fsm = M_IDLE;
302        break;
303    }
304    ///////////////////
305    case M_WRITE_BURST:  // Compute the number of flits in the burst
306    {
307        uint32_t offset = r_burst_offset.read();
308
309        if ( offset )                  // buffer not aligned
310        {
311            if ( r_burst_count.read() == 0 ) r_burst_nflits = m_flits_per_burst - offset;
312            else if ( r_burst_count.read() == m_bursts_per_block ) r_burst_nflits = offset;
313            else r_burst_nflits = m_flits_per_burst;
314        }
315        else                           // buffer aligned
316        {
317            r_burst_nflits = m_flits_per_burst;
318        }
319        r_initiator_fsm =  M_WRITE_CMD;
320        break;
321    }
322    /////////////////
323    case M_WRITE_CMD:   // This is actually a single flit VCI READ command
324    {
325            if ( p_vci_initiator.cmdack.read() ) r_initiator_fsm = M_WRITE_RSP;
326        break;
327    }
328    /////////////////
329    case M_WRITE_RSP:   // This is actually a multi-flits VCI READ response
330    {
331        bool aligned = (r_burst_offset.read() == 0);
332
333        if ( p_vci_initiator.rspval.read() )
334        {
335            r_local_buffer[r_index.read()] = (uint32_t)p_vci_initiator.rdata.read();
336            r_index = r_index.read() + 1;
337
338            if ( p_vci_initiator.reop.read() )  // last flit of the burst
339            {
340                r_flit_count  = 0;
341                r_buf_address = r_buf_address.read() + (r_burst_nflits.read()<<2); 
342
343                if( (p_vci_initiator.rerror.read()&0x1) != 0 ) 
344                {
345                    r_initiator_fsm = M_WRITE_ERROR;
346                }
347                else if ( (not aligned and (r_burst_count.read() == m_bursts_per_block)) or
348                          (aligned and (r_burst_count.read() == (m_bursts_per_block-1))) ) // last burst
349                {
350                    r_initiator_fsm  = M_WRITE_BLOCK;
351                }
352                else                                          // not the last burst
353                {
354                    r_burst_count = r_burst_count.read() + 1;
355                    r_initiator_fsm = M_WRITE_BURST;
356                }
357            }
358            else
359            {
360                    r_flit_count = r_flit_count.read() + 1;
361            }
362        }
363        break;
364    }
365    ///////////////////
366    case M_WRITE_BLOCK:         // write a block to disk after waiting m_latency cycles
367    {
368        if ( r_latency_count == 0 )
369        {
370            r_latency_count = m_latency;
371            ::lseek(m_fd, (r_lba + r_block_count)*m_flits_per_block*vci_param::B, SEEK_SET);
372            if( ::write(m_fd, r_local_buffer, m_flits_per_block*vci_param::B) < 0 )
373            {
374                r_initiator_fsm = M_WRITE_ERROR; 
375            }
376            else if ( r_block_count.read() == r_nblocks.read() - 1 ) 
377            {
378                r_initiator_fsm = M_WRITE_SUCCESS; 
379            }
380            else
381            {
382                r_burst_count    = 0;
383                r_index          = 0;
384                r_block_count    = r_block_count.read() + 1;
385                r_initiator_fsm = M_WRITE_BURST;
386            }
387        } 
388        else
389        {
390            r_latency_count = r_latency_count - 1;
391        }
392        break;
393    }
394    /////////////////////
395    case M_WRITE_SUCCESS:
396    case M_WRITE_ERROR:
397    {
398        if( !r_go ) r_initiator_fsm = M_IDLE;
399        break;
400    }
401    } // end switch r_initiator_fsm
402}  // end transition
403
404//////////////////////
405tmpl(void)::genMoore()
406{
407    // p_vci_target port   
408    p_vci_target.rsrcid = (sc_dt::sc_uint<vci_param::S>)r_srcid.read();
409    p_vci_target.rtrdid = (sc_dt::sc_uint<vci_param::T>)r_trdid.read();
410    p_vci_target.rpktid = (sc_dt::sc_uint<vci_param::P>)r_pktid.read();
411    p_vci_target.reop   = true;
412
413    switch(r_target_fsm) {
414    case T_IDLE:
415        p_vci_target.cmdack = true;
416        p_vci_target.rspval = false;
417        break;
418    case T_READ_STATUS:
419        p_vci_target.cmdack = false;
420        p_vci_target.rspval = true;
421        if     (r_initiator_fsm == M_IDLE)          p_vci_target.rdata = BLOCK_DEVICE_IDLE;
422        else if(r_initiator_fsm == M_READ_SUCCESS)  p_vci_target.rdata = BLOCK_DEVICE_READ_SUCCESS;
423        else if(r_initiator_fsm == M_WRITE_SUCCESS) p_vci_target.rdata = BLOCK_DEVICE_WRITE_SUCCESS;
424        else if(r_initiator_fsm == M_READ_ERROR)        p_vci_target.rdata = BLOCK_DEVICE_READ_ERROR;
425        else if(r_initiator_fsm == M_WRITE_ERROR)       p_vci_target.rdata = BLOCK_DEVICE_WRITE_ERROR;
426        else                                            p_vci_target.rdata = BLOCK_DEVICE_BUSY;
427        p_vci_target.rerror = VCI_READ_OK;
428        break;
429    case T_READ_BUFFER:
430        p_vci_target.cmdack = false;
431        p_vci_target.rspval = true;
432        p_vci_target.rdata  = (uint32_t)r_buf_address.read();
433        p_vci_target.rerror = VCI_READ_OK;
434        break;
435    case T_READ_COUNT:
436        p_vci_target.cmdack = false;
437        p_vci_target.rspval = true;
438        p_vci_target.rdata = (uint32_t)r_nblocks.read();
439        p_vci_target.rerror = VCI_READ_OK;
440        break;
441    case T_READ_LBA:
442        p_vci_target.cmdack = false;
443        p_vci_target.rspval = true;
444        p_vci_target.rdata = (uint32_t)r_lba.read();
445        p_vci_target.rerror = VCI_READ_OK;
446        break;
447    case T_READ_IRQEN:
448        p_vci_target.cmdack = false;
449        p_vci_target.rspval = true;
450        p_vci_target.rdata = (uint32_t)r_irq_enable.read();
451        p_vci_target.rerror = VCI_READ_OK;
452        break;
453    case T_READ_SIZE:
454        p_vci_target.cmdack = false;
455        p_vci_target.rspval = true;
456        p_vci_target.rdata = (uint32_t)m_device_size;
457        p_vci_target.rerror = VCI_READ_OK;
458        break;
459    case T_READ_BLOCK:
460        p_vci_target.cmdack = false;
461        p_vci_target.rspval = true;
462        p_vci_target.rdata = (uint32_t)m_flits_per_block*vci_param::B;
463        p_vci_target.rerror = VCI_READ_OK;
464        break;
465    case T_READ_ERROR:
466        p_vci_target.cmdack = false;
467        p_vci_target.rspval = true;
468        p_vci_target.rdata = 0;
469        p_vci_target.rerror = VCI_READ_ERROR;
470        break;
471    case T_WRITE_ERROR:
472        p_vci_target.cmdack = false;
473        p_vci_target.rspval = true;
474        p_vci_target.rdata = 0;
475        p_vci_target.rerror = VCI_WRITE_ERROR;
476        break;
477    default:
478        p_vci_target.cmdack = false;
479        p_vci_target.rspval = true;
480        p_vci_target.rdata = 0;
481        p_vci_target.rerror = VCI_WRITE_OK;
482        break;
483    } // end switch target fsm
484
485    // p_vci_initiator port
486    p_vci_initiator.srcid  = (sc_dt::sc_uint<vci_param::S>)m_srcid;
487    p_vci_initiator.trdid  = 0;
488    p_vci_initiator.pktid  = 0;
489    p_vci_initiator.contig = true;
490    p_vci_initiator.cons   = false;
491    p_vci_initiator.wrap   = false;
492    p_vci_initiator.cfixed = false;
493    p_vci_initiator.clen   = 0;
494
495    switch (r_initiator_fsm) {
496    case M_WRITE_CMD:           // It is actually a single flit VCI read command
497        p_vci_initiator.rspack  = false;
498        p_vci_initiator.cmdval  = true;
499        p_vci_initiator.address = (sc_dt::sc_uint<vci_param::N>)r_buf_address.read();
500        p_vci_initiator.cmd     = vci_param::CMD_READ;
501        p_vci_initiator.wdata   = 0;
502        p_vci_initiator.be      = (uint32_t)0xF;
503        p_vci_initiator.plen    = (sc_dt::sc_uint<vci_param::K>)(r_burst_nflits.read()<<2);
504        p_vci_initiator.eop     = true;
505        break;
506    case M_READ_CMD:            // It is actually a multi-flits VCI WRITE command
507        p_vci_initiator.rspack  = false;
508        p_vci_initiator.cmdval  = true;
509        p_vci_initiator.address = (sc_dt::sc_uint<vci_param::N>)r_buf_address.read(); 
510        p_vci_initiator.cmd     = vci_param::CMD_WRITE;
511        p_vci_initiator.wdata   = (uint32_t)r_local_buffer[r_index.read()];
512        p_vci_initiator.be      = 0xF;
513        p_vci_initiator.plen    = (sc_dt::sc_uint<vci_param::K>)(r_burst_nflits.read()<<2);
514        p_vci_initiator.eop     = ( r_flit_count.read() == (r_burst_nflits.read() - 1) );
515        break;
516    case M_READ_RSP:
517    case M_WRITE_RSP:
518        p_vci_initiator.rspack  = true;
519        p_vci_initiator.cmdval  = false;
520        break;
521    default:
522        p_vci_initiator.rspack  = false;
523        p_vci_initiator.cmdval  = false;
524        break;
525    }
526
527    // IRQ signal
528    if(((r_initiator_fsm == M_READ_SUCCESS)    ||
529                            (r_initiator_fsm == M_WRITE_SUCCESS)   ||
530                            (r_initiator_fsm == M_READ_ERROR)      ||
531                            (r_initiator_fsm == M_WRITE_ERROR) ) &&  r_irq_enable) p_irq = true;
532    else                                                       p_irq = false;
533} // end GenMoore()
534
535//////////////////////////////////////////////////////////////////////////////
536tmpl(/**/)::VciBlockDeviceTsarV4( sc_core::sc_module_name              name, 
537                                  const soclib::common::MappingTable   &mt,
538                                  const soclib::common::IntTab         &srcid,
539                                  const soclib::common::IntTab         &tgtid,
540                                  const std::string                    &filename,
541                                  const uint32_t                       block_size,
542                                  const uint32_t                       burst_size,
543                                  const uint32_t                       latency)
544
545: caba::BaseModule(name),
546        m_segment(mt.getSegment(tgtid)),
547        m_srcid(mt.indexForId(srcid)),
548        m_flits_per_block(block_size/vci_param::B),
549        m_flits_per_burst(burst_size/vci_param::B),
550        m_bursts_per_block(block_size/burst_size),
551        m_latency(latency),
552        p_clk("p_clk"),
553        p_resetn("p_resetn"),
554        p_vci_initiator("p_vci_initiator"),
555        p_vci_target("p_vci_target"),
556        p_irq("p_irq") 
557{
558        SC_METHOD(transition);
559        sensitive_pos << p_clk;
560
561        SC_METHOD(genMoore);
562        sensitive_neg << p_clk;
563
564        if( (block_size != 64 )  && 
565        (block_size != 128)  && 
566        (block_size != 256)  && 
567        (block_size != 512)  && 
568        (block_size != 1024) &&
569        (block_size != 2048) && 
570        (block_size != 4096) )
571        {
572                std::cout << "Error in component VciBlockDeviceTsarV4 : " << name << std::endl;
573                std::cout << "The block size must be 128, 256, 512, 1024, 2048 or 4096 bytes" << std::endl;
574                exit(1);
575        }
576        if( (burst_size != 1 ) && 
577                (burst_size != 2 ) && 
578                (burst_size != 4 ) && 
579                (burst_size != 8 ) && 
580                (burst_size != 16) && 
581                (burst_size != 32) && 
582                (burst_size != 64) )
583        {
584                std::cout << "Error in component VciBlockDeviceTsarV4 : " << name << std::endl;
585                std::cout << "The burst size must be 1, 2, 4, 8, 16, 32 or 64 bytes" << std::endl;
586                exit(1);
587        }
588        if ( m_segment.size() < 32 ) 
589        {
590                std::cout << "Error in component VciBlockDeviceTsarV4 : " << name << std::endl;
591                std::cout << "The size of the segment cannot be smaller than 32 bytes" << std::endl;
592                exit(1);
593        }
594        if ( (m_segment.baseAddress() & 0x0000001F) != 0 ) 
595        {
596                std::cout << "Error in component VciBlockDeviceTsarV4 : " << name << std::endl;
597                std::cout << "The base address of the segment must be multiple of 32 bytes" << std::endl;
598                exit(1);
599        }
600        if ( vci_param::B != 4 )
601        {
602                std::cout << "Error in component VciBlockDeviceTsarV4 : " << name << std::endl;
603                std::cout << "The VCI data fields must have 32 bits" << std::endl;
604                exit(1);
605        }
606        m_fd = ::open(filename.c_str(), O_RDWR);
607        if ( m_fd < 0 ) 
608        {
609                std::cout << "Error in component VciBlockDeviceTsarV4 : " << name << std::endl;
610                std::cout << "Unable to open file " << filename << std::endl;
611                exit(1);
612        }
613        m_device_size = lseek(m_fd, 0, SEEK_END) / block_size;
614        if ( m_device_size > ((uint64_t)1<<32) ) 
615        {
616                std::cout << "Warning: block device " << name << std::endl;
617                std::cout << "The file " << filename << std::endl;
618                std::cout << "has more blocks than addressable with the 32 bits PIBUS address" << std::endl;
619                m_device_size = ((uint64_t)1<<32);
620        }
621
622        r_local_buffer = new uint32_t[m_flits_per_block];
623
624} // end constructor
625
626//////////////////////////
627tmpl(void)::print_trace()
628{
629        const char* initiator_str[] = {
630                "IDLE",
631
632                "READ_BLOCK",
633                "READ_BURST",
634                "READ_CMD",
635                "READ_RSP",
636                "READ_TEST",
637                "READ_SUCCESS",
638                "READ_ERROR",
639
640                "WRITE_BURST",
641                "WRITE_CMD",
642                "WRITE_RSP",
643                "WRITE_BLOCK",
644                "WRITE_SUCCESS",
645                "WRITE_ERROR",
646        };
647        const char* target_str[] = {
648                "IDLE        ",
649                "WRITE_BUFFER",
650                "READ_BUFFER ",
651                "WRITE_COUNT ",
652                "READ_COUNT  ",
653                "WRITE_LBA   ",
654                "READ_LBA    ",
655                "WRITE_OP    ",
656                "READ_STATUS ",
657                "WRITE_IRQEN ",
658                "READ_IRQEN  ",
659                "READ_SIZE   ",
660                "READ_BLOCK  ",
661                "READ_ERROR  ",
662                "WRITE_ERROR ",
663        };
664
665        std::cout << "BDEV_TGT : " << target_str[r_target_fsm.read()] 
666                  << "  BDEV_INI : " << initiator_str[r_initiator_fsm.read()] 
667                  << "  block = " << r_block_count.read() 
668                  << "  burst = " << r_burst_count.read() 
669                  << "  flit  = " << r_flit_count.read() <<std::endl; 
670}
671
672
673}} // end namespace
674
675// Local Variables:
676// tab-width: 4
677// c-basic-offset: 4
678// c-file-offsets:((innamespace . 0)(inline-open . 0))
679// indent-tabs-mode: nil
680// End:
681
682// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
683
Note: See TracBrowser for help on using the repository browser.