source: trunk/modules/vci_iox_network/caba/source/src/vci_iox_network.cpp @ 451

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

Introducing the vci_iox_network modeling the external IO network.

File size: 11.3 KB
Line 
1/*
2 * SOCLIB_LGPL_HEADER_BEGIN
3 *
4 * This file is part of SoCLib, GNU LGPLv2.1.
5 *
6 * SoCLib is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU Lesser General Public License as published
8 * by the Free Software Foundation; version 2.1 of the License.
9 *
10 * SoCLib is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with SoCLib; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18 * 02110-1301 USA
19 *
20 * SOCLIB_LGPL_HEADER_END
21 *
22 * Copyright (c) UPMC, Lip6, Asim
23 *         Alain Greiner <alain.greiner@lip6.fr> 2013
24 *
25 * Maintainers: alain
26 */
27
28#include <systemc>
29#include <cassert>
30#include "vci_buffers.h"
31#include "../include/vci_iox_network.h"
32#include "alloc_elems.h"
33
34namespace soclib { namespace caba {
35
36using soclib::common::alloc_elems;
37using soclib::common::dealloc_elems;
38
39using namespace sc_core;
40
41///////////////////////////////////////////////////////////////////////////////////
42// The IoXbar class is instanciated twice, to implement the CMD & RSP XBARs
43///////////////////////////////////////////////////////////////////////////////////
44template<typename pkt_t> class IoXbar
45{
46    // pkt_t type must be VciCmdBuffer<vci_param> or VciRspBuffer<vci_param>
47    // the two following types can be found in these two classes
48
49    typedef typename pkt_t::input_port_t    input_port_t;
50    typedef typename pkt_t::output_port_t   output_port_t;
51
52    const bool                              m_is_cmd;         // CMD XBAR if true
53    const size_t                                    m_inputs;         // number of inputs
54    const size_t                                    m_outputs;        // number of outputs
55    AddressDecodingTable<uint64_t,size_t>*  m_rt;             // pointer on routing table (CMD or RSP)
56
57    sc_signal<bool>*                            r_out_allocated;  // for each output: allocation state
58    sc_signal<size_t>*                          r_out_origin;     // for each output: input port index
59    sc_signal<bool>*                            r_in_allocated;   // for each input: allocation state
60    sc_signal<size_t>*                          r_in_dest;        // for each input: output port index
61
62public:
63    ///////////////////////
64    IoXbar( bool                                    is_cmd, 
65            size_t                                  nb_inputs,
66            size_t                                  nb_outputs,
67                AddressDecodingTable<uint64_t,size_t>*  rt )
68        : m_is_cmd( is_cmd ),
69      m_inputs( nb_inputs ),
70      m_outputs( nb_outputs ),
71      m_rt ( rt )
72        {
73            r_out_allocated = new sc_signal<bool>[nb_outputs];
74            r_out_origin        = new sc_signal<size_t>[nb_outputs];
75            r_in_allocated  = new sc_signal<bool>[nb_inputs];
76            r_in_dest       = new sc_signal<size_t>[nb_inputs];
77        }
78
79    ////////////
80    void reset()
81    {
82            for (size_t i=0 ; i<m_outputs ; ++i) 
83        {
84                r_out_origin[i]    = 0;
85                r_out_allocated[i] = false;
86            }
87            for (size_t i=0 ; i<m_inputs ; ++i) 
88        {
89                r_in_dest[i]      = 0;
90                r_in_allocated[i] = false;
91            }
92    }
93
94    //////////////////
95    void print_trace()
96    {
97        if ( m_is_cmd )
98        {
99            std::cout << "IOX_CMD_XBAR : " << std::dec;
100            for( size_t out=0 ; out<m_outputs ; out++)
101            {
102                if( r_out_allocated[out].read() ) 
103                {
104                    std::cout << "ini " << r_out_origin[out].read() 
105                              << " => tgt " << out << " | ";
106                }
107            }
108        }
109        else
110        {
111            std::cout << "IOX_RSP_XBAR : " << std::dec;
112            for( size_t out=0 ; out<m_outputs ; out++)
113            {
114                if( r_out_allocated[out].read() ) 
115                {
116                    std::cout << "tgt " << r_out_origin[out].read() 
117                              << " => ini " << out << " | ";
118                }
119            }
120        }
121        std::cout << std::endl;
122    }
123
124    ///////////////////////////////////////////
125    void transition( input_port_t  **input_port, 
126                     output_port_t **output_port )
127    {
128        // loop on the output ports
129        for ( size_t out = 0; out < m_outputs; out++) 
130        {
131            if ( r_out_allocated[out].read() and
132                 output_port[out]->toPeerEnd() )        // desallocation
133            {
134                size_t in = r_out_origin[out].read();
135                r_out_allocated[out] = false;
136                r_in_allocated[in]   = false;
137            } 
138            else                                        // possible allocation
139            {
140                // loop on the intput ports
141                bool found = false;
142                for(size_t x = 0 ; (x < m_inputs) and not found ; x++) 
143                {
144                    size_t in = (x + r_out_origin[out] + 1) % m_inputs;
145                    if ( input_port[in]->getVal() )
146                    {
147                        size_t req;       // requested output port index
148                        if ( m_is_cmd ) 
149                        {
150                            req = ((AddressDecodingTable<uint64_t,size_t>*)m_rt)->get_value( 
151                                   (uint64_t)(input_port[in]->address.read()) ); 
152                        }
153                        else           
154                        {
155                            req = ((AddressDecodingTable<uint64_t,size_t>*)m_rt)->get_value( 
156                                   (uint64_t)(input_port[in]->rsrcid.read()) ); 
157                        }
158                        // allocate the output port if requested
159                        if ( out == req )
160                        {
161                            r_out_allocated[out] = true;
162                            r_in_allocated[in]   = true;
163                            r_out_origin[out]    = in;
164                            r_in_dest[in]        = out;
165                            found                = true;
166                        }
167                    }
168                }  // end loop inputs
169            }
170        }  // end loop outputs
171    } // end transition
172
173    //////////////////////////////////////////////
174    void genMealy_ack( input_port_t  **input_port,
175                       output_port_t **output_port )
176    {
177        for ( size_t in = 0 ; in < m_inputs ; in++ )
178        {
179            size_t out = r_in_dest[in].read();
180            bool   ack = r_in_allocated[in].read() and output_port[out]->getAck();
181            input_port[in]->setAck(ack);
182        }
183    }
184
185    ///////////////////////////////////////////////////////////////////////
186    void genMealy_val( input_port_t  **input_port, 
187                       output_port_t **output_port )
188    {
189        for( size_t out = 0 ; out < m_outputs ; out++) 
190        {
191            if (r_out_allocated[out]) 
192            {
193                        size_t in = r_out_origin[out];
194                pkt_t tmp;
195                tmp.readFrom(*input_port[in]);
196                tmp.writeTo(*output_port[out]);
197            } 
198            else 
199            {
200                output_port[out]->setVal(false);
201            }
202        }
203    } 
204
205}; // end class IoXbar
206
207
208///////////////////////////////////////////////////////////////////////////////////
209#define tmpl(x) template<typename vci_param> x VciIoxNetwork<vci_param>
210///////////////////////////////////////////////////////////////////////////////////
211
212/////////////////////////
213tmpl(void)::print_trace()
214{
215    m_cmd_xbar->print_trace();
216    m_rsp_xbar->print_trace();
217}
218
219////////////////////////
220tmpl(void)::transition()
221{
222    if ( ! p_resetn.read() ) 
223    {
224        m_cmd_xbar->reset();
225        m_rsp_xbar->reset();
226        return;
227    }
228
229    m_cmd_xbar->transition( m_ports_to_initiator, m_ports_to_target );
230    m_rsp_xbar->transition( m_ports_to_target, m_ports_to_initiator );
231}
232
233//////////////////////////////
234tmpl(void)::genMealy_cmd_val()
235{
236    m_cmd_xbar->genMealy_val( m_ports_to_initiator, m_ports_to_target );
237}
238
239//////////////////////////////
240tmpl(void)::genMealy_cmd_ack()
241{
242    m_cmd_xbar->genMealy_ack( m_ports_to_initiator, m_ports_to_target );
243}
244
245//////////////////////////////
246tmpl(void)::genMealy_rsp_val()
247{
248    m_rsp_xbar->genMealy_val( m_ports_to_target, m_ports_to_initiator );
249}
250
251//////////////////////////////
252tmpl(void)::genMealy_rsp_ack()
253{
254    m_rsp_xbar->genMealy_ack( m_ports_to_target, m_ports_to_initiator );
255}
256
257///////////////////////////////////////////////////////////////////////////
258tmpl(/**/)::VciIoxNetwork( sc_core::sc_module_name             name,
259                               const soclib::common::MappingTable  &mt,
260                           size_t                              cluster_id,
261                                           size_t                              nb_tgt,
262                                           size_t                              nb_ini )
263           : BaseModule(name),
264           p_clk("clk"),
265           p_resetn("resetn"),
266               p_to_tgt(soclib::common::alloc_elems<VciInitiator<vci_param> >(
267                          "p_to_tgt", nb_tgt)),
268               p_to_ini(soclib::common::alloc_elems<VciTarget<vci_param> >(
269                          "p_to_ini", nb_ini)),
270
271           m_nb_tgt( nb_tgt ),
272           m_nb_ini( nb_ini ),
273
274           m_cmd_rt( mt.getPortidFromAddress(cluster_id) ),
275           m_rsp_rt( mt.getPortidFromSrcid(cluster_id) )
276{
277    std::cout << "    Building VciIoxNetwork : " << name << std::endl;
278
279    SC_METHOD(transition);
280    dont_initialize();
281    sensitive << p_clk.pos();
282
283    SC_METHOD(genMealy_cmd_val);        // controls to targets CMDVAL
284    dont_initialize();
285    sensitive << p_clk.neg();
286        for ( size_t i=0; i<nb_ini; ++i )   sensitive << p_to_ini[i];
287
288    SC_METHOD(genMealy_cmd_ack);        // controls to intiators CMDACK
289    dont_initialize();
290    sensitive << p_clk.neg();
291        for ( size_t i=0; i<nb_tgt; ++i )   sensitive << p_to_tgt[i];
292
293    SC_METHOD(genMealy_rsp_val);        // controls to initiators RSPVAL
294    dont_initialize();
295    sensitive << p_clk.neg();
296        for ( size_t i=0; i<nb_tgt; ++i )   sensitive << p_to_tgt[i];
297
298    SC_METHOD(genMealy_rsp_ack);        // controls to targets RSPACK
299    dont_initialize();
300    sensitive << p_clk.neg();
301        for ( size_t i=0; i<nb_ini; ++i )   sensitive << p_to_ini[i];
302
303    // constructing CMD & RSP XBARs
304        m_rsp_xbar = new rsp_xbar_t( false,         // RSP XBAR
305                                 nb_tgt,
306                                 nb_ini,
307                                 &m_rsp_rt );
308
309        m_cmd_xbar = new cmd_xbar_t( true,          // CMD XBAR
310                                 nb_ini,
311                                 nb_tgt,
312                                 &m_cmd_rt );
313
314    // constructing  CMD & RSP XBARs input & output ports (pointers)
315    m_ports_to_initiator = new VciTarget<vci_param>*[nb_ini];
316    for (size_t g = 0 ; g < nb_ini ; g++) m_ports_to_initiator[g] = &p_to_ini[g];
317
318    m_ports_to_target = new VciInitiator<vci_param>*[nb_tgt];
319    for (size_t g = 0 ; g < nb_tgt ; g++) m_ports_to_target[g] = &p_to_tgt[g];
320}
321
322////////////////////////////
323tmpl(/**/)::~VciIoxNetwork()
324{
325    soclib::common::dealloc_elems(p_to_ini, m_nb_ini);
326    soclib::common::dealloc_elems(p_to_tgt, m_nb_tgt);
327}
328
329}}
330
331// Local Variables:
332// tab-width: 4
333// c-basic-offset: 4
334// c-file-offsets:((innamespace . 0)(inline-open . 0))
335// indent-tabs-mode: nil
336// End:
337
338// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
Note: See TracBrowser for help on using the repository browser.