コード例 #1
0
ファイル: SIM_router.cpp プロジェクト: joelbarca/nirgam
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;
}
コード例 #2
0
int FUNC(SIM_router_power_init, SIM_power_router_info_t *info, SIM_power_router_t *router)
{
  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(info->n_v_channel, PARM(v_class));
  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, so no virtual class -> no sharing */
  /* separate buffer & shared switch implies buffer has tri-state output driver, so no v class -> no sharing */
  if (info->n_v_class > 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->crossbar_in_len = PARM(crossbar_in_len);
  info->crossbar_out_len = PARM(crossbar_out_len);

  /* input buffer */
  info->in_buf = PARM(in_buf);
#if (PARM(in_buf))
  outdrv = !info->in_share_buf && info->in_share_switch;
  SIM_buf_set_para(&info->in_buf_info, info->in_share_buf, PARM(in_buf_rport), 1, PARM(in_buf_set), PARM(flit_width), outdrv);
#endif	/* PARM(in_buf) */

#if (PARM(cache_in_port))
  info->cache_in_buf = PARM(cache_in_buf);
#if (PARM(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;
#endif	/* PARM(cache_class) > 1 */
  SIM_buf_set_para(&info->cache_in_buf_info, share_buf, PARM(cache_in_buf_rport), 1, PARM(cache_in_buf_set), PARM(flit_width), outdrv);
#endif	/* PARM(cache_in_buf) */
#else
  info->cache_in_buf = 0;
#endif	/* PARM(cache_in_port) */

#if (PARM(mc_in_port))
  info->mc_in_buf = PARM(mc_in_buf);
#if (PARM(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;
#endif	/* PARM(mc_class) > 1 */
  SIM_buf_set_para(&info->mc_in_buf_info, share_buf, PARM(mc_in_buf_rport), 1, PARM(mc_in_buf_set), PARM(flit_width), outdrv);
#endif	/* PARM(mc_in_buf) */
#else
  info->mc_in_buf = 0;
#endif	/* PARM(mc_in_port) */

#if (PARM(io_in_port))
  info->io_in_buf = PARM(io_in_buf);
#if (PARM(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;
#endif	/* PARM(io_class) > 1 */
  SIM_buf_set_para(&info->io_in_buf_info, share_buf, PARM(io_in_buf_rport), 1, PARM(io_in_buf_set), PARM(flit_width), outdrv);
#endif	/* PARM(io_in_buf) */
#else
  info->io_in_buf = 0;
#endif	/* PARM(io_in_port) */

  /* output buffer */
  info->out_buf = PARM(out_buf);
#if (PARM(out_buf))
  /* output buffer has no tri-state buffer anyway */
  SIM_buf_set_para(&info->out_buf_info, info->out_share_buf, 1, PARM(out_buf_wport), PARM(out_buf_set), PARM(flit_width), 0);
#endif	/* PARM(out_buf) */
  
  /* central buffer */
  info->central_buf = PARM(central_buf);
#if (PARM(central_buf))
  info->pipe_depth = PARM(pipe_depth);
  /* central buffer is always shared */
  SIM_buf_set_para(&info->central_buf_info, 1, PARM(cbuf_rport), PARM(cbuf_wport), PARM(cbuf_set), PARM(cbuf_width) * PARM(flit_width), 0);
  /* dirty hack */
  info->cbuf_ff_model = NEG_DFF;
#endif	/* PARM(central_buf) */

  /* input port arbiter */
  if (info->n_v_class > 1) {
    if (info->in_arb_model = PARM(in_arb_model)) {
      if (PARM(in_arb_model) == QUEUE_ARBITER) {
        SIM_buf_set_para(&info->in_arb_queue_info, 0, 1, 1, info->n_v_class, SIM_power_logtwo(info->n_v_class), 0);
	if (info->cache_class > 1)
          SIM_buf_set_para(&info->cache_in_arb_queue_info, 0, 1, 1, info->cache_class, SIM_power_logtwo(info->cache_class), 0);
	if (info->mc_class > 1)
          SIM_buf_set_para(&info->mc_in_arb_queue_info, 0, 1, 1, info->mc_class, SIM_power_logtwo(info->mc_class), 0);
	if (info->io_class > 1)
          SIM_buf_set_para(&info->io_in_arb_queue_info, 0, 1, 1, info->io_class, SIM_power_logtwo(info->io_class), 0);

        info->in_arb_ff_model = SIM_NO_MODEL;
      }
      else
        info->in_arb_ff_model = PARM(in_arb_ff_model);
    }
    else
      info->in_arb_ff_model = SIM_NO_MODEL;
  }
  else {
    info->in_arb_model = SIM_NO_MODEL;
    info->in_arb_ff_model = SIM_NO_MODEL;
  }

  /* output port arbiter */
#if ((PARM(in_port) + PARM(cache_in_port) + PARM(mc_in_port) + PARM(io_in_port)) > 2)
  if (info->out_arb_model = PARM(out_arb_model)) {
    if (PARM(out_arb_model) == QUEUE_ARBITER) {
      line_width = SIM_power_logtwo(info->n_total_in - 1);
      SIM_buf_set_para(&info->out_arb_queue_info, 0, 1, 1, info->n_total_in - 1, line_width, 0);
      info->out_arb_ff_model = SIM_NO_MODEL;
    }
    else
      info->out_arb_ff_model = PARM(out_arb_ff_model);
  }
  else
    info->out_arb_ff_model = SIM_NO_MODEL;
#else
  info->out_arb_model = SIM_NO_MODEL;
  info->out_arb_ff_model = SIM_NO_MODEL;
#endif	/* (PARM(in_port) + PARM(cache_in_port) + PARM(mc_in_port) + PARM(io_in_port)) > 2 */
  
  /* 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;
  }
  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;
  }
  else
    info->n_switch_out += info->n_out;

  /* PHASE 2: initialization */
  SIM_router_power_init(info, router);

  return 0;
}
コード例 #3
0
ファイル: SIM_router.c プロジェクト: MortezaRamezani/macsim
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;
}