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.
@@ -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