source: branches/reconfiguration/modules/dspin_router/caba/test/synthetic_test/dspin_packet_generator/caba/source/src/dspin_packet_generator.cpp @ 998

Last change on this file since 998 was 998, checked in by cfuguet, 9 years ago

reconf: several improvements in the dspin_router synthetic test platform

File size: 10.4 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 * Authors  : alain.greiner@lip6.fr
23 * Date     : july 2010
24 * Copyright: UPMC - LIP6
25 *
26 * Modified by: Cesar Fuguet Tortolero
27 */
28
29#include "../include/dspin_packet_generator.h"
30#include <cassert>
31
32namespace soclib { namespace caba {
33
34using namespace soclib::caba;
35using namespace soclib::common;
36
37#define tmpl(x) template<int cmd_width, int rsp_width> x DspinPacketGenerator<cmd_width, rsp_width>
38
39
40//////////////////////////////////////////////////////
41tmpl(/**/)::DspinPacketGenerator( sc_module_name name,
42                                  const size_t   srcid,      // srcid for random
43                                  const size_t   length,     // packet length (flits)
44                                  const size_t   load,       // requested load * 1000
45                                  const size_t   fifo_depth, // Fifo depth
46                                  const size_t   bcp,        // broadcast period
47                                  const size_t   x_width,
48                                  const size_t   y_width,
49                                  const size_t   x_size,
50                                  const size_t   y_size,
51                                  const size_t   max_packets)
52    : BaseModule(name),
53
54    p_clk( "clk" ),
55    p_resetn( "resetn" ),
56    p_in( "p_in" ),
57    p_out( "p_out" ),
58
59    r_cycles( "r_cycles" ),
60
61        r_posted_bc_packets( "r_posted_bc_packets" ),
62        r_posted_packets( "r_posted_packets" ),
63
64    r_send_fsm( "r_send_fsm" ),
65    r_send_length( "r_send_length" ),
66    r_send_dest( "r_send_dest" ),
67    r_send_packets( "r_send_packets" ),
68    r_send_bc_packets( "r_send_bc_packets" ),
69
70    r_receive_fsm( "r_receive_fsm" ),
71    r_receive_packets( "r_receive_packets" ),
72    r_receive_latency( "r_receive_latency" ),
73    r_receive_bc_packets( "r_receive_bc_packets" ),
74    r_receive_bc_latency( "r_receive_bc_latency" ),
75
76    r_transaction_fifo( "r_transaction_fifo", fifo_depth ),
77
78    m_length( length ),
79    m_load( load ),
80    m_bcp( bcp ),
81    m_srcid( srcid ),
82    m_x_width( x_width ),
83    m_y_width( y_width ),
84    m_x_size( x_size ),
85    m_y_size( y_size ),
86    m_max_packets( max_packets )
87{
88    assert( (load <= 1000 ) and
89    "DSPIN PACKET GENERATOR ERROR: The load should be between 0 and 1000" );
90
91    assert( (cmd_width >= 33) and
92    "DSPIN PACKET GENERATOR ERROR: CMD flit width smaller than 33 bits");
93
94    assert( (length > 1 ) and
95    "DSPIN PACKET GENERATOR ERROR: Packet length smaller than 2 flits");
96
97    SC_METHOD (transition);
98    dont_initialize();
99    sensitive << p_clk.pos();
100
101    SC_METHOD (genMoore);
102    dont_initialize();
103    sensitive  << p_clk.neg();
104} //  end constructor
105
106////////////////////////
107tmpl(void)::transition()
108{
109    if ( not p_resetn.read() )
110    {
111        r_send_fsm            = SEND_IDLE;
112        r_receive_fsm         = RECEIVE_IDLE;
113        r_cycles              = 0;
114                r_posted_date         = 0;
115        r_posted_packets      = 0;
116        r_posted_bc_packets   = 0;
117        r_send_packets        = 0;
118        r_send_bc_packets     = 0;
119        r_receive_packets     = 0;
120        r_receive_latency     = 0;
121        r_receive_bc_packets  = 0;
122        r_receive_bc_latency  = 0;
123        return;
124    }
125
126    // default values
127    bool fifo_put = false;
128    bool fifo_get = false;
129
130    uint32_t alea = random();
131
132    /////////////////////////   GENERATOR FSM
133        size_t bcast_flits = r_posted_bc_packets.read() * 2;
134        size_t ucast_flits = r_posted_packets.read() * m_length;
135        size_t posted_flits = bcast_flits + ucast_flits;
136    size_t accepted_load = posted_flits * 1000 / (r_cycles.read() + 1);
137        size_t total_packets = r_posted_bc_packets.read() + r_posted_packets.read();
138        bool is_broadcast = ((m_bcp != 0) && (((total_packets + 1) % m_bcp) == 0));
139
140    if( ((accepted_load + ((alea >> 16) & 0xF)) < m_load) )
141    {
142                size_t total_packets = r_posted_packets.read() + r_posted_bc_packets.read();
143        bool max_not_reached = (total_packets < m_max_packets);
144        if ( (m_max_packets == 0) || max_not_reached )
145        {
146            fifo_put = true ;
147            if( r_transaction_fifo.wok() )
148                        {
149                if (is_broadcast)
150                                {
151                                        r_posted_bc_packets = r_posted_bc_packets.read() + 1;
152                                }
153                                else
154                                {
155                                        r_posted_packets = r_posted_packets.read() + 1;
156                                }
157                        }
158        }
159    }
160
161    /////////////////////////// CMD FSM
162    switch( r_send_fsm.read() )
163    {
164        case SEND_IDLE:
165            if ( r_transaction_fifo.rok() )
166            {
167                fifo_get = true;
168                                r_posted_date = (r_transaction_fifo.read() >> 1);
169
170                                // broadcast transaction
171                if ( (r_transaction_fifo.read() & 1) == 1 )
172                {
173                    r_send_length     = 2;
174                    r_send_fsm        = SEND_BROADCAST;
175                    r_send_bc_packets = r_send_bc_packets.read() + 1;
176                                        break;
177                }
178
179                                // unicast transaction
180                                int x_dest = ((alea >> 8) & 0xFF) % m_x_size;
181                                int y_dest = ((alea     ) & 0xFF) % m_y_size;
182
183                                r_send_length  = m_length;
184                                r_send_fsm     = SEND_UNICAST;
185                                r_send_packets = r_send_packets.read() + 1;
186                                r_send_dest    = (x_dest << m_y_width) | y_dest;
187            }
188                        break;
189        case SEND_UNICAST:
190        case SEND_BROADCAST:
191            if( p_out.read.read() )
192            {
193                r_send_length = r_send_length.read() - 1;
194                if( r_send_length.read() == 1 )
195                                {
196                                        r_send_fsm = SEND_IDLE;
197                                }
198            }
199                        break;
200    }  // end SEND FSM
201
202    //////////////////////////////      RECEIVE FSM
203    switch( r_receive_fsm.read() )
204    {
205        case RECEIVE_IDLE:
206            if ( p_in.write.read() )
207            {
208                if ( ((p_in.data.read() & 1) == 1) )
209                                {
210                    r_receive_fsm = RECEIVE_BROADCAST;
211                                }
212                else
213                                {
214                    r_receive_fsm = RECEIVE_UNICAST;
215                                }
216            }
217                        break;
218        case RECEIVE_BROADCAST:
219            if ( p_in.write.read() )
220            {
221                                uint32_t latency = r_cycles.read() - (uint32_t)p_in.data.read();
222                r_receive_bc_packets  = r_receive_bc_packets.read() + 1;
223                r_receive_bc_latency  = r_receive_bc_latency.read() + latency ;
224                r_receive_fsm = RECEIVE_IDLE;
225            }
226                        break;
227                case RECEIVE_UNICAST:
228                        if ( p_in.write.read() )
229                        {
230                                uint32_t latency = r_cycles.read() - (uint32_t)p_in.data.read();
231                                r_receive_packets = r_receive_packets.read() + 1;
232                                r_receive_latency = r_receive_latency.read() + latency;
233                                if ( p_in.eop.read() )
234                                {
235                                        r_receive_fsm = RECEIVE_IDLE;
236                                }
237                                else
238                                {
239                                        r_receive_fsm = RECEIVE_WAIT_EOP;
240                                }
241                        }
242                        break;
243        case RECEIVE_WAIT_EOP:
244            if ( p_in.write.read() and p_in.eop.read() )
245            {
246                r_receive_fsm = RECEIVE_IDLE;
247            }
248                        break;
249    } // end RECEIVE FSM
250
251    // increment date
252    r_cycles = r_cycles.read() + 1;
253
254    //  update fifos
255        uint32_t fifo_data = (r_cycles.read() << 1) | (is_broadcast ? 1 : 0);
256    r_transaction_fifo.update( fifo_get, fifo_put, fifo_data );
257
258} // end transition
259
260//////////////////////
261tmpl(void)::genMoore()
262{
263    // p_out
264    sc_uint<cmd_width>  data = 0;
265    bool                write = false;
266    bool                eop = false;
267
268    if ( r_send_fsm.read() == SEND_UNICAST )
269    {
270        write = true;
271        if ( r_send_length.read() == m_length )  // first flit
272        {
273                        sc_uint<cmd_width> dest = r_send_dest.read();
274            data = dest << (cmd_width - m_x_width - m_y_width);
275        }
276        else if ( r_send_length.read() == (m_length-1) )  // second flit
277        {
278            data = (sc_uint<cmd_width>)r_posted_date.read();
279        }
280                eop = (r_send_length.read() == 1);
281    }
282    else if ( r_send_fsm.read() == SEND_BROADCAST )
283    {
284        write = true;
285        if ( r_send_length.read() == 2 )  // first flit
286        {
287                        sc_uint<cmd_width> boundaries = 0x07C1F;
288            data = (boundaries << (cmd_width - 20)) | 1;
289        }
290        else                              // second flit
291        {
292            data = (sc_uint<cmd_width>)r_posted_date.read();
293        }
294                eop = (r_send_length.read() == 1);
295    }
296    p_out.data  = data;
297    p_out.eop   = eop;
298    p_out.write = write;
299
300    p_in.read = true;
301} // end genMoore
302
303/////////////////////////
304tmpl(void)::print_trace()
305{
306    const char* cmd_str[] = { "IDLE", "SEND_UNICAST", "SEND_BROADCAST" };
307    const char* rsp_str[] = { "IDLE", "RECEIVE_UNICAST", "RECEIVE_BROADCAST", "RECEIVE_WAIT" };
308
309    std::cout << "DSPIN_GENERATOR " << name()
310              << " : send_fsm = " << cmd_str[r_send_fsm.read()]
311              << " / recv_fsm = " << rsp_str[r_receive_fsm.read()]
312              << " / fifo_content = " << r_transaction_fifo.filled_status() << std::endl;
313} // end print_trace
314
315/////////////////////////
316tmpl(void)::print_stats()
317{
318        size_t   bcast_flits = r_send_bc_packets.read() * 2;
319        size_t   ucast_flits = r_send_packets.read() * m_length;
320    size_t   load        = (bcast_flits + ucast_flits * 1000) / r_cycles.read();
321    uint32_t latency     = r_receive_latency.read() / (r_receive_packets.read() + 1);
322    uint32_t bc_latency  = r_receive_bc_latency.read() / (r_receive_bc_packets.read() + 1);
323
324        std::cout << "DSPIN_GENERATOR " << name() << std::dec
325                << "\n - offered load               = " << m_load
326                << "\n - accepted load              = " << load
327                << "\n - unicast sent packets       = " << r_send_packets.read()
328                << "\n - unicast received packets   = " << r_receive_packets.read()
329                << "\n - unicast latency            = " << latency
330                << "\n - broadcast sent packets     = " << r_send_bc_packets.read()
331                << "\n - broadcast received packets = " << r_receive_bc_packets.read()
332                << "\n - broadcast latency          = " << bc_latency
333                << std::endl;
334} // end print_stats
335
336
337}} // end namespaces :w
338
Note: See TracBrowser for help on using the repository browser.