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 56

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 54 alirezamon
int * traffic_model_mapping;
43 48 alirezamon
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 54 alirezamon
        int i=0;
67 48 alirezamon
        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 54 alirezamon
        waiting  = (queue_t**) malloc( NE * sizeof(queue_t*) );
87
        inject   = (queue_t**) malloc( NE * sizeof(queue_t*) );
88
        traverse = (queue_t**) malloc( NE * sizeof(queue_t*) );
89 48 alirezamon
        if( (waiting == NULL) || (inject == NULL) || (traverse == NULL) ) {
90
                printf( "ERROR: malloc fail queues\n" );
91
                exit(0);
92
        }
93 54 alirezamon
 
94
        for( i = 0; i < NE; ++i ) {
95 48 alirezamon
                waiting[i]  = queue_new();
96
                inject[i]   = queue_new();
97
                traverse[i] = queue_new();
98
        }
99
 
100 54 alirezamon
 
101 48 alirezamon
        if( !reader_throttling ) {
102
                trace_packet = nt_read_packet();
103
        } else if( !ignore_dependencies ) {
104
                nt_init_self_throttling();
105
        }
106
 
107
        MIN_PACKET_SIZE = (8*8)/Fpay;
108
        MAX_PACKET_SIZE = (64*8)/Fpay;
109
        AVG_PACKET_SIZE=(MIN_PACKET_SIZE+MAX_PACKET_SIZE)/2;// average packet size
110
        int p=(MAX_PACKET_SIZE-MIN_PACKET_SIZE)+1;
111
        rsv_size_array = (unsigned int*) calloc ( p , sizeof(int));
112
        if (rsv_size_array==NULL){
113
                fprintf(stderr,"ERROR: cannot allocate (%d x int) memory for rsv_size_array. \n",p);
114
                 exit(1);
115
        }
116
 
117
 
118
        if(verbosity==1)        printf("\e[?25l"); //To hide the cursor:
119
 
120
}
121
 
122
 
123
 
124
 
125
void netrace_eval(unsigned int eval_num){
126
        int i;
127 54 alirezamon
        unsigned int pronoc_src_id,pronoc_dst_id;
128 48 alirezamon
 
129 56 alirezamon
        if((reset==reset_active_high) || (count_en==0))  return;
130 48 alirezamon
 
131
        if((( nt_cycle > header->num_cycles) || (read_done==1 )) && nt_packets_left==0 )  simulation_done=1;
132
 
133
        // Reset packets remaining check
134
        nt_packets_left = 0;
135
 
136
        // Get packets for this cycle
137
        if((end_sim_pck_num == 0 ) || (end_sim_pck_num > nt_total_rd_pck )){
138
                if( reader_throttling ) {
139
                        nt_packet_list_t* list;
140
                        for( list = nt_get_cleared_packets_list(); list != NULL; list = list->next ) {
141
                                if( list->node_packet != NULL ) {
142
                                        trace_packet = list->node_packet;
143
                                        queue_node_t* new_node = (queue_node_t*) nt_checked_malloc( sizeof(queue_node_t) );
144
                                        new_node->packet = trace_packet;
145
                                        new_node->cycle = (trace_packet->cycle > nt_cycle) ? trace_packet->cycle : nt_cycle;
146 54 alirezamon
                                        pronoc_src_id=traffic_model_mapping[trace_packet->src];
147
                                        queue_push( inject[pronoc_src_id], new_node, new_node->cycle );
148 48 alirezamon
                                        nt_total_rd_pck++;
149
                                } else {
150
                                        printf( "ERROR: Malformed packet list" );
151
                                        exit(-1);
152
                                }
153
                        }
154
                        nt_empty_cleared_packets_list();
155
                } else {
156
                        while( (trace_packet != NULL) && (trace_packet->cycle == nt_cycle) ) {
157
                                // Place in appropriate queue
158
                                queue_node_t* new_node = (queue_node_t*) nt_checked_malloc( sizeof(queue_node_t) );
159
                                new_node->packet = trace_packet;
160
                                new_node->cycle = (trace_packet->cycle > nt_cycle) ? trace_packet->cycle : nt_cycle;
161 54 alirezamon
                                pronoc_src_id=traffic_model_mapping[trace_packet->src];
162 48 alirezamon
                                if( ignore_dependencies || nt_dependencies_cleared( trace_packet ) ) {
163
                                        // Add to inject queue
164 54 alirezamon
                                        queue_push( inject[pronoc_src_id], new_node, new_node->cycle );
165 48 alirezamon
                                        nt_total_rd_pck++;
166
                                } else {
167
                                        // Add to waiting queue
168 54 alirezamon
                                        queue_push( waiting[pronoc_src_id], new_node, new_node->cycle );
169 48 alirezamon
                                        nt_total_rd_pck++;
170
                                }
171
                                // Get another packet from trace
172
                                trace_packet = nt_read_packet();
173
                        }
174
                        if( (trace_packet != NULL) && (trace_packet->cycle < nt_cycle) ) {
175
                                // Error check: Crash and burn
176
                                printf( "ERROR: Invalid trace_packet cycle time: %llu, current cycle: %llu\n", trace_packet->cycle, nt_cycle );
177
                                exit(-1);
178
                        }
179
                }
180
        }else {//if ~end_sim_pck_num
181
                read_done=1;
182
        }
183
 
184
        if(eval_num<netrace_speed_up-1) {
185
                nt_cycle++;
186
                nt_packets_left=1;
187
                return;
188
        }
189
 
190
 
191
        // Inject where possible (max one per node)
192 54 alirezamon
        //header->num_nodes;
193
        for( i = 0; i < NE; ++i ) {
194 48 alirezamon
                nt_packets_left |= !queue_empty( inject[i] );
195
                //TODO define sent vc policy
196
                int sent_vc = 0;
197
 
198 54 alirezamon
                if(pck_inj[i]->pck_injct_in_pck_wr){
199 48 alirezamon
                        //the wr_pck should be asserted only for single cycle
200 54 alirezamon
                        pck_inj[i]->pck_injct_in_pck_wr            = 0;
201 48 alirezamon
                        continue;
202
                }
203
 
204 54 alirezamon
                pck_inj[i]->pck_injct_in_pck_wr            = 0;
205
                if((pck_inj[i]->pck_injct_out_ready & (0x1<<sent_vc)) == 0){
206 48 alirezamon
                        //This pck injector is not ready yet
207
                        continue;
208
                }
209
 
210
                queue_node_t* temp_node = (queue_node_t*) queue_peek_front( inject[i] );
211
                if( temp_node != NULL ) {
212
                        packet = temp_node->packet;
213
                        if( (packet != NULL) && (temp_node->cycle <= nt_cycle) ) {
214
 
215
                                if(verbosity>1) {
216
                                        printf( "Inject: %llu ", nt_cycle );
217
                                        nt_print_packet( packet );
218
                                }
219
                                temp_node = (queue_node_t*) queue_pop_front( inject[i] );
220
                                temp_node->cycle = nt_cycle;//injection time
221 54 alirezamon
                                pronoc_dst_id =  traffic_model_mapping[packet->dst];
222
                                queue_push( traverse[pronoc_dst_id ], temp_node, temp_node->cycle );
223 48 alirezamon
                                long int ptr_addr = reinterpret_cast<long int> (temp_node);
224
                                int flit_num = (nt_get_packet_size(packet)* 8) / Fpay;
225 54 alirezamon
                                if(flit_num< pck_inj[i]->min_pck_size) flit_num = pck_inj[i]->min_pck_size;
226
 
227 48 alirezamon
                                if(IS_SELF_LOOP_EN ==0){
228 54 alirezamon
                                        if(pronoc_dst_id == i ){
229 48 alirezamon
                                                 fprintf(stderr,"ERROR: ProNoC is not configured with self-loop enable and Netrace aims to inject\n a "
230
                                                                 "packet with identical source and destination address. Enable the SELF_LOOP parameter\n"
231
                                                                 "in ProNoC and rebuild the simulation model\n");
232
                                                 exit(1);
233
                                        }
234
                                }
235
                                unsigned int sent_class =0;
236 54 alirezamon
                                pck_inj[i]->pck_injct_in_data         = ptr_addr;
237
                                pck_inj[i]->pck_injct_in_size         = flit_num;
238
                                pck_inj[i]->pck_injct_in_endp_addr    = endp_addr_encoder(pronoc_dst_id);
239
                                pck_inj[i]->pck_injct_in_class_num    = sent_class;
240
                                pck_inj[i]->pck_injct_in_init_weight  = 1;
241
                                pck_inj[i]->pck_injct_in_vc           = 0x1<<sent_vc;
242
                                pck_inj[i]->pck_injct_in_pck_wr            = 1;
243 48 alirezamon
                                total_sent_pck_num++;
244
 
245
                                #if (C>1)
246 54 alirezamon
                                        sent_stat[i][sent_class].pck_num ++;
247
                                        sent_stat[i][sent_class].flit_num +=flit_num;
248 48 alirezamon
                                #else
249 54 alirezamon
                                        sent_stat[i].pck_num ++;
250
                                        sent_stat[i].flit_num +=flit_num;
251 48 alirezamon
                                #endif
252
                        }
253
                }
254
        }
255
 
256
/*
257
        // Step all network components, Eject where possible
258
                for( i = 0; i < header->num_nodes; ++i ) {
259
                        nt_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 <= nt_cycle) ) {
264
                                        printf( "Eject: %llu ", nt_cycle );
265
                                        nt_print_packet( packet );
266
                                        nt_clear_dependencies_free_packet( packet );
267
                                        temp_node = (queue_node_t*) queue_pop_front( traverse[i] );
268
                                        free( temp_node );
269
                                }
270
                        }
271
                }
272
*/
273
 
274
        // Step all network components, Eject where possible
275
        for( i = 0; i < NE; ++i ) {
276
                nt_packets_left |= !queue_empty( traverse[i] );
277
                //check which pck injector got a packet
278
                if(pck_inj[i]->pck_injct_out_pck_wr==0) continue;
279
                //we have got a packet
280
                //printf( "data=%lx\n",pck_inj[i]->pck_injct_out_data);
281
 
282
                queue_node_t* temp_node = (queue_node_t*)  pck_inj[i]->pck_injct_out_data;
283
                if( temp_node != NULL ) {
284
                        packet = temp_node->packet;
285
                        if( packet != NULL){
286
                                if(verbosity>1) {
287
                                        printf( "Eject: %llu ", nt_cycle );
288
                                        nt_print_packet( packet );
289
                                }
290
                                // remove from traverse
291
                                nt_clear_dependencies_free_packet( packet );
292
                                queue_remove( traverse[i], temp_node );
293
                                unsigned long long int    clk_num_h2t= (nt_cycle - temp_node->cycle)/netrace_speed_up;
294
                                unsigned int    clk_num_h2h= clk_num_h2t - pck_inj[i]->pck_injct_out_h2t_delay;
295
                                /*
296
                                printf("clk_num_h2t (%llu) h2t_delay(%u)\n", clk_num_h2t , pck_inj[i]->pck_injct_out_h2t_delay);
297
                                if(clk_num_h2t < pck_inj[i]->pck_injct_out_h2t_delay){
298
                                        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);
299
                                        exit(1);
300
                                }
301
                                */
302 54 alirezamon
 
303
                                pronoc_src_id=traffic_model_mapping[packet->src];
304 48 alirezamon
                                update_statistic_at_ejection (
305
                                        i,//    core_num
306
                                        clk_num_h2h, // clk_num_h2h,
307
                                        (unsigned int) clk_num_h2t, // clk_num_h2t,
308
                                        pck_inj[i]->pck_injct_out_distance, //    distance,
309
                                        pck_inj[i]->pck_injct_out_class_num,//          class_num,
310 54 alirezamon
                                        pronoc_src_id,//                unsigned int    src
311
                                        pck_inj[i]->pck_injct_out_size
312 48 alirezamon
                                );
313 54 alirezamon
 
314 48 alirezamon
                                free( temp_node );
315
 
316
                        }
317
                }
318
        }
319
                // Check for cleared dependences... or not
320
                if( !reader_throttling ) {
321 54 alirezamon
                for( i = 0; i < NE; ++i ) {
322 48 alirezamon
                        nt_packets_left |= !queue_empty( waiting[i] );
323
                        node_t* temp = waiting[i]->head;
324
                        while( temp != NULL ) {
325
                                queue_node_t* temp_node = (queue_node_t*) temp->elem;
326
                                packet = temp_node->packet;
327
                                temp = temp->next;
328
                                if( nt_dependencies_cleared( packet ) ) {
329
                                        // remove from waiting
330
                                        queue_remove( waiting[i], temp_node );
331
                                        // add to inject
332
                                        queue_node_t* new_node = (queue_node_t*) nt_checked_malloc( sizeof(queue_node_t) );
333
                                        new_node->packet = packet;
334
                                        new_node->cycle = nt_cycle + L2_LATENCY;
335
                                        queue_push( inject[i], new_node, new_node->cycle );
336
                                        free( temp_node );
337
                                }
338
                        }
339
                }
340
        }
341
        nt_cycle++;
342
}
343
 
344
 
345
void netrace_posedge_event(){
346
        unsigned int i;
347
        clk = 1;       // Toggle clock
348 54 alirezamon
        update_all_router_stat();
349 48 alirezamon
        for(i=0;i<netrace_speed_up; i++)  netrace_eval(i);
350 54 alirezamon
        //connect_clk_reset_start_all();
351 48 alirezamon
        sim_eval_all();
352
        //print total sent packet each 1024 clock cycles
353
        if(verbosity==1) if(nt_cycle&0x3FF) printf("\rTotal sent packet: %9d", total_sent_pck_num);
354
}
355
 
356
 
357 54 alirezamon
void netrace_negedge_event( ){
358 48 alirezamon
        int i;
359
        clk = 0;
360
        topology_connect_all_nodes ();
361 54 alirezamon
        //connect_clk_reset_start_all();
362 48 alirezamon
        sim_eval_all();
363
}
364
 
365
 
366
 
367
 
368
void netrace_final_report(){
369
        int i;
370
        unsigned int worst_sent=0, worst_rsv=0;
371
        unsigned long long int total_clock = (nt_cycle-nt_start_cycle);
372
        unsigned long long int pronoc_total_clock = total_clock/netrace_speed_up;
373
 
374
        if(verbosity==1)        printf("\e[?25h");//To re-enable the cursor:
375
        printf("\nNetrace simulation results-------------------\n"
376
                        "\tNetrace end clock cycles: %llu\n"
377
                        "\tNetrace duration clock cycles: %llu\n"
378
                        "\tProNoC  duration clock cycles: %llu\n"
379 54 alirezamon
                        "\tSimulation clock cycles: %llu\n"
380
        ,nt_cycle,total_clock,pronoc_total_clock,pronoc_total_clock);
381 48 alirezamon
 
382
        print_statistic_new (pronoc_total_clock);
383 54 alirezamon
        printf("Netrace simulation results-------------------\n");
384 48 alirezamon
}
385
 
386
 
387
 
388
#endif

powered by: WebSVN 2.1.0

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