int SIM_router_init(SIM_router_info_t *info, SIM_router_power_t *router_power, SIM_router_area_t *router_area) { u_int line_width; int share_buf, outdrv; /* PHASE 1: set parameters */ /* general parameters */ info->n_in = PARM(in_port); info->n_cache_in = PARM(cache_in_port);//0 in our case info->n_mc_in = PARM(mc_in_port);//0 in our case info->n_io_in = PARM(io_in_port);//0 in our case info->n_total_in = PARM(in_port) + PARM(cache_in_port) + PARM(mc_in_port) + PARM(io_in_port);//equal to in_port info->n_out = PARM(out_port); info->n_cache_out = PARM(cache_out_port);//0 here info->n_mc_out = PARM(mc_out_port);//0 here info->n_io_out = PARM(io_out_port);//0 here info->n_total_out = PARM(out_port) + PARM(cache_out_port) + PARM(mc_out_port) + PARM(io_out_port);//equal to out_port info->flit_width = FLITSIZE*8;//FLITSIZE is defined in defaults.h and can be specified in nirgam.config in bytes /* virtual channel parameters */ info->n_v_channel = MAX(PARM(v_channel), 1); info->n_v_class = MAX(PARM(v_class), 1); info->cache_class = MAX(PARM(cache_class), 1);//0 here info->mc_class = MAX(PARM(mc_class), 1); //0 here info->io_class = MAX(PARM(io_class), 1);//0 here /* shared buffer implies buffer has tags */ /* separate buffer & shared switch implies buffer has tri-state output driver*/ if (info->n_v_class * info->n_v_channel > 1) //no sharing in our case { info->in_share_buf = PARM(in_share_buf); info->out_share_buf = PARM(out_share_buf); info->in_share_switch = PARM(in_share_switch); info->out_share_switch = PARM(out_share_switch); } else { info->in_share_buf = 0; info->out_share_buf = 0; info->in_share_switch = 0; info->out_share_switch = 0; } /* crossbar */ info->crossbar_model = PARM(crossbar_model); info->degree = PARM(crsbar_degree); info->connect_type = PARM(connect_type); info->trans_type = PARM(trans_type); info->xb_in_seg = PARM(xb_in_seg); info->xb_out_seg = PARM(xb_out_seg); info->crossbar_in_len = PARM(crossbar_in_len); info->crossbar_out_len = PARM(crossbar_out_len); /* HACK HACK HACK */ info->exp_xb_model = PARM(exp_xb_model); info->exp_in_seg = PARM(exp_in_seg); info->exp_out_seg = PARM(exp_out_seg); /* input buffer */ info->in_buf = PARM(in_buf);//have i/p buffer or not, we have info->in_buffer_model = PARM(in_buffer_type);//can be SRAM or REGISTER if (info->in_buf) { outdrv = !info->in_share_buf && info->in_share_switch;//outdrv ?? //NUM_BUFS is buffer depth, the 2nd parameter specifies whether buffer is fifo or not(1 means it is fifo) //parameters: router address, isfifo, no. of read ports, no. of write ports, buffer depth, data width in bits, outdrv, buffer model(SRAM or REGISTER) SIM_array_init(&info->in_buf_info, 1, PARM(in_buf_rport), 1, NUM_BUFS, FLITSIZE*8, outdrv, info->in_buffer_model); //this function in SIM_array_l.cpp } //no need for nirgam config. if (PARM(cache_in_port)) { info->cache_in_buf = PARM(cache_in_buf); if (info->cache_in_buf) { if (PARM(cache_class) > 1) { share_buf = info->in_share_buf; outdrv = !share_buf && info->in_share_switch; } else { outdrv = share_buf = 0; } SIM_array_init(&info->cache_in_buf_info, 1, PARM(cache_in_buf_rport), 1, PARM(cache_in_buf_set), FLITSIZE*8, outdrv, SRAM); } } //no need for nirgam config. if (PARM(mc_in_port)) { info->mc_in_buf = PARM(mc_in_buf); if (info->mc_in_buf) { if (PARM(mc_class) > 1) { share_buf = info->in_share_buf; outdrv = !share_buf && info->in_share_switch; } else { outdrv = share_buf = 0; } SIM_array_init(&info->mc_in_buf_info, 1, PARM(mc_in_buf_rport), 1, PARM(mc_in_buf_set),FLITSIZE*8, outdrv, SRAM); } } //not needed if (PARM(io_in_port)) { info->io_in_buf = PARM(io_in_buf); if (info->io_in_buf) { if (PARM(io_class) > 1) { share_buf = info->in_share_buf; outdrv = !share_buf && info->in_share_switch; } else { outdrv = share_buf = 0; } SIM_array_init(&info->io_in_buf_info, 1, PARM(io_in_buf_rport), 1, PARM(io_in_buf_set), FLITSIZE*8, outdrv, SRAM); } } /* output buffer */ info->out_buf = PARM(out_buf); info->out_buffer_model = PARM(out_buffer_type); if (info->out_buf) { /* output buffer has no tri-state buffer anyway */ SIM_array_init(&info->out_buf_info, 1, 1, PARM(out_buf_wport), PARM(out_buf_set), FLITSIZE*8, 0, info->out_buffer_model); } //not needed /* central buffer */ info->central_buf = PARM(central_buf); if (info->central_buf) { info->pipe_depth = PARM(pipe_depth); /* central buffer is no FIFO */ SIM_array_init(&info->central_buf_info, 0, PARM(cbuf_rport), PARM(cbuf_wport), PARM(cbuf_set), PARM(cbuf_width) * FLITSIZE*8, 0, SRAM); /* dirty hack */ info->cbuf_ff_model = NEG_DFF; } /* switch allocator input port arbiter */ if (info->n_v_class * info->n_v_channel > 1) { if (info->sw_in_arb_model = PARM(sw_in_arb_model)) { if (PARM(sw_in_arb_model) == QUEUE_ARBITER) { SIM_array_init(&info->sw_in_arb_queue_info, 1, 1, 1, info->n_v_class*info->n_v_channel, SIM_logtwo(info->n_v_class*info->n_v_channel), 0, REGISTER); if (info->cache_class > 1) SIM_array_init(&info->cache_in_arb_queue_info, 1, 1, 1, info->cache_class, SIM_logtwo(info->cache_class), 0, REGISTER); if (info->mc_class > 1) SIM_array_init(&info->mc_in_arb_queue_info, 1, 1, 1, info->mc_class, SIM_logtwo(info->mc_class), 0, REGISTER); if (info->io_class > 1) SIM_array_init(&info->io_in_arb_queue_info, 1, 1, 1, info->io_class, SIM_logtwo(info->io_class), 0, REGISTER); info->sw_in_arb_ff_model = SIM_NO_MODEL; } else info->sw_in_arb_ff_model = PARM(sw_in_arb_ff_model); } else info->sw_in_arb_ff_model = SIM_NO_MODEL; } else { info->sw_in_arb_model = SIM_NO_MODEL; info->sw_in_arb_ff_model = SIM_NO_MODEL; } /* switch allocator output port arbiter */ if (info->n_total_in > 2) { info->sw_out_arb_model = PARM(sw_out_arb_model); if (info->sw_out_arb_model) { if (info->sw_out_arb_model == QUEUE_ARBITER) { line_width = SIM_logtwo(info->n_total_in - 1); SIM_array_init(&info->sw_out_arb_queue_info, 1, 1, 1, info->n_total_in - 1, line_width, 0, REGISTER); info->sw_out_arb_ff_model = SIM_NO_MODEL; } else { info->sw_out_arb_ff_model = PARM(sw_out_arb_ff_model); } } else { info->sw_out_arb_ff_model = SIM_NO_MODEL; } } else { info->sw_out_arb_model = SIM_NO_MODEL; info->sw_out_arb_ff_model = SIM_NO_MODEL; } /* virtual channel allocator type */ if (info->n_v_channel > 1) { info->vc_allocator_type = PARM(vc_allocator_type); } else info->vc_allocator_type = SIM_NO_MODEL; /* virtual channel allocator input port arbiter */ if ( info->n_v_channel > 1 && info->n_in > 1) { if (info->vc_in_arb_model = PARM(vc_in_arb_model)) { if (PARM(vc_in_arb_model) == QUEUE_ARBITER) { SIM_array_init(&info->vc_in_arb_queue_info, 1, 1, 1, info->n_v_channel, SIM_logtwo(info->n_v_channel), 0, REGISTER); info->vc_in_arb_ff_model = SIM_NO_MODEL; } else { info->vc_in_arb_ff_model = PARM(vc_in_arb_ff_model); } } else { info->vc_in_arb_ff_model = SIM_NO_MODEL; } } else { info->vc_in_arb_model = SIM_NO_MODEL; info->vc_in_arb_ff_model = SIM_NO_MODEL; } /* virtual channel allocator output port arbiter */ if (info->n_in > 1 && info->n_v_channel > 1) { info->vc_out_arb_model = PARM(vc_out_arb_model); if (info->vc_out_arb_model) { if (info->vc_out_arb_model == QUEUE_ARBITER) { line_width = SIM_logtwo((info->n_total_in - 1)*info->n_v_channel); SIM_array_init(&info->vc_out_arb_queue_info, 1, 1, 1, (info->n_total_in -1) * info->n_v_channel, line_width, 0, REGISTER); info->vc_out_arb_ff_model = SIM_NO_MODEL; } else { info->vc_out_arb_ff_model = PARM(vc_out_arb_ff_model); } } else { info->vc_out_arb_ff_model = SIM_NO_MODEL; } } else { info->vc_out_arb_model = SIM_NO_MODEL; info->vc_out_arb_ff_model = SIM_NO_MODEL; } /*virtual channel allocation vc selection model */ // for NIRGAM //total number of entries = Number of Vcs //total cell width =log2(num_vcs) bit //in nirgam, we have assumed a list of available VCs(no. of Vcs) . info->vc_select_buf_type = PARM(vc_select_buf_type); if (info->vc_allocator_type == VC_SELECT && info->n_v_channel > 1 && info->n_in > 1) { info->vc_select_buf_type = PARM(vc_select_buf_type); SIM_array_init(&info->vc_select_buf_info, 1, 1, 1, info->n_v_channel, SIM_logtwo(info->n_v_channel), 0, info->vc_select_buf_type); } else { info->vc_select_buf_type = SIM_NO_MODEL; } /* redundant fields */ if (info->in_buf) { if (info->in_share_buf) info->in_n_switch = info->in_buf_info.read_ports; else if (info->in_share_switch) info->in_n_switch = 1; else info->in_n_switch = info->n_v_class * info->n_v_channel; } else info->in_n_switch = 1; if (info->cache_in_buf) { if (info->in_share_buf) info->cache_n_switch = info->cache_in_buf_info.read_ports; else if (info->in_share_switch) info->cache_n_switch = 1; else info->cache_n_switch = info->cache_class; } else info->cache_n_switch = 1; if (info->mc_in_buf) { if (info->in_share_buf) info->mc_n_switch = info->mc_in_buf_info.read_ports; else if (info->in_share_switch) info->mc_n_switch = 1; else info->mc_n_switch = info->mc_class; } else info->mc_n_switch = 1; if (info->io_in_buf) { if (info->in_share_buf) info->io_n_switch = info->io_in_buf_info.read_ports; else if (info->in_share_switch) info->io_n_switch = 1; else info->io_n_switch = info->io_class; } else info->io_n_switch = 1; info->n_switch_in = info->n_in * info->in_n_switch + info->n_cache_in * info->cache_n_switch + info->n_mc_in * info->mc_n_switch + info->n_io_in * info->io_n_switch; /* no buffering for local output ports */ info->n_switch_out = info->n_cache_out + info->n_mc_out + info->n_io_out; if (info->out_buf) { if (info->out_share_buf) info->n_switch_out += info->n_out * info->out_buf_info.write_ports; else if (info->out_share_switch) info->n_switch_out += info->n_out; else info->n_switch_out += info->n_out * info->n_v_class * info->n_v_channel; } else info->n_switch_out += info->n_out; /* clock related parameters */ info->pipelined = PARM(pipelined); info->H_tree_clock = PARM(H_tree_clock); info->router_diagonal = PARM(router_diagonal); if (info->pipelined || info->H_tree_clock) { info->clock_enabled = 1; } /* PHASE 2: initialization */ if (router_power) { SIM_router_power_init(info, router_power); } if (router_area) { SIM_router_area_init(info, router_area); } return 0; }
int SIM_router_init(SIM_router_info_t *info, SIM_router_power_t *router_power, SIM_router_area_t *router_area) { u_int line_width; int share_buf, outdrv; /* PHASE 1: set parameters */ /* general parameters */ info->n_in = PARM(in_port); info->n_cache_in = PARM(cache_in_port); info->n_mc_in = PARM(mc_in_port); info->n_io_in = PARM(io_in_port); info->n_total_in = PARM(in_port) + PARM(cache_in_port) + PARM(mc_in_port) + PARM(io_in_port); info->n_out = PARM(out_port); info->n_cache_out = PARM(cache_out_port); info->n_mc_out = PARM(mc_out_port); info->n_io_out = PARM(io_out_port); info->n_total_out = PARM(out_port) + PARM(cache_out_port) + PARM(mc_out_port) + PARM(io_out_port); info->flit_width = PARM(flit_width); /* virtual channel parameters */ info->n_v_channel = MAX(PARM(v_channel), 1); info->n_v_class = MAX(PARM(v_class), 1); info->cache_class = MAX(PARM(cache_class), 1); info->mc_class = MAX(PARM(mc_class), 1); info->io_class = MAX(PARM(io_class), 1); /* shared buffer implies buffer has tags */ /* separate buffer & shared switch implies buffer has tri-state output driver*/ if (info->n_v_class * info->n_v_channel > 1) { info->in_share_buf = PARM(in_share_buf); info->out_share_buf = PARM(out_share_buf); info->in_share_switch = PARM(in_share_switch); info->out_share_switch = PARM(out_share_switch); } else { info->in_share_buf = 0; info->out_share_buf = 0; info->in_share_switch = 0; info->out_share_switch = 0; } /* crossbar */ info->crossbar_model = PARM(crossbar_model); info->degree = PARM(crsbar_degree); info->connect_type = PARM(connect_type); info->trans_type = PARM(trans_type); info->xb_in_seg = PARM(xb_in_seg); info->xb_out_seg = PARM(xb_out_seg); info->crossbar_in_len = PARM(crossbar_in_len); info->crossbar_out_len = PARM(crossbar_out_len); /* HACK HACK HACK */ info->exp_xb_model = PARM(exp_xb_model); info->exp_in_seg = PARM(exp_in_seg); info->exp_out_seg = PARM(exp_out_seg); /* input buffer */ info->in_buf = PARM(in_buf); info->in_buffer_model = PARM(in_buffer_type); if(info->in_buf){ outdrv = !info->in_share_buf && info->in_share_switch; SIM_array_init(&info->in_buf_info, 1, PARM(in_buf_rport), 1, PARM(in_buf_set), PARM(flit_width), outdrv, info->in_buffer_model); } if (PARM(cache_in_port)){ info->cache_in_buf = PARM(cache_in_buf); if (info->cache_in_buf){ if (PARM(cache_class) > 1){ share_buf = info->in_share_buf; outdrv = !share_buf && info->in_share_switch; } else{ outdrv = share_buf = 0; } SIM_array_init(&info->cache_in_buf_info, 1, PARM(cache_in_buf_rport), 1, PARM(cache_in_buf_set), PARM(flit_width), outdrv, SRAM); } } if (PARM(mc_in_port)){ info->mc_in_buf = PARM(mc_in_buf); if (info->mc_in_buf){ if (PARM(mc_class) > 1){ share_buf = info->in_share_buf; outdrv = !share_buf && info->in_share_switch; } else{ outdrv = share_buf = 0; } SIM_array_init(&info->mc_in_buf_info, 1, PARM(mc_in_buf_rport), 1, PARM(mc_in_buf_set), PARM(flit_width), outdrv, SRAM); } } if (PARM(io_in_port)){ info->io_in_buf = PARM(io_in_buf); if (info->io_in_buf){ if (PARM(io_class) > 1){ share_buf = info->in_share_buf; outdrv = !share_buf && info->in_share_switch; } else{ outdrv = share_buf = 0; } SIM_array_init(&info->io_in_buf_info, 1, PARM(io_in_buf_rport), 1, PARM(io_in_buf_set), PARM(flit_width), outdrv, SRAM); } } /* output buffer */ info->out_buf = PARM(out_buf); info->out_buffer_model = PARM(out_buffer_type); if (info->out_buf){ /* output buffer has no tri-state buffer anyway */ SIM_array_init(&info->out_buf_info, 1, 1, PARM(out_buf_wport), PARM(out_buf_set), PARM(flit_width), 0, info->out_buffer_model); } /* central buffer */ info->central_buf = PARM(central_buf); if (info->central_buf){ info->pipe_depth = PARM(pipe_depth); /* central buffer is no FIFO */ SIM_array_init(&info->central_buf_info, 0, PARM(cbuf_rport), PARM(cbuf_wport), PARM(cbuf_set), PARM(cbuf_width) * PARM(flit_width), 0, SRAM); /* dirty hack */ info->cbuf_ff_model = NEG_DFF; } /* switch allocator input port arbiter */ if (info->n_v_class * info->n_v_channel > 1) { if (info->sw_in_arb_model = PARM(sw_in_arb_model)) { if (PARM(sw_in_arb_model) == QUEUE_ARBITER) { SIM_array_init(&info->sw_in_arb_queue_info, 1, 1, 1, info->n_v_class*info->n_v_channel, SIM_logtwo(info->n_v_class*info->n_v_channel), 0, REGISTER); if (info->cache_class > 1) SIM_array_init(&info->cache_in_arb_queue_info, 1, 1, 1, info->cache_class, SIM_logtwo(info->cache_class), 0, REGISTER); if (info->mc_class > 1) SIM_array_init(&info->mc_in_arb_queue_info, 1, 1, 1, info->mc_class, SIM_logtwo(info->mc_class), 0, REGISTER); if (info->io_class > 1) SIM_array_init(&info->io_in_arb_queue_info, 1, 1, 1, info->io_class, SIM_logtwo(info->io_class), 0, REGISTER); info->sw_in_arb_ff_model = SIM_NO_MODEL; } else info->sw_in_arb_ff_model = PARM(sw_in_arb_ff_model); } else info->sw_in_arb_ff_model = SIM_NO_MODEL; } else { info->sw_in_arb_model = SIM_NO_MODEL; info->sw_in_arb_ff_model = SIM_NO_MODEL; } /* switch allocator output port arbiter */ if(info->n_total_in > 2){ info->sw_out_arb_model = PARM(sw_out_arb_model); if (info->sw_out_arb_model) { if (info->sw_out_arb_model == QUEUE_ARBITER) { line_width = SIM_logtwo(info->n_total_in - 1); SIM_array_init(&info->sw_out_arb_queue_info, 1, 1, 1, info->n_total_in - 1, line_width, 0, REGISTER); info->sw_out_arb_ff_model = SIM_NO_MODEL; } else{ info->sw_out_arb_ff_model = PARM(sw_out_arb_ff_model); } } else{ info->sw_out_arb_ff_model = SIM_NO_MODEL; } } else{ info->sw_out_arb_model = SIM_NO_MODEL; info->sw_out_arb_ff_model = SIM_NO_MODEL; } /* virtual channel allocator type */ if (info->n_v_channel > 1) { info->vc_allocator_type = PARM(vc_allocator_type); } else info->vc_allocator_type = SIM_NO_MODEL; /* virtual channel allocator input port arbiter */ if ( info->n_v_channel > 1 && info->n_in > 1) { if (info->vc_in_arb_model = PARM(vc_in_arb_model)) { if (PARM(vc_in_arb_model) == QUEUE_ARBITER) { SIM_array_init(&info->vc_in_arb_queue_info, 1, 1, 1, info->n_v_channel, SIM_logtwo(info->n_v_channel), 0, REGISTER); info->vc_in_arb_ff_model = SIM_NO_MODEL; } else{ info->vc_in_arb_ff_model = PARM(vc_in_arb_ff_model); } } else { info->vc_in_arb_ff_model = SIM_NO_MODEL; } } else { info->vc_in_arb_model = SIM_NO_MODEL; info->vc_in_arb_ff_model = SIM_NO_MODEL; } /* virtual channel allocator output port arbiter */ if(info->n_in > 1 && info->n_v_channel > 1){ info->vc_out_arb_model = PARM(vc_out_arb_model); if (info->vc_out_arb_model) { if (info->vc_out_arb_model == QUEUE_ARBITER) { line_width = SIM_logtwo((info->n_total_in - 1)*info->n_v_channel); SIM_array_init(&info->vc_out_arb_queue_info, 1, 1, 1, (info->n_total_in -1) * info->n_v_channel, line_width, 0, REGISTER); info->vc_out_arb_ff_model = SIM_NO_MODEL; } else{ info->vc_out_arb_ff_model = PARM(vc_out_arb_ff_model); } } else{ info->vc_out_arb_ff_model = SIM_NO_MODEL; } } else{ info->vc_out_arb_model = SIM_NO_MODEL; info->vc_out_arb_ff_model = SIM_NO_MODEL; } /*virtual channel allocation vc selection model */ info->vc_select_buf_type = PARM(vc_select_buf_type); if(info->vc_allocator_type == VC_SELECT && info->n_v_channel > 1 && info->n_in > 1){ info->vc_select_buf_type = PARM(vc_select_buf_type); SIM_array_init(&info->vc_select_buf_info, 1, 1, 1, info->n_v_channel, SIM_logtwo(info->n_v_channel), 0, info->vc_select_buf_type); } else{ info->vc_select_buf_type = SIM_NO_MODEL; } /* redundant fields */ if (info->in_buf) { if (info->in_share_buf) info->in_n_switch = info->in_buf_info.read_ports; else if (info->in_share_switch) info->in_n_switch = 1; else info->in_n_switch = info->n_v_class * info->n_v_channel; } else info->in_n_switch = 1; if (info->cache_in_buf) { if (info->in_share_buf) info->cache_n_switch = info->cache_in_buf_info.read_ports; else if (info->in_share_switch) info->cache_n_switch = 1; else info->cache_n_switch = info->cache_class; } else info->cache_n_switch = 1; if (info->mc_in_buf) { if (info->in_share_buf) info->mc_n_switch = info->mc_in_buf_info.read_ports; else if (info->in_share_switch) info->mc_n_switch = 1; else info->mc_n_switch = info->mc_class; } else info->mc_n_switch = 1; if (info->io_in_buf) { if (info->in_share_buf) info->io_n_switch = info->io_in_buf_info.read_ports; else if (info->in_share_switch) info->io_n_switch = 1; else info->io_n_switch = info->io_class; } else info->io_n_switch = 1; info->n_switch_in = info->n_in * info->in_n_switch + info->n_cache_in * info->cache_n_switch + info->n_mc_in * info->mc_n_switch + info->n_io_in * info->io_n_switch; /* no buffering for local output ports */ info->n_switch_out = info->n_cache_out + info->n_mc_out + info->n_io_out; if (info->out_buf) { if (info->out_share_buf) info->n_switch_out += info->n_out * info->out_buf_info.write_ports; else if (info->out_share_switch) info->n_switch_out += info->n_out; else info->n_switch_out += info->n_out * info->n_v_class * info->n_v_channel; } else info->n_switch_out += info->n_out; /* clock related parameters */ info->pipeline_stages = PARM(pipeline_stages); info->H_tree_clock = PARM(H_tree_clock); info->router_diagonal = PARM(router_diagonal); /* PHASE 2: initialization */ if(router_power){ SIM_router_power_init(info, router_power); } if(router_area){ SIM_router_area_init(info, router_area); } return 0; }