logic.cc (10152:52c552138ba1) logic.cc (10234:5cb711fa6176)
1/*****************************************************************************
2 * McPAT
3 * SOFTWARE LICENSE AGREEMENT
4 * Copyright 2012 Hewlett-Packard Development Company, L.P.
1/*****************************************************************************
2 * McPAT
3 * SOFTWARE LICENSE AGREEMENT
4 * Copyright 2012 Hewlett-Packard Development Company, L.P.
5 * Copyright (c) 2010-2013 Advanced Micro Devices, Inc.
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

--- 7 unchanged lines hidden (view full) ---

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
6 * All Rights Reserved
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions are
10 * met: redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer;
12 * redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the

--- 7 unchanged lines hidden (view full) ---

21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28 * (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 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 *
30 ***************************************************************************/
31
30 *
31 ***************************************************************************/
32
33#include "common.h"
32#include "logic.h"
33
34#include "logic.h"
35
34
35//selection_logic
36//selection_logic
36selection_logic::selection_logic(
37 bool _is_default,
38 int win_entries_,
39 int issue_width_,
40 const InputParameter *configure_interface,
41 enum Device_ty device_ty_,
42 enum Core_type core_ty_)
43 //const ParseXML *_XML_interface)
44 :is_default(_is_default),
45 win_entries(win_entries_),
46 issue_width(issue_width_),
47 device_ty(device_ty_),
48 core_ty(core_ty_)
49 {
50 //uca_org_t result2;
51 l_ip=*configure_interface;
52 local_result = init_interface(&l_ip);
53 //init_tech_params(l_ip.F_sz_um, false);
54 //win_entries=numIBEntries;//IQentries;
55 //issue_width=issueWidth;
56 selection_power();
57 double sckRation = g_tp.sckt_co_eff;
58 power.readOp.dynamic *= sckRation;
59 power.writeOp.dynamic *= sckRation;
60 power.searchOp.dynamic *= sckRation;
37selection_logic::selection_logic(XMLNode* _xml_data, bool _is_default,
38 int _win_entries, int issue_width_,
39 const InputParameter *configure_interface,
40 string _name, double _accesses,
41 double clockRate_, enum Device_ty device_ty_,
42 enum Core_type core_ty_)
43 : McPATComponent(_xml_data), is_default(_is_default),
44 win_entries(_win_entries),
45 issue_width(issue_width_),
46 accesses(_accesses),
47 device_ty(device_ty_),
48 core_ty(core_ty_) {
49 clockRate = clockRate_;
50 name = _name;
51 l_ip = *configure_interface;
52 local_result = init_interface(&l_ip, name);
53}
61
54
62 double long_channel_device_reduction = longer_channel_device_reduction(device_ty,core_ty);
63 power.readOp.longer_channel_leakage = power.readOp.leakage*long_channel_device_reduction;
64 }
55void selection_logic::computeArea() {
56 output_data.area = local_result.area;
57}
65
58
66void selection_logic::selection_power()
67{//based on cost effective superscalar processor TR pp27-31
68 double Ctotal, Cor, Cpencode;
69 int num_arbiter;
70 double WSelORn, WSelORprequ, WSelPn, WSelPp, WSelEnn, WSelEnp;
59void selection_logic::computeEnergy() {
60 //based on cost effective superscalar processor TR pp27-31
61 double Ctotal, Cor, Cpencode;
62 int num_arbiter;
63 double WSelORn, WSelORprequ, WSelPn, WSelPp, WSelEnn, WSelEnp;
71
64
72 //TODO: the 0.8um process data is used.
73 WSelORn = 12.5 * l_ip.F_sz_um;//this was 10 micron for the 0.8 micron process
74 WSelORprequ = 50 * l_ip.F_sz_um;//this was 40 micron for the 0.8 micron process
75 WSelPn = 12.5 * l_ip.F_sz_um;//this was 10mcron for the 0.8 micron process
76 WSelPp = 18.75 * l_ip.F_sz_um;//this was 15 micron for the 0.8 micron process
77 WSelEnn = 6.25 * l_ip.F_sz_um;//this was 5 micron for the 0.8 micron process
78 WSelEnp = 12.5 * l_ip.F_sz_um;//this was 10 micron for the 0.8 micron process
65 //the 0.8um process data is used.
66 //this was 10 micron for the 0.8 micron process
67 WSelORn = 12.5 * l_ip.F_sz_um;
68 //this was 40 micron for the 0.8 micron process
69 WSelORprequ = 50 * l_ip.F_sz_um;
70 //this was 10mcron for the 0.8 micron process
71 WSelPn = 12.5 * l_ip.F_sz_um;
72 //this was 15 micron for the 0.8 micron process
73 WSelPp = 18.75 * l_ip.F_sz_um;
74 //this was 5 micron for the 0.8 micron process
75 WSelEnn = 6.25 * l_ip.F_sz_um;
76 //this was 10 micron for the 0.8 micron process
77 WSelEnp = 12.5 * l_ip.F_sz_um;
79
78
80
81 Ctotal=0;
82 num_arbiter=1;
83 while(win_entries > 4)
84 {
85 win_entries = (int)ceil((double)win_entries / 4.0);
86 num_arbiter += win_entries;
79 Ctotal = 0;
80 num_arbiter = 1;
81 while (win_entries > 4) {
82 win_entries = (int)ceil((double)win_entries / 4.0);
83 num_arbiter += win_entries;
87 }
84 }
88 //the 4-input OR logic to generate anyreq
89 Cor = 4 * drain_C_(WSelORn,NCH,1,1, g_tp.cell_h_def) + drain_C_(WSelORprequ,PCH,1,1, g_tp.cell_h_def);
90 power.readOp.gate_leakage = cmos_Ig_leakage(WSelORn, WSelORprequ, 4, nor)*g_tp.peri_global.Vdd;
85 //the 4-input OR logic to generate anyreq
86 Cor = 4 * drain_C_(WSelORn, NCH, 1, 1, g_tp.cell_h_def) +
87 drain_C_(WSelORprequ, PCH, 1, 1, g_tp.cell_h_def);
88 power.readOp.gate_leakage =
89 cmos_Ig_leakage(WSelORn, WSelORprequ, 4, nor) * g_tp.peri_global.Vdd;
91
90
92 //The total capacity of the 4-bit priority encoder
93 Cpencode = drain_C_(WSelPn,NCH,1, 1, g_tp.cell_h_def) + drain_C_(WSelPp,PCH,1, 1, g_tp.cell_h_def) +
94 2*drain_C_(WSelPn,NCH,1, 1, g_tp.cell_h_def) + drain_C_(WSelPp,PCH,2, 1, g_tp.cell_h_def) +
95 3*drain_C_(WSelPn,NCH,1, 1, g_tp.cell_h_def) + drain_C_(WSelPp,PCH,3, 1, g_tp.cell_h_def) +
96 4*drain_C_(WSelPn,NCH,1, 1, g_tp.cell_h_def) + drain_C_(WSelPp,PCH,4, 1, g_tp.cell_h_def) +//precompute priority logic
97 2*4*gate_C(WSelEnn+WSelEnp,20.0)+
98 4*drain_C_(WSelEnn,NCH,1, 1, g_tp.cell_h_def) + 2*4*drain_C_(WSelEnp,PCH,1, 1, g_tp.cell_h_def)+//enable logic
99 (2*4+2*3+2*2+2)*gate_C(WSelPn+WSelPp,10.0);//requests signal
91 //The total capacity of the 4-bit priority encoder
92 Cpencode = drain_C_(WSelPn, NCH, 1, 1, g_tp.cell_h_def) +
93 drain_C_(WSelPp, PCH, 1, 1, g_tp.cell_h_def) +
94 2 * drain_C_(WSelPn, NCH, 1, 1, g_tp.cell_h_def) +
95 drain_C_(WSelPp, PCH, 2, 1, g_tp.cell_h_def) +
96 3 * drain_C_(WSelPn, NCH, 1, 1, g_tp.cell_h_def) +
97 drain_C_(WSelPp, PCH, 3, 1, g_tp.cell_h_def) +
98 4 * drain_C_(WSelPn, NCH, 1, 1, g_tp.cell_h_def) +
99 drain_C_(WSelPp, PCH, 4, 1, g_tp.cell_h_def) +//precompute priority logic
100 2 * 4 * gate_C(WSelEnn + WSelEnp, 20.0) +
101 4 * drain_C_(WSelEnn, NCH, 1, 1, g_tp.cell_h_def) +
102 2 * 4 * drain_C_(WSelEnp, PCH, 1, 1, g_tp.cell_h_def) +//enable logic
103 (2 * 4 + 2 * 3 + 2 * 2 + 2) *
104 gate_C(WSelPn + WSelPp, 10.0);//requests signal
100
105
101 Ctotal += issue_width * num_arbiter*(Cor+Cpencode);
106 Ctotal += issue_width * num_arbiter * (Cor + Cpencode);
102
107
103 power.readOp.dynamic = Ctotal*g_tp.peri_global.Vdd*g_tp.peri_global.Vdd*2;//2 means the abitration signal need to travel round trip
104 power.readOp.leakage = issue_width * num_arbiter *
105 (cmos_Isub_leakage(WSelPn, WSelPp, 2, nor)/*approximate precompute with a nor gate*///grant1p
106 + cmos_Isub_leakage(WSelPn, WSelPp, 3, nor)//grant2p
107 + cmos_Isub_leakage(WSelPn, WSelPp, 4, nor)//grant3p
108 + cmos_Isub_leakage(WSelEnn, WSelEnp, 2, nor)*4//enable logic
109 + cmos_Isub_leakage(WSelEnn, WSelEnp, 1, inv)*2*3//for each grant there are two inverters, there are 3 grant sIsubnals
110 )*g_tp.peri_global.Vdd;
111 power.readOp.gate_leakage = issue_width * num_arbiter *
112 (cmos_Ig_leakage(WSelPn, WSelPp, 2, nor)/*approximate precompute with a nor gate*///grant1p
113 + cmos_Ig_leakage(WSelPn, WSelPp, 3, nor)//grant2p
114 + cmos_Ig_leakage(WSelPn, WSelPp, 4, nor)//grant3p
115 + cmos_Ig_leakage(WSelEnn, WSelEnp, 2, nor)*4//enable logic
116 + cmos_Ig_leakage(WSelEnn, WSelEnp, 1, inv)*2*3//for each grant there are two inverters, there are 3 grant signals
117 )*g_tp.peri_global.Vdd;
118}
108 //2 means the abitration signal need to travel round trip
109 power.readOp.dynamic =
110 Ctotal * g_tp.peri_global.Vdd * g_tp.peri_global.Vdd * 2;
111 power.readOp.leakage = issue_width * num_arbiter *
112 (cmos_Isub_leakage(WSelPn, WSelPp, 2, nor)/*approximate precompute with a nor gate*///grant1p
113 + cmos_Isub_leakage(WSelPn, WSelPp, 3, nor)//grant2p
114 + cmos_Isub_leakage(WSelPn, WSelPp, 4, nor)//grant3p
115 + cmos_Isub_leakage(WSelEnn, WSelEnp, 2, nor)*4//enable logic
116 + cmos_Isub_leakage(WSelEnn, WSelEnp, 1, inv)*2*3//for each grant there are two inverters, there are 3 grant sIsubnals
117 ) * g_tp.peri_global.Vdd;
118 power.readOp.gate_leakage = issue_width * num_arbiter *
119 (cmos_Ig_leakage(WSelPn, WSelPp, 2, nor)/*approximate precompute with a nor gate*///grant1p
120 + cmos_Ig_leakage(WSelPn, WSelPp, 3, nor)//grant2p
121 + cmos_Ig_leakage(WSelPn, WSelPp, 4, nor)//grant3p
122 + cmos_Ig_leakage(WSelEnn, WSelEnp, 2, nor)*4//enable logic
123 + cmos_Ig_leakage(WSelEnn, WSelEnp, 1, inv)*2*3//for each grant there are two inverters, there are 3 grant signals
124 ) * g_tp.peri_global.Vdd;
125 double sckRation = g_tp.sckt_co_eff;
126 power.readOp.dynamic *= sckRation;
127 power.writeOp.dynamic *= sckRation;
128 power.searchOp.dynamic *= sckRation;
119
129
130 double long_channel_device_reduction =
131 longer_channel_device_reduction(device_ty, core_ty);
132 power.readOp.longer_channel_leakage =
133 power.readOp.leakage * long_channel_device_reduction;
120
134
135 output_data.peak_dynamic_power = power.readOp.dynamic * clockRate;
136 output_data.subthreshold_leakage_power = power.readOp.leakage;
137 output_data.gate_leakage_power = power.readOp.gate_leakage;
138 output_data.runtime_dynamic_energy = power.readOp.dynamic * accesses;
139}
140
121dep_resource_conflict_check::dep_resource_conflict_check(
141dep_resource_conflict_check::dep_resource_conflict_check(
122 const InputParameter *configure_interface,
123 const CoreDynParam & dyn_p_,
124 int compare_bits_,
125 bool _is_default)
126 : l_ip(*configure_interface),
127 coredynp(dyn_p_),
128 compare_bits(compare_bits_),
129 is_default(_is_default)
130{
131 Wcompn = 25 * l_ip.F_sz_um;//this was 20.0 micron for the 0.8 micron process
132 Wevalinvp = 25 * l_ip.F_sz_um;//this was 20.0 micron for the 0.8 micron process
133 Wevalinvn = 100 * l_ip.F_sz_um;//this was 80.0 mcron for the 0.8 micron process
134 Wcomppreequ = 50 * l_ip.F_sz_um;//this was 40.0 micron for the 0.8 micron process
135 WNORn = 6.75 * l_ip.F_sz_um;//this was 5.4 micron for the 0.8 micron process
136 WNORp = 38.125 * l_ip.F_sz_um;//this was 30.5 micron for the 0.8 micron process
142 XMLNode* _xml_data, const string _name,
143 const InputParameter *configure_interface,
144 const CoreParameters & dyn_p_, int compare_bits_,
145 double clockRate_, bool _is_default)
146 : McPATComponent(_xml_data), l_ip(*configure_interface),
147 coredynp(dyn_p_), compare_bits(compare_bits_), is_default(_is_default) {
137
148
138 local_result = init_interface(&l_ip);
149 name = _name;
150 clockRate = clockRate_;
151 //this was 20.0 micron for the 0.8 micron process
152 Wcompn = 25 * l_ip.F_sz_um;
153 //this was 20.0 micron for the 0.8 micron process
154 Wevalinvp = 25 * l_ip.F_sz_um;
155 //this was 80.0 mcron for the 0.8 micron process
156 Wevalinvn = 100 * l_ip.F_sz_um;
157 //this was 40.0 micron for the 0.8 micron process
158 Wcomppreequ = 50 * l_ip.F_sz_um;
159 //this was 5.4 micron for the 0.8 micron process
160 WNORn = 6.75 * l_ip.F_sz_um;
161 //this was 30.5 micron for the 0.8 micron process
162 WNORp = 38.125 * l_ip.F_sz_um;
139
163
140 if (coredynp.core_ty==Inorder)
141 compare_bits += 16 + 8 + 8;//TODO: opcode bits + log(shared resources) + REG TAG BITS-->opcode comparator
142 else
143 compare_bits += 16 + 8 + 8;
164 // To make CACTI happy.
165 l_ip.cache_sz = MIN_BUFFER_SIZE;
166 local_result = init_interface(&l_ip, name);
144
167
145 conflict_check_power();
146 double sckRation = g_tp.sckt_co_eff;
147 power.readOp.dynamic *= sckRation;
148 power.writeOp.dynamic *= sckRation;
149 power.searchOp.dynamic *= sckRation;
168 if (coredynp.core_ty == Inorder)
169 //TODO: opcode bits + log(shared resources) + REG TAG BITS -->
170 //opcode comparator
171 compare_bits += 16 + 8 + 8;
172 else
173 compare_bits += 16 + 8 + 8;
150
174
175 conflict_check_power();
176 double sckRation = g_tp.sckt_co_eff;
177 power.readOp.dynamic *= sckRation;
178 power.writeOp.dynamic *= sckRation;
179 power.searchOp.dynamic *= sckRation;
180
151}
152
181}
182
153void dep_resource_conflict_check::conflict_check_power()
154{
155 double Ctotal;
156 int num_comparators;
157 num_comparators = 3*((coredynp.decodeW) * (coredynp.decodeW)-coredynp.decodeW);//2(N*N-N) is used for source to dest comparison, (N*N-N) is used for dest to dest comparision.
158 //When decode-width ==1, no dcl logic
183void dep_resource_conflict_check::conflict_check_power() {
184 double Ctotal;
185 int num_comparators;
186 //2(N*N-N) is used for source to dest comparison, (N*N-N) is used for
187 //dest to dest comparision.
188 num_comparators = 3 * ((coredynp.decodeW) * (coredynp.decodeW) -
189 coredynp.decodeW);
159
190
160 Ctotal = num_comparators * compare_cap();
161 //printf("%i,%s\n",XML_interface->sys.core[0].predictor.predictor_entries,XML_interface->sys.core[0].predictor.prediction_scheme);
191 Ctotal = num_comparators * compare_cap();
162
192
163 power.readOp.dynamic=Ctotal*/*CLOCKRATE*/g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/*AF*/;
164 power.readOp.leakage=num_comparators*compare_bits*2*simplified_nmos_leakage(Wcompn, false);
193 power.readOp.dynamic = Ctotal * /*CLOCKRATE*/ g_tp.peri_global.Vdd *
194 g_tp.peri_global.Vdd /*AF*/;
195 power.readOp.leakage = num_comparators * compare_bits * 2 *
196 simplified_nmos_leakage(Wcompn, false);
165
197
166 double long_channel_device_reduction = longer_channel_device_reduction(Core_device, coredynp.core_ty);
167 power.readOp.longer_channel_leakage = power.readOp.leakage*long_channel_device_reduction;
168 power.readOp.gate_leakage=num_comparators*compare_bits*2*cmos_Ig_leakage(Wcompn, 0, 2, nmos);
198 double long_channel_device_reduction =
199 longer_channel_device_reduction(Core_device, coredynp.core_ty);
200 power.readOp.longer_channel_leakage =
201 power.readOp.leakage * long_channel_device_reduction;
202 power.readOp.gate_leakage = num_comparators * compare_bits * 2 *
203 cmos_Ig_leakage(Wcompn, 0, 2, nmos);
169
170}
171
172/* estimate comparator power consumption (this comparator is similar
173 to the tag-match structure in a CAM */
204
205}
206
207/* estimate comparator power consumption (this comparator is similar
208 to the tag-match structure in a CAM */
174double dep_resource_conflict_check::compare_cap()
175{
176 double c1, c2;
209double dep_resource_conflict_check::compare_cap() {
210 double c1, c2;
177
211
178 WNORp = WNORp * compare_bits/2.0;//resize the big NOR gate at the DCL according to fan in.
179 /* bottom part of comparator */
180 c2 = (compare_bits)*(drain_C_(Wcompn,NCH,1,1, g_tp.cell_h_def)+drain_C_(Wcompn,NCH,2,1, g_tp.cell_h_def))+
181 drain_C_(Wevalinvp,PCH,1,1, g_tp.cell_h_def) + drain_C_(Wevalinvn,NCH,1,1, g_tp.cell_h_def);
212 //resize the big NOR gate at the DCL according to fan in.
213 WNORp = WNORp * compare_bits / 2.0;
214 /* bottom part of comparator */
215 c2 = (compare_bits) * (drain_C_(Wcompn, NCH, 1, 1, g_tp.cell_h_def) +
216 drain_C_(Wcompn, NCH, 2, 1, g_tp.cell_h_def)) +
217 drain_C_(Wevalinvp, PCH, 1, 1, g_tp.cell_h_def) +
218 drain_C_(Wevalinvn, NCH, 1, 1, g_tp.cell_h_def);
182
219
183 /* top part of comparator */
184 c1 = (compare_bits)*(drain_C_(Wcompn,NCH,1,1, g_tp.cell_h_def)+drain_C_(Wcompn,NCH,2,1, g_tp.cell_h_def)+
185 drain_C_(Wcomppreequ,NCH,1,1, g_tp.cell_h_def)) + gate_C(WNORn + WNORp,10.0) +
186 drain_C_(WNORp,NCH,2,1, g_tp.cell_h_def) + compare_bits*drain_C_(WNORn,NCH,2,1, g_tp.cell_h_def);
187 return(c1 + c2);
220 /* top part of comparator */
221 c1 = (compare_bits) * (drain_C_(Wcompn, NCH, 1, 1, g_tp.cell_h_def) +
222 drain_C_(Wcompn, NCH, 2, 1, g_tp.cell_h_def) +
223 drain_C_(Wcomppreequ, NCH, 1, 1, g_tp.cell_h_def)) +
224 gate_C(WNORn + WNORp, 10.0) +
225 drain_C_(WNORp, NCH, 2, 1, g_tp.cell_h_def) + compare_bits *
226 drain_C_(WNORn, NCH, 2, 1, g_tp.cell_h_def);
227 return(c1 + c2);
188
189}
190
191void dep_resource_conflict_check::leakage_feedback(double temperature)
192{
193 l_ip.temp = (unsigned int)round(temperature/10.0)*10;
228
229}
230
231void dep_resource_conflict_check::leakage_feedback(double temperature)
232{
233 l_ip.temp = (unsigned int)round(temperature/10.0)*10;
194 uca_org_t init_result = init_interface(&l_ip); // init_result is dummy
234 uca_org_t init_result = init_interface(&l_ip, name); // init_result is dummy
195
196 // This is part of conflict_check_power()
235
236 // This is part of conflict_check_power()
197 int num_comparators = 3*((coredynp.decodeW) * (coredynp.decodeW)-coredynp.decodeW);//2(N*N-N) is used for source to dest comparison, (N*N-N) is used for dest to dest comparision.
198 power.readOp.leakage=num_comparators*compare_bits*2*simplified_nmos_leakage(Wcompn, false);
237 // 2(N*N-N) is used for source to dest comparison, (N*N-N) is used for dest
238 // to dest comparison.
239 int num_comparators = 3 * ((coredynp.decodeW) * (coredynp.decodeW) -
240 coredynp.decodeW);
241 power.readOp.leakage = num_comparators * compare_bits * 2 *
242 simplified_nmos_leakage(Wcompn, false);
199
243
200 double long_channel_device_reduction = longer_channel_device_reduction(Core_device, coredynp.core_ty);
201 power.readOp.longer_channel_leakage = power.readOp.leakage*long_channel_device_reduction;
202 power.readOp.gate_leakage=num_comparators*compare_bits*2*cmos_Ig_leakage(Wcompn, 0, 2, nmos);
244 double long_channel_device_reduction =
245 longer_channel_device_reduction(Core_device, coredynp.core_ty);
246 power.readOp.longer_channel_leakage = power.readOp.leakage *
247 long_channel_device_reduction;
248 power.readOp.gate_leakage = num_comparators * compare_bits * 2 *
249 cmos_Ig_leakage(Wcompn, 0, 2, nmos);
203}
204
250}
251
205//TODO: add inverter and transmission gate base DFF.
206
207DFFCell::DFFCell(
252
253DFFCell::DFFCell(
208 bool _is_dram,
209 double _WdecNANDn,
210 double _WdecNANDp,
211 double _cell_load,
212 const InputParameter *configure_interface)
213:is_dram(_is_dram),
214cell_load(_cell_load),
215WdecNANDn(_WdecNANDn),
216WdecNANDp(_WdecNANDp)
217{//this model is based on the NAND2 based DFF.
218 l_ip=*configure_interface;
219// area.set_area(730*l_ip.F_sz_um*l_ip.F_sz_um);
220 area.set_area(5*compute_gate_area(NAND, 2,WdecNANDn,WdecNANDp, g_tp.cell_h_def)
221 + compute_gate_area(NAND, 2,WdecNANDn,WdecNANDn, g_tp.cell_h_def));
254 bool _is_dram,
255 double _WdecNANDn,
256 double _WdecNANDp,
257 double _cell_load,
258 const InputParameter *configure_interface)
259 : is_dram(_is_dram),
260 cell_load(_cell_load),
261 WdecNANDn(_WdecNANDn),
262 WdecNANDp(_WdecNANDp) { //this model is based on the NAND2 based DFF.
263 l_ip = *configure_interface;
264 area.set_area(5 * compute_gate_area(NAND, 2,WdecNANDn,WdecNANDp,
265 g_tp.cell_h_def)
266 + compute_gate_area(NAND, 2,WdecNANDn,WdecNANDn,
267 g_tp.cell_h_def));
222
223
224}
225
226
268
269
270}
271
272
227double DFFCell::fpfp_node_cap(unsigned int fan_in, unsigned int fan_out)
228{
229 double Ctotal = 0;
230 //printf("WdecNANDn = %E\n", WdecNANDn);
273double DFFCell::fpfp_node_cap(unsigned int fan_in, unsigned int fan_out) {
274 double Ctotal = 0;
231
275
232 /* part 1: drain cap of NAND gate */
233 Ctotal += drain_C_(WdecNANDn, NCH, 2, 1, g_tp.cell_h_def, is_dram) + fan_in * drain_C_(WdecNANDp, PCH, 1, 1, g_tp.cell_h_def, is_dram);
276 /* part 1: drain cap of NAND gate */
277 Ctotal += drain_C_(WdecNANDn, NCH, 2, 1, g_tp.cell_h_def, is_dram) + fan_in * drain_C_(WdecNANDp, PCH, 1, 1, g_tp.cell_h_def, is_dram);
234
278
235 /* part 2: gate cap of NAND gates */
236 Ctotal += fan_out * gate_C(WdecNANDn + WdecNANDp, 0, is_dram);
279 /* part 2: gate cap of NAND gates */
280 Ctotal += fan_out * gate_C(WdecNANDn + WdecNANDp, 0, is_dram);
237
281
238 return Ctotal;
282 return Ctotal;
239}
240
241
283}
284
285
242void DFFCell::compute_DFF_cell()
243{
244 double c1, c2, c3, c4, c5, c6;
245 /* node 5 and node 6 are identical to node 1 in capacitance */
246 c1 = c5 = c6 = fpfp_node_cap(2, 1);
247 c2 = fpfp_node_cap(2, 3);
248 c3 = fpfp_node_cap(3, 2);
249 c4 = fpfp_node_cap(2, 2);
286void DFFCell::compute_DFF_cell() {
287 double c1, c2, c3, c4, c5, c6;
288 /* node 5 and node 6 are identical to node 1 in capacitance */
289 c1 = c5 = c6 = fpfp_node_cap(2, 1);
290 c2 = fpfp_node_cap(2, 3);
291 c3 = fpfp_node_cap(3, 2);
292 c4 = fpfp_node_cap(2, 2);
250
293
251 //cap-load of the clock signal in each Dff, actually the clock signal only connected to one NAND2
252 clock_cap= 2 * gate_C(WdecNANDn + WdecNANDp, 0, is_dram);
253 e_switch.readOp.dynamic += (c4 + c1 + c2 + c3 + c5 + c6 + 2*cell_load)*0.5*g_tp.peri_global.Vdd * g_tp.peri_global.Vdd;;
294 //cap-load of the clock signal in each Dff, actually the clock signal only connected to one NAND2
295 clock_cap = 2 * gate_C(WdecNANDn + WdecNANDp, 0, is_dram);
296 e_switch.readOp.dynamic += (c4 + c1 + c2 + c3 + c5 + c6 + 2 * cell_load) *
297 0.5 * g_tp.peri_global.Vdd * g_tp.peri_global.Vdd;;
254
298
255 /* no 1/2 for e_keep and e_clock because clock signal switches twice in one cycle */
256 e_keep_1.readOp.dynamic += c3 * g_tp.peri_global.Vdd * g_tp.peri_global.Vdd ;
257 e_keep_0.readOp.dynamic += c2 * g_tp.peri_global.Vdd * g_tp.peri_global.Vdd ;
258 e_clock.readOp.dynamic += clock_cap* g_tp.peri_global.Vdd * g_tp.peri_global.Vdd;;
299 /* no 1/2 for e_keep and e_clock because clock signal switches twice in one cycle */
300 e_keep_1.readOp.dynamic +=
301 c3 * g_tp.peri_global.Vdd * g_tp.peri_global.Vdd ;
302 e_keep_0.readOp.dynamic +=
303 c2 * g_tp.peri_global.Vdd * g_tp.peri_global.Vdd ;
304 e_clock.readOp.dynamic +=
305 clock_cap * g_tp.peri_global.Vdd * g_tp.peri_global.Vdd;;
259
306
260 /* static power */
261 e_switch.readOp.leakage += (cmos_Isub_leakage(WdecNANDn, WdecNANDp, 2, nand)*5//5 NAND2 and 1 NAND3 in a DFF
262 + cmos_Isub_leakage(WdecNANDn, WdecNANDn, 3, nand))*g_tp.peri_global.Vdd;
263 e_switch.readOp.gate_leakage += (cmos_Ig_leakage(WdecNANDn, WdecNANDp, 2, nand)*5//5 NAND2 and 1 NAND3 in a DFF
264 + cmos_Ig_leakage(WdecNANDn, WdecNANDn, 3, nand))*g_tp.peri_global.Vdd;
265 //printf("leakage =%E\n",cmos_Ileak(1, is_dram) );
307 /* static power */
308 e_switch.readOp.leakage +=
309 (cmos_Isub_leakage(WdecNANDn, WdecNANDp, 2, nand) *
310 5//5 NAND2 and 1 NAND3 in a DFF
311 + cmos_Isub_leakage(WdecNANDn, WdecNANDn, 3, nand)) *
312 g_tp.peri_global.Vdd;
313 e_switch.readOp.gate_leakage +=
314 (cmos_Ig_leakage(WdecNANDn, WdecNANDp, 2, nand) *
315 5//5 NAND2 and 1 NAND3 in a DFF
316 + cmos_Ig_leakage(WdecNANDn, WdecNANDn, 3, nand)) *
317 g_tp.peri_global.Vdd;
266}
267
318}
319
268Pipeline::Pipeline(
269 const InputParameter *configure_interface,
270 const CoreDynParam & dyn_p_,
271 enum Device_ty device_ty_,
272 bool _is_core_pipeline,
273 bool _is_default)
274: l_ip(*configure_interface),
275 coredynp(dyn_p_),
276 device_ty(device_ty_),
277 is_core_pipeline(_is_core_pipeline),
278 is_default(_is_default),
279 num_piperegs(0.0)
320Pipeline::Pipeline(XMLNode* _xml_data,
321 const InputParameter *configure_interface,
322 const CoreParameters & dyn_p_,
323 enum Device_ty device_ty_,
324 bool _is_core_pipeline,
325 bool _is_default)
326 : McPATComponent(_xml_data), l_ip(*configure_interface),
327 coredynp(dyn_p_), device_ty(device_ty_),
328 is_core_pipeline(_is_core_pipeline), is_default(_is_default),
329 num_piperegs(0.0) {
330 name = "Pipeline?";
280
331
281 {
282 local_result = init_interface(&l_ip);
283 if (!coredynp.Embedded)
284 process_ind = true;
285 else
286 process_ind = false;
287 WNANDn = (process_ind)? 25 * l_ip.F_sz_um : g_tp.min_w_nmos_ ;//this was 20 micron for the 0.8 micron process
288 WNANDp = (process_ind)? 37.5 * l_ip.F_sz_um : g_tp.min_w_nmos_*pmos_to_nmos_sz_ratio();//this was 30 micron for the 0.8 micron process
289 load_per_pipeline_stage = 2*gate_C(WNANDn + WNANDp, 0, false);
290 compute();
332 local_result = init_interface(&l_ip, name);
333 if (!coredynp.Embedded) {
334 process_ind = true;
335 } else {
336 process_ind = false;
337 }
338 //this was 20 micron for the 0.8 micron process
339 WNANDn = (process_ind) ? 25 * l_ip.F_sz_um : g_tp.min_w_nmos_ ;
340 //this was 30 micron for the 0.8 micron process
341 WNANDp = (process_ind) ? 37.5 * l_ip.F_sz_um : g_tp.min_w_nmos_ *
342 pmos_to_nmos_sz_ratio();
343 load_per_pipeline_stage = 2 * gate_C(WNANDn + WNANDp, 0, false);
344 compute();
291
292}
293
345
346}
347
294void Pipeline::compute()
295{
296 compute_stage_vector();
297 DFFCell pipe_reg(false, WNANDn,WNANDp, load_per_pipeline_stage, &l_ip);
298 pipe_reg.compute_DFF_cell();
348void Pipeline::compute() {
349 compute_stage_vector();
350 DFFCell pipe_reg(false, WNANDn, WNANDp, load_per_pipeline_stage, &l_ip);
351 pipe_reg.compute_DFF_cell();
299
352
300 double clock_power_pipereg = num_piperegs * pipe_reg.e_clock.readOp.dynamic;
301 //******************pipeline power: currently, we average all the possibilities of the states of DFFs in the pipeline. A better way to do it is to consider
302 //the harming distance of two consecutive signals, However McPAT does not have plan to do this in near future as it focuses on worst case power.
303 double pipe_reg_power = num_piperegs * (pipe_reg.e_switch.readOp.dynamic+pipe_reg.e_keep_0.readOp.dynamic+pipe_reg.e_keep_1.readOp.dynamic)/3+clock_power_pipereg;
304 double pipe_reg_leakage = num_piperegs * pipe_reg.e_switch.readOp.leakage;
305 double pipe_reg_gate_leakage = num_piperegs * pipe_reg.e_switch.readOp.gate_leakage;
306 power.readOp.dynamic +=pipe_reg_power;
307 power.readOp.leakage +=pipe_reg_leakage;
308 power.readOp.gate_leakage +=pipe_reg_gate_leakage;
309 area.set_area(num_piperegs * pipe_reg.area.get_area());
353 double clock_power_pipereg = num_piperegs * pipe_reg.e_clock.readOp.dynamic;
354 //******************pipeline power: currently, we average all the possibilities of the states of DFFs in the pipeline. A better way to do it is to consider
355 //the harming distance of two consecutive signals, However McPAT does not have plan to do this in near future as it focuses on worst case power.
356 double pipe_reg_power = num_piperegs *
357 (pipe_reg.e_switch.readOp.dynamic + pipe_reg.e_keep_0.readOp.dynamic +
358 pipe_reg.e_keep_1.readOp.dynamic) / 3 + clock_power_pipereg;
359 double pipe_reg_leakage = num_piperegs * pipe_reg.e_switch.readOp.leakage;
360 double pipe_reg_gate_leakage = num_piperegs *
361 pipe_reg.e_switch.readOp.gate_leakage;
362 power.readOp.dynamic += pipe_reg_power;
363 power.readOp.leakage += pipe_reg_leakage;
364 power.readOp.gate_leakage += pipe_reg_gate_leakage;
365 area.set_area(num_piperegs * pipe_reg.area.get_area());
310
366
311 double long_channel_device_reduction = longer_channel_device_reduction(device_ty, coredynp.core_ty);
312 power.readOp.longer_channel_leakage = power.readOp.leakage*long_channel_device_reduction;
367 double long_channel_device_reduction =
368 longer_channel_device_reduction(device_ty, coredynp.core_ty);
369 power.readOp.longer_channel_leakage = power.readOp.leakage *
370 long_channel_device_reduction;
313
314
371
372
315 double sckRation = g_tp.sckt_co_eff;
316 power.readOp.dynamic *= sckRation;
317 power.writeOp.dynamic *= sckRation;
318 power.searchOp.dynamic *= sckRation;
319 double macro_layout_overhead = g_tp.macro_layout_overhead;
373 double sckRation = g_tp.sckt_co_eff;
374 power.readOp.dynamic *= sckRation;
375 power.writeOp.dynamic *= sckRation;
376 power.searchOp.dynamic *= sckRation;
377 double macro_layout_overhead = g_tp.macro_layout_overhead;
320 if (!coredynp.Embedded)
378 if (!coredynp.Embedded)
321 area.set_area(area.get_area()*macro_layout_overhead);
379 area.set_area(area.get_area() * macro_layout_overhead);
380
381 output_data.area = area.get_area() / 1e6;
382 output_data.peak_dynamic_power = power.readOp.dynamic * clockRate;
383 output_data.subthreshold_leakage_power = power.readOp.leakage;
384 output_data.gate_leakage_power = power.readOp.gate_leakage;
385 output_data.runtime_dynamic_energy = power.readOp.dynamic * total_cycles;
322}
323
386}
387
324void Pipeline::compute_stage_vector()
325{
326 double num_stages, tot_stage_vector, per_stage_vector;
327 int opcode_length = coredynp.x86? coredynp.micro_opcode_length:coredynp.opcode_length;
328 //Hthread = thread_clock_gated? 1:num_thread;
388void Pipeline::compute_stage_vector() {
389 double num_stages, tot_stage_vector, per_stage_vector;
390 int opcode_length = coredynp.x86 ?
391 coredynp.micro_opcode_length : coredynp.opcode_width;
329
392
330 if (!is_core_pipeline)
331 {
332 num_piperegs=l_ip.pipeline_stages*l_ip.per_stage_vector;//The number of pipeline stages are calculated based on the achievable throughput and required throughput
333 }
334 else
335 {
336 if (coredynp.core_ty==Inorder)
337 {
338 /* assume 6 pipe stages and try to estimate bits per pipe stage */
339 /* pipe stage 0/IF */
340 num_piperegs += coredynp.pc_width*2*coredynp.num_hthreads;
341 /* pipe stage IF/ID */
342 num_piperegs += coredynp.fetchW*(coredynp.instruction_length + coredynp.pc_width)*coredynp.num_hthreads;
343 /* pipe stage IF/ThreadSEL */
344 if (coredynp.multithreaded) num_piperegs += coredynp.num_hthreads*coredynp.perThreadState; //8 bit thread states
345 /* pipe stage ID/EXE */
346 num_piperegs += coredynp.decodeW*(coredynp.instruction_length + coredynp.pc_width + pow(2.0,opcode_length)+ 2*coredynp.int_data_width)*coredynp.num_hthreads;
347 /* pipe stage EXE/MEM */
348 num_piperegs += coredynp.issueW*(3 * coredynp.arch_ireg_width + pow(2.0,opcode_length) + 8*2*coredynp.int_data_width/*+2*powers (2,reg_length)*/);
349 /* pipe stage MEM/WB the 2^opcode_length means the total decoded signal for the opcode*/
350 num_piperegs += coredynp.issueW*(2*coredynp.int_data_width + pow(2.0,opcode_length) + 8*2*coredynp.int_data_width/*+2*powers (2,reg_length)*/);
351// /* pipe stage 5/6 */
352// num_piperegs += issueWidth*(data_width + powers (2,opcode_length)/*+2*powers (2,reg_length)*/);
353// /* pipe stage 6/7 */
354// num_piperegs += issueWidth*(data_width + powers (2,opcode_length)/*+2*powers (2,reg_length)*/);
355// /* pipe stage 7/8 */
356// num_piperegs += issueWidth*(data_width + powers (2,opcode_length)/**2*powers (2,reg_length)*/);
357// /* assume 50% extra in control signals (rule of thumb) */
358 num_stages=6;
393 if (!is_core_pipeline) {
394 //The number of pipeline stages are calculated based on the achievable
395 //throughput and required throughput
396 num_piperegs = l_ip.pipeline_stages * l_ip.per_stage_vector;
397 } else {
398 if (coredynp.core_ty == Inorder) {
399 /* assume 6 pipe stages and try to estimate bits per pipe stage */
400 /* pipe stage 0/IF */
401 num_piperegs += coredynp.pc_width * 2 * coredynp.num_hthreads;
402 /* pipe stage IF/ID */
403 num_piperegs += coredynp.fetchW *
404 (coredynp.instruction_length + coredynp.pc_width) *
405 coredynp.num_hthreads;
406 /* pipe stage IF/ThreadSEL */
407 if (coredynp.multithreaded) {
408 num_piperegs += coredynp.num_hthreads *
409 coredynp.perThreadState; //8 bit thread states
410 }
411 /* pipe stage ID/EXE */
412 num_piperegs += coredynp.decodeW *
413 (coredynp.instruction_length + coredynp.pc_width +
414 pow(2.0, opcode_length) + 2 * coredynp.int_data_width) *
415 coredynp.num_hthreads;
416 /* pipe stage EXE/MEM */
417 num_piperegs += coredynp.issueW *
418 (3 * coredynp.arch_ireg_width + pow(2.0, opcode_length) + 8 *
419 2 * coredynp.int_data_width/*+2*powers (2,reg_length)*/);
420 /* pipe stage MEM/WB the 2^opcode_length means the total decoded signal for the opcode*/
421 num_piperegs += coredynp.issueW *
422 (2 * coredynp.int_data_width + pow(2.0, opcode_length) + 8 *
423 2 * coredynp.int_data_width/*+2*powers (2,reg_length)*/);
424 num_stages = 6;
425 } else {
426 /* assume 12 stage pipe stages and try to estimate bits per pipe stage */
427 /*OOO: Fetch, decode, rename, IssueQ, dispatch, regread, EXE, MEM, WB, CM */
359
428
360 }
361 else
362 {
363 /* assume 12 stage pipe stages and try to estimate bits per pipe stage */
364 /*OOO: Fetch, decode, rename, IssueQ, dispatch, regread, EXE, MEM, WB, CM */
429 /* pipe stage 0/1F*/
430 num_piperegs +=
431 coredynp.pc_width * 2 * coredynp.num_hthreads ;//PC and Next PC
432 /* pipe stage IF/ID */
433 num_piperegs += coredynp.fetchW *
434 (coredynp.instruction_length + coredynp.pc_width) *
435 coredynp.num_hthreads;//PC is used to feed branch predictor in ID
436 /* pipe stage 1D/Renaming*/
437 num_piperegs += coredynp.decodeW *
438 (coredynp.instruction_length + coredynp.pc_width) *
439 coredynp.num_hthreads;//PC is for branch exe in later stage.
440 /* pipe stage Renaming/wire_drive */
441 num_piperegs += coredynp.decodeW *
442 (coredynp.instruction_length + coredynp.pc_width);
443 /* pipe stage Renaming/IssueQ */
444 //3*coredynp.phy_ireg_width means 2 sources and 1 dest
445 num_piperegs += coredynp.issueW *
446 (coredynp.instruction_length + coredynp.pc_width + 3 *
447 coredynp.phy_ireg_width) * coredynp.num_hthreads;
448 /* pipe stage IssueQ/Dispatch */
449 num_piperegs += coredynp.issueW *
450 (coredynp.instruction_length + 3 * coredynp.phy_ireg_width);
451 /* pipe stage Dispatch/EXE */
365
452
366 /* pipe stage 0/1F*/
367 num_piperegs += coredynp.pc_width*2*coredynp.num_hthreads ;//PC and Next PC
368 /* pipe stage IF/ID */
369 num_piperegs += coredynp.fetchW*(coredynp.instruction_length + coredynp.pc_width)*coredynp.num_hthreads;//PC is used to feed branch predictor in ID
370 /* pipe stage 1D/Renaming*/
371 num_piperegs += coredynp.decodeW*(coredynp.instruction_length + coredynp.pc_width)*coredynp.num_hthreads;//PC is for branch exe in later stage.
372 /* pipe stage Renaming/wire_drive */
373 num_piperegs += coredynp.decodeW*(coredynp.instruction_length + coredynp.pc_width);
374 /* pipe stage Renaming/IssueQ */
375 num_piperegs += coredynp.issueW*(coredynp.instruction_length + coredynp.pc_width + 3*coredynp.phy_ireg_width)*coredynp.num_hthreads;//3*coredynp.phy_ireg_width means 2 sources and 1 dest
376 /* pipe stage IssueQ/Dispatch */
377 num_piperegs += coredynp.issueW*(coredynp.instruction_length + 3 * coredynp.phy_ireg_width);
378 /* pipe stage Dispatch/EXE */
453 num_piperegs += coredynp.issueW *
454 (3 * coredynp.phy_ireg_width + coredynp.pc_width +
455 pow(2.0, opcode_length)/*+2*powers (2,reg_length)*/);
456 /* 2^opcode_length means the total decoded signal for the opcode*/
457 num_piperegs += coredynp.issueW *
458 (2 * coredynp.int_data_width + pow(2.0, opcode_length)
459 /*+2*powers (2,reg_length)*/);
460 /*2 source operands in EXE; Assume 2EXE stages* since we do not really distinguish OP*/
461 num_piperegs += coredynp.issueW *
462 (2 * coredynp.int_data_width + pow(2.0, opcode_length)
463 /*+2*powers (2,reg_length)*/);
464 /* pipe stage EXE/MEM, data need to be read/write, address*/
465 //memory Opcode still need to be passed
466 num_piperegs += coredynp.issueW *
467 (coredynp.int_data_width + coredynp.v_address_width +
468 pow(2.0, opcode_length)/*+2*powers (2,reg_length)*/);
469 /* pipe stage MEM/WB; result data, writeback regs */
470 num_piperegs += coredynp.issueW *
471 (coredynp.int_data_width + coredynp.phy_ireg_width
472 /* powers (2,opcode_length) +
473 (2,opcode_length)+2*powers (2,reg_length)*/);
474 /* pipe stage WB/CM ; result data, regs need to be updated, address for resolve memory ops in ROB's top*/
475 num_piperegs += coredynp.commitW *
476 (coredynp.int_data_width + coredynp.v_address_width +
477 coredynp.phy_ireg_width
478 /*+ powers (2,opcode_length)*2*powers (2,reg_length)*/) *
479 coredynp.num_hthreads;
480 num_stages = 12;
379
481
380 num_piperegs += coredynp.issueW*(3 * coredynp.phy_ireg_width + coredynp.pc_width + pow(2.0,opcode_length)/*+2*powers (2,reg_length)*/);
381 /* 2^opcode_length means the total decoded signal for the opcode*/
382 num_piperegs += coredynp.issueW*(2*coredynp.int_data_width + pow(2.0,opcode_length)/*+2*powers (2,reg_length)*/);
383 /*2 source operands in EXE; Assume 2EXE stages* since we do not really distinguish OP*/
384 num_piperegs += coredynp.issueW*(2*coredynp.int_data_width + pow(2.0,opcode_length)/*+2*powers (2,reg_length)*/);
385 /* pipe stage EXE/MEM, data need to be read/write, address*/
386 num_piperegs += coredynp.issueW*(coredynp.int_data_width + coredynp.v_address_width + pow(2.0,opcode_length)/*+2*powers (2,reg_length)*/);//memory Opcode still need to be passed
387 /* pipe stage MEM/WB; result data, writeback regs */
388 num_piperegs += coredynp.issueW*(coredynp.int_data_width + coredynp.phy_ireg_width /* powers (2,opcode_length) + (2,opcode_length)+2*powers (2,reg_length)*/);
389 /* pipe stage WB/CM ; result data, regs need to be updated, address for resolve memory ops in ROB's top*/
390 num_piperegs += coredynp.commitW*(coredynp.int_data_width + coredynp.v_address_width + coredynp.phy_ireg_width/*+ powers (2,opcode_length)*2*powers (2,reg_length)*/)*coredynp.num_hthreads;
391// if (multithreaded)
392// {
393//
394// }
395 num_stages=12;
396
397 }
398
399 /* assume 50% extra in control registers and interrupt registers (rule of thumb) */
400 num_piperegs = num_piperegs * 1.5;
482 }
483
484 /* assume 50% extra in control registers and interrupt registers (rule of thumb) */
485 num_piperegs = num_piperegs * 1.5;
401 tot_stage_vector=num_piperegs;
402 per_stage_vector=tot_stage_vector/num_stages;
486 tot_stage_vector = num_piperegs;
487 per_stage_vector = tot_stage_vector / num_stages;
403
488
404 if (coredynp.core_ty==Inorder)
405 {
406 if (coredynp.pipeline_stages>6)
407 num_piperegs= per_stage_vector*coredynp.pipeline_stages;
489 if (coredynp.core_ty == Inorder) {
490 if (coredynp.pipeline_stages > 6)
491 num_piperegs = per_stage_vector * coredynp.pipeline_stages;
492 } else { //OOO
493 if (coredynp.pipeline_stages > 12)
494 num_piperegs = per_stage_vector * coredynp.pipeline_stages;
408 }
495 }
409 else//OOO
410 {
411 if (coredynp.pipeline_stages>12)
412 num_piperegs= per_stage_vector*coredynp.pipeline_stages;
413 }
414 }
496 }
415
416}
417
497
498}
499
418FunctionalUnit::FunctionalUnit(ParseXML *XML_interface, int ithCore_, InputParameter* interface_ip_,const CoreDynParam & dyn_p_, enum FU_type fu_type_)
419:XML(XML_interface),
420 ithCore(ithCore_),
421 interface_ip(*interface_ip_),
422 coredynp(dyn_p_),
423 fu_type(fu_type_)
424{
425 double area_t;//, leakage, gate_leakage;
500FunctionalUnit::FunctionalUnit(XMLNode* _xml_data,
501 InputParameter* interface_ip_,
502 const CoreParameters & _core_params,
503 const CoreStatistics & _core_stats,
504 enum FU_type fu_type_)
505 : McPATComponent(_xml_data),
506 interface_ip(*interface_ip_), core_params(_core_params),
507 core_stats(_core_stats), fu_type(fu_type_) {
508 double area_t;
509 double leakage;
510 double gate_leakage;
426 double pmos_to_nmos_sizing_r = pmos_to_nmos_sz_ratio();
511 double pmos_to_nmos_sizing_r = pmos_to_nmos_sz_ratio();
427 clockRate = coredynp.clockRate;
428 executionTime = coredynp.executionTime;
512 clockRate = core_params.clockRate;
429
513
430 //XML_interface=_XML_interface;
431 uca_org_t result2;
432 result2 = init_interface(&interface_ip);
433 if (XML->sys.Embedded)
434 {
435 if (fu_type == FPU)
436 {
437 num_fu=coredynp.num_fpus;
514 uca_org_t result2;
515 // Temp name for the following function call
516 name = "Functional Unit";
517
518 result2 = init_interface(&interface_ip, name);
519
520 if (core_params.Embedded) {
521 if (fu_type == FPU) {
522 num_fu=core_params.num_fpus;
438 //area_t = 8.47*1e6*g_tp.scaling_factor.logic_scaling_co_eff;//this is um^2
439 area_t = 4.47*1e6*(g_ip->F_sz_nm*g_ip->F_sz_nm/90.0/90.0);//this is um^2 The base number
440 //4.47 contains both VFP and NEON processing unit, VFP is about 40% and NEON is about 60%
441 if (g_ip->F_sz_nm>90)
442 area_t = 4.47*1e6*g_tp.scaling_factor.logic_scaling_co_eff;//this is um^2
443 leakage = area_t *(g_tp.scaling_factor.core_tx_density)*cmos_Isub_leakage(5*g_tp.min_w_nmos_, 5*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd/2;//unit W
444 gate_leakage = area_t *(g_tp.scaling_factor.core_tx_density)*cmos_Ig_leakage(5*g_tp.min_w_nmos_, 5*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd/2;//unit W
445 //energy = 0.3529/10*1e-9;//this is the energy(nJ) for a FP instruction in FPU usually it can have up to 20 cycles.
446// base_energy = coredynp.core_ty==Inorder? 0: 89e-3*3; //W The base energy of ALU average numbers from Intel 4G and 773Mhz (Wattch)
447// base_energy *=(g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/1.2/1.2);
448 base_energy = 0;
449 per_access_energy = 1.15/1e9/4/1.3/1.3*g_tp.peri_global.Vdd*g_tp.peri_global.Vdd*(g_ip->F_sz_nm/90.0);//g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/1.2/1.2);//0.00649*1e-9; //This is per Hz energy(nJ)
450 //FPU power from Sandia's processor sizing tech report
451 FU_height=(18667*num_fu)*interface_ip.F_sz_um;//FPU from Sun's data
523 //area_t = 8.47*1e6*g_tp.scaling_factor.logic_scaling_co_eff;//this is um^2
524 area_t = 4.47*1e6*(g_ip->F_sz_nm*g_ip->F_sz_nm/90.0/90.0);//this is um^2 The base number
525 //4.47 contains both VFP and NEON processing unit, VFP is about 40% and NEON is about 60%
526 if (g_ip->F_sz_nm>90)
527 area_t = 4.47*1e6*g_tp.scaling_factor.logic_scaling_co_eff;//this is um^2
528 leakage = area_t *(g_tp.scaling_factor.core_tx_density)*cmos_Isub_leakage(5*g_tp.min_w_nmos_, 5*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd/2;//unit W
529 gate_leakage = area_t *(g_tp.scaling_factor.core_tx_density)*cmos_Ig_leakage(5*g_tp.min_w_nmos_, 5*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd/2;//unit W
530 //energy = 0.3529/10*1e-9;//this is the energy(nJ) for a FP instruction in FPU usually it can have up to 20 cycles.
531// base_energy = coredynp.core_ty==Inorder? 0: 89e-3*3; //W The base energy of ALU average numbers from Intel 4G and 773Mhz (Wattch)
532// base_energy *=(g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/1.2/1.2);
533 base_energy = 0;
534 per_access_energy = 1.15/1e9/4/1.3/1.3*g_tp.peri_global.Vdd*g_tp.peri_global.Vdd*(g_ip->F_sz_nm/90.0);//g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/1.2/1.2);//0.00649*1e-9; //This is per Hz energy(nJ)
535 //FPU power from Sandia's processor sizing tech report
536 FU_height=(18667*num_fu)*interface_ip.F_sz_um;//FPU from Sun's data
452 }
453 else if (fu_type == ALU)
454 {
455 num_fu=coredynp.num_alus;
537 } else if (fu_type == ALU) {
538 num_fu=core_params.num_alus;
456 area_t = 280*260*g_tp.scaling_factor.logic_scaling_co_eff;//this is um^2 ALU + MUl
457 leakage = area_t *(g_tp.scaling_factor.core_tx_density)*cmos_Isub_leakage(20*g_tp.min_w_nmos_, 20*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd/2;//unit W
458 gate_leakage = area_t*(g_tp.scaling_factor.core_tx_density)*cmos_Ig_leakage(20*g_tp.min_w_nmos_, 20*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd/2;
459// base_energy = coredynp.core_ty==Inorder? 0:89e-3; //W The base energy of ALU average numbers from Intel 4G and 773Mhz (Wattch)
460// base_energy *=(g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/1.2/1.2);
461 base_energy = 0;
462 per_access_energy = 1.15/3/1e9/4/1.3/1.3*g_tp.peri_global.Vdd*g_tp.peri_global.Vdd*(g_ip->F_sz_nm/90.0);//(g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/1.2/1.2);//0.00649*1e-9; //This is per cycle energy(nJ)
463 FU_height=(6222*num_fu)*interface_ip.F_sz_um;//integer ALU
464
539 area_t = 280*260*g_tp.scaling_factor.logic_scaling_co_eff;//this is um^2 ALU + MUl
540 leakage = area_t *(g_tp.scaling_factor.core_tx_density)*cmos_Isub_leakage(20*g_tp.min_w_nmos_, 20*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd/2;//unit W
541 gate_leakage = area_t*(g_tp.scaling_factor.core_tx_density)*cmos_Ig_leakage(20*g_tp.min_w_nmos_, 20*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd/2;
542// base_energy = coredynp.core_ty==Inorder? 0:89e-3; //W The base energy of ALU average numbers from Intel 4G and 773Mhz (Wattch)
543// base_energy *=(g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/1.2/1.2);
544 base_energy = 0;
545 per_access_energy = 1.15/3/1e9/4/1.3/1.3*g_tp.peri_global.Vdd*g_tp.peri_global.Vdd*(g_ip->F_sz_nm/90.0);//(g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/1.2/1.2);//0.00649*1e-9; //This is per cycle energy(nJ)
546 FU_height=(6222*num_fu)*interface_ip.F_sz_um;//integer ALU
547
465 }
466 else if (fu_type == MUL)
467 {
468 num_fu=coredynp.num_muls;
548 } else if (fu_type == MUL) {
549 num_fu=core_params.num_muls;
469 area_t = 280*260*3*g_tp.scaling_factor.logic_scaling_co_eff;//this is um^2 ALU + MUl
470 leakage = area_t *(g_tp.scaling_factor.core_tx_density)*cmos_Isub_leakage(20*g_tp.min_w_nmos_, 20*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd/2;//unit W
471 gate_leakage = area_t*(g_tp.scaling_factor.core_tx_density)*cmos_Ig_leakage(20*g_tp.min_w_nmos_, 20*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd/2;
472// base_energy = coredynp.core_ty==Inorder? 0:89e-3*2; //W The base energy of ALU average numbers from Intel 4G and 773Mhz (Wattch)
473// base_energy *=(g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/1.2/1.2);
474 base_energy = 0;
475 per_access_energy = 1.15*2/3/1e9/4/1.3/1.3*g_tp.peri_global.Vdd*g_tp.peri_global.Vdd*(g_ip->F_sz_nm/90.0);//(g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/1.2/1.2);//0.00649*1e-9; //This is per cycle energy(nJ), coefficient based on Wattch
476 FU_height=(9334*num_fu )*interface_ip.F_sz_um;//divider/mul from Sun's data
550 area_t = 280*260*3*g_tp.scaling_factor.logic_scaling_co_eff;//this is um^2 ALU + MUl
551 leakage = area_t *(g_tp.scaling_factor.core_tx_density)*cmos_Isub_leakage(20*g_tp.min_w_nmos_, 20*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd/2;//unit W
552 gate_leakage = area_t*(g_tp.scaling_factor.core_tx_density)*cmos_Ig_leakage(20*g_tp.min_w_nmos_, 20*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd/2;
553// base_energy = coredynp.core_ty==Inorder? 0:89e-3*2; //W The base energy of ALU average numbers from Intel 4G and 773Mhz (Wattch)
554// base_energy *=(g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/1.2/1.2);
555 base_energy = 0;
556 per_access_energy = 1.15*2/3/1e9/4/1.3/1.3*g_tp.peri_global.Vdd*g_tp.peri_global.Vdd*(g_ip->F_sz_nm/90.0);//(g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/1.2/1.2);//0.00649*1e-9; //This is per cycle energy(nJ), coefficient based on Wattch
557 FU_height=(9334*num_fu )*interface_ip.F_sz_um;//divider/mul from Sun's data
477 }
478 else
479 {
558 } else {
480 cout<<"Unknown Functional Unit Type"<<endl;
481 exit(0);
482 }
483 per_access_energy *=0.5;//According to ARM data embedded processor has much lower per acc energy
559 cout<<"Unknown Functional Unit Type"<<endl;
560 exit(0);
561 }
562 per_access_energy *=0.5;//According to ARM data embedded processor has much lower per acc energy
563 } else {
564 if (fu_type == FPU) {
565 name = "Floating Point Unit(s)";
566 num_fu = core_params.num_fpus;
567 area_t = 8.47 * 1e6 * (g_ip->F_sz_nm * g_ip->F_sz_nm / 90.0 /
568 90.0);//this is um^2
569 if (g_ip->F_sz_nm > 90)
570 area_t = 8.47 * 1e6 *
571 g_tp.scaling_factor.logic_scaling_co_eff;//this is um^2
572 leakage = area_t *(g_tp.scaling_factor.core_tx_density)*cmos_Isub_leakage(5*g_tp.min_w_nmos_, 5*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd/2;//unit W
573 gate_leakage = area_t *(g_tp.scaling_factor.core_tx_density)*cmos_Ig_leakage(5*g_tp.min_w_nmos_, 5*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd/2;//unit W
574 //W The base energy of ALU average numbers from Intel 4G and
575 //773Mhz (Wattch)
576 base_energy = core_params.core_ty == Inorder ? 0 : 89e-3 * 3;
577 base_energy *= (g_tp.peri_global.Vdd * g_tp.peri_global.Vdd / 1.2 /
578 1.2);
579 per_access_energy = 1.15*3/1e9/4/1.3/1.3*g_tp.peri_global.Vdd*g_tp.peri_global.Vdd*(g_ip->F_sz_nm/90.0);//g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/1.2/1.2);//0.00649*1e-9; //This is per op energy(nJ)
580 FU_height=(38667*num_fu)*interface_ip.F_sz_um;//FPU from Sun's data
581 } else if (fu_type == ALU) {
582 name = "Integer ALU(s)";
583 num_fu = core_params.num_alus;
584 //this is um^2 ALU + MUl
585 area_t = 280 * 260 * 2 * g_tp.scaling_factor.logic_scaling_co_eff;
586 leakage = area_t *(g_tp.scaling_factor.core_tx_density)*cmos_Isub_leakage(20*g_tp.min_w_nmos_, 20*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd/2;//unit W
587 gate_leakage = area_t*(g_tp.scaling_factor.core_tx_density)*cmos_Ig_leakage(20*g_tp.min_w_nmos_, 20*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd/2;
588 //W The base energy of ALU average numbers from Intel 4G and 773Mhz
589 //(Wattch)
590 base_energy = core_params.core_ty == Inorder ? 0 : 89e-3;
591 base_energy *= (g_tp.peri_global.Vdd * g_tp.peri_global.Vdd / 1.2 /
592 1.2);
593 per_access_energy = 1.15/1e9/4/1.3/1.3*g_tp.peri_global.Vdd*g_tp.peri_global.Vdd*(g_ip->F_sz_nm/90.0);//(g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/1.2/1.2);//0.00649*1e-9; //This is per cycle energy(nJ)
594 FU_height=(6222*num_fu)*interface_ip.F_sz_um;//integer ALU
595 } else if (fu_type == MUL) {
596 name = "Multiply/Divide Unit(s)";
597 num_fu = core_params.num_muls;
598 //this is um^2 ALU + MUl
599 area_t = 280 * 260 * 2 * 3 *
600 g_tp.scaling_factor.logic_scaling_co_eff;
601 leakage = area_t *(g_tp.scaling_factor.core_tx_density)*cmos_Isub_leakage(20*g_tp.min_w_nmos_, 20*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd/2;//unit W
602 gate_leakage = area_t*(g_tp.scaling_factor.core_tx_density)*cmos_Ig_leakage(20*g_tp.min_w_nmos_, 20*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd/2;
603 //W The base energy of ALU average numbers from Intel 4G and 773Mhz
604 //(Wattch)
605 base_energy = core_params.core_ty == Inorder ? 0 : 89e-3 * 2;
606 base_energy *= (g_tp.peri_global.Vdd * g_tp.peri_global.Vdd / 1.2 /
607 1.2);
608 per_access_energy = 1.15*2/1e9/4/1.3/1.3*g_tp.peri_global.Vdd*g_tp.peri_global.Vdd*(g_ip->F_sz_nm/90.0);//(g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/1.2/1.2);//0.00649*1e-9; //This is per cycle energy(nJ), coefficient based on Wattch
609 FU_height=(9334*num_fu )*interface_ip.F_sz_um;//divider/mul from Sun's data
610 } else {
611 cout << "Unknown Functional Unit Type" << endl;
612 exit(0);
484 }
613 }
485 else
486 {
487 if (fu_type == FPU)
488 {
489 num_fu=coredynp.num_fpus;
490 //area_t = 8.47*1e6*g_tp.scaling_factor.logic_scaling_co_eff;//this is um^2
491 area_t = 8.47*1e6*(g_ip->F_sz_nm*g_ip->F_sz_nm/90.0/90.0);//this is um^2
492 if (g_ip->F_sz_nm>90)
493 area_t = 8.47*1e6*g_tp.scaling_factor.logic_scaling_co_eff;//this is um^2
494 leakage = area_t *(g_tp.scaling_factor.core_tx_density)*cmos_Isub_leakage(5*g_tp.min_w_nmos_, 5*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd/2;//unit W
495 gate_leakage = area_t *(g_tp.scaling_factor.core_tx_density)*cmos_Ig_leakage(5*g_tp.min_w_nmos_, 5*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd/2;//unit W
496 //energy = 0.3529/10*1e-9;//this is the energy(nJ) for a FP instruction in FPU usually it can have up to 20 cycles.
497 base_energy = coredynp.core_ty==Inorder? 0: 89e-3*3; //W The base energy of ALU average numbers from Intel 4G and 773Mhz (Wattch)
498 base_energy *=(g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/1.2/1.2);
499 per_access_energy = 1.15*3/1e9/4/1.3/1.3*g_tp.peri_global.Vdd*g_tp.peri_global.Vdd*(g_ip->F_sz_nm/90.0);//g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/1.2/1.2);//0.00649*1e-9; //This is per op energy(nJ)
500 FU_height=(38667*num_fu)*interface_ip.F_sz_um;//FPU from Sun's data
501 }
502 else if (fu_type == ALU)
503 {
504 num_fu=coredynp.num_alus;
505 area_t = 280*260*2*g_tp.scaling_factor.logic_scaling_co_eff;//this is um^2 ALU + MUl
506 leakage = area_t *(g_tp.scaling_factor.core_tx_density)*cmos_Isub_leakage(20*g_tp.min_w_nmos_, 20*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd/2;//unit W
507 gate_leakage = area_t*(g_tp.scaling_factor.core_tx_density)*cmos_Ig_leakage(20*g_tp.min_w_nmos_, 20*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd/2;
508 base_energy = coredynp.core_ty==Inorder? 0:89e-3; //W The base energy of ALU average numbers from Intel 4G and 773Mhz (Wattch)
509 base_energy *=(g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/1.2/1.2);
510 per_access_energy = 1.15/1e9/4/1.3/1.3*g_tp.peri_global.Vdd*g_tp.peri_global.Vdd*(g_ip->F_sz_nm/90.0);//(g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/1.2/1.2);//0.00649*1e-9; //This is per cycle energy(nJ)
511 FU_height=(6222*num_fu)*interface_ip.F_sz_um;//integer ALU
614 }
512
615
513 }
514 else if (fu_type == MUL)
515 {
516 num_fu=coredynp.num_muls;
517 area_t = 280*260*2*3*g_tp.scaling_factor.logic_scaling_co_eff;//this is um^2 ALU + MUl
518 leakage = area_t *(g_tp.scaling_factor.core_tx_density)*cmos_Isub_leakage(20*g_tp.min_w_nmos_, 20*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd/2;//unit W
519 gate_leakage = area_t*(g_tp.scaling_factor.core_tx_density)*cmos_Ig_leakage(20*g_tp.min_w_nmos_, 20*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd/2;
520 base_energy = coredynp.core_ty==Inorder? 0:89e-3*2; //W The base energy of ALU average numbers from Intel 4G and 773Mhz (Wattch)
521 base_energy *=(g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/1.2/1.2);
522 per_access_energy = 1.15*2/1e9/4/1.3/1.3*g_tp.peri_global.Vdd*g_tp.peri_global.Vdd*(g_ip->F_sz_nm/90.0);//(g_tp.peri_global.Vdd*g_tp.peri_global.Vdd/1.2/1.2);//0.00649*1e-9; //This is per cycle energy(nJ), coefficient based on Wattch
523 FU_height=(9334*num_fu )*interface_ip.F_sz_um;//divider/mul from Sun's data
524 }
525 else
526 {
527 cout<<"Unknown Functional Unit Type"<<endl;
528 exit(0);
529 }
530 }
531 //IEXEU, simple ALU and FPU
532 // double C_ALU, C_EXEU, C_FPU; //Lum Equivalent capacitance of IEXEU and FPU. Based on Intel and Sun 90nm process fabracation.
533 //
534 // C_ALU = 0.025e-9;//F
535 // C_EXEU = 0.05e-9; //F
536 // C_FPU = 0.35e-9;//F
537 area.set_area(area_t*num_fu);
616 area.set_area(area_t*num_fu);
538 leakage *= num_fu;
539 gate_leakage *=num_fu;
540 double macro_layout_overhead = g_tp.macro_layout_overhead;
541// if (!XML->sys.Embedded)
542 area.set_area(area.get_area()*macro_layout_overhead);
617 power.readOp.leakage = leakage * num_fu;
618 power.readOp.gate_leakage = gate_leakage * num_fu;
619
620 double long_channel_device_reduction =
621 longer_channel_device_reduction(Core_device, core_params.core_ty);
622 power.readOp.longer_channel_leakage =
623 power.readOp.leakage * long_channel_device_reduction;
624 double macro_layout_overhead = g_tp.macro_layout_overhead;
625 area.set_area(area.get_area()*macro_layout_overhead);
543}
544
626}
627
545void FunctionalUnit::computeEnergy(bool is_tdp)
546{
547 double pppm_t[4] = {1,1,1,1};
548 double FU_duty_cycle;
549 if (is_tdp)
550 {
628void FunctionalUnit::computeEnergy() {
629 double pppm_t[4] = {1, 1, 1, 1};
630 double FU_duty_cycle;
631 double sckRation = g_tp.sckt_co_eff;
551
632
633 // TDP power calculation
634 //2 means two source operands needs to be passed for each int instruction.
635 set_pppm(pppm_t, 2, 2, 2, 2);
636 tdp_stats.readAc.access = num_fu;
637 if (fu_type == FPU) {
638 FU_duty_cycle = core_stats.FPU_duty_cycle;
639 } else if (fu_type == ALU) {
640 FU_duty_cycle = core_stats.ALU_duty_cycle;
641 } else if (fu_type == MUL) {
642 FU_duty_cycle = core_stats.MUL_duty_cycle;
643 }
552
644
553 set_pppm(pppm_t, 2, 2, 2, 2);//2 means two source operands needs to be passed for each int instruction.
554 if (fu_type == FPU)
555 {
556 stats_t.readAc.access = num_fu;
557 tdp_stats = stats_t;
558 FU_duty_cycle = coredynp.FPU_duty_cycle;
559 }
560 else if (fu_type == ALU)
561 {
562 stats_t.readAc.access = 1*num_fu;
563 tdp_stats = stats_t;
564 FU_duty_cycle = coredynp.ALU_duty_cycle;
565 }
566 else if (fu_type == MUL)
567 {
568 stats_t.readAc.access = num_fu;
569 tdp_stats = stats_t;
570 FU_duty_cycle = coredynp.MUL_duty_cycle;
571 }
645 power.readOp.dynamic =
646 per_access_energy * tdp_stats.readAc.access + base_energy / clockRate;
647 power.readOp.dynamic *= sckRation * FU_duty_cycle;
572
648
573 //power.readOp.dynamic = base_energy/clockRate + energy*stats_t.readAc.access;
574 power.readOp.dynamic = per_access_energy*stats_t.readAc.access + base_energy/clockRate;
575 double sckRation = g_tp.sckt_co_eff;
576 power.readOp.dynamic *= sckRation*FU_duty_cycle;
577 power.writeOp.dynamic *= sckRation;
578 power.searchOp.dynamic *= sckRation;
649 // Runtime power calculation
650 if (fu_type == FPU) {
651 rtp_stats.readAc.access = core_stats.fpu_accesses;
652 } else if (fu_type == ALU) {
653 rtp_stats.readAc.access = core_stats.ialu_accesses;
654 } else if (fu_type == MUL) {
655 rtp_stats.readAc.access = core_stats.mul_accesses;
656 }
579
657
580 power.readOp.leakage = leakage;
581 power.readOp.gate_leakage = gate_leakage;
582 double long_channel_device_reduction = longer_channel_device_reduction(Core_device, coredynp.core_ty);
583 power.readOp.longer_channel_leakage = power.readOp.leakage*long_channel_device_reduction;
658 rt_power.readOp.dynamic = per_access_energy * rtp_stats.readAc.access +
659 base_energy * execution_time;
660 rt_power.readOp.dynamic *= sckRation;
584
661
585 }
586 else
587 {
588 if (fu_type == FPU)
589 {
590 stats_t.readAc.access = XML->sys.core[ithCore].fpu_accesses;
591 rtp_stats = stats_t;
592 }
593 else if (fu_type == ALU)
594 {
595 stats_t.readAc.access = XML->sys.core[ithCore].ialu_accesses;
596 rtp_stats = stats_t;
597 }
598 else if (fu_type == MUL)
599 {
600 stats_t.readAc.access = XML->sys.core[ithCore].mul_accesses;
601 rtp_stats = stats_t;
602 }
603
604 //rt_power.readOp.dynamic = base_energy*executionTime + energy*stats_t.readAc.access;
605 rt_power.readOp.dynamic = per_access_energy*stats_t.readAc.access + base_energy*executionTime;
606 double sckRation = g_tp.sckt_co_eff;
607 rt_power.readOp.dynamic *= sckRation;
608 rt_power.writeOp.dynamic *= sckRation;
609 rt_power.searchOp.dynamic *= sckRation;
610
611 }
612
613
662 output_data.area = area.get_area() / 1e6;
663 output_data.peak_dynamic_power = power.readOp.dynamic * clockRate;
664 output_data.subthreshold_leakage_power =
665 (longer_channel_device) ? power.readOp.longer_channel_leakage :
666 power.readOp.leakage;
667 output_data.gate_leakage_power = power.readOp.gate_leakage;
668 output_data.runtime_dynamic_energy = rt_power.readOp.dynamic;
614}
615
669}
670
616void FunctionalUnit::displayEnergy(uint32_t indent,int plevel,bool is_tdp)
617{
618 string indent_str(indent, ' ');
619 string indent_str_next(indent+2, ' ');
620 bool long_channel = XML->sys.longer_channel_device;
621
622// cout << indent_str_next << "Results Broadcast Bus Area = " << bypass->area.get_area() *1e-6 << " mm^2" << endl;
623 if (is_tdp)
624 {
625 if (fu_type == FPU)
626 {
627 cout << indent_str << "Floating Point Units (FPUs) (Count: "<< coredynp.num_fpus <<" ):" << endl;
628 cout << indent_str_next << "Area = " << area.get_area()*1e-6 << " mm^2" << endl;
629 cout << indent_str_next << "Peak Dynamic = " << power.readOp.dynamic*clockRate << " W" << endl;
630// cout << indent_str_next << "Subthreshold Leakage = " << power.readOp.leakage << " W" << endl;
631 cout << indent_str_next<< "Subthreshold Leakage = "
632 << (long_channel? power.readOp.longer_channel_leakage:power.readOp.leakage) <<" W" << endl;
633 cout << indent_str_next << "Gate Leakage = " << power.readOp.gate_leakage << " W" << endl;
634 cout << indent_str_next << "Runtime Dynamic = " << rt_power.readOp.dynamic/executionTime << " W" << endl;
635 cout <<endl;
636 }
637 else if (fu_type == ALU)
638 {
639 cout << indent_str << "Integer ALUs (Count: "<< coredynp.num_alus <<" ):" << endl;
640 cout << indent_str_next << "Area = " << area.get_area()*1e-6 << " mm^2" << endl;
641 cout << indent_str_next << "Peak Dynamic = " << power.readOp.dynamic*clockRate << " W" << endl;
642// cout << indent_str_next << "Subthreshold Leakage = " << power.readOp.leakage << " W" << endl;
643 cout << indent_str_next<< "Subthreshold Leakage = "
644 << (long_channel? power.readOp.longer_channel_leakage:power.readOp.leakage) <<" W" << endl;
645 cout << indent_str_next << "Gate Leakage = " << power.readOp.gate_leakage << " W" << endl;
646 cout << indent_str_next << "Runtime Dynamic = " << rt_power.readOp.dynamic/executionTime << " W" << endl;
647 cout <<endl;
648 }
649 else if (fu_type == MUL)
650 {
651 cout << indent_str << "Complex ALUs (Mul/Div) (Count: "<< coredynp.num_muls <<" ):" << endl;
652 cout << indent_str_next << "Area = " << area.get_area()*1e-6 << " mm^2" << endl;
653 cout << indent_str_next << "Peak Dynamic = " << power.readOp.dynamic*clockRate << " W" << endl;
654// cout << indent_str_next << "Subthreshold Leakage = " << power.readOp.leakage << " W" << endl;
655 cout << indent_str_next<< "Subthreshold Leakage = "
656 << (long_channel? power.readOp.longer_channel_leakage:power.readOp.leakage) <<" W" << endl;
657 cout << indent_str_next << "Gate Leakage = " << power.readOp.gate_leakage << " W" << endl;
658 cout << indent_str_next << "Runtime Dynamic = " << rt_power.readOp.dynamic/executionTime << " W" << endl;
659 cout <<endl;
660
661 }
662
663 }
664 else
665 {
666 }
667
668}
669
670void FunctionalUnit::leakage_feedback(double temperature)
671{
672 // Update the temperature and initialize the global interfaces.
673 interface_ip.temp = (unsigned int)round(temperature/10.0)*10;
674
671void FunctionalUnit::leakage_feedback(double temperature)
672{
673 // Update the temperature and initialize the global interfaces.
674 interface_ip.temp = (unsigned int)round(temperature/10.0)*10;
675
675 uca_org_t init_result = init_interface(&interface_ip); // init_result is dummy
676 // init_result is dummy
677 uca_org_t init_result = init_interface(&interface_ip, name);
676
677 // This is part of FunctionalUnit()
678 double area_t, leakage, gate_leakage;
679 double pmos_to_nmos_sizing_r = pmos_to_nmos_sz_ratio();
680
681 if (fu_type == FPU)
682 {
683 area_t = 4.47*1e6*(g_ip->F_sz_nm*g_ip->F_sz_nm/90.0/90.0);//this is um^2 The base number

--- 17 unchanged lines hidden (view full) ---

701 else
702 {
703 cout<<"Unknown Functional Unit Type"<<endl;
704 exit(1);
705 }
706
707 power.readOp.leakage = leakage*num_fu;
708 power.readOp.gate_leakage = gate_leakage*num_fu;
678
679 // This is part of FunctionalUnit()
680 double area_t, leakage, gate_leakage;
681 double pmos_to_nmos_sizing_r = pmos_to_nmos_sz_ratio();
682
683 if (fu_type == FPU)
684 {
685 area_t = 4.47*1e6*(g_ip->F_sz_nm*g_ip->F_sz_nm/90.0/90.0);//this is um^2 The base number

--- 17 unchanged lines hidden (view full) ---

703 else
704 {
705 cout<<"Unknown Functional Unit Type"<<endl;
706 exit(1);
707 }
708
709 power.readOp.leakage = leakage*num_fu;
710 power.readOp.gate_leakage = gate_leakage*num_fu;
709 power.readOp.longer_channel_leakage = longer_channel_device_reduction(Core_device, coredynp.core_ty);
711 power.readOp.longer_channel_leakage =
712 longer_channel_device_reduction(Core_device, core_params.core_ty);
710}
711
713}
714
712UndiffCore::UndiffCore(ParseXML* XML_interface, int ithCore_, InputParameter* interface_ip_, const CoreDynParam & dyn_p_, bool exist_, bool embedded_)
713:XML(XML_interface),
714 ithCore(ithCore_),
715 interface_ip(*interface_ip_),
716 coredynp(dyn_p_),
717 core_ty(coredynp.core_ty),
718 embedded(XML->sys.Embedded),
719 pipeline_stage(coredynp.pipeline_stages),
720 num_hthreads(coredynp.num_hthreads),
721 issue_width(coredynp.issueW),
722 exist(exist_)
723// is_default(_is_default)
724{
725 if (!exist) return;
726 double undifferentiated_core=0;
727 double core_tx_density=0;
728 double pmos_to_nmos_sizing_r = pmos_to_nmos_sz_ratio();
715UndiffCore::UndiffCore(XMLNode* _xml_data, InputParameter* interface_ip_,
716 const CoreParameters & dyn_p_,
717 bool exist_)
718 : McPATComponent(_xml_data),
719 interface_ip(*interface_ip_), coredynp(dyn_p_),
720 core_ty(coredynp.core_ty), embedded(coredynp.Embedded),
721 pipeline_stage(coredynp.pipeline_stages),
722 num_hthreads(coredynp.num_hthreads), issue_width(coredynp.issueW),
723 exist(exist_) {
724 if (!exist) return;
725
726 name = "Undifferentiated Core";
727 clockRate = coredynp.clockRate;
728
729 double undifferentiated_core = 0;
730 double core_tx_density = 0;
731 double pmos_to_nmos_sizing_r = pmos_to_nmos_sz_ratio();
729 double undifferentiated_core_coe;
732 double undifferentiated_core_coe;
730 //XML_interface=_XML_interface;
731 uca_org_t result2;
732 result2 = init_interface(&interface_ip);
733 uca_org_t result2;
734 result2 = init_interface(&interface_ip, name);
733
735
734 //Compute undifferentiated core area at 90nm.
735 if (embedded==false)
736 {
737 //Based on the results of polynomial/log curve fitting based on undifferentiated core of Niagara, Niagara2, Merom, Penyrn, Prescott, Opteron die measurements
738 if (core_ty==OOO)
739 {
740 //undifferentiated_core = (0.0764*pipeline_stage*pipeline_stage -2.3685*pipeline_stage + 10.405);//OOO
741 undifferentiated_core = (3.57*log(pipeline_stage)-1.2643)>0?(3.57*log(pipeline_stage)-1.2643):0;
742 }
743 else if (core_ty==Inorder)
744 {
745 //undifferentiated_core = (0.1238*pipeline_stage + 7.2572)*0.9;//inorder
746 undifferentiated_core = (-2.19*log(pipeline_stage)+6.55)>0?(-2.19*log(pipeline_stage)+6.55):0;
747 }
748 else
749 {
750 cout<<"invalid core type"<<endl;
751 exit(0);
752 }
753 undifferentiated_core *= (1+ logtwo(num_hthreads)* 0.0716);
736 //Compute undifferentiated core area at 90nm.
737 if (embedded == false) {
738 //Based on the results of polynomial/log curve fitting based on undifferentiated core of Niagara, Niagara2, Merom, Penyrn, Prescott, Opteron die measurements
739 if (core_ty == OOO) {
740 undifferentiated_core = (3.57 * log(pipeline_stage) - 1.2643) > 0 ?
741 (3.57 * log(pipeline_stage) - 1.2643) : 0;
742 } else if (core_ty == Inorder) {
743 undifferentiated_core = (-2.19 * log(pipeline_stage) + 6.55) > 0 ?
744 (-2.19 * log(pipeline_stage) + 6.55) : 0;
745 } else {
746 cout << "invalid core type" << endl;
747 exit(0);
754 }
748 }
755 else
756 {
757 //Based on the results in paper "parametrized processor models" Sandia Labs
758 if (XML->sys.opt_clockrate)
749 undifferentiated_core *= (1 + logtwo(num_hthreads) * 0.0716);
750 } else {
751 //Based on the results in paper "parametrized processor models" Sandia Labs
752 if (opt_for_clk)
759 undifferentiated_core_coe = 0.05;
760 else
761 undifferentiated_core_coe = 0;
753 undifferentiated_core_coe = 0.05;
754 else
755 undifferentiated_core_coe = 0;
762 undifferentiated_core = (0.4109* pipeline_stage - 0.776)*undifferentiated_core_coe;
763 undifferentiated_core *= (1+ logtwo(num_hthreads)* 0.0426);
764 }
756 undifferentiated_core = (0.4109 * pipeline_stage - 0.776) *
757 undifferentiated_core_coe;
758 undifferentiated_core *= (1 + logtwo(num_hthreads) * 0.0426);
759 }
765
760
766 undifferentiated_core *= g_tp.scaling_factor.logic_scaling_co_eff*1e6;//change from mm^2 to um^2
767 core_tx_density = g_tp.scaling_factor.core_tx_density;
768 //undifferentiated_core = 3*1e6;
769 //undifferentiated_core *= g_tp.scaling_factor.logic_scaling_co_eff;//(g_ip->F_sz_um*g_ip->F_sz_um/0.09/0.09)*;
770 power.readOp.leakage = undifferentiated_core*(core_tx_density)*cmos_Isub_leakage(5*g_tp.min_w_nmos_, 5*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd;//unit W
771 power.readOp.gate_leakage = undifferentiated_core*(core_tx_density)*cmos_Ig_leakage(5*g_tp.min_w_nmos_, 5*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd;
761 undifferentiated_core *= g_tp.scaling_factor.logic_scaling_co_eff *
762 1e6;//change from mm^2 to um^2
763 core_tx_density = g_tp.scaling_factor.core_tx_density;
764 power.readOp.leakage = undifferentiated_core*(core_tx_density)*cmos_Isub_leakage(5*g_tp.min_w_nmos_, 5*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd;//unit W
765 power.readOp.gate_leakage = undifferentiated_core*(core_tx_density)*cmos_Ig_leakage(5*g_tp.min_w_nmos_, 5*g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, 1, inv)*g_tp.peri_global.Vdd;
772
766
773 double long_channel_device_reduction = longer_channel_device_reduction(Core_device, coredynp.core_ty);
774 power.readOp.longer_channel_leakage = power.readOp.leakage*long_channel_device_reduction;
775 area.set_area(undifferentiated_core);
767 double long_channel_device_reduction = longer_channel_device_reduction(Core_device, coredynp.core_ty);
768 power.readOp.longer_channel_leakage =
769 power.readOp.leakage * long_channel_device_reduction;
770 area.set_area(undifferentiated_core);
776
771
777 scktRatio = g_tp.sckt_co_eff;
778 power.readOp.dynamic *= scktRatio;
779 power.writeOp.dynamic *= scktRatio;
780 power.searchOp.dynamic *= scktRatio;
781 macro_PR_overhead = g_tp.macro_layout_overhead;
782 area.set_area(area.get_area()*macro_PR_overhead);
772 scktRatio = g_tp.sckt_co_eff;
773 power.readOp.dynamic *= scktRatio;
774 power.writeOp.dynamic *= scktRatio;
775 power.searchOp.dynamic *= scktRatio;
776 macro_PR_overhead = g_tp.macro_layout_overhead;
777 area.set_area(area.get_area()*macro_PR_overhead);
783
778
784
785
786// double vt=g_tp.peri_global.Vth;
787// double velocity_index=1.1;
788// double c_in=gate_C(g_tp.min_w_nmos_, g_tp.min_w_nmos_*pmos_to_nmos_sizing_r , 0.0, false);
789// double c_out= drain_C_(g_tp.min_w_nmos_, NCH, 2, 1, g_tp.cell_h_def, false) + drain_C_(g_tp.min_w_nmos_*pmos_to_nmos_sizing_r, PCH, 1, 1, g_tp.cell_h_def, false) + c_in;
790// double w_nmos=g_tp.min_w_nmos_;
791// double w_pmos=g_tp.min_w_nmos_*pmos_to_nmos_sizing_r;
792// double i_on_n=1.0;
793// double i_on_p=1.0;
794// double i_on_n_in=1.0;
795// double i_on_p_in=1;
796// double vdd=g_tp.peri_global.Vdd;
797
798// power.readOp.sc=shortcircuit_simple(vt, velocity_index, c_in, c_out, w_nmos,w_pmos, i_on_n, i_on_p,i_on_n_in, i_on_p_in, vdd);
799// power.readOp.dynamic=c_out*vdd*vdd/2;
800
801// cout<<power.readOp.dynamic << "dynamic" <<endl;
802// cout<<power.readOp.sc << "sc" << endl;
803
804// power.readOp.sc=shortcircuit(vt, velocity_index, c_in, c_out, w_nmos,w_pmos, i_on_n, i_on_p,i_on_n_in, i_on_p_in, vdd);
805// power.readOp.dynamic=c_out*vdd*vdd/2;
806//
807// cout<<power.readOp.dynamic << "dynamic" <<endl;
808// cout<<power.readOp.sc << "sc" << endl;
809
810
811
779 output_data.area = area.get_area() / 1e6;
780 output_data.peak_dynamic_power = power.readOp.dynamic * clockRate;
781 output_data.subthreshold_leakage_power =
782 longer_channel_device ? power.readOp.longer_channel_leakage :
783 power.readOp.leakage;
784 output_data.gate_leakage_power = power.readOp.gate_leakage;
812}
813
785}
786
787InstructionDecoder::InstructionDecoder(XMLNode* _xml_data, const string _name,
788 bool _is_default,
789 const InputParameter *configure_interface,
790 int opcode_length_, int num_decoders_,
791 bool x86_,
792 double clockRate_,
793 enum Device_ty device_ty_,
794 enum Core_type core_ty_)
795 : McPATComponent(_xml_data), is_default(_is_default),
796 opcode_length(opcode_length_), num_decoders(num_decoders_), x86(x86_),
797 device_ty(device_ty_), core_ty(core_ty_) {
798 /*
799 * Instruction decoder is different from n to 2^n decoders
800 * that are commonly used in row decoders in memory arrays.
801 * The RISC instruction decoder is typically a very simple device.
802 * We can decode an instruction by simply
803 * separating the machine word into small parts using wire slices
804 * The RISC instruction decoder can be approximate by the n to 2^n decoders,
805 * although this approximation usually underestimate power since each decoded
806 * instruction normally has more than 1 active signal.
807 *
808 * However, decoding a CISC instruction word is much more difficult
809 * than the RISC case. A CISC decoder is typically set up as a state machine.
810 * The machine reads the opcode field to determine
811 * what type of instruction it is,
812 * and where the other data values are.
813 * The instruction word is read in piece by piece,
814 * and decisions are made at each stage as to
815 * how the remainder of the instruction word will be read.
816 * (sequencer and ROM are usually needed)
817 * An x86 decoder can be even more complex since
818 * it involve both decoding instructions into u-ops and
819 * merge u-ops when doing micro-ops fusion.
820 */
821 name = _name;
822 clockRate = clockRate_;
823 bool is_dram = false;
824 double pmos_to_nmos_sizing_r;
825 double load_nmos_width, load_pmos_width;
826 double C_driver_load, R_wire_load;
827 Area cell;
814
828
815void UndiffCore::displayEnergy(uint32_t indent,int plevel,bool is_tdp)
816{
817 string indent_str(indent, ' ');
818 string indent_str_next(indent+2, ' ');
819 bool long_channel = XML->sys.longer_channel_device;
829 l_ip = *configure_interface;
830 local_result = init_interface(&l_ip, name);
831 cell.h = g_tp.cell_h_def;
832 cell.w = g_tp.cell_h_def;
820
833
821 if (is_tdp)
822 {
823 cout << indent_str << "UndiffCore:" << endl;
824 cout << indent_str_next << "Area = " << area.get_area()*1e-6<< " mm^2" << endl;
825 cout << indent_str_next << "Peak Dynamic = " << power.readOp.dynamic*clockRate << " W" << endl;
826 //cout << indent_str_next << "Subthreshold Leakage = " << power.readOp.leakage <<" W" << endl;
827 cout << indent_str_next<< "Subthreshold Leakage = "
828 << (long_channel? power.readOp.longer_channel_leakage:power.readOp.leakage) <<" W" << endl;
829 cout << indent_str_next << "Gate Leakage = " << power.readOp.gate_leakage << " W" << endl;
830 //cout << indent_str_next << "Runtime Dynamic = " << rt_power.readOp.dynamic/executionTime << " W" << endl;
831 cout <<endl;
832 }
833 else
834 {
835 cout << indent_str << "UndiffCore:" << endl;
836 cout << indent_str_next << "Area = " << area.get_area()*1e-6<< " mm^2" << endl;
837 cout << indent_str_next << "Peak Dynamic = " << power.readOp.dynamic*clockRate << " W" << endl;
838 cout << indent_str_next << "Subthreshold Leakage = " << power.readOp.leakage <<" W" << endl;
839 cout << indent_str_next << "Gate Leakage = " << power.readOp.gate_leakage << " W" << endl;
840 //cout << indent_str_next << "Runtime Dynamic = " << rt_power.readOp.dynamic/executionTime << " W" << endl;
841 cout <<endl;
842 }
834 num_decoder_segments = (int)ceil(opcode_length / 18.0);
835 if (opcode_length > 18) opcode_length = 18;
836 num_decoded_signals = (int)pow(2.0, opcode_length);
837 pmos_to_nmos_sizing_r = pmos_to_nmos_sz_ratio();
838 load_nmos_width = g_tp.max_w_nmos_ / 2;
839 load_pmos_width = g_tp.max_w_nmos_ * pmos_to_nmos_sizing_r;
840 C_driver_load = 1024 * gate_C(load_nmos_width + load_pmos_width, 0, is_dram);
841 R_wire_load = 3000 * l_ip.F_sz_um * g_tp.wire_outside_mat.R_per_um;
843
842
844}
843 final_dec = new Decoder(
844 num_decoded_signals,
845 false,
846 C_driver_load,
847 R_wire_load,
848 false/*is_fa*/,
849 false/*is_dram*/,
850 false/*wl_tr*/, //to use peri device
851 cell);
845
852
846inst_decoder::inst_decoder(
847 bool _is_default,
848 const InputParameter *configure_interface,
849 int opcode_length_,
850 int num_decoders_,
851 bool x86_,
852 enum Device_ty device_ty_,
853 enum Core_type core_ty_)
854:is_default(_is_default),
855 opcode_length(opcode_length_),
856 num_decoders(num_decoders_),
857 x86(x86_),
858 device_ty(device_ty_),
859 core_ty(core_ty_)
860 {
861 /*
862 * Instruction decoder is different from n to 2^n decoders
863 * that are commonly used in row decoders in memory arrays.
864 * The RISC instruction decoder is typically a very simple device.
865 * We can decode an instruction by simply
866 * separating the machine word into small parts using wire slices
867 * The RISC instruction decoder can be approximate by the n to 2^n decoders,
868 * although this approximation usually underestimate power since each decoded
869 * instruction normally has more than 1 active signal.
870 *
871 * However, decoding a CISC instruction word is much more difficult
872 * than the RISC case. A CISC decoder is typically set up as a state machine.
873 * The machine reads the opcode field to determine
874 * what type of instruction it is,
875 * and where the other data values are.
876 * The instruction word is read in piece by piece,
877 * and decisions are made at each stage as to
878 * how the remainder of the instruction word will be read.
879 * (sequencer and ROM are usually needed)
880 * An x86 decoder can be even more complex since
881 * it involve both decoding instructions into u-ops and
882 * merge u-ops when doing micro-ops fusion.
883 */
884 bool is_dram=false;
885 double pmos_to_nmos_sizing_r;
886 double load_nmos_width, load_pmos_width;
887 double C_driver_load, R_wire_load;
888 Area cell;
853 PredecBlk * predec_blk1 = new PredecBlk(
854 num_decoded_signals,
855 final_dec,
856 0,//Assuming predec and dec are back to back
857 0,
858 1,//Each Predec only drives one final dec
859 false/*is_dram*/,
860 true);
861 PredecBlk * predec_blk2 = new PredecBlk(
862 num_decoded_signals,
863 final_dec,
864 0,//Assuming predec and dec are back to back
865 0,
866 1,//Each Predec only drives one final dec
867 false/*is_dram*/,
868 false);
889
869
890 l_ip=*configure_interface;
891 local_result = init_interface(&l_ip);
892 cell.h =g_tp.cell_h_def;
893 cell.w =g_tp.cell_h_def;
870 PredecBlkDrv * predec_blk_drv1 = new PredecBlkDrv(0, predec_blk1, false);
871 PredecBlkDrv * predec_blk_drv2 = new PredecBlkDrv(0, predec_blk2, false);
894
872
895 num_decoder_segments = (int)ceil(opcode_length/18.0);
896 if (opcode_length > 18) opcode_length = 18;
897 num_decoded_signals= (int)pow(2.0,opcode_length);
898 pmos_to_nmos_sizing_r = pmos_to_nmos_sz_ratio();
899 load_nmos_width=g_tp.max_w_nmos_ /2;
900 load_pmos_width= g_tp.max_w_nmos_ * pmos_to_nmos_sizing_r;
901 C_driver_load = 1024*gate_C(load_nmos_width + load_pmos_width, 0, is_dram); //TODO: this number 1024 needs to be revisited
902 R_wire_load = 3000*l_ip.F_sz_um * g_tp.wire_outside_mat.R_per_um;
873 pre_dec = new Predec(predec_blk_drv1, predec_blk_drv2);
903
874
904 final_dec = new Decoder(
905 num_decoded_signals,
906 false,
907 C_driver_load,
908 R_wire_load,
909 false/*is_fa*/,
910 false/*is_dram*/,
911 false/*wl_tr*/, //to use peri device
912 cell);
875 double area_decoder = final_dec->area.get_area() * num_decoded_signals *
876 num_decoder_segments * num_decoders;
877 //double w_decoder = area_decoder / area.get_h();
878 double area_pre_dec = (predec_blk_drv1->area.get_area() +
879 predec_blk_drv2->area.get_area() +
880 predec_blk1->area.get_area() +
881 predec_blk2->area.get_area()) *
882 num_decoder_segments * num_decoders;
883 area.set_area(area.get_area() + area_decoder + area_pre_dec);
884 double macro_layout_overhead = g_tp.macro_layout_overhead;
885 double chip_PR_overhead = g_tp.chip_layout_overhead;
886 area.set_area(area.get_area()*macro_layout_overhead*chip_PR_overhead);
913
887
914 PredecBlk * predec_blk1 = new PredecBlk(
915 num_decoded_signals,
916 final_dec,
917 0,//Assuming predec and dec are back to back
918 0,
919 1,//Each Predec only drives one final dec
920 false/*is_dram*/,
921 true);
922 PredecBlk * predec_blk2 = new PredecBlk(
923 num_decoded_signals,
924 final_dec,
925 0,//Assuming predec and dec are back to back
926 0,
927 1,//Each Predec only drives one final dec
928 false/*is_dram*/,
929 false);
888 inst_decoder_delay_power();
930
889
931 PredecBlkDrv * predec_blk_drv1 = new PredecBlkDrv(0, predec_blk1, false);
932 PredecBlkDrv * predec_blk_drv2 = new PredecBlkDrv(0, predec_blk2, false);
890 double sckRation = g_tp.sckt_co_eff;
891 power.readOp.dynamic *= sckRation;
892 power.writeOp.dynamic *= sckRation;
893 power.searchOp.dynamic *= sckRation;
933
894
934 pre_dec = new Predec(predec_blk_drv1, predec_blk_drv2);
895 double long_channel_device_reduction =
896 longer_channel_device_reduction(device_ty, core_ty);
897 power.readOp.longer_channel_leakage = power.readOp.leakage *
898 long_channel_device_reduction;
935
899
936 double area_decoder = final_dec->area.get_area() * num_decoded_signals * num_decoder_segments*num_decoders;
937 //double w_decoder = area_decoder / area.get_h();
938 double area_pre_dec = (predec_blk_drv1->area.get_area() +
939 predec_blk_drv2->area.get_area() +
940 predec_blk1->area.get_area() +
941 predec_blk2->area.get_area())*
942 num_decoder_segments*num_decoders;
943 area.set_area(area.get_area()+ area_decoder + area_pre_dec);
944 double macro_layout_overhead = g_tp.macro_layout_overhead;
945 double chip_PR_overhead = g_tp.chip_layout_overhead;
946 area.set_area(area.get_area()*macro_layout_overhead*chip_PR_overhead);
947
948 inst_decoder_delay_power();
949
950 double sckRation = g_tp.sckt_co_eff;
951 power.readOp.dynamic *= sckRation;
952 power.writeOp.dynamic *= sckRation;
953 power.searchOp.dynamic *= sckRation;
954
955 double long_channel_device_reduction = longer_channel_device_reduction(device_ty,core_ty);
956 power.readOp.longer_channel_leakage = power.readOp.leakage*long_channel_device_reduction;
957
900 output_data.area = area.get_area() / 1e6;
901 output_data.peak_dynamic_power = power.readOp.dynamic * clockRate;
902 output_data.subthreshold_leakage_power = power.readOp.leakage;
903 output_data.gate_leakage_power = power.readOp.gate_leakage;
958}
959
904}
905
960void inst_decoder::inst_decoder_delay_power()
961{
906void InstructionDecoder::inst_decoder_delay_power() {
962
907
963 double dec_outrisetime;
964 double inrisetime=0, outrisetime;
965 double pppm_t[4] = {1,1,1,1};
966 double squencer_passes = x86?2:1;
908 double dec_outrisetime;
909 double inrisetime = 0, outrisetime;
910 double pppm_t[4] = {1, 1, 1, 1};
911 double squencer_passes = x86 ? 2 : 1;
967
912
968 outrisetime = pre_dec->compute_delays(inrisetime);
969 dec_outrisetime = final_dec->compute_delays(outrisetime);
970 set_pppm(pppm_t, squencer_passes*num_decoder_segments, num_decoder_segments, squencer_passes*num_decoder_segments, num_decoder_segments);
971 power = power + pre_dec->power*pppm_t;
913 outrisetime = pre_dec->compute_delays(inrisetime);
914 dec_outrisetime = final_dec->compute_delays(outrisetime);
915 set_pppm(pppm_t, squencer_passes*num_decoder_segments, num_decoder_segments, squencer_passes*num_decoder_segments, num_decoder_segments);
916 power = power + pre_dec->power * pppm_t;
972 set_pppm(pppm_t, squencer_passes*num_decoder_segments, num_decoder_segments*num_decoded_signals,
917 set_pppm(pppm_t, squencer_passes*num_decoder_segments, num_decoder_segments*num_decoded_signals,
973 num_decoder_segments*num_decoded_signals, squencer_passes*num_decoder_segments);
974 power = power + final_dec->power*pppm_t;
918 num_decoder_segments*num_decoded_signals, squencer_passes*num_decoder_segments);
919 power = power + final_dec->power * pppm_t;
975}
920}
976void inst_decoder::leakage_feedback(double temperature)
977{
921
922void InstructionDecoder::leakage_feedback(double temperature) {
978 l_ip.temp = (unsigned int)round(temperature/10.0)*10;
923 l_ip.temp = (unsigned int)round(temperature/10.0)*10;
979 uca_org_t init_result = init_interface(&l_ip); // init_result is dummy
924 uca_org_t init_result = init_interface(&l_ip, name); // init_result is dummy
980
981 final_dec->leakage_feedback(temperature);
982 pre_dec->leakage_feedback(temperature);
983
984 double pppm_t[4] = {1,1,1,1};
985 double squencer_passes = x86?2:1;
986
987 set_pppm(pppm_t, squencer_passes*num_decoder_segments, num_decoder_segments, squencer_passes*num_decoder_segments, num_decoder_segments);

--- 7 unchanged lines hidden (view full) ---

995 power.readOp.dynamic *= sckRation;
996 power.writeOp.dynamic *= sckRation;
997 power.searchOp.dynamic *= sckRation;
998
999 double long_channel_device_reduction = longer_channel_device_reduction(device_ty,core_ty);
1000 power.readOp.longer_channel_leakage = power.readOp.leakage*long_channel_device_reduction;
1001}
1002
925
926 final_dec->leakage_feedback(temperature);
927 pre_dec->leakage_feedback(temperature);
928
929 double pppm_t[4] = {1,1,1,1};
930 double squencer_passes = x86?2:1;
931
932 set_pppm(pppm_t, squencer_passes*num_decoder_segments, num_decoder_segments, squencer_passes*num_decoder_segments, num_decoder_segments);

--- 7 unchanged lines hidden (view full) ---

940 power.readOp.dynamic *= sckRation;
941 power.writeOp.dynamic *= sckRation;
942 power.searchOp.dynamic *= sckRation;
943
944 double long_channel_device_reduction = longer_channel_device_reduction(device_ty,core_ty);
945 power.readOp.longer_channel_leakage = power.readOp.leakage*long_channel_device_reduction;
946}
947
1003inst_decoder::~inst_decoder()
1004{
1005 local_result.cleanup();
948InstructionDecoder::~InstructionDecoder() {
949 local_result.cleanup();
1006
950
1007 delete final_dec;
951 delete final_dec;
1008
952
1009 delete pre_dec->blk1;
1010 delete pre_dec->blk2;
1011 delete pre_dec->drv1;
1012 delete pre_dec->drv2;
1013 delete pre_dec;
953 delete pre_dec->blk1;
954 delete pre_dec->blk2;
955 delete pre_dec->drv1;
956 delete pre_dec->drv2;
957 delete pre_dec;
1014}
958}