source: branches/v5/modules/dspin_local_ring_fast_c/caba/source/src/dspin_local_ring_fast_c.cpp @ 326

Last change on this file since 326 was 326, checked in by simerabe, 11 years ago

introducing 2 new components : simple and local ring interconnect using dspin interface

  • Property svn:executable set to *
File size: 9.2 KB
Line 
1/* -*- c++ -*-
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 * Author   : Abdelmalek SI MERABET
23 * Date     : February 2011
24 * Copyright: UPMC - LIP6
25 */
26
27#include <iostream> 
28#include <string>
29#include <stdarg.h>
30#include "alloc_elems.h"
31#include "../include/dspin_local_ring_fast_c.h"
32
33namespace soclib { namespace caba {
34
35using soclib::common::alloc_elems;
36using soclib::common::dealloc_elems;
37
38#define tmpl(x) template<typename vci_param, int ring_cmd_data_size, int ring_rsp_data_size > x DspinLocalRingFastC<vci_param, ring_cmd_data_size, ring_rsp_data_size >
39
40////////////////////////////////
41//      constructor           //
42////////////////////////////////
43tmpl(/**/)::DspinLocalRingFastC( sc_module_name insname,
44                         const soclib::common::MappingTable &mt,
45                         const soclib::common::IntTab &ringid,
46                         const int &wrapper_fifo_depth,
47                         const int &half_gateway_fifo_depth,
48                         int nb_attached_initiator,
49                         int nb_attached_target, 
50                         const int x_width,
51                         const int y_width)                                           
52                         : soclib::caba::BaseModule(insname), 
53                           m_ns(nb_attached_initiator+nb_attached_target+2), 
54                           m_nai(nb_attached_initiator), 
55                           m_nat(nb_attached_target)
56 {
57        p_cmd_out = soclib::common::alloc_elems<soclib::caba::DspinOutput<ring_cmd_data_size> >("p_cmd_out", m_nat+1);
58        p_rsp_in  = soclib::common::alloc_elems<soclib::caba::DspinInput<ring_rsp_data_size> >("p_rsp_in" , m_nat+1);
59
60        p_cmd_in  = soclib::common::alloc_elems<soclib::caba::DspinInput<ring_cmd_data_size> >("p_cmd_in" , m_nai+1);
61        p_rsp_out = soclib::common::alloc_elems<soclib::caba::DspinOutput<ring_rsp_data_size> >("p_rsp_out", m_nai+1);
62
63//-- to keep trace on ring traffic
64        init_cmd     = new cmd_str[m_nai+1];
65        tgt_rsp      = new rsp_str[m_nat+1];
66        tgt_cmd_val  = new bool[m_nat+1];
67        init_rsp_val = new bool[m_nai+1];
68//--
69        m_ring_initiator = new ring_initiator_t*[m_nai];
70        m_ring_target    = new ring_target_t*[m_nat]; 
71        m_ring_signal    = new ring_signal_t[m_ns];
72
73        std::ostringstream o;
74        o << name() << "_hg_init";
75        bool alloc_hg_init = (m_nai == 0);
76        m_half_gateway_initiator = new half_gateway_initiator_t(o.str().c_str(), alloc_hg_init, half_gateway_fifo_depth, mt, ringid, nb_attached_target, x_width, y_width);
77
78        std::ostringstream p;
79        p << name() << "_hg_target";
80        bool alloc_hg_target = (m_nat == 0);
81        m_half_gateway_target    = new half_gateway_target_t(p.str().c_str(), alloc_hg_target, half_gateway_fifo_depth, mt, ringid, m_nat);
82
83
84        for(int i=0; i<m_nai; ++i) {
85                bool alloc_init = (i==0);
86                std::ostringstream o;
87                o << name() << "_init_" << i;
88                m_ring_initiator[i] = new ring_initiator_t(o.str().c_str(), alloc_init, wrapper_fifo_depth, mt, ringid, i, nb_attached_target, x_width, y_width);
89        }
90
91        for(int i=0; i<m_nat; ++i) {
92                bool alloc_target = (i==0);
93                std::ostringstream o;
94                o << name() << "_target_" << i;
95                m_ring_target[i]  = new ring_target_t(o.str().c_str(), alloc_target, wrapper_fifo_depth, mt, ringid, i);
96        }
97
98        SC_METHOD(transition);
99        dont_initialize();
100        sensitive << p_clk.pos();
101
102        SC_METHOD(genMoore);
103        dont_initialize();
104        sensitive << p_clk.neg();
105 }
106//--------------------------//
107tmpl(void)::transition()    //
108//--------------------------//
109{
110        if ( ! p_resetn.read() ) {
111                for(int i=0;i<m_nai;i++) {
112                        m_ring_initiator[i]->reset();
113                }
114                for(int t=0;t<m_nat;t++) {     
115                        m_ring_target[t]->reset();
116                }
117
118                m_half_gateway_initiator->reset();
119                m_half_gateway_target->reset();
120                return;
121        }
122
123// update ring signals four times
124// in order to break the loop due to dependency existing between ring signals
125// this rule is based on relaxation principle
126        for (int niter = 0; niter < m_ns - 1; niter++) 
127        { 
128                for(int i=0;i<m_nai;i++) {
129                        int h = 0;
130                        if(i == 0) h = m_ns-1;
131                        else h = i-1;
132                        m_ring_initiator[i]->update_ring_signals(m_ring_signal[h], m_ring_signal[i]);
133                }
134
135                for(int i=0;i<m_nat;i++){
136                        m_ring_target[i]->update_ring_signals(m_ring_signal[m_nai+i-1], m_ring_signal[m_nai+i] );
137                }
138
139                m_half_gateway_initiator->update_ring_signals(m_ring_signal[m_nai+m_nat-1], m_ring_signal[m_nai+m_nat], tga, iga);
140               
141                m_half_gateway_target->update_ring_signals(m_ring_signal[m_ns-2], m_ring_signal[m_ns-1], tga, iga);
142        }
143//-----------------------------------------------//
144// transition                                    //
145//----------------------------------------------//
146        for(int i=0;i<m_nai;i++) {
147                int h = 0;
148                if(i == 0) h = m_ns-1;
149                else h = i-1;
150                m_ring_initiator[i]->transition(p_cmd_in[i], p_rsp_out[i], m_ring_signal[h], init_cmd[i], init_rsp_val[i]);
151        }
152
153        for(int t=0;t<m_nat;t++) {
154                m_ring_target[t]->transition(p_cmd_out[t], p_rsp_in[t], m_ring_signal[m_nai+t-1], tgt_cmd_val[t], tgt_rsp[t]);
155        }
156
157        m_half_gateway_initiator->transition(p_cmd_in[m_nai], p_rsp_out[m_nai], m_ring_signal[m_nai+m_nat-1], init_cmd[m_nai], init_rsp_val[m_nai], tga);
158        m_half_gateway_target->transition(p_cmd_out[m_nat], p_rsp_in[m_nat], m_ring_signal[m_nai+m_nat], tgt_cmd_val[m_nat], tgt_rsp[m_nat], iga);
159}
160
161tmpl(void)::genMoore()
162{
163
164        for(int i=0;i<m_nai;i++) 
165                m_ring_initiator[i]->genMoore(p_cmd_in[i], p_rsp_out[i]);
166        for(int t=0;t<m_nat;t++)
167                m_ring_target[t]->genMoore(p_cmd_out[t], p_rsp_in[t]);
168
169        m_half_gateway_initiator->genMoore(p_cmd_in[m_nai], p_rsp_out[m_nai]);
170   
171        m_half_gateway_target->genMoore(p_cmd_out[m_nat], p_rsp_in[m_nat]);
172}
173//---------------- destructor
174tmpl(/**/)::~DspinLocalRingFastC()
175    {
176
177        delete m_half_gateway_initiator;
178        delete m_half_gateway_target;
179
180        for(int x = 0; x < m_nai; x++)
181                delete m_ring_initiator[x];
182       
183        for(int x = 0; x < m_nat; x++)
184                delete m_ring_target[x];
185
186        delete [] m_ring_initiator;
187        delete [] m_ring_target;
188        delete [] m_ring_signal;
189       
190        dealloc_elems(p_cmd_out, m_nat+1);
191        dealloc_elems(p_cmd_in,  m_nai+1);
192        dealloc_elems(p_rsp_in,  m_nat+1);
193        dealloc_elems(p_rsp_out, m_nai+1);       
194    }
195
196tmpl(void)::print_trace()
197{
198        int init_cmd_index = 0;
199        bool init_cmd_found   = false;
200        int tgt_rsp_index = 0;
201        bool tgt_rsp_found = false;
202
203        // cmd trace
204        //*-- one initiator has token at one time
205        for(int i=0;i<m_nai+1;i++) {
206               if(init_cmd[i].cmdval) {
207                        init_cmd_index = i;
208                        init_cmd_found = true;
209                        break;
210                }
211       
212        }
213
214        // rsp trace
215        //*-- one target has token at one time
216        for(int t=0;t<m_nat+1;t++) {
217               if(tgt_rsp[t].rspval) {
218                        tgt_rsp_index = t;
219                        tgt_rsp_found = true;
220                        break;
221                }
222       
223        }
224       
225        // cmd display
226        if(init_cmd_found) {
227                //*-- in case of broadcast (on coherence ring), all targets can receive the command at the same time
228                for(int t=0;t<m_nat+1;t++) {
229                        if(tgt_cmd_val[t]) {
230                                std::cout << "RING " << name() 
231                                          << " -- initiator_" << std::dec << init_cmd_index
232                                          << " ... cmd to ... target_" << t
233                                          << " -state : " << init_cmd[init_cmd_index].state     
234                                          << " -flit : "  << std::hex << init_cmd[init_cmd_index].flit
235                                          << std::endl;
236                        }
237                }
238        }
239
240        // rsp display
241        if(tgt_rsp_found) {
242                for(int i=0;i<m_nai+1;i++) {
243                        if(init_rsp_val[i]) {
244                                std::cout << "RING " << name() 
245                                          << " ++ target_" << std::dec << tgt_rsp_index
246                                          << " ... rsp to ... initiator_" << i
247                                          << " +state : " << tgt_rsp[tgt_rsp_index].state
248                                          << " +flit : "  << std::hex << tgt_rsp[tgt_rsp_index].flit
249                                          << std::endl;
250                        }
251                }
252        }
253
254}
255#ifdef VCI_LOCAL_RING_FAST_STAT
256tmpl(void)::print_stats(uint32_t local)
257{
258  std::cout << name() << " , cycles , flits sent , token wait , fifo full  , preempt , palloc wait " << std::endl;
259        if(!local)
260        {
261
262#ifdef I_STATS
263                for(int i=0;i<m_nai;i++) 
264                        m_ring_initiator[i]->print_stats();
265#endif
266        }
267#ifdef HI_STATS
268        else
269                m_half_gateway_initiator->print_stats();
270#endif
271}
272#endif
273}} // end namespace
Note: See TracBrowser for help on using the repository browser.