iocontrollers.cc revision 10152:52c552138ba1
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#include <algorithm>
32#include <cassert>
33#include <cmath>
34#include <iostream>
35#include <string>
36
37#include "XML_Parse.h"
38#include "basic_circuit.h"
39#include "basic_components.h"
40#include "const.h"
41#include "io.h"
42#include "iocontrollers.h"
43#include "logic.h"
44#include "parameter.h"
45
46/*
47SUN Niagara 2 I/O power analysis:
48total signal bits: 711
49Total FBDIMM bits: (14+10)*2*8= 384
50PCIe bits:         (8 + 8)*2 = 32
5110Gb NIC:          (4*2+4*2)*2 = 32
52Debug I/Os:        168
53Other I/Os:        711- 32-32 - 384 - 168 = 95
54
55According to "Implementation of an 8-Core, 64-Thread, Power-Efficient SPARC Server on a Chip"
5690% of I/Os are SerDers (the calucaltion is 384+64/(711-168)=83% about the same as the 90% reported in the paper)
57--> around 80Pins are common I/Os.
58Common I/Os consumes 71mW/Gb/s according to Cadence ChipEstimate @65nm
59Niagara 2 I/O clock is 1/4 of core clock. --> 87pin (<--((711-168)*17%)) * 71mW/Gb/s *0.25*1.4Ghz = 2.17W
60
61Total dynamic power of FBDIMM, NIC, PCIe = 84*0.132 + 84*0.049*0.132 = 11.14 - 2.17 = 8.98
62Further, if assuming I/O logic power is about 50% of I/Os then Total energy of FBDIMM, NIC, PCIe = 11.14 - 2.17*1.5 = 7.89
63 */
64
65/*
66 * A bug in Cadence ChipEstimator: After update the clock rate in the clock tab, a user
67 * need to re-select the IP clock (the same clk) and then click Estimate. if not reselect
68 * the new clock rate may not be propogate into the IPs.
69 *
70 */
71
72NIUController::NIUController(ParseXML *XML_interface,InputParameter* interface_ip_)
73:XML(XML_interface),
74 interface_ip(*interface_ip_)
75 {
76          local_result = init_interface(&interface_ip);
77
78          double frontend_area, phy_area, mac_area, SerDer_area;
79      double frontend_dyn, mac_dyn, SerDer_dyn;
80      double frontend_gates, mac_gates, SerDer_gates;
81          double pmos_to_nmos_sizing_r = pmos_to_nmos_sz_ratio();
82          double NMOS_sizing, PMOS_sizing;
83
84          set_niu_param();
85
86          if (niup.type == 0) //high performance NIU
87          {
88                  //Area estimation based on average of die photo from Niagara 2 and Cadence ChipEstimate using 65nm.
89                  mac_area = (1.53 + 0.3)/2 * (interface_ip.F_sz_um/0.065)* (interface_ip.F_sz_um/0.065);
90                  //Area estimation based on average of die photo from Niagara 2, ISSCC "An 800mW 10Gb Ethernet Transceiver in 0.13μm CMOS"
91                  //and"A 1.2-V-Only 900-mW 10 Gb Ethernet Transceiver and XAUI Interface With Robust VCO Tuning Technique" Frontend is PCS
92                  frontend_area = (9.8 + (6 + 18)*65/130*65/130)/3 * (interface_ip.F_sz_um/0.065)* (interface_ip.F_sz_um/0.065);
93                  //Area estimation based on average of die photo from Niagara 2 and Cadence ChipEstimate hard IP @65nm.
94                  //SerDer is very hard to scale
95                  SerDer_area = (1.39 + 0.36) * (interface_ip.F_sz_um/0.065);//* (interface_ip.F_sz_um/0.065);
96                  phy_area = frontend_area + SerDer_area;
97                  //total area
98                  area.set_area((mac_area + frontend_area + SerDer_area)*1e6);
99                  //Power
100                  //Cadence ChipEstimate using 65nm (mac, front_end are all energy. E=P*T = P/F = 1.37/1Ghz = 1.37e-9);
101                  mac_dyn      = 2.19e-9*g_tp.peri_global.Vdd/1.1*g_tp.peri_global.Vdd/1.1*(interface_ip.F_sz_nm/65.0);//niup.clockRate; //2.19W@1GHz fully active according to Cadence ChipEstimate @65nm
102                  //Cadence ChipEstimate using 65nm soft IP;
103                  frontend_dyn = 0.27e-9*g_tp.peri_global.Vdd/1.1*g_tp.peri_global.Vdd/1.1*(interface_ip.F_sz_nm/65.0);//niup.clockRate;
104                  //according to "A 100mW 9.6Gb/s Transceiver in 90nm CMOS..." ISSCC 2006
105                  //SerDer_dyn is power not energy, scaling from 10mw/Gb/s @90nm
106                  SerDer_dyn   = 0.01*10*sqrt(interface_ip.F_sz_um/0.09)*g_tp.peri_global.Vdd/1.2*g_tp.peri_global.Vdd/1.2;
107                  SerDer_dyn   /= niup.clockRate;//covert to energy per clock cycle of whole NIU
108
109                  //Cadence ChipEstimate using 65nm
110                  mac_gates       = 111700;
111                  frontend_gates  = 320000;
112                  SerDer_gates    = 200000;
113                  NMOS_sizing 	  = 5*g_tp.min_w_nmos_;
114                  PMOS_sizing	  = 5*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r;
115
116
117          }
118          else
119          {//Low power implementations are mostly from Cadence ChipEstimator; Ignore the multiple IP effect
120                  // ---When there are multiple IP (same kind or not) selected, Cadence ChipEstimator results are not
121                  // a simple summation of all IPs. Ignore this effect
122                  mac_area      = 0.24 * (interface_ip.F_sz_um/0.065)* (interface_ip.F_sz_um/0.065);
123                  frontend_area = 0.1  * (interface_ip.F_sz_um/0.065)* (interface_ip.F_sz_um/0.065);//Frontend is the PCS layer
124                  SerDer_area   = 0.35 * (interface_ip.F_sz_um/0.065)* (interface_ip.F_sz_um/0.065);
125                  //Compare 130um implementation in "A 1.2-V-Only 900-mW 10 Gb Ethernet Transceiver and XAUI Interface With Robust VCO Tuning Technique"
126                  //and the ChipEstimator XAUI PHY hard IP, confirm that even PHY can scale perfectly with the technology
127                  //total area
128                  area.set_area((mac_area + frontend_area + SerDer_area)*1e6);
129                  //Power
130                  //Cadence ChipEstimate using 65nm (mac, front_end are all energy. E=P*T = P/F = 1.37/1Ghz = 1.37e-9);
131                  mac_dyn      = 1.257e-9*g_tp.peri_global.Vdd/1.1*g_tp.peri_global.Vdd/1.1*(interface_ip.F_sz_nm/65.0);//niup.clockRate; //2.19W@1GHz fully active according to Cadence ChipEstimate @65nm
132                  //Cadence ChipEstimate using 65nm soft IP;
133                  frontend_dyn = 0.6e-9*g_tp.peri_global.Vdd/1.1*g_tp.peri_global.Vdd/1.1*(interface_ip.F_sz_nm/65.0);//niup.clockRate;
134                  //SerDer_dyn is power not energy, scaling from 216mw/10Gb/s @130nm
135                  SerDer_dyn   = 0.0216*10*(interface_ip.F_sz_um/0.13)*g_tp.peri_global.Vdd/1.2*g_tp.peri_global.Vdd/1.2;
136                  SerDer_dyn   /= niup.clockRate;//covert to energy per clock cycle of whole NIU
137
138                  mac_gates       = 111700;
139                  frontend_gates  = 52000;
140                  SerDer_gates    = 199260;
141
142                  NMOS_sizing 	  = g_tp.min_w_nmos_;
143                  PMOS_sizing	  = g_tp.min_w_nmos_*pmos_to_nmos_sizing_r;
144
145          }
146
147          power_t.readOp.dynamic = mac_dyn + frontend_dyn + SerDer_dyn;
148          power_t.readOp.leakage = (mac_gates + frontend_gates + frontend_gates)*cmos_Isub_leakage(NMOS_sizing, PMOS_sizing, 2, nand)*g_tp.peri_global.Vdd;//unit W
149          double long_channel_device_reduction = longer_channel_device_reduction(Uncore_device);
150          power_t.readOp.longer_channel_leakage = power_t.readOp.leakage * long_channel_device_reduction;
151          power_t.readOp.gate_leakage = (mac_gates + frontend_gates + frontend_gates)*cmos_Ig_leakage(NMOS_sizing, PMOS_sizing, 2, nand)*g_tp.peri_global.Vdd;//unit W
152 }
153
154void NIUController::computeEnergy(bool is_tdp)
155{
156        if (is_tdp)
157    {
158
159
160                power	= power_t;
161        power.readOp.dynamic *= niup.duty_cycle;
162
163    }
164    else
165    {
166        rt_power = power_t;
167        rt_power.readOp.dynamic *= niup.perc_load;
168    }
169}
170
171void NIUController::displayEnergy(uint32_t indent,int plevel,bool is_tdp)
172{
173        string indent_str(indent, ' ');
174        string indent_str_next(indent+2, ' ');
175        bool long_channel = XML->sys.longer_channel_device;
176
177        if (is_tdp)
178        {
179                cout << "NIU:" << endl;
180                cout << indent_str<< "Area = " << area.get_area()*1e-6<< " mm^2" << endl;
181                cout << indent_str << "Peak Dynamic = " << power.readOp.dynamic*niup.clockRate  << " W" << endl;
182                cout << indent_str<< "Subthreshold Leakage = "
183                        << (long_channel? power.readOp.longer_channel_leakage:power.readOp.leakage) <<" W" << endl;
184                //cout << indent_str<< "Subthreshold Leakage = " << power.readOp.longer_channel_leakage <<" W" << endl;
185                cout << indent_str<< "Gate Leakage = " << power.readOp.gate_leakage << " W" << endl;
186                cout << indent_str << "Runtime Dynamic = " << rt_power.readOp.dynamic*niup.clockRate << " W" << endl;
187                cout<<endl;
188        }
189        else
190        {
191
192        }
193
194}
195
196void NIUController::set_niu_param()
197{
198          niup.clockRate       = XML->sys.niu.clockrate;
199          niup.clockRate       *= 1e6;
200          niup.num_units       = XML->sys.niu.number_units;
201          niup.duty_cycle      = XML->sys.niu.duty_cycle;
202          niup.perc_load       = XML->sys.niu.total_load_perc;
203          niup.type            = XML->sys.niu.type;
204//	  niup.executionTime   = XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6);
205}
206
207PCIeController::PCIeController(ParseXML *XML_interface,InputParameter* interface_ip_)
208:XML(XML_interface),
209 interface_ip(*interface_ip_)
210 {
211          local_result = init_interface(&interface_ip);
212          double frontend_area, phy_area, ctrl_area, SerDer_area;
213      double ctrl_dyn, frontend_dyn, SerDer_dyn;
214      double ctrl_gates,frontend_gates, SerDer_gates;
215          double pmos_to_nmos_sizing_r = pmos_to_nmos_sz_ratio();
216          double NMOS_sizing, PMOS_sizing;
217
218          /* Assuming PCIe is bit-slice based architecture
219           * This is the reason for /8 in both area and power calculation
220           * to get per lane numbers
221           */
222
223          set_pcie_param();
224          if (pciep.type == 0) //high performance NIU
225          {
226                  //Area estimation based on average of die photo from Niagara 2 and Cadence ChipEstimate @ 65nm.
227                  ctrl_area = (5.2 + 0.5)/2 * (interface_ip.F_sz_um/0.065)* (interface_ip.F_sz_um/0.065);
228                  //Area estimation based on average of die photo from Niagara 2, and Cadence ChipEstimate @ 65nm.
229                  frontend_area = (5.2 + 0.1)/2 * (interface_ip.F_sz_um/0.065)* (interface_ip.F_sz_um/0.065);
230                  //Area estimation based on average of die photo from Niagara 2 and Cadence ChipEstimate hard IP @65nm.
231                  //SerDer is very hard to scale
232                  SerDer_area = (3.03 + 0.36) * (interface_ip.F_sz_um/0.065);//* (interface_ip.F_sz_um/0.065);
233                  phy_area = frontend_area + SerDer_area;
234                  //total area
235                  //Power
236                  //Cadence ChipEstimate using 65nm the controller includes everything: the PHY, the data link and transaction layer
237                  ctrl_dyn      = 3.75e-9/8*g_tp.peri_global.Vdd/1.1*g_tp.peri_global.Vdd/1.1*(interface_ip.F_sz_nm/65.0);
238                  //	  //Cadence ChipEstimate using 65nm soft IP;
239                  //	  frontend_dyn = 0.27e-9/8*g_tp.peri_global.Vdd/1.1*g_tp.peri_global.Vdd/1.1*(interface_ip.F_sz_nm/65.0);
240                  //SerDer_dyn is power not energy, scaling from 10mw/Gb/s @90nm
241                  SerDer_dyn   = 0.01*4*(interface_ip.F_sz_um/0.09)*g_tp.peri_global.Vdd/1.2*g_tp.peri_global.Vdd/1.2;//PCIe 2.0 max per lane speed is 4Gb/s
242                  SerDer_dyn   /= pciep.clockRate;//covert to energy per clock cycle
243
244                  //power_t.readOp.dynamic = (ctrl_dyn)*pciep.num_channels;
245                  //Cadence ChipEstimate using 65nm
246                  ctrl_gates       = 900000/8*pciep.num_channels;
247                  //	  frontend_gates   = 120000/8;
248                  //	  SerDer_gates     = 200000/8;
249                  NMOS_sizing 	  = 5*g_tp.min_w_nmos_;
250                  PMOS_sizing	  = 5*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r;
251          }
252          else
253          {
254                  ctrl_area = 0.412 * (interface_ip.F_sz_um/0.065)* (interface_ip.F_sz_um/0.065);
255                  //Area estimation based on average of die photo from Niagara 2, and Cadence ChipEstimate @ 65nm.
256          SerDer_area = 0.36 * (interface_ip.F_sz_um/0.065)* (interface_ip.F_sz_um/0.065);
257                  //total area
258                  //Power
259                  //Cadence ChipEstimate using 65nm the controller includes everything: the PHY, the data link and transaction layer
260                  ctrl_dyn      = 2.21e-9/8*g_tp.peri_global.Vdd/1.1*g_tp.peri_global.Vdd/1.1*(interface_ip.F_sz_nm/65.0);
261                  //	  //Cadence ChipEstimate using 65nm soft IP;
262                  //	  frontend_dyn = 0.27e-9/8*g_tp.peri_global.Vdd/1.1*g_tp.peri_global.Vdd/1.1*(interface_ip.F_sz_nm/65.0);
263                  //SerDer_dyn is power not energy, scaling from 10mw/Gb/s @90nm
264                  SerDer_dyn   = 0.01*4*(interface_ip.F_sz_um/0.09)*g_tp.peri_global.Vdd/1.2*g_tp.peri_global.Vdd/1.2;//PCIe 2.0 max per lane speed is 4Gb/s
265                  SerDer_dyn   /= pciep.clockRate;//covert to energy per clock cycle
266
267                  //Cadence ChipEstimate using 65nm
268                  ctrl_gates       = 200000/8*pciep.num_channels;
269                  //	  frontend_gates   = 120000/8;
270                  SerDer_gates     = 200000/8*pciep.num_channels;
271                  NMOS_sizing 	  = g_tp.min_w_nmos_;
272                  PMOS_sizing	  = g_tp.min_w_nmos_*pmos_to_nmos_sizing_r;
273
274          }
275          area.set_area(((ctrl_area + (pciep.withPHY? SerDer_area:0))/8*pciep.num_channels)*1e6);
276          power_t.readOp.dynamic = (ctrl_dyn + (pciep.withPHY? SerDer_dyn:0))*pciep.num_channels;
277          power_t.readOp.leakage = (ctrl_gates + (pciep.withPHY? SerDer_gates:0))*cmos_Isub_leakage(NMOS_sizing, PMOS_sizing, 2, nand)*g_tp.peri_global.Vdd;//unit W
278          double long_channel_device_reduction = longer_channel_device_reduction(Uncore_device);
279          power_t.readOp.longer_channel_leakage = power_t.readOp.leakage * long_channel_device_reduction;
280          power_t.readOp.gate_leakage = (ctrl_gates + (pciep.withPHY? SerDer_gates:0))*cmos_Ig_leakage(NMOS_sizing, PMOS_sizing, 2, nand)*g_tp.peri_global.Vdd;//unit W
281 }
282
283void PCIeController::computeEnergy(bool is_tdp)
284{
285        if (is_tdp)
286    {
287
288
289                power	= power_t;
290        power.readOp.dynamic *= pciep.duty_cycle;
291
292    }
293    else
294    {
295        rt_power = power_t;
296        rt_power.readOp.dynamic *= pciep.perc_load;
297    }
298}
299
300void PCIeController::displayEnergy(uint32_t indent,int plevel,bool is_tdp)
301{
302        string indent_str(indent, ' ');
303        string indent_str_next(indent+2, ' ');
304        bool long_channel = XML->sys.longer_channel_device;
305
306        if (is_tdp)
307        {
308                cout << "PCIe:" << endl;
309                cout << indent_str<< "Area = " << area.get_area()*1e-6<< " mm^2" << endl;
310                cout << indent_str << "Peak Dynamic = " << power.readOp.dynamic*pciep.clockRate  << " W" << endl;
311                cout << indent_str<< "Subthreshold Leakage = "
312                        << (long_channel? power.readOp.longer_channel_leakage:power.readOp.leakage) <<" W" << endl;
313                //cout << indent_str<< "Subthreshold Leakage = " << power.readOp.longer_channel_leakage <<" W" << endl;
314                cout << indent_str<< "Gate Leakage = " << power.readOp.gate_leakage << " W" << endl;
315                cout << indent_str << "Runtime Dynamic = " << rt_power.readOp.dynamic*pciep.clockRate << " W" << endl;
316                cout<<endl;
317        }
318        else
319        {
320
321        }
322
323}
324
325void PCIeController::set_pcie_param()
326{
327          pciep.clockRate       = XML->sys.pcie.clockrate;
328          pciep.clockRate       *= 1e6;
329          pciep.num_units       = XML->sys.pcie.number_units;
330          pciep.num_channels    = XML->sys.pcie.num_channels;
331          pciep.duty_cycle      = XML->sys.pcie.duty_cycle;
332          pciep.perc_load       = XML->sys.pcie.total_load_perc;
333          pciep.type            = XML->sys.pcie.type;
334          pciep.withPHY         = XML->sys.pcie.withPHY;
335//	  pciep.executionTime   = XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6);
336
337}
338
339FlashController::FlashController(ParseXML *XML_interface,InputParameter* interface_ip_)
340:XML(XML_interface),
341 interface_ip(*interface_ip_)
342 {
343          local_result = init_interface(&interface_ip);
344          double frontend_area, phy_area, ctrl_area, SerDer_area;
345      double ctrl_dyn, frontend_dyn, SerDer_dyn;
346      double ctrl_gates,frontend_gates, SerDer_gates;
347          double pmos_to_nmos_sizing_r = pmos_to_nmos_sz_ratio();
348          double NMOS_sizing, PMOS_sizing;
349
350          /* Assuming PCIe is bit-slice based architecture
351           * This is the reason for /8 in both area and power calculation
352           * to get per lane numbers
353           */
354
355          set_fc_param();
356          if (fcp.type == 0) //high performance NIU
357          {
358                  cout<<"Current McPAT does not support high performance flash contorller since even low power designs are enough for maintain throughput"<<endl;
359                  exit(0);
360                  NMOS_sizing 	  = 5*g_tp.min_w_nmos_;
361                  PMOS_sizing	  = 5*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r;
362          }
363          else
364          {
365                  ctrl_area   = 0.243 * (interface_ip.F_sz_um/0.065)* (interface_ip.F_sz_um/0.065);
366                  //Area estimation based on Cadence ChipEstimate @ 65nm: NANDFLASH-CTRL from CAST
367          SerDer_area = 0.36/8 * (interface_ip.F_sz_um/0.065)* (interface_ip.F_sz_um/0.065);
368          //based On PCIe PHY TSMC65GP from Cadence ChipEstimate @ 65nm, it support 8x lanes with each lane
369          //speed up to 250MB/s (PCIe1.1x) This is already saturate the 200MB/s of the flash controller core above.
370                  ctrl_gates      = 129267;
371                  SerDer_gates    = 200000/8;
372                  NMOS_sizing 	  = g_tp.min_w_nmos_;
373                  PMOS_sizing	  = g_tp.min_w_nmos_*pmos_to_nmos_sizing_r;
374
375                  //Power
376                  //Cadence ChipEstimate using 65nm the controller 125mW for every 200MB/s This is power not energy!
377                  ctrl_dyn      = 0.125*g_tp.peri_global.Vdd/1.1*g_tp.peri_global.Vdd/1.1*(interface_ip.F_sz_nm/65.0);
378                  //SerDer_dyn is power not energy, scaling from 10mw/Gb/s @90nm
379                  SerDer_dyn   = 0.01*1.6*(interface_ip.F_sz_um/0.09)*g_tp.peri_global.Vdd/1.2*g_tp.peri_global.Vdd/1.2;
380                  //max  Per controller speed is 1.6Gb/s (200MB/s)
381          }
382          double number_channel = 1+(fcp.num_channels-1)*0.2;
383          area.set_area((ctrl_area + (fcp.withPHY? SerDer_area:0))*1e6*number_channel);
384          power_t.readOp.dynamic = (ctrl_dyn + (fcp.withPHY? SerDer_dyn:0))*number_channel;
385          power_t.readOp.leakage = ((ctrl_gates + (fcp.withPHY? SerDer_gates:0))*number_channel)*cmos_Isub_leakage(NMOS_sizing, PMOS_sizing, 2, nand)*g_tp.peri_global.Vdd;//unit W
386          double long_channel_device_reduction = longer_channel_device_reduction(Uncore_device);
387          power_t.readOp.longer_channel_leakage = power_t.readOp.leakage * long_channel_device_reduction;
388          power_t.readOp.gate_leakage = ((ctrl_gates + (fcp.withPHY? SerDer_gates:0))*number_channel)*cmos_Ig_leakage(NMOS_sizing, PMOS_sizing, 2, nand)*g_tp.peri_global.Vdd;//unit W
389 }
390
391void FlashController::computeEnergy(bool is_tdp)
392{
393        if (is_tdp)
394    {
395
396
397                power	= power_t;
398        power.readOp.dynamic *= fcp.duty_cycle;
399
400    }
401    else
402    {
403        rt_power = power_t;
404        rt_power.readOp.dynamic *= fcp.perc_load;
405    }
406}
407
408void FlashController::displayEnergy(uint32_t indent,int plevel,bool is_tdp)
409{
410        string indent_str(indent, ' ');
411        string indent_str_next(indent+2, ' ');
412        bool long_channel = XML->sys.longer_channel_device;
413
414        if (is_tdp)
415        {
416                cout << "Flash Controller:" << endl;
417                cout << indent_str<< "Area = " << area.get_area()*1e-6<< " mm^2" << endl;
418                cout << indent_str << "Peak Dynamic = " << power.readOp.dynamic << " W" << endl;//no multiply of clock since this is power already
419                cout << indent_str<< "Subthreshold Leakage = "
420                        << (long_channel? power.readOp.longer_channel_leakage:power.readOp.leakage) <<" W" << endl;
421                //cout << indent_str<< "Subthreshold Leakage = " << power.readOp.longer_channel_leakage <<" W" << endl;
422                cout << indent_str<< "Gate Leakage = " << power.readOp.gate_leakage << " W" << endl;
423                cout << indent_str << "Runtime Dynamic = " << rt_power.readOp.dynamic << " W" << endl;
424                cout<<endl;
425        }
426        else
427        {
428
429        }
430
431}
432
433void FlashController::set_fc_param()
434{
435//	  fcp.clockRate       = XML->sys.flashc.mc_clock;
436//	  fcp.clockRate       *= 1e6;
437          fcp.peakDataTransferRate = XML->sys.flashc.peak_transfer_rate;
438          fcp.num_channels    = ceil(fcp.peakDataTransferRate/200);
439          fcp.num_mcs         = XML->sys.flashc.number_mcs;
440          fcp.duty_cycle      = XML->sys.flashc.duty_cycle;
441          fcp.perc_load       = XML->sys.flashc.total_load_perc;
442          fcp.type            = XML->sys.flashc.type;
443          fcp.withPHY         = XML->sys.flashc.withPHY;
444//	  flashcp.executionTime   = XML->sys.total_cycles/(XML->sys.target_core_clockrate*1e6);
445
446}
447