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

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

Introducing support for physical addresses larger than 32 bits.
A new addressable register has been defined: BLOCK_DEVICE_BUFFER_EXT

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