hwcomponents-library 1.1.0.dev21__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- hwcomponents_library/__init__.py +12 -0
- hwcomponents_library/_version.py +34 -0
- hwcomponents_library/_version_scheme.py +43 -0
- hwcomponents_library/base.py +12 -0
- hwcomponents_library/library/__init__.py +0 -0
- hwcomponents_library/library/aladdin.py +409 -0
- hwcomponents_library/library/atomlayer.py +204 -0
- hwcomponents_library/library/brahms.py +85 -0
- hwcomponents_library/library/dummy.py +172 -0
- hwcomponents_library/library/forms.py +80 -0
- hwcomponents_library/library/isaac.py +602 -0
- hwcomponents_library/library/jia.py +232 -0
- hwcomponents_library/library/misc.py +199 -0
- hwcomponents_library/library/newton.py +127 -0
- hwcomponents_library/library/raella.py +89 -0
- hwcomponents_library/library/timely.py +437 -0
- hwcomponents_library/library/wan.py +288 -0
- hwcomponents_library-1.1.0.dev21.dist-info/METADATA +57 -0
- hwcomponents_library-1.1.0.dev21.dist-info/RECORD +21 -0
- hwcomponents_library-1.1.0.dev21.dist-info/WHEEL +5 -0
- hwcomponents_library-1.1.0.dev21.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,602 @@
|
|
|
1
|
+
"""
|
|
2
|
+
@INPROCEEDINGS{7551379,
|
|
3
|
+
author={Shafiee, Ali and Nag, Anirban and Muralimanohar, Naveen and Balasubramonian, Rajeev and Strachan, John Paul and Hu, Miao and Williams, R. Stanley and Srikumar, Vivek},
|
|
4
|
+
booktitle={2016 ACM/IEEE 43rd Annual International Symposium on Computer Architecture (ISCA)},
|
|
5
|
+
title={ISAAC: A Convolutional Neural Network Accelerator with In-Situ Analog Arithmetic in Crossbars},
|
|
6
|
+
year={2016},
|
|
7
|
+
volume={},
|
|
8
|
+
number={},
|
|
9
|
+
pages={14-26},
|
|
10
|
+
doi={10.1109/ISCA.2016.12}}
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from hwcomponents_library.base import LibraryEstimatorClassBase
|
|
14
|
+
from hwcomponents.scaling import *
|
|
15
|
+
from hwcomponents import actionDynamicEnergy
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
# Original CSV contents:
|
|
19
|
+
# tech_node,global_cycle_period,width|datawidth,depth,energy,area,action
|
|
20
|
+
# 32nm,1e-9,256,2048,20.45,83000,read|write|update,energy in pJ; area in um^2;
|
|
21
|
+
# 32nm,1e-9,256,2048,0,83000,leak
|
|
22
|
+
# # Power * Time / (Reads+Writes) = Energy per read/write
|
|
23
|
+
# # (20.7e-3 / 12 W/IMA) power
|
|
24
|
+
# # (16384 / ((128*8*10^7*1.2) * 100 / 128)) time for DACs/ADCs to consume entire input buffer
|
|
25
|
+
# # (16384 + 2048) * 2 / 256 reads+writes, including IMA<->eDRAM<->network
|
|
26
|
+
# # (20.7e-3 / 12) * (16384 / ((128*8*10^7*1.2) * 100 / 128)) / ((16384 + 2048) * 2 / 256) * 1e12
|
|
27
|
+
class IsaacEDRAM(LibraryEstimatorClassBase):
|
|
28
|
+
"""
|
|
29
|
+
The embedded DRAM from the ISAAC paper.
|
|
30
|
+
|
|
31
|
+
Parameters
|
|
32
|
+
----------
|
|
33
|
+
tech_node: float
|
|
34
|
+
Technology node in meters.
|
|
35
|
+
width: int
|
|
36
|
+
Width of the eDRAM in bits. This is the width of a reads/write port. Total size =
|
|
37
|
+
width * depth.
|
|
38
|
+
depth: int
|
|
39
|
+
Depth of the eDRAM in bits. This is the number of entries in the eDRAM, each
|
|
40
|
+
with `width` bits. Total size = width * depth.
|
|
41
|
+
"""
|
|
42
|
+
component_name = "isaac_eDRAM"
|
|
43
|
+
priority = 0.9
|
|
44
|
+
|
|
45
|
+
def __init__(self, tech_node: float, width: int = 256, depth: int = 2048):
|
|
46
|
+
super().__init__(leak_power=0.0, area=83000.0e-12)
|
|
47
|
+
self.tech_node: float = self.scale(
|
|
48
|
+
"tech_node",
|
|
49
|
+
tech_node,
|
|
50
|
+
32e-9,
|
|
51
|
+
tech_node_energy,
|
|
52
|
+
tech_node_area,
|
|
53
|
+
tech_node_leak,
|
|
54
|
+
)
|
|
55
|
+
self.width: int = self.scale("width", width, 256, linear, linear, linear)
|
|
56
|
+
self.depth: int = self.scale(
|
|
57
|
+
"depth", depth, 2048, linear, cacti_depth_energy, cacti_depth_energy
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
@actionDynamicEnergy(bits_per_action="width")
|
|
61
|
+
def read(self) -> float:
|
|
62
|
+
"""
|
|
63
|
+
Returns the energy of one read operation in Joules.
|
|
64
|
+
|
|
65
|
+
Returns
|
|
66
|
+
-------
|
|
67
|
+
float
|
|
68
|
+
Energy of one read operation in Joules
|
|
69
|
+
"""
|
|
70
|
+
return 20.45e-12
|
|
71
|
+
|
|
72
|
+
@actionDynamicEnergy(bits_per_action="width")
|
|
73
|
+
def write(self) -> float:
|
|
74
|
+
"""
|
|
75
|
+
Returns the energy of one write operation in Joules.
|
|
76
|
+
|
|
77
|
+
Returns
|
|
78
|
+
-------
|
|
79
|
+
float
|
|
80
|
+
Energy of one write operation in Joules
|
|
81
|
+
"""
|
|
82
|
+
return 20.45e-12
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
# Original CSV contents:
|
|
86
|
+
# tech_node,global_cycle_period,width|datawidth,energy,area,action
|
|
87
|
+
# 65nm,1e-9,128,26,23000000,read|write|update
|
|
88
|
+
# 65nm,1e-9,128,0, 23000000,leak
|
|
89
|
+
class IsaacChip2ChipLink(LibraryEstimatorClassBase):
|
|
90
|
+
"""
|
|
91
|
+
The chip-to-chip link from the ISAAC paper. This connects multiple chips together.
|
|
92
|
+
|
|
93
|
+
Parameters
|
|
94
|
+
----------
|
|
95
|
+
tech_node: float
|
|
96
|
+
Technology node in meters.
|
|
97
|
+
width: int
|
|
98
|
+
Width of the link in bits. This is the width of a read/write port.
|
|
99
|
+
"""
|
|
100
|
+
component_name = "isaac_chip2chip_link"
|
|
101
|
+
priority = 0.9
|
|
102
|
+
|
|
103
|
+
def __init__(self, tech_node: float, width: int = 128):
|
|
104
|
+
super().__init__(leak_power=0.0, area=23000000.0e-12)
|
|
105
|
+
self.tech_node: float = self.scale(
|
|
106
|
+
"tech_node",
|
|
107
|
+
tech_node,
|
|
108
|
+
65e-9,
|
|
109
|
+
tech_node_energy,
|
|
110
|
+
tech_node_area,
|
|
111
|
+
tech_node_leak,
|
|
112
|
+
)
|
|
113
|
+
self.width: int = self.scale("width", width, 128, linear, linear, linear)
|
|
114
|
+
|
|
115
|
+
@actionDynamicEnergy(bits_per_action="width")
|
|
116
|
+
def read(self) -> float:
|
|
117
|
+
"""
|
|
118
|
+
Returns the energy of one read operation in Joules.
|
|
119
|
+
|
|
120
|
+
Returns
|
|
121
|
+
-------
|
|
122
|
+
float
|
|
123
|
+
Energy of one read operation in Joules
|
|
124
|
+
"""
|
|
125
|
+
return 26.0e-12
|
|
126
|
+
|
|
127
|
+
@actionDynamicEnergy(bits_per_action="width")
|
|
128
|
+
def write(self) -> float:
|
|
129
|
+
"""
|
|
130
|
+
Returns the energy of one write operation in Joules.
|
|
131
|
+
|
|
132
|
+
Returns
|
|
133
|
+
-------
|
|
134
|
+
float
|
|
135
|
+
Energy of one write operation in Joules
|
|
136
|
+
"""
|
|
137
|
+
return 26.0e-12
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
# Original CSV contents:
|
|
141
|
+
# tech_node,global_cycle_period,width|datawidth,energy,area,action
|
|
142
|
+
# 32nm,1e-9,256,20.74,37500,read,energy in pJ; area in um^2;
|
|
143
|
+
# 32nm,1e-9,256,0,37500,leak|update|write
|
|
144
|
+
# # To match the paper where ISAAC shares each of these between 4 tiles. Quarter the area
|
|
145
|
+
# # relative to isaac_router
|
|
146
|
+
# # Assuming router BW = eDRAM BW per tile
|
|
147
|
+
# # Power * Time / (Reads+Writes) = Energy per read/write
|
|
148
|
+
# # (42e-3 / 4 / 12) power
|
|
149
|
+
# # (16384 / ((128*8*10^7*1.2) * 100 / 128)) time for DACs/ADCs to consume entire input buffer
|
|
150
|
+
# # (16384 + 2048) / 256 reads+writes
|
|
151
|
+
# # (42e-3 / 4 / 12) * (16384 / ((128*8*10^7*1.2) * 100 / 128)) / ((16384 + 2048) / 256) * 1e12
|
|
152
|
+
class IsaacRouterSharedByFour(LibraryEstimatorClassBase):
|
|
153
|
+
"""
|
|
154
|
+
This is the router from the ISAAC paper. In the paper, it is shared by four tiles,
|
|
155
|
+
so this area is divided by four to match the paper.
|
|
156
|
+
"""
|
|
157
|
+
|
|
158
|
+
component_name = "isaac_router_shared_by_four"
|
|
159
|
+
priority = 0.9
|
|
160
|
+
|
|
161
|
+
def __init__(self, tech_node: float, width: int = 256):
|
|
162
|
+
super().__init__(leak_power=0.0, area=37500.0e-12)
|
|
163
|
+
self.tech_node: float = self.scale(
|
|
164
|
+
"tech_node",
|
|
165
|
+
tech_node,
|
|
166
|
+
32e-9,
|
|
167
|
+
tech_node_energy,
|
|
168
|
+
tech_node_area,
|
|
169
|
+
tech_node_leak,
|
|
170
|
+
)
|
|
171
|
+
self.width: int = self.scale("width", width, 256, linear, linear, linear)
|
|
172
|
+
|
|
173
|
+
@actionDynamicEnergy(bits_per_action="width")
|
|
174
|
+
def read(self) -> float:
|
|
175
|
+
"""
|
|
176
|
+
Returns the energy to transfer data in Joules.
|
|
177
|
+
|
|
178
|
+
Parameters
|
|
179
|
+
----------
|
|
180
|
+
bits_per_action: int
|
|
181
|
+
The number of bits transferred.
|
|
182
|
+
|
|
183
|
+
Returns
|
|
184
|
+
-------
|
|
185
|
+
float
|
|
186
|
+
Energy to transfer data in Joules
|
|
187
|
+
"""
|
|
188
|
+
return self.transfer()
|
|
189
|
+
|
|
190
|
+
@actionDynamicEnergy(bits_per_action="width")
|
|
191
|
+
def write(self) -> float:
|
|
192
|
+
"""
|
|
193
|
+
Write energy is zero because transfer costs are already included in the read
|
|
194
|
+
energy.
|
|
195
|
+
|
|
196
|
+
Parameters
|
|
197
|
+
----------
|
|
198
|
+
bits_per_action: int
|
|
199
|
+
The number of bits transferred.
|
|
200
|
+
|
|
201
|
+
Returns
|
|
202
|
+
-------
|
|
203
|
+
float
|
|
204
|
+
Energy to transfer data in Joules
|
|
205
|
+
"""
|
|
206
|
+
return 0
|
|
207
|
+
|
|
208
|
+
@actionDynamicEnergy(bits_per_action="width")
|
|
209
|
+
def transfer(self) -> float:
|
|
210
|
+
"""
|
|
211
|
+
Returns the energy to transfer data in Joules.
|
|
212
|
+
|
|
213
|
+
Parameters
|
|
214
|
+
----------
|
|
215
|
+
bits_per_action: int
|
|
216
|
+
The number of bits transferred.
|
|
217
|
+
|
|
218
|
+
Returns
|
|
219
|
+
-------
|
|
220
|
+
float
|
|
221
|
+
Energy to transfer data in Joules
|
|
222
|
+
"""
|
|
223
|
+
return 20.74e-12
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
# Original CSV contents:
|
|
227
|
+
# tech_node,global_cycle_period,resolution,energy,area,n_instances,action
|
|
228
|
+
# 32nm,1e-9,8,1.666666667,1200,1,convert|read
|
|
229
|
+
# 32nm,1e-9,8,0,1200,1,leak|update|write
|
|
230
|
+
# # Energy: 16*10^-3 W / (1.2*8*10^9 ADC BW) * 10 ^ 12 J->pJ
|
|
231
|
+
# # 16*10^-3 / (1.2*8*10^9) * 10 ^ 12
|
|
232
|
+
# # Area: 9600um^2 / 8
|
|
233
|
+
# # L. Kull et al.," ""A 3.1mW 8b 1.2GS/s single-channel asynchronous SAR ADC
|
|
234
|
+
# # with alternate comparators for enhanced speed in 32nm digital SOI
|
|
235
|
+
# # CMOS",2013,pp. 468-469,doi: 10.1109/ISSCC.2013.6487818.," 2013 IEEE
|
|
236
|
+
# # International Solid-State Circuits Conference Digest of Technical Papers
|
|
237
|
+
# # Below are scaled versions based on M. Saberi, R. Lotfi, K. Mafinezhad, W.
|
|
238
|
+
# # Serdijn et al., “Analysis of Power Consumption and Linearity in Capacitive
|
|
239
|
+
# # Digital-to-Analog Converters used in Successive Approximation ADCs,” 2011.
|
|
240
|
+
# # 32nm,1e-9,4,0.79,361.04,1,convert|read
|
|
241
|
+
# # 32nm,1e-9,5,0.99,476.91,1,convert|read
|
|
242
|
+
# # 32nm,1e-9,6,1.20,626.91,1,convert|read
|
|
243
|
+
# # 32nm,1e-9,7,1.42,845.18,1,convert|read
|
|
244
|
+
# # 32nm,1e-9,8,1.67,1200,1,convert|read
|
|
245
|
+
# # 32nm,1e-9,9,1.969078145,1827.911647,1,convert|read
|
|
246
|
+
# # 32nm,1e-9,10,2.379022742,3002.008032,1,convert|read
|
|
247
|
+
class IsaacADC(LibraryEstimatorClassBase):
|
|
248
|
+
"""
|
|
249
|
+
The analog-digital-converter (ADC) from the ISAAC paper.
|
|
250
|
+
|
|
251
|
+
Parameters
|
|
252
|
+
----------
|
|
253
|
+
tech_node: float
|
|
254
|
+
Technology node in meters.
|
|
255
|
+
resolution: int
|
|
256
|
+
Resolution of the ADC in bits.
|
|
257
|
+
"""
|
|
258
|
+
component_name = "isaac_adc"
|
|
259
|
+
priority = 0.9
|
|
260
|
+
|
|
261
|
+
def __init__(self, tech_node: float, resolution: int = 8):
|
|
262
|
+
super().__init__(leak_power=0.0, area=1200.0e-12)
|
|
263
|
+
self.tech_node: float = self.scale(
|
|
264
|
+
"tech_node",
|
|
265
|
+
tech_node,
|
|
266
|
+
32e-9,
|
|
267
|
+
tech_node_energy,
|
|
268
|
+
tech_node_area,
|
|
269
|
+
tech_node_leak,
|
|
270
|
+
)
|
|
271
|
+
self.resolution: int = self.scale(
|
|
272
|
+
"resolution", resolution, 8, pow_base(2), pow_base(2), pow_base(2)
|
|
273
|
+
)
|
|
274
|
+
|
|
275
|
+
@actionDynamicEnergy
|
|
276
|
+
def convert(self) -> float:
|
|
277
|
+
"""
|
|
278
|
+
Returns the energy of one ADC conversion in Joules
|
|
279
|
+
|
|
280
|
+
Returns
|
|
281
|
+
-------
|
|
282
|
+
float
|
|
283
|
+
Energy of one ADC conversion in Joules
|
|
284
|
+
"""
|
|
285
|
+
return 1.666666667e-12
|
|
286
|
+
|
|
287
|
+
@actionDynamicEnergy
|
|
288
|
+
def read(self) -> float:
|
|
289
|
+
"""
|
|
290
|
+
Returns the energy of one ADC conversion in Joules
|
|
291
|
+
|
|
292
|
+
Returns
|
|
293
|
+
-------
|
|
294
|
+
float
|
|
295
|
+
Energy of one ADC conversion in Joules
|
|
296
|
+
"""
|
|
297
|
+
return 1.666666667e-12
|
|
298
|
+
|
|
299
|
+
|
|
300
|
+
# Original CSV contents:
|
|
301
|
+
# tech_node,global_cycle_period,width|datawidth,energy,area,action
|
|
302
|
+
# 32nm,1e-9,256,20.74,150000,read,energy in pJ; area in um^2;
|
|
303
|
+
# 32nm,1e-9,256,0,150000,leak|update|write
|
|
304
|
+
# # ISAAC shares each of these between 4 tiles
|
|
305
|
+
# # Assuming router BW = eDRAM BW per tile
|
|
306
|
+
# # Power * Time / (Reads+Writes) = Energy per read/write
|
|
307
|
+
# # (42e-3 / 4 / 12) power
|
|
308
|
+
# # (16384 / ((128*8*10^7*1.2) * 100 / 128)) time for DACs/ADCs to consume entire input buffer
|
|
309
|
+
# # (16384 + 2048) / 256 reads+writes
|
|
310
|
+
# # (42e-3 / 4 / 12) * (16384 / ((128*8*10^7*1.2) * 100 / 128)) / ((16384 + 2048) / 256) * 1e12
|
|
311
|
+
class IsaacRouter(LibraryEstimatorClassBase):
|
|
312
|
+
"""
|
|
313
|
+
The router from the ISAAC paper. This is the router shared by four tiles in the
|
|
314
|
+
paper, so divide this area by four if you'd like to get the per-tile area from the
|
|
315
|
+
paper.
|
|
316
|
+
|
|
317
|
+
Parameters
|
|
318
|
+
----------
|
|
319
|
+
tech_node: float
|
|
320
|
+
Technology node in meters.
|
|
321
|
+
width: int
|
|
322
|
+
Width of the router in bits. This is the width of a read/write port.
|
|
323
|
+
"""
|
|
324
|
+
component_name = "isaac_router"
|
|
325
|
+
priority = 0.9
|
|
326
|
+
|
|
327
|
+
def __init__(self, tech_node: float, width: int = 256):
|
|
328
|
+
super().__init__(leak_power=0.0, area=150000.0e-12)
|
|
329
|
+
self.tech_node: float = self.scale(
|
|
330
|
+
"tech_node",
|
|
331
|
+
tech_node,
|
|
332
|
+
32e-9,
|
|
333
|
+
tech_node_energy,
|
|
334
|
+
tech_node_area,
|
|
335
|
+
tech_node_leak,
|
|
336
|
+
)
|
|
337
|
+
self.width: int = self.scale("width", width, 256, linear, linear, linear)
|
|
338
|
+
|
|
339
|
+
@actionDynamicEnergy(bits_per_action="width")
|
|
340
|
+
def read(self) -> float:
|
|
341
|
+
"""
|
|
342
|
+
Returns the energy to transfer data in Joules.
|
|
343
|
+
|
|
344
|
+
Returns
|
|
345
|
+
-------
|
|
346
|
+
float
|
|
347
|
+
Energy to transfer data in Joules
|
|
348
|
+
"""
|
|
349
|
+
return self.transfer()
|
|
350
|
+
|
|
351
|
+
@actionDynamicEnergy(bits_per_action="width")
|
|
352
|
+
def write(self) -> float:
|
|
353
|
+
"""
|
|
354
|
+
Returns the energy to transfer data in Joules.
|
|
355
|
+
|
|
356
|
+
Returns
|
|
357
|
+
-------
|
|
358
|
+
float
|
|
359
|
+
Energy to transfer data in Joules
|
|
360
|
+
"""
|
|
361
|
+
return 0
|
|
362
|
+
|
|
363
|
+
|
|
364
|
+
@actionDynamicEnergy(bits_per_action="width")
|
|
365
|
+
def transfer(self) -> float:
|
|
366
|
+
"""
|
|
367
|
+
Returns the energy to transfer data in Joules.
|
|
368
|
+
|
|
369
|
+
Parameters
|
|
370
|
+
----------
|
|
371
|
+
bits_per_action: int
|
|
372
|
+
The number of bits transferred.
|
|
373
|
+
|
|
374
|
+
Returns
|
|
375
|
+
"""
|
|
376
|
+
return 20.74e-12
|
|
377
|
+
|
|
378
|
+
|
|
379
|
+
# Original CSV contents:
|
|
380
|
+
# tech_node,global_cycle_period,width|datawidth,energy,area,action
|
|
381
|
+
# 32nm,1e-9,16,0.021,60,shift_add|read|write,energy in pJ; area in um^2
|
|
382
|
+
# 32nm,1e-9,16,0.00E+00,60,leak|update
|
|
383
|
+
# # Energy: 16*10^-3 W / (1.2*8*10^9 ADC BW) * 10 ^ 12 J->pJ
|
|
384
|
+
# # Energy: .2e-3 W / (1.2*8*10^9 ADC BW) * 10 ^ 12 J->pJ
|
|
385
|
+
# # .2e-3 / (1.2*8*10^9) * 10 ^ 12
|
|
386
|
+
# # There are 4 of these in an ISAAC IMA
|
|
387
|
+
class IsaacShiftAdd(LibraryEstimatorClassBase):
|
|
388
|
+
"""
|
|
389
|
+
The shift-and-add unit from the ISAAC paper. This unit will sum and accumulate
|
|
390
|
+
values in a register, while also shifting the register contents to accept various
|
|
391
|
+
power-of-two scaling factors for the summed values.
|
|
392
|
+
|
|
393
|
+
Parameters
|
|
394
|
+
----------
|
|
395
|
+
tech_node: float
|
|
396
|
+
Technology node in meters.
|
|
397
|
+
width: int
|
|
398
|
+
Width of the shift-and-add unit in bits. This is the number of bits of each
|
|
399
|
+
input value that is added to the register.
|
|
400
|
+
"""
|
|
401
|
+
component_name = "isaac_shift_add"
|
|
402
|
+
priority = 0.9
|
|
403
|
+
|
|
404
|
+
def __init__(self, tech_node: float, width: int = 16):
|
|
405
|
+
super().__init__(leak_power=0.0, area=60.0e-12)
|
|
406
|
+
self.tech_node: float = self.scale(
|
|
407
|
+
"tech_node",
|
|
408
|
+
tech_node,
|
|
409
|
+
32e-9,
|
|
410
|
+
tech_node_energy,
|
|
411
|
+
tech_node_area,
|
|
412
|
+
tech_node_leak,
|
|
413
|
+
)
|
|
414
|
+
self.width: int = self.scale("width", width, 16, linear, linear, linear)
|
|
415
|
+
|
|
416
|
+
@actionDynamicEnergy
|
|
417
|
+
def shift_add(self) -> float:
|
|
418
|
+
"""
|
|
419
|
+
Returns the energy of one shift-and-add operation in Joules.
|
|
420
|
+
|
|
421
|
+
Returns
|
|
422
|
+
-------
|
|
423
|
+
float
|
|
424
|
+
Energy of one shift-and-add operation in Joules
|
|
425
|
+
"""
|
|
426
|
+
return 0.021e-12
|
|
427
|
+
|
|
428
|
+
@actionDynamicEnergy
|
|
429
|
+
def read(self) -> float:
|
|
430
|
+
"""
|
|
431
|
+
Returns the energy to read the shift-and-add unit's output in Joules.
|
|
432
|
+
|
|
433
|
+
Returns
|
|
434
|
+
-------
|
|
435
|
+
float
|
|
436
|
+
Energy to read the shift-and-add unit's output in Joules
|
|
437
|
+
"""
|
|
438
|
+
return 0
|
|
439
|
+
|
|
440
|
+
@actionDynamicEnergy
|
|
441
|
+
def write(self) -> float:
|
|
442
|
+
"""
|
|
443
|
+
Returns the energy of one shift-and-add operation in Joules.
|
|
444
|
+
|
|
445
|
+
Returns
|
|
446
|
+
-------
|
|
447
|
+
float
|
|
448
|
+
Energy of one shift-and-add operation in Joules
|
|
449
|
+
"""
|
|
450
|
+
return 0.021e-12
|
|
451
|
+
|
|
452
|
+
|
|
453
|
+
# Original CSV contents:
|
|
454
|
+
# tech_node,global_cycle_period,width|datawidth,energy,area,action
|
|
455
|
+
# 32nm,1e-9,1,0.054,29.296875,read,energy in pJ; area in um^2;
|
|
456
|
+
# 32nm,1e-9,1,0,29.296875,leak|update|write,energy in pJ; area in um^2;
|
|
457
|
+
# # Power * Time / (Reads+Writes) = Energy per read/write
|
|
458
|
+
# # (7e-3 / 12 W/IMA) power
|
|
459
|
+
# # (16384 / ((128*8*10^7*1.2) * 100 / 128)) time for DACs/ADCs to consume entire input buffer
|
|
460
|
+
# # (16384 + 2048) * reads+writes
|
|
461
|
+
# # (7e-3 / 12) * (16384 / ((128*8*10^7*1.2) * 100 / 128)) / ((16384 + 2048)) * 1e12
|
|
462
|
+
# # Assuming bus BW = eDRAM BW
|
|
463
|
+
# # Area reported per IMA. In ISAAC, a bus connects 12 IMAs
|
|
464
|
+
# # Area: 7500 / (Width 256) = 29.296875 um^2 per bit width
|
|
465
|
+
class IsaacEDRAMBus(LibraryEstimatorClassBase):
|
|
466
|
+
"""
|
|
467
|
+
The eDRAM bus from the ISAAC paper. This bus connects the eDRAM to the router.
|
|
468
|
+
|
|
469
|
+
Parameters
|
|
470
|
+
----------
|
|
471
|
+
tech_node: float
|
|
472
|
+
Technology node in meters.
|
|
473
|
+
width: int
|
|
474
|
+
Width of the eDRAM bus in bits. This is the width of a read/write port.
|
|
475
|
+
"""
|
|
476
|
+
component_name = "isaac_eDRAM_bus"
|
|
477
|
+
priority = 0.9
|
|
478
|
+
|
|
479
|
+
def __init__(self, tech_node: float, width: int = 1):
|
|
480
|
+
super().__init__(leak_power=0.0, area=29.296875e-12)
|
|
481
|
+
self.tech_node: float = self.scale(
|
|
482
|
+
"tech_node",
|
|
483
|
+
tech_node,
|
|
484
|
+
32e-9,
|
|
485
|
+
tech_node_energy,
|
|
486
|
+
tech_node_area,
|
|
487
|
+
tech_node_leak,
|
|
488
|
+
)
|
|
489
|
+
self.width: int = self.scale("width", width, 1, linear, linear, linear)
|
|
490
|
+
|
|
491
|
+
@actionDynamicEnergy(bits_per_action="width")
|
|
492
|
+
def read(self) -> float:
|
|
493
|
+
"""
|
|
494
|
+
Returns the energy to read the eDRAM bus in Joules.
|
|
495
|
+
|
|
496
|
+
Parameters
|
|
497
|
+
----------
|
|
498
|
+
bits_per_action: int
|
|
499
|
+
The number of bits transferred.
|
|
500
|
+
|
|
501
|
+
Returns
|
|
502
|
+
-------
|
|
503
|
+
float
|
|
504
|
+
Energy to read the eDRAM bus in Joules
|
|
505
|
+
"""
|
|
506
|
+
return self.transfer()
|
|
507
|
+
|
|
508
|
+
@actionDynamicEnergy(bits_per_action="width")
|
|
509
|
+
def transfer(self) -> float:
|
|
510
|
+
"""
|
|
511
|
+
Returns the energy to transfer data in Joules.
|
|
512
|
+
|
|
513
|
+
Parameters
|
|
514
|
+
----------
|
|
515
|
+
bits_per_action: int
|
|
516
|
+
The number of bits transferred.
|
|
517
|
+
|
|
518
|
+
Returns
|
|
519
|
+
-------
|
|
520
|
+
float
|
|
521
|
+
Energy to transfer data in Joules
|
|
522
|
+
"""
|
|
523
|
+
return 0.054e-12
|
|
524
|
+
|
|
525
|
+
@actionDynamicEnergy(bits_per_action="width")
|
|
526
|
+
def write(self) -> float:
|
|
527
|
+
"""
|
|
528
|
+
Returns 0 because transfer costs are already included in the read energy.
|
|
529
|
+
|
|
530
|
+
Parameters
|
|
531
|
+
----------
|
|
532
|
+
bits_per_action: int
|
|
533
|
+
The number of bits transferred.
|
|
534
|
+
|
|
535
|
+
Returns
|
|
536
|
+
-------
|
|
537
|
+
float
|
|
538
|
+
Zero
|
|
539
|
+
"""
|
|
540
|
+
return 0
|
|
541
|
+
|
|
542
|
+
|
|
543
|
+
# Original CSV contents:
|
|
544
|
+
# tech_node,global_cycle_period,resolution,energy,area,rows,action
|
|
545
|
+
# 32nm,1e-9,1,0.41667,0.166015625,1,drive|read
|
|
546
|
+
# 32nm,1e-9,1,0,0.166015625,1,write|leak|update
|
|
547
|
+
# # Energy: 4*10^-3 W / (128*8*10^7*1.2 DAC BW) * 10 ^ 12 J->pJ * 128/100 underutilized due to ADC
|
|
548
|
+
# # 4e-3 / (128 * 8 * 1.2 * 10 ^ 7) * 10 ^ 12 * 128/100
|
|
549
|
+
# # 0.3255 * 8 * 128 * 1.2e9 / 100 * 1e-9
|
|
550
|
+
# # Area: 170um^2 / 128 / 8
|
|
551
|
+
class IsaacDAC(LibraryEstimatorClassBase):
|
|
552
|
+
"""
|
|
553
|
+
The digital-analog converter (DAC) from the ISAAC paper.
|
|
554
|
+
|
|
555
|
+
Parameters
|
|
556
|
+
----------
|
|
557
|
+
tech_node: float
|
|
558
|
+
Technology node in meters.
|
|
559
|
+
resolution: int
|
|
560
|
+
Resolution of the DAC in bits.
|
|
561
|
+
"""
|
|
562
|
+
component_name = "isaac_dac"
|
|
563
|
+
priority = 0.9
|
|
564
|
+
|
|
565
|
+
def __init__(self, tech_node: float, resolution: int = 1, rows: int = 1):
|
|
566
|
+
super().__init__(leak_power=0.0, area=0.166015625e-12)
|
|
567
|
+
self.tech_node: float = self.scale(
|
|
568
|
+
"tech_node",
|
|
569
|
+
tech_node,
|
|
570
|
+
32e-9,
|
|
571
|
+
tech_node_energy,
|
|
572
|
+
tech_node_area,
|
|
573
|
+
tech_node_leak,
|
|
574
|
+
)
|
|
575
|
+
self.resolution: int = self.scale(
|
|
576
|
+
"resolution", resolution, 1, pow_base(2), pow_base(2), pow_base(2)
|
|
577
|
+
)
|
|
578
|
+
self.rows: int = self.scale("rows", rows, 1, linear, noscale, noscale)
|
|
579
|
+
|
|
580
|
+
@actionDynamicEnergy
|
|
581
|
+
def convert(self) -> float:
|
|
582
|
+
"""
|
|
583
|
+
Returns the energy to convert with the the DAC in Joules.
|
|
584
|
+
|
|
585
|
+
Returns
|
|
586
|
+
-------
|
|
587
|
+
float
|
|
588
|
+
Energy to convert with the the DAC in Joules
|
|
589
|
+
"""
|
|
590
|
+
return 0.41667e-12
|
|
591
|
+
|
|
592
|
+
@actionDynamicEnergy
|
|
593
|
+
def read(self) -> float:
|
|
594
|
+
"""
|
|
595
|
+
Returns the energy to read the DAC in Joules.
|
|
596
|
+
|
|
597
|
+
Returns
|
|
598
|
+
-------
|
|
599
|
+
float
|
|
600
|
+
Energy to read the DAC in Joules
|
|
601
|
+
"""
|
|
602
|
+
return 0.41667e-12
|