#ifndef NETRACE_LIB_H
|
#ifndef NETRACE_LIB_H
|
#define NETRACE_LIB_H
|
#define NETRACE_LIB_H
|
|
|
|
|
#include "netrace-1.0/queue.h"
|
#include "netrace-1.0/queue.h"
|
#include "netrace-1.0/netrace.h"
|
#include "netrace-1.0/netrace.h"
|
#include "netrace-1.0/queue.c"
|
#include "netrace-1.0/queue.c"
|
#include "netrace-1.0/netrace.c"
|
#include "netrace-1.0/netrace.c"
|
|
|
|
|
extern int reset,clk;
|
extern int reset,clk;
|
extern char simulation_done;
|
extern char simulation_done;
|
extern void connect_clk_reset_start_all(void);
|
extern void connect_clk_reset_start_all(void);
|
extern void sim_eval_all (void);
|
extern void sim_eval_all (void);
|
extern void topology_connect_all_nodes (void);
|
extern void topology_connect_all_nodes (void);
|
extern Vpck_inj *pck_inj[NE];
|
extern Vpck_inj *pck_inj[NE];
|
extern unsigned int count_en;
|
extern unsigned int count_en;
|
extern unsigned long int main_time; // Current simulation time
|
extern unsigned long int main_time; // Current simulation time
|
extern int verbosity;
|
extern int verbosity;
|
|
|
|
|
|
|
|
|
#define L2_LATENCY 8
|
#define L2_LATENCY 8
|
|
|
|
|
int ignore_dependencies = 0;
|
int ignore_dependencies = 0;
|
int start_region = 0;
|
int start_region = 0;
|
int reader_throttling = 0;
|
int reader_throttling = 0;
|
unsigned long long int nt_cycle=0;
|
unsigned long long int nt_cycle=0;
|
unsigned long long int nt_start_cycle=0;
|
unsigned long long int nt_start_cycle=0;
|
|
|
nt_header_t* header;
|
nt_header_t* header;
|
queue_t** waiting;
|
queue_t** waiting;
|
queue_t** inject;
|
queue_t** inject;
|
queue_t** traverse;
|
queue_t** traverse;
|
nt_packet_t* trace_packet = NULL;
|
nt_packet_t* trace_packet = NULL;
|
nt_packet_t* packet = NULL;
|
nt_packet_t* packet = NULL;
|
int nt_packets_left = 0;
|
int nt_packets_left = 0;
|
|
|
|
|
int netrace_to_pronoc_map [64];
|
int * traffic_model_mapping;
|
int pronoc_to_netrace_map [NE];
|
int pronoc_to_netrace_map [NE];
|
int pck_injct_in_pck_wr[NE];
|
int pck_injct_in_pck_wr[NE];
|
|
|
unsigned int nt_total_rd_pck=0; // from trace file
|
unsigned int nt_total_rd_pck=0; // from trace file
|
unsigned int read_done=0;
|
unsigned int read_done=0;
|
|
|
typedef struct queue_node queue_node_t;
|
typedef struct queue_node queue_node_t;
|
struct queue_node {
|
struct queue_node {
|
nt_packet_t* packet;
|
nt_packet_t* packet;
|
unsigned long long int cycle;
|
unsigned long long int cycle;
|
};
|
};
|
|
|
|
|
unsigned long long int calc_packet_timing( nt_packet_t* packet ) {
|
unsigned long long int calc_packet_timing( nt_packet_t* packet ) {
|
|
|
int n_hops = abs( packet->src - packet->dst );
|
int n_hops = abs( packet->src - packet->dst );
|
if( n_hops <= 0 ) n_hops = 1;
|
if( n_hops <= 0 ) n_hops = 1;
|
return 3*n_hops;
|
return 3*n_hops;
|
}
|
}
|
|
|
|
|
|
|
void netrace_init( char * tracefile){
|
void netrace_init( char * tracefile){
|
int i=0;
|
int i=0;
|
nt_open_trfile( tracefile );
|
nt_open_trfile( tracefile );
|
if( ignore_dependencies ) {
|
if( ignore_dependencies ) {
|
nt_disable_dependencies();
|
nt_disable_dependencies();
|
printf("\tDependencies is turned off in tracking cleared packets list\n");
|
printf("\tDependencies is turned off in tracking cleared packets list\n");
|
}
|
}
|
if( reader_throttling ) {
|
if( reader_throttling ) {
|
printf("\treader throttling is enabled\n");
|
printf("\treader throttling is enabled\n");
|
}
|
}
|
nt_print_trheader();
|
nt_print_trheader();
|
header = nt_get_trheader();
|
header = nt_get_trheader();
|
nt_seek_region( &header->regions[start_region] );
|
nt_seek_region( &header->regions[start_region] );
|
for(i = 0; i < start_region; i++ ) {
|
for(i = 0; i < start_region; i++ ) {
|
nt_cycle += header->regions[i].num_cycles;
|
nt_cycle += header->regions[i].num_cycles;
|
}
|
}
|
if(nt_cycle){
|
if(nt_cycle){
|
printf("\tThe simulation start at region %u and %llu cycle\n",start_region,nt_cycle);
|
printf("\tThe simulation start at region %u and %llu cycle\n",start_region,nt_cycle);
|
nt_start_cycle=nt_cycle;
|
nt_start_cycle=nt_cycle;
|
}
|
}
|
|
|
waiting = (queue_t**) malloc( header->num_nodes * sizeof(queue_t*) );
|
waiting = (queue_t**) malloc( NE * sizeof(queue_t*) );
|
inject = (queue_t**) malloc( header->num_nodes * sizeof(queue_t*) );
|
inject = (queue_t**) malloc( NE * sizeof(queue_t*) );
|
traverse = (queue_t**) malloc( header->num_nodes * sizeof(queue_t*) );
|
traverse = (queue_t**) malloc( NE * sizeof(queue_t*) );
|
if( (waiting == NULL) || (inject == NULL) || (traverse == NULL) ) {
|
if( (waiting == NULL) || (inject == NULL) || (traverse == NULL) ) {
|
printf( "ERROR: malloc fail queues\n" );
|
printf( "ERROR: malloc fail queues\n" );
|
exit(0);
|
exit(0);
|
}
|
}
|
for( i = 0; i < header->num_nodes; ++i ) {
|
|
|
for( i = 0; i < NE; ++i ) {
|
waiting[i] = queue_new();
|
waiting[i] = queue_new();
|
inject[i] = queue_new();
|
inject[i] = queue_new();
|
traverse[i] = queue_new();
|
traverse[i] = queue_new();
|
}
|
}
|
|
|
|
|
if( !reader_throttling ) {
|
if( !reader_throttling ) {
|
trace_packet = nt_read_packet();
|
trace_packet = nt_read_packet();
|
} else if( !ignore_dependencies ) {
|
} else if( !ignore_dependencies ) {
|
nt_init_self_throttling();
|
nt_init_self_throttling();
|
}
|
}
|
|
|
MIN_PACKET_SIZE = (8*8)/Fpay;
|
MIN_PACKET_SIZE = (8*8)/Fpay;
|
MAX_PACKET_SIZE = (64*8)/Fpay;
|
MAX_PACKET_SIZE = (64*8)/Fpay;
|
AVG_PACKET_SIZE=(MIN_PACKET_SIZE+MAX_PACKET_SIZE)/2;// average packet size
|
AVG_PACKET_SIZE=(MIN_PACKET_SIZE+MAX_PACKET_SIZE)/2;// average packet size
|
int p=(MAX_PACKET_SIZE-MIN_PACKET_SIZE)+1;
|
int p=(MAX_PACKET_SIZE-MIN_PACKET_SIZE)+1;
|
rsv_size_array = (unsigned int*) calloc ( p , sizeof(int));
|
rsv_size_array = (unsigned int*) calloc ( p , sizeof(int));
|
if (rsv_size_array==NULL){
|
if (rsv_size_array==NULL){
|
fprintf(stderr,"ERROR: cannot allocate (%d x int) memory for rsv_size_array. \n",p);
|
fprintf(stderr,"ERROR: cannot allocate (%d x int) memory for rsv_size_array. \n",p);
|
exit(1);
|
exit(1);
|
}
|
}
|
|
|
|
|
if(verbosity==1) printf("\e[?25l"); //To hide the cursor:
|
if(verbosity==1) printf("\e[?25l"); //To hide the cursor:
|
|
|
}
|
}
|
|
|
|
|
|
|
|
|
void netrace_eval(unsigned int eval_num){
|
void netrace_eval(unsigned int eval_num){
|
int i;
|
int i;
|
|
unsigned int pronoc_src_id,pronoc_dst_id;
|
|
|
if((reset==1) || (count_en==0)) return;
|
if((reset==1) || (count_en==0)) return;
|
|
|
if((( nt_cycle > header->num_cycles) || (read_done==1 )) && nt_packets_left==0 ) simulation_done=1;
|
if((( nt_cycle > header->num_cycles) || (read_done==1 )) && nt_packets_left==0 ) simulation_done=1;
|
|
|
// Reset packets remaining check
|
// Reset packets remaining check
|
nt_packets_left = 0;
|
nt_packets_left = 0;
|
|
|
// Get packets for this cycle
|
// Get packets for this cycle
|
if((end_sim_pck_num == 0 ) || (end_sim_pck_num > nt_total_rd_pck )){
|
if((end_sim_pck_num == 0 ) || (end_sim_pck_num > nt_total_rd_pck )){
|
if( reader_throttling ) {
|
if( reader_throttling ) {
|
nt_packet_list_t* list;
|
nt_packet_list_t* list;
|
for( list = nt_get_cleared_packets_list(); list != NULL; list = list->next ) {
|
for( list = nt_get_cleared_packets_list(); list != NULL; list = list->next ) {
|
if( list->node_packet != NULL ) {
|
if( list->node_packet != NULL ) {
|
trace_packet = list->node_packet;
|
trace_packet = list->node_packet;
|
queue_node_t* new_node = (queue_node_t*) nt_checked_malloc( sizeof(queue_node_t) );
|
queue_node_t* new_node = (queue_node_t*) nt_checked_malloc( sizeof(queue_node_t) );
|
new_node->packet = trace_packet;
|
new_node->packet = trace_packet;
|
new_node->cycle = (trace_packet->cycle > nt_cycle) ? trace_packet->cycle : nt_cycle;
|
new_node->cycle = (trace_packet->cycle > nt_cycle) ? trace_packet->cycle : nt_cycle;
|
queue_push( inject[trace_packet->src], new_node, new_node->cycle );
|
pronoc_src_id=traffic_model_mapping[trace_packet->src];
|
|
queue_push( inject[pronoc_src_id], new_node, new_node->cycle );
|
nt_total_rd_pck++;
|
nt_total_rd_pck++;
|
} else {
|
} else {
|
printf( "ERROR: Malformed packet list" );
|
printf( "ERROR: Malformed packet list" );
|
exit(-1);
|
exit(-1);
|
}
|
}
|
}
|
}
|
nt_empty_cleared_packets_list();
|
nt_empty_cleared_packets_list();
|
} else {
|
} else {
|
while( (trace_packet != NULL) && (trace_packet->cycle == nt_cycle) ) {
|
while( (trace_packet != NULL) && (trace_packet->cycle == nt_cycle) ) {
|
// Place in appropriate queue
|
// Place in appropriate queue
|
queue_node_t* new_node = (queue_node_t*) nt_checked_malloc( sizeof(queue_node_t) );
|
queue_node_t* new_node = (queue_node_t*) nt_checked_malloc( sizeof(queue_node_t) );
|
new_node->packet = trace_packet;
|
new_node->packet = trace_packet;
|
new_node->cycle = (trace_packet->cycle > nt_cycle) ? trace_packet->cycle : nt_cycle;
|
new_node->cycle = (trace_packet->cycle > nt_cycle) ? trace_packet->cycle : nt_cycle;
|
|
pronoc_src_id=traffic_model_mapping[trace_packet->src];
|
if( ignore_dependencies || nt_dependencies_cleared( trace_packet ) ) {
|
if( ignore_dependencies || nt_dependencies_cleared( trace_packet ) ) {
|
// Add to inject queue
|
// Add to inject queue
|
queue_push( inject[trace_packet->src], new_node, new_node->cycle );
|
queue_push( inject[pronoc_src_id], new_node, new_node->cycle );
|
nt_total_rd_pck++;
|
nt_total_rd_pck++;
|
} else {
|
} else {
|
// Add to waiting queue
|
// Add to waiting queue
|
queue_push( waiting[trace_packet->src], new_node, new_node->cycle );
|
queue_push( waiting[pronoc_src_id], new_node, new_node->cycle );
|
nt_total_rd_pck++;
|
nt_total_rd_pck++;
|
}
|
}
|
// Get another packet from trace
|
// Get another packet from trace
|
trace_packet = nt_read_packet();
|
trace_packet = nt_read_packet();
|
}
|
}
|
if( (trace_packet != NULL) && (trace_packet->cycle < nt_cycle) ) {
|
if( (trace_packet != NULL) && (trace_packet->cycle < nt_cycle) ) {
|
// Error check: Crash and burn
|
// Error check: Crash and burn
|
printf( "ERROR: Invalid trace_packet cycle time: %llu, current cycle: %llu\n", trace_packet->cycle, nt_cycle );
|
printf( "ERROR: Invalid trace_packet cycle time: %llu, current cycle: %llu\n", trace_packet->cycle, nt_cycle );
|
exit(-1);
|
exit(-1);
|
}
|
}
|
}
|
}
|
}else {//if ~end_sim_pck_num
|
}else {//if ~end_sim_pck_num
|
read_done=1;
|
read_done=1;
|
}
|
}
|
|
|
if(eval_num<netrace_speed_up-1) {
|
if(eval_num<netrace_speed_up-1) {
|
nt_cycle++;
|
nt_cycle++;
|
nt_packets_left=1;
|
nt_packets_left=1;
|
return;
|
return;
|
}
|
}
|
|
|
|
|
// Inject where possible (max one per node)
|
// Inject where possible (max one per node)
|
for( i = 0; i < header->num_nodes; ++i ) {
|
//header->num_nodes;
|
|
for( i = 0; i < NE; ++i ) {
|
nt_packets_left |= !queue_empty( inject[i] );
|
nt_packets_left |= !queue_empty( inject[i] );
|
//TODO define RRA if multiple netrace sources are mapped to one node. only one can sent packt at each cycle
|
|
int pronoc_src = netrace_to_pronoc_map[i];
|
|
//TODO define sent vc policy
|
//TODO define sent vc policy
|
int sent_vc = 0;
|
int sent_vc = 0;
|
|
|
if(pck_inj[pronoc_src]->pck_injct_in_pck_wr){
|
if(pck_inj[i]->pck_injct_in_pck_wr){
|
//the wr_pck should be asserted only for single cycle
|
//the wr_pck should be asserted only for single cycle
|
pck_inj[pronoc_src]->pck_injct_in_pck_wr = 0;
|
pck_inj[i]->pck_injct_in_pck_wr = 0;
|
continue;
|
continue;
|
}
|
}
|
|
|
pck_inj[pronoc_src]->pck_injct_in_pck_wr = 0;
|
pck_inj[i]->pck_injct_in_pck_wr = 0;
|
if((pck_inj[pronoc_src]->pck_injct_out_ready & (0x1<<sent_vc)) == 0){
|
if((pck_inj[i]->pck_injct_out_ready & (0x1<<sent_vc)) == 0){
|
//This pck injector is not ready yet
|
//This pck injector is not ready yet
|
continue;
|
continue;
|
}
|
}
|
|
|
queue_node_t* temp_node = (queue_node_t*) queue_peek_front( inject[i] );
|
queue_node_t* temp_node = (queue_node_t*) queue_peek_front( inject[i] );
|
if( temp_node != NULL ) {
|
if( temp_node != NULL ) {
|
packet = temp_node->packet;
|
packet = temp_node->packet;
|
if( (packet != NULL) && (temp_node->cycle <= nt_cycle) ) {
|
if( (packet != NULL) && (temp_node->cycle <= nt_cycle) ) {
|
|
|
if(verbosity>1) {
|
if(verbosity>1) {
|
printf( "Inject: %llu ", nt_cycle );
|
printf( "Inject: %llu ", nt_cycle );
|
nt_print_packet( packet );
|
nt_print_packet( packet );
|
}
|
}
|
temp_node = (queue_node_t*) queue_pop_front( inject[i] );
|
temp_node = (queue_node_t*) queue_pop_front( inject[i] );
|
temp_node->cycle = nt_cycle;//injection time
|
temp_node->cycle = nt_cycle;//injection time
|
queue_push( traverse[packet->dst], temp_node, temp_node->cycle );
|
pronoc_dst_id = traffic_model_mapping[packet->dst];
|
|
queue_push( traverse[pronoc_dst_id ], temp_node, temp_node->cycle );
|
long int ptr_addr = reinterpret_cast<long int> (temp_node);
|
long int ptr_addr = reinterpret_cast<long int> (temp_node);
|
int flit_num = (nt_get_packet_size(packet)* 8) / Fpay;
|
int flit_num = (nt_get_packet_size(packet)* 8) / Fpay;
|
if(flit_num< pck_inj[pronoc_src]->min_pck_size) flit_num = pck_inj[pronoc_src]->min_pck_size;
|
if(flit_num< pck_inj[i]->min_pck_size) flit_num = pck_inj[i]->min_pck_size;
|
int pronoc_dst = netrace_to_pronoc_map[packet->dst];
|
|
if(IS_SELF_LOOP_EN ==0){
|
if(IS_SELF_LOOP_EN ==0){
|
if(packet->dst == pronoc_src ){
|
if(pronoc_dst_id == i ){
|
fprintf(stderr,"ERROR: ProNoC is not configured with self-loop enable and Netrace aims to inject\n a "
|
fprintf(stderr,"ERROR: ProNoC is not configured with self-loop enable and Netrace aims to inject\n a "
|
"packet with identical source and destination address. Enable the SELF_LOOP parameter\n"
|
"packet with identical source and destination address. Enable the SELF_LOOP parameter\n"
|
"in ProNoC and rebuild the simulation model\n");
|
"in ProNoC and rebuild the simulation model\n");
|
exit(1);
|
exit(1);
|
}
|
}
|
}
|
}
|
unsigned int sent_class =0;
|
unsigned int sent_class =0;
|
pck_inj[pronoc_src]->pck_injct_in_data = ptr_addr;
|
pck_inj[i]->pck_injct_in_data = ptr_addr;
|
pck_inj[pronoc_src]->pck_injct_in_size = flit_num;
|
pck_inj[i]->pck_injct_in_size = flit_num;
|
pck_inj[pronoc_src]->pck_injct_in_endp_addr = endp_addr_encoder(pronoc_dst);
|
pck_inj[i]->pck_injct_in_endp_addr = endp_addr_encoder(pronoc_dst_id);
|
pck_inj[pronoc_src]->pck_injct_in_class_num = sent_class;
|
pck_inj[i]->pck_injct_in_class_num = sent_class;
|
pck_inj[pronoc_src]->pck_injct_in_init_weight = 1;
|
pck_inj[i]->pck_injct_in_init_weight = 1;
|
pck_inj[pronoc_src]->pck_injct_in_vc = 0x1<<sent_vc;
|
pck_inj[i]->pck_injct_in_vc = 0x1<<sent_vc;
|
pck_inj[pronoc_src]->pck_injct_in_pck_wr = 1;
|
pck_inj[i]->pck_injct_in_pck_wr = 1;
|
total_sent_pck_num++;
|
total_sent_pck_num++;
|
|
|
#if (C>1)
|
#if (C>1)
|
sent_stat[pronoc_src][sent_class].pck_num ++;
|
sent_stat[i][sent_class].pck_num ++;
|
sent_stat[pronoc_src][sent_class].flit_num +=flit_num;
|
sent_stat[i][sent_class].flit_num +=flit_num;
|
#else
|
#else
|
sent_stat[pronoc_src].pck_num ++;
|
sent_stat[i].pck_num ++;
|
sent_stat[pronoc_src].flit_num +=flit_num;
|
sent_stat[i].flit_num +=flit_num;
|
#endif
|
#endif
|
}
|
}
|
}
|
}
|
}
|
}
|
|
|
/*
|
/*
|
// Step all network components, Eject where possible
|
// Step all network components, Eject where possible
|
for( i = 0; i < header->num_nodes; ++i ) {
|
for( i = 0; i < header->num_nodes; ++i ) {
|
nt_packets_left |= !queue_empty( traverse[i] );
|
nt_packets_left |= !queue_empty( traverse[i] );
|
queue_node_t* temp_node = (queue_node_t*) queue_peek_front( traverse[i] );
|
queue_node_t* temp_node = (queue_node_t*) queue_peek_front( traverse[i] );
|
if( temp_node != NULL ) {
|
if( temp_node != NULL ) {
|
packet = temp_node->packet;
|
packet = temp_node->packet;
|
if( (packet != NULL) && (temp_node->cycle <= nt_cycle) ) {
|
if( (packet != NULL) && (temp_node->cycle <= nt_cycle) ) {
|
printf( "Eject: %llu ", nt_cycle );
|
printf( "Eject: %llu ", nt_cycle );
|
nt_print_packet( packet );
|
nt_print_packet( packet );
|
nt_clear_dependencies_free_packet( packet );
|
nt_clear_dependencies_free_packet( packet );
|
temp_node = (queue_node_t*) queue_pop_front( traverse[i] );
|
temp_node = (queue_node_t*) queue_pop_front( traverse[i] );
|
free( temp_node );
|
free( temp_node );
|
}
|
}
|
}
|
}
|
}
|
}
|
*/
|
*/
|
|
|
// Step all network components, Eject where possible
|
// Step all network components, Eject where possible
|
for( i = 0; i < NE; ++i ) {
|
for( i = 0; i < NE; ++i ) {
|
nt_packets_left |= !queue_empty( traverse[i] );
|
nt_packets_left |= !queue_empty( traverse[i] );
|
//check which pck injector got a packet
|
//check which pck injector got a packet
|
if(pck_inj[i]->pck_injct_out_pck_wr==0) continue;
|
if(pck_inj[i]->pck_injct_out_pck_wr==0) continue;
|
//we have got a packet
|
//we have got a packet
|
//printf( "data=%lx\n",pck_inj[i]->pck_injct_out_data);
|
//printf( "data=%lx\n",pck_inj[i]->pck_injct_out_data);
|
|
|
queue_node_t* temp_node = (queue_node_t*) pck_inj[i]->pck_injct_out_data;
|
queue_node_t* temp_node = (queue_node_t*) pck_inj[i]->pck_injct_out_data;
|
if( temp_node != NULL ) {
|
if( temp_node != NULL ) {
|
packet = temp_node->packet;
|
packet = temp_node->packet;
|
if( packet != NULL){
|
if( packet != NULL){
|
if(verbosity>1) {
|
if(verbosity>1) {
|
printf( "Eject: %llu ", nt_cycle );
|
printf( "Eject: %llu ", nt_cycle );
|
nt_print_packet( packet );
|
nt_print_packet( packet );
|
}
|
}
|
// remove from traverse
|
// remove from traverse
|
nt_clear_dependencies_free_packet( packet );
|
nt_clear_dependencies_free_packet( packet );
|
queue_remove( traverse[i], temp_node );
|
queue_remove( traverse[i], temp_node );
|
unsigned long long int clk_num_h2t= (nt_cycle - temp_node->cycle)/netrace_speed_up;
|
unsigned long long int clk_num_h2t= (nt_cycle - temp_node->cycle)/netrace_speed_up;
|
unsigned int clk_num_h2h= clk_num_h2t - pck_inj[i]->pck_injct_out_h2t_delay;
|
unsigned int clk_num_h2h= clk_num_h2t - pck_inj[i]->pck_injct_out_h2t_delay;
|
/*
|
/*
|
printf("clk_num_h2t (%llu) h2t_delay(%u)\n", clk_num_h2t , pck_inj[i]->pck_injct_out_h2t_delay);
|
printf("clk_num_h2t (%llu) h2t_delay(%u)\n", clk_num_h2t , pck_inj[i]->pck_injct_out_h2t_delay);
|
if(clk_num_h2t < pck_inj[i]->pck_injct_out_h2t_delay){
|
if(clk_num_h2t < pck_inj[i]->pck_injct_out_h2t_delay){
|
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);
|
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);
|
exit(1);
|
exit(1);
|
}
|
}
|
*/
|
*/
|
|
|
|
pronoc_src_id=traffic_model_mapping[packet->src];
|
update_statistic_at_ejection (
|
update_statistic_at_ejection (
|
i,// core_num
|
i,// core_num
|
clk_num_h2h, // clk_num_h2h,
|
clk_num_h2h, // clk_num_h2h,
|
(unsigned int) clk_num_h2t, // clk_num_h2t,
|
(unsigned int) clk_num_h2t, // clk_num_h2t,
|
pck_inj[i]->pck_injct_out_distance, // distance,
|
pck_inj[i]->pck_injct_out_distance, // distance,
|
pck_inj[i]->pck_injct_out_class_num,// class_num,
|
pck_inj[i]->pck_injct_out_class_num,// class_num,
|
packet->src// unsigned int src
|
pronoc_src_id,// unsigned int src
|
|
pck_inj[i]->pck_injct_out_size
|
);
|
);
|
#if(C>1)
|
|
rsvd_stat[i][pck_inj[i]->pck_injct_out_class_num].flit_num +=pck_inj[i]->pck_injct_out_size;
|
|
#else
|
|
rsvd_stat[i].flit_num+=pck_inj[i]->pck_injct_out_size;
|
|
#endif
|
|
free( temp_node );
|
free( temp_node );
|
|
|
}
|
}
|
}
|
}
|
}
|
}
|
// Check for cleared dependences... or not
|
// Check for cleared dependences... or not
|
if( !reader_throttling ) {
|
if( !reader_throttling ) {
|
for( i = 0; i < header->num_nodes; ++i ) {
|
for( i = 0; i < NE; ++i ) {
|
nt_packets_left |= !queue_empty( waiting[i] );
|
nt_packets_left |= !queue_empty( waiting[i] );
|
node_t* temp = waiting[i]->head;
|
node_t* temp = waiting[i]->head;
|
while( temp != NULL ) {
|
while( temp != NULL ) {
|
queue_node_t* temp_node = (queue_node_t*) temp->elem;
|
queue_node_t* temp_node = (queue_node_t*) temp->elem;
|
packet = temp_node->packet;
|
packet = temp_node->packet;
|
temp = temp->next;
|
temp = temp->next;
|
if( nt_dependencies_cleared( packet ) ) {
|
if( nt_dependencies_cleared( packet ) ) {
|
// remove from waiting
|
// remove from waiting
|
queue_remove( waiting[i], temp_node );
|
queue_remove( waiting[i], temp_node );
|
// add to inject
|
// add to inject
|
queue_node_t* new_node = (queue_node_t*) nt_checked_malloc( sizeof(queue_node_t) );
|
queue_node_t* new_node = (queue_node_t*) nt_checked_malloc( sizeof(queue_node_t) );
|
new_node->packet = packet;
|
new_node->packet = packet;
|
new_node->cycle = nt_cycle + L2_LATENCY;
|
new_node->cycle = nt_cycle + L2_LATENCY;
|
queue_push( inject[i], new_node, new_node->cycle );
|
queue_push( inject[i], new_node, new_node->cycle );
|
free( temp_node );
|
free( temp_node );
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
nt_cycle++;
|
nt_cycle++;
|
}
|
}
|
|
|
|
|
void netrace_posedge_event(){
|
void netrace_posedge_event(){
|
unsigned int i;
|
unsigned int i;
|
clk = 1; // Toggle clock
|
clk = 1; // Toggle clock
|
|
update_all_router_stat();
|
for(i=0;i<netrace_speed_up; i++) netrace_eval(i);
|
for(i=0;i<netrace_speed_up; i++) netrace_eval(i);
|
connect_clk_reset_start_all();
|
//connect_clk_reset_start_all();
|
sim_eval_all();
|
sim_eval_all();
|
//print total sent packet each 1024 clock cycles
|
//print total sent packet each 1024 clock cycles
|
if(verbosity==1) if(nt_cycle&0x3FF) printf("\rTotal sent packet: %9d", total_sent_pck_num);
|
if(verbosity==1) if(nt_cycle&0x3FF) printf("\rTotal sent packet: %9d", total_sent_pck_num);
|
}
|
}
|
|
|
|
|
void netrace_clk_negedge_event( ){
|
void netrace_negedge_event( ){
|
int i;
|
int i;
|
clk = 0;
|
clk = 0;
|
topology_connect_all_nodes ();
|
topology_connect_all_nodes ();
|
connect_clk_reset_start_all();
|
//connect_clk_reset_start_all();
|
sim_eval_all();
|
sim_eval_all();
|
|
|
}
|
}
|
|
|
|
|
|
|
|
|
void netrace_final_report(){
|
void netrace_final_report(){
|
int i;
|
int i;
|
unsigned int worst_sent=0, worst_rsv=0;
|
unsigned int worst_sent=0, worst_rsv=0;
|
unsigned long long int total_clock = (nt_cycle-nt_start_cycle);
|
unsigned long long int total_clock = (nt_cycle-nt_start_cycle);
|
unsigned long long int pronoc_total_clock = total_clock/netrace_speed_up;
|
unsigned long long int pronoc_total_clock = total_clock/netrace_speed_up;
|
|
|
if(verbosity==1) printf("\e[?25h");//To re-enable the cursor:
|
if(verbosity==1) printf("\e[?25h");//To re-enable the cursor:
|
printf("\nNetrace simulation results-------------------\n"
|
printf("\nNetrace simulation results-------------------\n"
|
"\tNetrace end clock cycles: %llu\n"
|
"\tNetrace end clock cycles: %llu\n"
|
"\tNetrace duration clock cycles: %llu\n"
|
"\tNetrace duration clock cycles: %llu\n"
|
"\tProNoC duration clock cycles: %llu\n"
|
"\tProNoC duration clock cycles: %llu\n"
|
,nt_cycle,total_clock,pronoc_total_clock);
|
"\tSimulation clock cycles: %llu\n"
|
|
,nt_cycle,total_clock,pronoc_total_clock,pronoc_total_clock);
|
|
|
|
|
print_statistic_new (pronoc_total_clock);
|
print_statistic_new (pronoc_total_clock);
|
/*
|
printf("Netrace simulation results-------------------\n");
|
printf("\t total , %u , %u, %u, %u \n",total_sent_pck_num, total_rsv_pck_num,total_sent_flit_number,total_rsv_flit_number);
|
|
printf("\nper node\n");
|
|
for(i=0;i<NE;i++){
|
|
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]
|
|
sent_core_worst_delay[i], rsvd_core_worst_delay[i]
|
|
|
|
);
|
|
}
|
|
*/
|
|
}
|
}
|
|
|
|
|
|
|
#endif
|
#endif
|
|
|