interconnect.cc revision 10152
1/*****************************************************************************
2 *                                McPAT
3 *                      SOFTWARE LICENSE AGREEMENT
4 *            Copyright 2012 Hewlett-Packard Development Company, L.P.
5 *                          All Rights Reserved
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
9 * met: redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer;
11 * redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution;
14 * neither the name of the copyright holders nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
17
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.”
29 *
30 ***************************************************************************/
31
32
33#include <cassert>
34#include <iostream>
35
36#include "globalvar.h"
37#include "interconnect.h"
38#include "wire.h"
39
40interconnect::interconnect(
41    string name_,
42    enum Device_ty device_ty_,
43        double base_w, double base_h,
44    int data_w, double len,const InputParameter *configure_interface,
45    int start_wiring_level_,
46    bool pipelinable_ ,
47    double route_over_perc_ ,
48    bool opt_local_,
49    enum Core_type core_ty_,
50    enum Wire_type wire_model,
51    double width_s, double space_s,
52    TechnologyParameter::DeviceType *dt
53)
54 :name(name_),
55  device_ty(device_ty_),
56  in_rise_time(0),
57  out_rise_time(0),
58  base_width(base_w),
59  base_height(base_h),
60  data_width(data_w),
61  wt(wire_model),
62  width_scaling(width_s),
63  space_scaling(space_s),
64  start_wiring_level(start_wiring_level_),
65  length(len),
66  //interconnect_latency(1e-12),
67  //interconnect_throughput(1e-12),
68  opt_local(opt_local_),
69  core_ty(core_ty_),
70  pipelinable(pipelinable_),
71  route_over_perc(route_over_perc_),
72  deviceType(dt)
73{
74
75  wt = Global;
76  l_ip=*configure_interface;
77  local_result = init_interface(&l_ip);
78
79
80  max_unpipelined_link_delay = 0; //TODO
81  min_w_nmos = g_tp.min_w_nmos_;
82  min_w_pmos = deviceType->n_to_p_eff_curr_drv_ratio * min_w_nmos;
83
84
85
86  latency               = l_ip.latency;
87  throughput            = l_ip.throughput;
88  latency_overflow=false;
89  throughput_overflow=false;
90
91  /*
92   * TODO: Add wiring option from semi-global to global automatically
93   * And directly jump to global if semi-global cannot satisfy timing
94   * Fat wires only available for global wires, thus
95   * if signal wiring layer starts from semi-global,
96   * the next layer up will be global, i.e., semi-global does
97   * not have fat wires.
98   */
99  if (pipelinable == false)
100  //Non-pipelinable wires, such as bypass logic, care latency
101  {
102          compute();
103          if (opt_for_clk && opt_local)
104          {
105                  while (delay > latency && width_scaling<3.0)
106                  {
107                          width_scaling *= 2;
108                          space_scaling *= 2;
109                          Wire winit(width_scaling, space_scaling);
110                          compute();
111                  }
112                  if (delay > latency)
113                  {
114                          latency_overflow=true;
115                  }
116          }
117  }
118  else //Pipelinable wires, such as bus, does not care latency but throughput
119  {
120          /*
121           * TODO: Add pipe regs power, area, and timing;
122           * Pipelinable wires optimize latency first.
123           */
124          compute();
125          if (opt_for_clk && opt_local)
126          {
127                  while (delay > throughput && width_scaling<3.0)
128                  {
129                          width_scaling *= 2;
130                          space_scaling *= 2;
131                          Wire winit(width_scaling, space_scaling);
132                          compute();
133                  }
134                  if (delay > throughput)
135                          // insert pipeline stages
136                  {
137                          num_pipe_stages = (int)ceil(delay/throughput);
138                          assert(num_pipe_stages>0);
139                          delay = delay/num_pipe_stages + num_pipe_stages*0.05*delay;
140                  }
141          }
142  }
143
144  power_bit = power;
145  power.readOp.dynamic *= data_width;
146  power.readOp.leakage *= data_width;
147  power.readOp.gate_leakage *= data_width;
148  area.set_area(area.get_area()*data_width);
149  no_device_under_wire_area.h *= data_width;
150
151  if (latency_overflow==true)
152                cout<< "Warning: "<< name <<" wire structure cannot satisfy latency constraint." << endl;
153
154
155  assert(power.readOp.dynamic > 0);
156  assert(power.readOp.leakage > 0);
157  assert(power.readOp.gate_leakage > 0);
158
159  double long_channel_device_reduction = longer_channel_device_reduction(device_ty,core_ty);
160
161  double sckRation = g_tp.sckt_co_eff;
162  power.readOp.dynamic *= sckRation;
163  power.writeOp.dynamic *= sckRation;
164  power.searchOp.dynamic *= sckRation;
165
166  power.readOp.longer_channel_leakage =
167          power.readOp.leakage*long_channel_device_reduction;
168
169  if (pipelinable)//Only global wires has the option to choose whether routing over or not
170          area.set_area(area.get_area()*route_over_perc + no_device_under_wire_area.get_area()*(1-route_over_perc));
171
172  Wire wreset();
173}
174
175
176
177void
178interconnect::compute()
179{
180
181  Wire *wtemp1 = 0;
182  wtemp1 = new Wire(wt, length, 1, width_scaling, space_scaling);
183  delay = wtemp1->delay;
184  power.readOp.dynamic = wtemp1->power.readOp.dynamic;
185  power.readOp.leakage = wtemp1->power.readOp.leakage;
186  power.readOp.gate_leakage = wtemp1->power.readOp.gate_leakage;
187
188  area.set_area(wtemp1->area.get_area());
189  no_device_under_wire_area.h =  (wtemp1->wire_width + wtemp1->wire_spacing);
190  no_device_under_wire_area.w = length;
191
192  if (wtemp1)
193   delete wtemp1;
194
195}
196
197void interconnect::leakage_feedback(double temperature)
198{
199  l_ip.temp = (unsigned int)round(temperature/10.0)*10;
200  uca_org_t init_result = init_interface(&l_ip); // init_result is dummy
201
202  compute();
203
204  power_bit = power;
205  power.readOp.dynamic *= data_width;
206  power.readOp.leakage *= data_width;
207  power.readOp.gate_leakage *= data_width;
208
209  assert(power.readOp.dynamic > 0);
210  assert(power.readOp.leakage > 0);
211  assert(power.readOp.gate_leakage > 0);
212
213  double long_channel_device_reduction = longer_channel_device_reduction(device_ty,core_ty);
214
215  double sckRation = g_tp.sckt_co_eff;
216  power.readOp.dynamic *= sckRation;
217  power.writeOp.dynamic *= sckRation;
218  power.searchOp.dynamic *= sckRation;
219
220  power.readOp.longer_channel_leakage = power.readOp.leakage*long_channel_device_reduction;
221}
222
223