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_verilator/] [netrace_lib.h] - Blame information for rev 48

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 48 alirezamon
#ifndef NETRACE_LIB_H
2
#define NETRACE_LIB_H
3
 
4
 
5
#include "netrace-1.0/queue.h"
6
#include "netrace-1.0/netrace.h"
7
#include "netrace-1.0/queue.c"
8
#include "netrace-1.0/netrace.c"
9
 
10
 
11
extern int reset,clk;
12
extern char simulation_done;
13
extern void connect_clk_reset_start_all(void);
14
extern void sim_eval_all (void);
15
extern void topology_connect_all_nodes (void);
16
extern Vpck_inj        *pck_inj[NE];
17
extern unsigned int  count_en;
18
extern unsigned long int main_time;     // Current simulation time
19
extern int verbosity;
20
 
21
 
22
 
23
 
24
#define L2_LATENCY 8
25
 
26
 
27
int ignore_dependencies = 0;
28
int start_region = 0;
29
int reader_throttling = 0;
30
unsigned long long int nt_cycle=0;
31
unsigned long long int nt_start_cycle=0;
32
 
33
nt_header_t* header;
34
queue_t** waiting;
35
queue_t** inject;
36
queue_t** traverse;
37
nt_packet_t* trace_packet = NULL;
38
nt_packet_t* packet = NULL;
39
int nt_packets_left = 0;
40
 
41
 
42
int netrace_to_pronoc_map [64];
43
int pronoc_to_netrace_map [NE];
44
int pck_injct_in_pck_wr[NE];
45
 
46
unsigned int nt_total_rd_pck=0; // from trace file
47
unsigned int read_done=0;
48
 
49
typedef struct queue_node queue_node_t;
50
struct queue_node {
51
        nt_packet_t* packet;
52
        unsigned long long int cycle;
53
};
54
 
55
 
56
unsigned long long int calc_packet_timing( nt_packet_t* packet ) {
57
 
58
        int n_hops = abs( packet->src -  packet->dst );
59
        if( n_hops <= 0 ) n_hops = 1;
60
        return 3*n_hops;
61
}
62
 
63
 
64
 
65
void netrace_init( char * tracefile){
66
    int i=0;
67
        nt_open_trfile( tracefile );
68
        if( ignore_dependencies ) {
69
                nt_disable_dependencies();
70
                printf("\tDependencies is turned off in tracking cleared packets list\n");
71
        }
72
        if( reader_throttling ) {
73
                printf("\treader throttling is enabled\n");
74
        }
75
        nt_print_trheader();
76
        header = nt_get_trheader();
77
        nt_seek_region( &header->regions[start_region] );
78
        for(i = 0; i < start_region; i++ ) {
79
                nt_cycle += header->regions[i].num_cycles;
80
        }
81
        if(nt_cycle){
82
                printf("\tThe simulation start at region %u and %llu cycle\n",start_region,nt_cycle);
83
                nt_start_cycle=nt_cycle;
84
        }
85
 
86
        waiting  = (queue_t**) malloc( header->num_nodes * sizeof(queue_t*) );
87
        inject   = (queue_t**) malloc( header->num_nodes * sizeof(queue_t*) );
88
        traverse = (queue_t**) malloc( header->num_nodes * sizeof(queue_t*) );
89
        if( (waiting == NULL) || (inject == NULL) || (traverse == NULL) ) {
90
                printf( "ERROR: malloc fail queues\n" );
91
                exit(0);
92
        }
93
        for( i = 0; i < header->num_nodes; ++i ) {
94
                waiting[i]  = queue_new();
95
                inject[i]   = queue_new();
96
                traverse[i] = queue_new();
97
        }
98
 
99
        if( !reader_throttling ) {
100
                trace_packet = nt_read_packet();
101
        } else if( !ignore_dependencies ) {
102
                nt_init_self_throttling();
103
        }
104
 
105
        MIN_PACKET_SIZE = (8*8)/Fpay;
106
        MAX_PACKET_SIZE = (64*8)/Fpay;
107
        AVG_PACKET_SIZE=(MIN_PACKET_SIZE+MAX_PACKET_SIZE)/2;// average packet size
108
        int p=(MAX_PACKET_SIZE-MIN_PACKET_SIZE)+1;
109
        rsv_size_array = (unsigned int*) calloc ( p , sizeof(int));
110
        if (rsv_size_array==NULL){
111
                fprintf(stderr,"ERROR: cannot allocate (%d x int) memory for rsv_size_array. \n",p);
112
                 exit(1);
113
        }
114
 
115
 
116
        if(verbosity==1)        printf("\e[?25l"); //To hide the cursor:
117
 
118
}
119
 
120
 
121
 
122
 
123
void netrace_eval(unsigned int eval_num){
124
        int i;
125
 
126
        if((reset==1) || (count_en==0))  return;
127
 
128
        if((( nt_cycle > header->num_cycles) || (read_done==1 )) && nt_packets_left==0 )  simulation_done=1;
129
 
130
        // Reset packets remaining check
131
        nt_packets_left = 0;
132
 
133
        // Get packets for this cycle
134
        if((end_sim_pck_num == 0 ) || (end_sim_pck_num > nt_total_rd_pck )){
135
                if( reader_throttling ) {
136
                        nt_packet_list_t* list;
137
                        for( list = nt_get_cleared_packets_list(); list != NULL; list = list->next ) {
138
                                if( list->node_packet != NULL ) {
139
                                        trace_packet = list->node_packet;
140
                                        queue_node_t* new_node = (queue_node_t*) nt_checked_malloc( sizeof(queue_node_t) );
141
                                        new_node->packet = trace_packet;
142
                                        new_node->cycle = (trace_packet->cycle > nt_cycle) ? trace_packet->cycle : nt_cycle;
143
                                        queue_push( inject[trace_packet->src], new_node, new_node->cycle );
144
                                        nt_total_rd_pck++;
145
                                } else {
146
                                        printf( "ERROR: Malformed packet list" );
147
                                        exit(-1);
148
                                }
149
                        }
150
                        nt_empty_cleared_packets_list();
151
                } else {
152
                        while( (trace_packet != NULL) && (trace_packet->cycle == nt_cycle) ) {
153
                                // Place in appropriate queue
154
                                queue_node_t* new_node = (queue_node_t*) nt_checked_malloc( sizeof(queue_node_t) );
155
                                new_node->packet = trace_packet;
156
                                new_node->cycle = (trace_packet->cycle > nt_cycle) ? trace_packet->cycle : nt_cycle;
157
                                if( ignore_dependencies || nt_dependencies_cleared( trace_packet ) ) {
158
                                        // Add to inject queue
159
                                        queue_push( inject[trace_packet->src], new_node, new_node->cycle );
160
                                        nt_total_rd_pck++;
161
                                } else {
162
                                        // Add to waiting queue
163
                                        queue_push( waiting[trace_packet->src], new_node, new_node->cycle );
164
                                        nt_total_rd_pck++;
165
                                }
166
                                // Get another packet from trace
167
                                trace_packet = nt_read_packet();
168
                        }
169
                        if( (trace_packet != NULL) && (trace_packet->cycle < nt_cycle) ) {
170
                                // Error check: Crash and burn
171
                                printf( "ERROR: Invalid trace_packet cycle time: %llu, current cycle: %llu\n", trace_packet->cycle, nt_cycle );
172
                                exit(-1);
173
                        }
174
                }
175
        }else {//if ~end_sim_pck_num
176
                read_done=1;
177
        }
178
 
179
        if(eval_num<netrace_speed_up-1) {
180
                nt_cycle++;
181
                nt_packets_left=1;
182
                return;
183
        }
184
 
185
 
186
        // Inject where possible (max one per node)
187
        for( i = 0; i < header->num_nodes; ++i ) {
188
                nt_packets_left |= !queue_empty( inject[i] );
189
                //TODO define RRA if multiple netrace sources are mapped to one node. only one can sent packt at each cycle
190
                int pronoc_src =  netrace_to_pronoc_map[i];
191
                //TODO define sent vc policy
192
                int sent_vc = 0;
193
 
194
                if(pck_inj[pronoc_src]->pck_injct_in_pck_wr){
195
                        //the wr_pck should be asserted only for single cycle
196
                        pck_inj[pronoc_src]->pck_injct_in_pck_wr           = 0;
197
                        continue;
198
                }
199
 
200
                pck_inj[pronoc_src]->pck_injct_in_pck_wr           = 0;
201
                if((pck_inj[pronoc_src]->pck_injct_out_ready & (0x1<<sent_vc)) == 0){
202
                        //This pck injector is not ready yet
203
                        continue;
204
                }
205
 
206
                queue_node_t* temp_node = (queue_node_t*) queue_peek_front( inject[i] );
207
                if( temp_node != NULL ) {
208
                        packet = temp_node->packet;
209
                        if( (packet != NULL) && (temp_node->cycle <= nt_cycle) ) {
210
 
211
                                if(verbosity>1) {
212
                                        printf( "Inject: %llu ", nt_cycle );
213
                                        nt_print_packet( packet );
214
                                }
215
                                temp_node = (queue_node_t*) queue_pop_front( inject[i] );
216
                                temp_node->cycle = nt_cycle;//injection time
217
                                queue_push( traverse[packet->dst], temp_node, temp_node->cycle );
218
                                long int ptr_addr = reinterpret_cast<long int> (temp_node);
219
                                int flit_num = (nt_get_packet_size(packet)* 8) / Fpay;
220
                                if(flit_num< pck_inj[pronoc_src]->min_pck_size) flit_num = pck_inj[pronoc_src]->min_pck_size;
221
                                int pronoc_dst =  netrace_to_pronoc_map[packet->dst];
222
                                if(IS_SELF_LOOP_EN ==0){
223
                                        if(packet->dst == pronoc_src ){
224
                                                 fprintf(stderr,"ERROR: ProNoC is not configured with self-loop enable and Netrace aims to inject\n a "
225
                                                                 "packet with identical source and destination address. Enable the SELF_LOOP parameter\n"
226
                                                                 "in ProNoC and rebuild the simulation model\n");
227
                                                 exit(1);
228
                                        }
229
                                }
230
                                unsigned int sent_class =0;
231
                                pck_inj[pronoc_src]->pck_injct_in_data         = ptr_addr;
232
                                pck_inj[pronoc_src]->pck_injct_in_size         = flit_num;
233
                                pck_inj[pronoc_src]->pck_injct_in_endp_addr    = endp_addr_encoder(pronoc_dst);
234
                                pck_inj[pronoc_src]->pck_injct_in_class_num    = sent_class;
235
                                pck_inj[pronoc_src]->pck_injct_in_init_weight  = 1;
236
                                pck_inj[pronoc_src]->pck_injct_in_vc           = 0x1<<sent_vc;
237
                                pck_inj[pronoc_src]->pck_injct_in_pck_wr           = 1;
238
                                total_sent_pck_num++;
239
 
240
                                #if (C>1)
241
                                        sent_stat[pronoc_src][sent_class].pck_num ++;
242
                                        sent_stat[pronoc_src][sent_class].flit_num +=flit_num;
243
                                #else
244
                                        sent_stat[pronoc_src].pck_num ++;
245
                                        sent_stat[pronoc_src].flit_num +=flit_num;
246
                                #endif
247
                        }
248
                }
249
        }
250
 
251
/*
252
        // Step all network components, Eject where possible
253
                for( i = 0; i < header->num_nodes; ++i ) {
254
                        nt_packets_left |= !queue_empty( traverse[i] );
255
                        queue_node_t* temp_node = (queue_node_t*) queue_peek_front( traverse[i] );
256
                        if( temp_node != NULL ) {
257
                                packet = temp_node->packet;
258
                                if( (packet != NULL) && (temp_node->cycle <= nt_cycle) ) {
259
                                        printf( "Eject: %llu ", nt_cycle );
260
                                        nt_print_packet( packet );
261
                                        nt_clear_dependencies_free_packet( packet );
262
                                        temp_node = (queue_node_t*) queue_pop_front( traverse[i] );
263
                                        free( temp_node );
264
                                }
265
                        }
266
                }
267
*/
268
 
269
        // Step all network components, Eject where possible
270
        for( i = 0; i < NE; ++i ) {
271
                nt_packets_left |= !queue_empty( traverse[i] );
272
                //check which pck injector got a packet
273
                if(pck_inj[i]->pck_injct_out_pck_wr==0) continue;
274
                //we have got a packet
275
                //printf( "data=%lx\n",pck_inj[i]->pck_injct_out_data);
276
 
277
                queue_node_t* temp_node = (queue_node_t*)  pck_inj[i]->pck_injct_out_data;
278
                if( temp_node != NULL ) {
279
                        packet = temp_node->packet;
280
                        if( packet != NULL){
281
                                if(verbosity>1) {
282
                                        printf( "Eject: %llu ", nt_cycle );
283
                                        nt_print_packet( packet );
284
                                }
285
                                // remove from traverse
286
                                nt_clear_dependencies_free_packet( packet );
287
                                queue_remove( traverse[i], temp_node );
288
                                unsigned long long int    clk_num_h2t= (nt_cycle - temp_node->cycle)/netrace_speed_up;
289
                                unsigned int    clk_num_h2h= clk_num_h2t - pck_inj[i]->pck_injct_out_h2t_delay;
290
                                /*
291
                                printf("clk_num_h2t (%llu) h2t_delay(%u)\n", clk_num_h2t , pck_inj[i]->pck_injct_out_h2t_delay);
292
                                if(clk_num_h2t < pck_inj[i]->pck_injct_out_h2t_delay){
293
                                        fprintf(stderr, "ERROR:clk_num_h2t (%llu) is smaller than  injector h2t_delay(%u)\n", clk_num_h2t , pck_inj[i]->pck_injct_out_h2t_delay);
294
                                        exit(1);
295
                                }
296
                                */
297
                                update_statistic_at_ejection (
298
                                        i,//    core_num
299
                                        clk_num_h2h, // clk_num_h2h,
300
                                        (unsigned int) clk_num_h2t, // clk_num_h2t,
301
                                        pck_inj[i]->pck_injct_out_distance, //    distance,
302
                                        pck_inj[i]->pck_injct_out_class_num,//          class_num,
303
                                        packet->src//           unsigned int    src
304
                                );
305
                                #if(C>1)
306
                                        rsvd_stat[i][pck_inj[i]->pck_injct_out_class_num].flit_num +=pck_inj[i]->pck_injct_out_size;
307
                                #else
308
                                        rsvd_stat[i].flit_num+=pck_inj[i]->pck_injct_out_size;
309
                                #endif
310
                                free( temp_node );
311
 
312
                        }
313
                }
314
        }
315
                // Check for cleared dependences... or not
316
                if( !reader_throttling ) {
317
                for( i = 0; i < header->num_nodes; ++i ) {
318
                        nt_packets_left |= !queue_empty( waiting[i] );
319
                        node_t* temp = waiting[i]->head;
320
                        while( temp != NULL ) {
321
                                queue_node_t* temp_node = (queue_node_t*) temp->elem;
322
                                packet = temp_node->packet;
323
                                temp = temp->next;
324
                                if( nt_dependencies_cleared( packet ) ) {
325
                                        // remove from waiting
326
                                        queue_remove( waiting[i], temp_node );
327
                                        // add to inject
328
                                        queue_node_t* new_node = (queue_node_t*) nt_checked_malloc( sizeof(queue_node_t) );
329
                                        new_node->packet = packet;
330
                                        new_node->cycle = nt_cycle + L2_LATENCY;
331
                                        queue_push( inject[i], new_node, new_node->cycle );
332
                                        free( temp_node );
333
                                }
334
                        }
335
                }
336
        }
337
        nt_cycle++;
338
}
339
 
340
 
341
void netrace_posedge_event(){
342
        unsigned int i;
343
        clk = 1;       // Toggle clock
344
        for(i=0;i<netrace_speed_up; i++)  netrace_eval(i);
345
        connect_clk_reset_start_all();
346
        sim_eval_all();
347
        //print total sent packet each 1024 clock cycles
348
        if(verbosity==1) if(nt_cycle&0x3FF) printf("\rTotal sent packet: %9d", total_sent_pck_num);
349
}
350
 
351
 
352
void netrace_clk_negedge_event( ){
353
        int i;
354
        clk = 0;
355
        topology_connect_all_nodes ();
356
        connect_clk_reset_start_all();
357
        sim_eval_all();
358
 
359
}
360
 
361
 
362
 
363
 
364
void netrace_final_report(){
365
        int i;
366
        unsigned int worst_sent=0, worst_rsv=0;
367
        unsigned long long int total_clock = (nt_cycle-nt_start_cycle);
368
        unsigned long long int pronoc_total_clock = total_clock/netrace_speed_up;
369
 
370
        if(verbosity==1)        printf("\e[?25h");//To re-enable the cursor:
371
        printf("\nNetrace simulation results-------------------\n"
372
                        "\tNetrace end clock cycles: %llu\n"
373
                        "\tNetrace duration clock cycles: %llu\n"
374
                        "\tProNoC  duration clock cycles: %llu\n"
375
        ,nt_cycle,total_clock,pronoc_total_clock);
376
 
377
 
378
 
379
        print_statistic_new (pronoc_total_clock);
380
/*
381
        printf("\t total , %u , %u, %u, %u  \n",total_sent_pck_num,     total_rsv_pck_num,total_sent_flit_number,total_rsv_flit_number);
382
        printf("\nper node\n");
383
        for(i=0;i<NE;i++){
384
                printf("\t %u  , %u , %u , %u , %u \n", i,sent_core_total_pck_num[i],rsvd_core_total_pck_num[i], sent_core_total_flit_num[i],rsv_core_total_flit_num[i]
385
                sent_core_worst_delay[i], rsvd_core_worst_delay[i]
386
 
387
                );
388
        }
389
        */
390
}
391
 
392
 
393
 
394
#endif

powered by: WebSVN 2.1.0

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