OpenCores
URL https://opencores.org/ocsvn/an-fpga-implementation-of-low-latency-noc-based-mpsoc/an-fpga-implementation-of-low-latency-noc-based-mpsoc/trunk

Subversion Repositories an-fpga-implementation-of-low-latency-noc-based-mpsoc

[/] [an-fpga-implementation-of-low-latency-noc-based-mpsoc/] [trunk/] [mpsoc/] [src_c/] [netrace-1.0/] [main.c] - Blame information for rev 48

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 48 alirezamon
/*
2
 * Copyright (c) 2010-2011 The University of Texas at Austin
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are
7
 * met: redistributions of source code must retain the above copyright
8
 * notice, this list of conditions and the following disclaimer;
9
 * redistributions in binary form must reproduce the above copyright
10
 * notice, this list of conditions and the following disclaimer in the
11
 * documentation and/or other materials provided with the distribution;
12
 * neither the name of the copyright holders nor the names of its
13
 * contributors may be used to endorse or promote products derived from
14
 * this software without specific prior written permission.
15
 *
16
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
 */
28
 
29
#include <stdio.h>
30
#include <stdlib.h>
31
#include <math.h>
32
unsigned long int nt_tr_list_pck=0;
33
 
34
unsigned char done=0;
35
unsigned long int end_sim_pck_num=0;
36
 
37
#include "queue.h"
38
#include "netrace.h"
39
 
40
#include "queue.c"
41
#include "netrace.c"
42
 
43
#include "inttypes.h"
44
 
45
#define L2_LATENCY 8
46
 
47
 
48
unsigned long int nt_total_rd_pck=0;
49
unsigned long int nt_total_ejected_pck=0;
50
 
51
unsigned long long int calc_packet_timing( nt_packet_t* );
52
 
53
int verbosity=1;
54
 
55
nt_header_t* header;
56
int x_nodes, y_nodes;
57
unsigned long long int cycle;
58
 
59
 
60
unsigned long long int start_cycle=0;
61
unsigned int router_pipe_latency=3;
62
 
63
typedef struct queue_node queue_node_t;
64
struct queue_node {
65
        nt_packet_t* packet;
66
        unsigned long long int cycle;
67
};
68
 
69
int main( int argc, char** argv ) {
70
 
71
        int i;
72
        int ignore_dependencies = 0;
73
        int start_region = 0;
74
        int reader_throttling = 0;
75
 
76
 
77
        char* tracefile;
78
        if( argc > 1 ) {
79
                tracefile = argv[1];
80
                for( i = 2; i < argc; ++i ) {
81
                        if( strcmp(argv[i], "-d") == 0 ) {
82
                                ignore_dependencies = 1;
83
                        } else if( strcmp(argv[i], "-r") == 0 ) {
84
                                if( argc > ++i ) {
85
                                        start_region = atoi(argv[i]);
86
                                } else {
87
                                        fprintf( stderr, "ERROR: Need to specify parameter to -r option\n" );
88
                                        exit(0);
89
                                }
90
                        }
91
                        else if( strcmp(argv[i], "-n") == 0 ) {
92
                                if( argc > ++i ) {
93
                                        end_sim_pck_num=atoi(argv[i]);
94
                    printf ("\tSimulation ends on total packet num of =%ld\n", end_sim_pck_num);
95
                                } else {
96
                                        fprintf( stderr, "ERROR: Need to specify parameter to -n option\n" );
97
                                        exit(0);
98
                                }
99
                        }
100
 
101
                        else if( strcmp(argv[i], "-p") == 0 ) {
102
                                if( argc > ++i ) {
103
                                        router_pipe_latency=atoi(argv[i]);
104
                                } else {
105
                                        fprintf( stderr, "ERROR: Need to specify parameter to -p option\n" );
106
                                        exit(0);
107
                                }
108
                        }
109
 
110
 
111
 
112
 
113
                        else if( strcmp(argv[i], "-v") == 0 ) {
114
                                if( argc > ++i ) {
115
                                        verbosity=atoi(argv[i]);
116
                                } else {
117
                                        fprintf( stderr, "ERROR: Need to specify parameter to -v option\n" );
118
                                        exit(0);
119
                                }
120
                        }
121
 
122
 
123
 
124
                        else if( strcmp(argv[i], "-t") == 0 ) {
125
                                reader_throttling = 1;
126
                        } else {
127
                                fprintf( stderr, "ERROR: Unknown parameter %s\n", argv[i] );
128
                                exit(0);
129
                        }
130
                }
131
        } else {
132
                printf( "ERROR: Please specify trace file\n" );
133
                exit(0);
134
        }
135
 
136
 
137
 
138
        int packets_left = 0;
139
        cycle = 0;
140
        nt_packet_t* trace_packet = NULL;
141
        nt_packet_t* packet = NULL;
142
        queue_t** waiting;
143
        queue_t** inject;
144
        queue_t** traverse;
145
        nt_open_trfile( tracefile );
146
        if( ignore_dependencies ) {
147
                nt_disable_dependencies();
148
        }
149
        nt_print_trheader();
150
        header = nt_get_trheader();
151
        nt_seek_region( &header->regions[start_region] );
152
        for( i = 0; i < start_region; i++ ) {
153
                cycle += header->regions[i].num_cycles;
154
        }
155
        start_cycle = cycle;
156
        x_nodes = sqrt( header->num_nodes );
157
        y_nodes = header->num_nodes / x_nodes;
158
        waiting = (queue_t**) malloc( header->num_nodes * sizeof(queue_t*) );
159
        inject = (queue_t**) malloc( header->num_nodes * sizeof(queue_t*) );
160
        traverse = (queue_t**) malloc( header->num_nodes * sizeof(queue_t*) );
161
        if( (waiting == NULL) || (inject == NULL) || (traverse == NULL) ) {
162
                printf( "malloc fail queues\n" );
163
                exit(0);
164
        }
165
        for( i = 0; i < header->num_nodes; ++i ) {
166
                waiting[i] = queue_new();
167
                inject[i] = queue_new();
168
                traverse[i] = queue_new();
169
        }
170
 
171
        if( !reader_throttling ) {
172
                trace_packet = nt_read_packet();
173
 
174
        } else if( !ignore_dependencies ) {
175
                nt_init_self_throttling();
176
        }
177
 
178
        while( (done==0 &&  ( cycle <= header->num_cycles )) || packets_left!=0 ) {
179
 
180
                // Reset packets remaining check
181
                packets_left = 0;
182
 
183
                // Get packets for this cycle
184
        if((end_sim_pck_num == 0 ) || (end_sim_pck_num > nt_total_rd_pck )){
185
                        if( reader_throttling ) {
186
                                nt_packet_list_t* list;
187
                                for( list = nt_get_cleared_packets_list(); list != NULL; list = list->next ) {
188
                                        if( list->node_packet != NULL ) {
189
                                                trace_packet = list->node_packet;
190
                                                queue_node_t* new_node = (queue_node_t*) nt_checked_malloc( sizeof(queue_node_t) );
191
                                                new_node->packet = trace_packet;
192
                                                new_node->cycle = (trace_packet->cycle > cycle) ? trace_packet->cycle : cycle;
193
                                                queue_push( inject[trace_packet->src], new_node, new_node->cycle );
194
                                                nt_total_rd_pck++;
195
                                        } else {
196
                                                printf( "Malformed packet list" );
197
                                                exit(-1);
198
                                        }
199
                                }
200
                                nt_empty_cleared_packets_list();
201
                        } else {
202
                                while( (trace_packet != NULL) && (trace_packet->cycle == cycle) ) {
203
                                        // Place in appropriate queue
204
                                        queue_node_t* new_node = (queue_node_t*) nt_checked_malloc( sizeof(queue_node_t) );
205
                                        new_node->packet = trace_packet;
206
 
207
                                        new_node->cycle = (trace_packet->cycle > cycle) ? trace_packet->cycle : cycle;
208
 
209
                                        if( ignore_dependencies || nt_dependencies_cleared( trace_packet ) ) {
210
                                                // Add to inject queue
211
                                                queue_push( inject[trace_packet->src], new_node, new_node->cycle );
212
                                        } else {
213
                                                // Add to waiting queue
214
                                                queue_push( waiting[trace_packet->src], new_node, new_node->cycle );
215
                                        }
216
                                        // Get another packet from trace
217
                                        trace_packet = nt_read_packet();
218
                    nt_total_rd_pck++;
219
 
220
                                }
221
                                if( (trace_packet != NULL) && (trace_packet->cycle < cycle) ) {
222
                                        // Error check: Crash and burn
223
                                        printf( "Invalid trace_packet cycle time: %llu, current cycle: %llu\n", trace_packet->cycle, cycle );
224
                                        exit(-1);
225
                                }
226
                        }
227
                }//endsim packet
228
                else done=1;
229
 
230
                // Inject where possible (max one per node)
231
                for( i = 0; i < header->num_nodes; ++i ) {
232
                        packets_left |= !queue_empty( inject[i] );
233
                        queue_node_t* temp_node = (queue_node_t*) queue_peek_front( inject[i] );
234
                        if( temp_node != NULL ) {
235
                                packet = temp_node->packet;
236
                                if( (packet != NULL) && (temp_node->cycle <= cycle) ) {
237
 
238
                                if(verbosity>1) {
239
                                        printf( "Inject: %llu ", cycle );
240
                                        nt_print_packet( packet );
241
                                }
242
                                        temp_node = (queue_node_t*) queue_pop_front( inject[i] );
243
                                        temp_node->cycle = cycle + calc_packet_timing( packet );
244
                                        queue_push( traverse[packet->dst], temp_node, temp_node->cycle );
245
                                        //printf("\tInject packet to ProNoC:\n");
246
                                        //printf ("\t\tsize=%u\n", nt_get_packet_size(packet));
247
                                        //long int ptr_addr = reinterpret_cast<long int> (temp_node);
248
                                        //printf ("\t\tpacket pointer addr: %p\n" ,temp_node);
249
                                        //printf ("\t\tpacket pointer addr: %lx\n" ,ptr_addr);
250
                                        //printf("0x%.16" PRIXPTR " contains 0x%" PRIXPTR "\n", (uintptr_t)&ptr_addr, (uintptr_t)ptr_addr);
251
                                }
252
                        }
253
                }
254
 
255
 
256
 
257
                        // Step all network components, Eject where possible
258
                        for( i = 0; i < header->num_nodes; ++i ) {
259
                                packets_left |= !queue_empty( traverse[i] );
260
                                queue_node_t* temp_node = (queue_node_t*) queue_peek_front( traverse[i] );
261
                                if( temp_node != NULL ) {
262
                                        packet = temp_node->packet;
263
                                        if( (packet != NULL) && (temp_node->cycle <= cycle) ) {
264
                                        if(verbosity>1) {
265
                                                printf( "Eject: %llu ", cycle );
266
                                                nt_print_packet( packet );
267
                                        }
268
                                                nt_total_ejected_pck++;
269
                                                nt_clear_dependencies_free_packet( packet );
270
                                                temp_node = (queue_node_t*) queue_pop_front( traverse[i] );
271
                                                free( temp_node );
272
                                        }
273
                                }
274
                        }
275
 
276
                // Check for cleared dependences... or not
277
                if( !reader_throttling ) {
278
                        for( i = 0; i < header->num_nodes; ++i ) {
279
                                packets_left |= !queue_empty( waiting[i] );
280
                                node_t* temp = waiting[i]->head;
281
                                while( temp != NULL ) {
282
                                        queue_node_t* temp_node = (queue_node_t*) temp->elem;
283
                                        packet = temp_node->packet;
284
                                        temp = temp->next;
285
                                        if( nt_dependencies_cleared( packet ) ) {
286
                                                // remove from waiting
287
                                                queue_remove( waiting[i], temp_node );
288
                                                // add to inject
289
                                                queue_node_t* new_node = (queue_node_t*) nt_checked_malloc( sizeof(queue_node_t) );
290
                                                new_node->packet = packet;
291
                                                new_node->cycle = cycle + L2_LATENCY;
292
                                                queue_push( inject[i], new_node, new_node->cycle );
293
                                                free( temp_node );
294
                                        }
295
                                }
296
                        }
297
                }
298
 
299
                cycle++;
300
                if(verbosity==1) if(cycle&0xFFF) printf("\rTotal read packet: %9ld", nt_total_rd_pck);
301
 
302
        }
303
        for( i = 0; i < header->num_nodes; ++i ) {
304
                queue_delete( waiting[i] );
305
                queue_delete( inject[i] );
306
                queue_delete( traverse[i] );
307
        }
308
        free( waiting );
309
        free( inject );
310
        free( traverse );
311
        nt_close_trfile();
312
    printf ("\nrouter_pipe_latency =%d\n", router_pipe_latency);
313
        printf( "Start cycle: %llu \n",start_cycle);
314
        printf( "End cycle:   %llu \n", cycle );
315
        printf( "Sim cycle:   %llu \n", cycle - start_cycle);
316
        printf( "total rd pck:  %lu  \n",nt_total_rd_pck);
317
        printf( "total ejected pck:  %lu  \n",nt_total_ejected_pck);
318
        return 0;
319
 
320
}
321
 
322
unsigned long long int calc_packet_timing( nt_packet_t* packet ) {
323
        int src_x = packet->src % x_nodes;
324
        int src_y = packet->src / x_nodes;
325
        int dst_x = packet->dst % x_nodes;
326
        int dst_y = packet->dst / x_nodes;
327
        int n_hops = abs( src_x - dst_x ) + abs( src_y - dst_y );
328
        if( n_hops <= 0 ) n_hops = 1;
329
        return router_pipe_latency*n_hops;
330
}
331
 
332
 
333
 
334
 
335
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.