source: branches/fault_tolerance/module/internal_component/vci_simple_rom/caba/source/src/vci_simple_rom.cpp @ 656

Last change on this file since 656 was 656, checked in by cfuguet, 10 years ago

TSAR FAULT TOLERANCE BRANCH

vci_simple_rom:

  • Introducing ROM component which can discard most significant bits when calling the load function of the loader. This allows us to replicate some code in several cluster as we can mask the cluster ID bits of the address.

vci_cc_vcache_wrapper:

  • Introducing a INST_PADDR_EXT register. This register allows to access addresses further than 4Gbytes when MMU is de-activated.
  • Introducing a way to initialize the INST_PADDR_EXT and DATA_ PADDR_EXT registers during reset.
File size: 9.5 KB
Line 
1/*
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 <alain.greiner@lip6.fr>, 2008
25 *
26 * Maintainers: alain
27 */
28
29#include <iostream>
30#include <cstring>
31#include "arithmetics.h"
32#include "vci_simple_rom.h"
33
34namespace soclib {
35namespace caba {
36
37using namespace soclib;
38
39#define tmpl(x) template<typename vci_param> x VciSimpleRom<vci_param>
40
41//////////////////////////
42tmpl(/**/)::VciSimpleRom(
43    sc_module_name name,
44    const soclib::common::IntTab index,
45    const soclib::common::MappingTable &mt,
46    const soclib::common::Loader &loader,
47    const int nb_msb_drop)
48    : caba::BaseModule(name),
49      m_loader(loader),
50      m_seglist(mt.getSegmentList(index)),
51      m_drop_msb(nb_msb_drop),
52
53      r_fsm_state("r_fsm_state"),
54      r_flit_count("r_flit_count"),
55      r_odd_words("r_odd_words"),
56      r_seg_index("r_seg_index"),
57      r_rom_index("r_rom_index"),
58      r_srcid("r_srcid"),
59      r_trdid("r_trdid"),
60      r_pktid("r_pktid"),
61
62      p_resetn("p_resetn"),
63      p_clk("p_clk"),
64      p_vci("p_vci")
65{
66    std::cout << "  - Building SimpleRom " << name << std::endl;
67
68    size_t nsegs = 0;
69
70    assert( (m_seglist.empty() == false) and
71    "VCI_SIMPLE_ROM error : no segment allocated");
72
73    std::list<soclib::common::Segment>::iterator seg;
74    for ( seg = m_seglist.begin() ; seg != m_seglist.end() ; seg++ )
75    {
76        std::cout << "    => segment " << seg->name()
77                  << " / base = " << std::hex << seg->baseAddress()
78                  << " / size = " << seg->size() << std::endl; 
79        nsegs++;
80    }
81
82    m_nbseg = nsegs;
83
84    assert( ((vci_param::B == 4) or (vci_param::B == 8)) and
85    "VCI_SIMPLE_ROM error : The VCI DATA field must be 32 or 64 bits");
86
87    // actual memory allocation
88    m_rom = new uint32_t*[m_nbseg];
89    m_seg = new soclib::common::Segment*[m_nbseg];
90
91    size_t i = 0;
92    for ( seg = m_seglist.begin() ; seg != m_seglist.end() ; seg++ ) 
93    { 
94        m_rom[i] = new uint32_t[ (seg->size()+3)/4 ];
95        m_seg[i] = &(*seg);
96        i++;
97    }
98
99    SC_METHOD(transition);
100    dont_initialize();
101    sensitive << p_clk.pos();
102
103    SC_METHOD(genMoore);
104    dont_initialize();
105    sensitive << p_clk.neg();
106}
107
108///////////////////////////
109tmpl(/**/)::~VciSimpleRom()
110{
111    for (size_t i=0 ; i<m_nbseg ; ++i) delete [] m_rom[i];
112    delete [] m_rom;
113    delete [] m_seg;
114}
115
116/////////////////////
117tmpl(void)::reload()
118{
119    uint64_t mask = (1ULL << (vci_param::N - m_drop_msb)) - 1;
120    for ( size_t i=0 ; i<m_nbseg ; ++i ) 
121    {
122        uint64_t base_address = m_seg[i]->baseAddress() & mask; 
123        m_loader.load(&m_rom[i][0], base_address, m_seg[i]->size());
124        for ( size_t addr = 0 ; addr < m_seg[i]->size()/vci_param::B ; ++addr )
125            m_rom[i][addr] = le_to_machine(m_rom[i][addr]);
126    }
127}
128
129////////////////////
130tmpl(void)::reset()
131{
132    for ( size_t i=0 ; i<m_nbseg ; ++i ) std::memset(&m_rom[i][0], 0, m_seg[i]->size()); 
133    r_fsm_state = FSM_IDLE;
134}
135
136//////////////////////////
137tmpl(void)::print_trace()
138{
139    const char* state_str[] = { "IDLE", "READ", "ERROR" };
140    std::cout << "SIMPLE_ROM " << name() 
141              << " : state = " << state_str[r_fsm_state] 
142              << " / flit_count = " << std::dec << r_flit_count << std::endl;
143}
144
145/////////////////////////
146tmpl(void)::transition()
147{
148    if (!p_resetn) 
149    {
150        reset();
151        reload();
152        return;
153    }
154
155    switch ( r_fsm_state ) 
156    {
157        //////////////
158        case FSM_IDLE:  // waiting a VCI command
159        {
160            if ( p_vci.cmdval.read() ) 
161            {
162                bool error = true;
163
164                assert( ((p_vci.address.read() & 0x3) == 0) and
165                "VCI_SIMPLE_ROM ERROR : The VCI ADDRESS must be multiple of 4");
166
167                assert( ((p_vci.plen.read() & 0x3) == 0) and
168                "VCI_SIMPLE_ROM ERROR : The VCI PLEN must be multiple of 4");
169
170                assert( (p_vci.plen.read() != 0) and
171                "VCI_SIMPLE_ROM ERROR : The VCI PLEN should be != 0");
172
173                assert( (p_vci.cmd.read() == vci_param::CMD_READ) and
174                "VCI_SIMPLE_ROM ERROR : The VCI command must be a READ");
175           
176                assert( p_vci.eop.read() and
177                "VCI_SIMPLE_ROM ERROR : The VCI command packet must be 1 flit");
178
179                for ( size_t index = 0 ; index<m_nbseg  && error ; ++index) 
180                {
181                    if ( (m_seg[index]->contains(p_vci.address.read())) and
182                         (m_seg[index]->contains(p_vci.address.read()+p_vci.plen.read()-1)) ) 
183                    {
184                        error = false;
185                        r_seg_index  = index;
186                    }
187                } 
188
189                if ( error )   
190                {
191                    r_fsm_state = FSM_RSP_ERROR;
192                }
193                else
194                {
195                    unsigned int plen = p_vci.plen.read();
196
197                    r_fsm_state  = FSM_RSP_READ;
198                    r_srcid      = p_vci.srcid.read();
199                    r_trdid      = p_vci.trdid.read();
200                    r_pktid      = p_vci.pktid.read();
201                    r_rom_index  = (size_t)((p_vci.address.read() -
202                                            m_seg[r_seg_index.read()]->baseAddress())>>2);
203
204                    if ( vci_param::B == 8 )   // 64 bits data width
205                    {
206                        if ( plen & 0x4 )      // odd number of words
207                        {
208                            r_flit_count = (plen>>3) + 1;
209                            r_odd_words  = true;
210                        }
211                        else                   // even number of words
212                        {
213                            r_flit_count = plen>>3;
214                            r_odd_words  = false;
215                        }
216                    }
217                    else                       // 32 bits data width
218                    {
219                        r_flit_count = plen>>2;
220                    }
221                }
222            }
223            break;
224        }
225        //////////////////
226        case FSM_RSP_READ:  // send one response flit
227        {
228            if ( p_vci.rspack.read() )
229            {
230                r_flit_count = r_flit_count - 1;
231                r_rom_index  = r_rom_index.read() + (vci_param::B>>2);
232                if ( r_flit_count.read() == 1)   r_fsm_state = FSM_IDLE;
233            }
234            break;
235        }
236        ///////////////////
237        case FSM_RSP_ERROR: // waits lat flit of a VCI CMD erroneous packet
238        {
239            if ( p_vci.rspack.read() && p_vci.eop.read() )
240            {
241                r_fsm_state = FSM_IDLE;
242            }
243            break;
244        }
245    } // end switch fsm_state
246
247} // end transition()
248
249///////////////////////
250tmpl(void)::genMoore()
251{
252    switch ( r_fsm_state.read() ) 
253    {
254        case FSM_IDLE:
255        {
256            p_vci.cmdack  = true;
257            p_vci.rspval  = false;
258            p_vci.rdata   = 0;
259            p_vci.rsrcid  = 0;
260            p_vci.rtrdid  = 0;
261            p_vci.rpktid  = 0;
262            p_vci.rerror  = 0;
263            p_vci.reop    = false;
264            break;
265        }
266        case FSM_RSP_READ:
267        {
268            vci_data_t rdata;
269            size_t     seg_index = r_seg_index.read();
270            size_t     rom_index = r_rom_index.read();
271
272            if ( (vci_param::B == 4) or                                  // 32 bits data
273                 ( r_odd_words.read() and (r_flit_count.read() == 1)) )  // last odd flit
274            {
275                rdata = (vci_data_t)m_rom[seg_index][rom_index];
276            }
277            else                                                         // 64 bits data
278            {
279                rdata = (uint64_t)m_rom[seg_index][rom_index] | 
280                        (((uint64_t)m_rom[seg_index][rom_index+1]) << 32);
281            }
282           
283            p_vci.cmdack  = false;
284            p_vci.rspval  = true;
285            p_vci.rdata   = rdata;
286            p_vci.rsrcid  = r_srcid.read();
287            p_vci.rtrdid  = r_trdid.read();
288            p_vci.rpktid  = r_pktid.read();
289            p_vci.rerror  = vci_param::ERR_NORMAL;
290            p_vci.reop   = (r_flit_count.read() == 1);
291            break;
292        }
293        case FSM_RSP_ERROR:
294        {
295            p_vci.cmdack  = false;
296            p_vci.rspval  = true;
297            p_vci.rdata   = 0;
298            p_vci.rsrcid  = r_srcid.read();
299            p_vci.rtrdid  = r_trdid.read();
300            p_vci.rpktid  = r_pktid.read();
301            p_vci.rerror  = vci_param::ERR_GENERAL_DATA_ERROR;
302            p_vci.reop    = true;
303            break;
304        }
305    } // end switch fsm_state
306} // end genMoore()
307
308}} 
309
310// Local Variables:
311// tab-width: 4
312// c-basic-offset: 4
313// c-file-offsets:((innamespace . 0)(inline-open . 0))
314// indent-tabs-mode: nil
315// End:
316
317// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
318
Note: See TracBrowser for help on using the repository browser.