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,204 @@
|
|
|
1
|
+
"""
|
|
2
|
+
@INPROCEEDINGS{8465832,
|
|
3
|
+
author={Qiao, Ximing and Cao, Xiong and Yang, Huanrui and Song, Linghao and Li, Hai},
|
|
4
|
+
booktitle={2018 55th ACM/ESDA/IEEE Design Automation Conference (DAC)},
|
|
5
|
+
title={AtomLayer: A Universal ReRAM-Based CNN Accelerator with Atomic Layer Computation},
|
|
6
|
+
year={2018},
|
|
7
|
+
volume={},
|
|
8
|
+
number={},
|
|
9
|
+
pages={1-6},
|
|
10
|
+
doi={10.1109/DAC.2018.8465832}}
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from hwcomponents_library.base import LibraryEstimatorClassBase
|
|
14
|
+
from hwcomponents.scaling import *
|
|
15
|
+
from hwcomponents import actionDynamicEnergy
|
|
16
|
+
from .isaac import IsaacADC
|
|
17
|
+
from .isaac import IsaacDAC
|
|
18
|
+
from .isaac import IsaacEDRAM
|
|
19
|
+
from .isaac import IsaacEDRAMBus
|
|
20
|
+
from .isaac import IsaacRouter
|
|
21
|
+
from .isaac import IsaacShiftAdd
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
# Original CSV contents:
|
|
25
|
+
# tech_node,global_cycle_period,width|datawidth,depth,energy,area,action
|
|
26
|
+
# 32nm,1e-9,16,128,0.083,1620,read|write,energy in pJ; area in um^2;
|
|
27
|
+
# 32nm,1e-9,16,128,0,1620,update|leak
|
|
28
|
+
# # 1 read, 1 write per DAC activation
|
|
29
|
+
# # Reported power = 0.39 / 4 x DAC
|
|
30
|
+
# # 0.166015625 / 2 = 0.083
|
|
31
|
+
class AtomlayerRegisterLadder(LibraryEstimatorClassBase):
|
|
32
|
+
"""
|
|
33
|
+
A register ladder from the AtomLayer paper. Is a series of registers that shift
|
|
34
|
+
stored values along themselves.
|
|
35
|
+
|
|
36
|
+
Parameters
|
|
37
|
+
----------
|
|
38
|
+
tech_node : str
|
|
39
|
+
The technology node in meters.
|
|
40
|
+
width : int, optional
|
|
41
|
+
The width of the register ladder in bits. This is the bits in each register.
|
|
42
|
+
Total size = width * depth.
|
|
43
|
+
depth : int, optional
|
|
44
|
+
The number of entries in the register ladder, each with `width` bits. Total size
|
|
45
|
+
= width * depth.
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
component_name = "atomlayer_register_ladder"
|
|
49
|
+
priority = 0.9
|
|
50
|
+
|
|
51
|
+
def __init__(self, tech_node: float, width: int = 16, depth: int = 128):
|
|
52
|
+
super().__init__(leak_power=0.0, area=1620.0e-12)
|
|
53
|
+
self.tech_node: float = self.scale(
|
|
54
|
+
"tech_node",
|
|
55
|
+
tech_node,
|
|
56
|
+
32e-9,
|
|
57
|
+
tech_node_energy,
|
|
58
|
+
tech_node_area,
|
|
59
|
+
tech_node_leak,
|
|
60
|
+
)
|
|
61
|
+
self.width: int = self.scale("width", width, 16, linear, linear, linear)
|
|
62
|
+
self.depth: int = self.scale(
|
|
63
|
+
"depth", depth, 128, linear, cacti_depth_energy, cacti_depth_energy
|
|
64
|
+
)
|
|
65
|
+
|
|
66
|
+
@actionDynamicEnergy(bits_per_action="width")
|
|
67
|
+
def read(self) -> float:
|
|
68
|
+
"""
|
|
69
|
+
Returns the energy for one read operation in Joules.
|
|
70
|
+
|
|
71
|
+
Parameters
|
|
72
|
+
----------
|
|
73
|
+
bits_per_action : int
|
|
74
|
+
The number of bits that are read.
|
|
75
|
+
|
|
76
|
+
Returns
|
|
77
|
+
-------
|
|
78
|
+
float
|
|
79
|
+
The energy for one read operation in Joules.
|
|
80
|
+
"""
|
|
81
|
+
return 0.083e-12
|
|
82
|
+
|
|
83
|
+
@actionDynamicEnergy(bits_per_action="width")
|
|
84
|
+
def write(self) -> float:
|
|
85
|
+
"""
|
|
86
|
+
Returns the energy for one write operation in Joules.
|
|
87
|
+
|
|
88
|
+
Parameters
|
|
89
|
+
----------
|
|
90
|
+
bits_per_action : int
|
|
91
|
+
The number of bits that are written.
|
|
92
|
+
|
|
93
|
+
Returns
|
|
94
|
+
-------
|
|
95
|
+
float
|
|
96
|
+
The energy for one write operation in Joules.
|
|
97
|
+
"""
|
|
98
|
+
return 0.083e-12
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
# Original CSV contents:
|
|
102
|
+
# tech_node,global_cycle_period,width|datawidth,depth,energy,area,action
|
|
103
|
+
# 32nm,1e-9,16,128,6.46,2100,read, energy in pJ; area in um^2;
|
|
104
|
+
# 32nm,1e-9,16,128,0,2100,write|update|leak
|
|
105
|
+
# # Power calculation for input buffers:
|
|
106
|
+
# # Power * Time / (Reads+Writes) = Energy per read/write
|
|
107
|
+
# # (1.24e-3 W) power * (16 * 100e-9s time/MAC / 1.2) / (128+128 reads+writes)
|
|
108
|
+
# # (1.24e-3) * (16 * 100e-9 / 1.2) / (128+128) * 1e12
|
|
109
|
+
# # Now for the transfers calculation, we also mark write energy = 0 so we don't
|
|
110
|
+
# # double charge for writes with the actual buffers. Only charge for reads when
|
|
111
|
+
# # another
|
|
112
|
+
# # buffer reads from the inter-buffer transfer network.
|
|
113
|
+
class AtomlayerInputBufferTransfers(LibraryEstimatorClassBase):
|
|
114
|
+
"""
|
|
115
|
+
This component measures transfer energy between input buffers in the AtomLayer
|
|
116
|
+
paper.
|
|
117
|
+
|
|
118
|
+
Parameters
|
|
119
|
+
----------
|
|
120
|
+
tech_node : str
|
|
121
|
+
The technology node in meters.
|
|
122
|
+
width : int, optional
|
|
123
|
+
The width of the read/write port of each input buffer in bits. Total size =
|
|
124
|
+
width * depth.
|
|
125
|
+
depth : int, optional
|
|
126
|
+
The number of entries in each input buffer, each with `width` bits. Total size =
|
|
127
|
+
width * depth.
|
|
128
|
+
"""
|
|
129
|
+
|
|
130
|
+
component_name = "atomlayer_input_buffer_transfers"
|
|
131
|
+
priority = 0.9
|
|
132
|
+
|
|
133
|
+
def __init__(self, tech_node: float, width: int = 16, depth: int = 128):
|
|
134
|
+
super().__init__(leak_power=0.0, area=2100.0e-12)
|
|
135
|
+
self.tech_node: float = self.scale(
|
|
136
|
+
"tech_node",
|
|
137
|
+
tech_node,
|
|
138
|
+
32e-9,
|
|
139
|
+
tech_node_energy,
|
|
140
|
+
tech_node_area,
|
|
141
|
+
tech_node_leak,
|
|
142
|
+
)
|
|
143
|
+
self.width: int = self.scale("width", width, 16, linear, linear, linear)
|
|
144
|
+
self.depth: int = self.scale(
|
|
145
|
+
"depth", depth, 128, linear, cacti_depth_energy, cacti_depth_energy
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
@actionDynamicEnergy(bits_per_action="width")
|
|
149
|
+
def read(self) -> float:
|
|
150
|
+
"""
|
|
151
|
+
Returns the energy for one read operation in Joules.
|
|
152
|
+
|
|
153
|
+
Parameters
|
|
154
|
+
----------
|
|
155
|
+
bits_per_action : int
|
|
156
|
+
The number of bits that are transferred.
|
|
157
|
+
|
|
158
|
+
Returns
|
|
159
|
+
-------
|
|
160
|
+
float
|
|
161
|
+
The energy for one transfer operation in Joules.
|
|
162
|
+
"""
|
|
163
|
+
return 6.46e-12
|
|
164
|
+
|
|
165
|
+
@actionDynamicEnergy(bits_per_action="width")
|
|
166
|
+
def transfer(self) -> float:
|
|
167
|
+
"""
|
|
168
|
+
Returns the energy for one transfer operation in Joules.
|
|
169
|
+
|
|
170
|
+
Parameters
|
|
171
|
+
----------
|
|
172
|
+
bits_per_action : int
|
|
173
|
+
The number of bits that are transferred.
|
|
174
|
+
|
|
175
|
+
Returns
|
|
176
|
+
-------
|
|
177
|
+
float
|
|
178
|
+
The energy for one transfer operation in Joules.
|
|
179
|
+
"""
|
|
180
|
+
return 6.46e-12
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
class AtomlayerADC(IsaacADC):
|
|
184
|
+
pass
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
class AtomlayerDAC(IsaacDAC):
|
|
188
|
+
pass
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
class AtomlayerRouter(IsaacRouter):
|
|
192
|
+
pass
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
class AtomlayerEDRAM(IsaacEDRAM):
|
|
196
|
+
pass
|
|
197
|
+
|
|
198
|
+
|
|
199
|
+
class AtomlayerEDRAMBus(IsaacEDRAMBus):
|
|
200
|
+
pass
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
class AtomlayerShiftAdd(IsaacShiftAdd):
|
|
204
|
+
pass
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
"""
|
|
2
|
+
@INPROCEEDINGS{9586247,
|
|
3
|
+
author={Song, Tao and Chen, Xiaoming and Zhang, Xiaoyu and Han, Yinhe},
|
|
4
|
+
booktitle={2021 58th ACM/IEEE Design Automation Conference (DAC)},
|
|
5
|
+
title={BRAHMS: Beyond Conventional RRAM-based Neural Network Accelerators Using Hybrid Analog Memory System},
|
|
6
|
+
year={2021},
|
|
7
|
+
volume={},
|
|
8
|
+
number={},
|
|
9
|
+
pages={1033-1038},
|
|
10
|
+
doi={10.1109/DAC18074.2021.9586247}}
|
|
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,resolution,energy,area,action
|
|
20
|
+
# 40nm,1e-9,8,0.291,438,read|convert
|
|
21
|
+
# 40nm,1e-9,8,0,438,update|write|leak
|
|
22
|
+
# # H. Chen,X. Zhot,F. Zhang and Q. Li,"A >3GHz ERBW 1.1GS/S 8B Two-Sten SAR ADC
|
|
23
|
+
# # with,Q. Yu Recursive-Weight DAC," 2018 IEEE Symposium on VLSI Circuits,pp.
|
|
24
|
+
# # 97-98,2018 doi: 10.1109/VLSIC.2018.8502370.
|
|
25
|
+
# # Reported energy: 0.32mW @ 1.1GHz
|
|
26
|
+
# # SAR ADC, so the DAC does 1 8b convert for every convert
|
|
27
|
+
# # E/op: .32e-3 W * 1 / 1.1e9 seconds * 1e12pJ/J =
|
|
28
|
+
# # .32e-3 / 1.1e9 * 1e12 = 0.291pJ/convert
|
|
29
|
+
# # Area from chip picture:
|
|
30
|
+
# # (Picture was scaled when I screencapped it)
|
|
31
|
+
# # 1629px * 743px / (2805px * 1625px) * 75e-6m * 22e-6m
|
|
32
|
+
# # = 1629 * 743 / (2805 * 1625) * 75 * 22 = 438um^2
|
|
33
|
+
class BrahmsDAC(LibraryEstimatorClassBase):
|
|
34
|
+
"""
|
|
35
|
+
Digital-analog converter (DAC) from the BRAHMS paper
|
|
36
|
+
|
|
37
|
+
Parameters
|
|
38
|
+
----------
|
|
39
|
+
tech_node: float
|
|
40
|
+
Technology node in meters
|
|
41
|
+
resolution: int
|
|
42
|
+
Resolution of the DAC in bits
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
component_name = "brahms_dac"
|
|
46
|
+
priority = 0.9
|
|
47
|
+
|
|
48
|
+
def __init__(self, tech_node: float, resolution: int = 8):
|
|
49
|
+
super().__init__(leak_power=0.0, area=438.0e-12)
|
|
50
|
+
self.tech_node: float = self.scale(
|
|
51
|
+
"tech_node",
|
|
52
|
+
tech_node,
|
|
53
|
+
40e-9,
|
|
54
|
+
tech_node_energy,
|
|
55
|
+
tech_node_area,
|
|
56
|
+
tech_node_leak,
|
|
57
|
+
)
|
|
58
|
+
self.resolution: int = self.scale(
|
|
59
|
+
"resolution", resolution, 8, pow_base(2), pow_base(2), pow_base(2)
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
@actionDynamicEnergy
|
|
63
|
+
def read(self) -> float:
|
|
64
|
+
"""
|
|
65
|
+
Returns the energy of one DAC conversion in Joules
|
|
66
|
+
|
|
67
|
+
Returns
|
|
68
|
+
-------
|
|
69
|
+
float
|
|
70
|
+
Energy of one DAC conversion in Joules
|
|
71
|
+
"""
|
|
72
|
+
return 0.291e-12
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
@actionDynamicEnergy
|
|
76
|
+
def convert(self) -> float:
|
|
77
|
+
"""
|
|
78
|
+
Returns the energy of one DAC conversion in Joules
|
|
79
|
+
|
|
80
|
+
Returns
|
|
81
|
+
-------
|
|
82
|
+
float
|
|
83
|
+
Energy of one DAC conversion in Joules
|
|
84
|
+
"""
|
|
85
|
+
return 0.291e-12
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
from hwcomponents_library.base import LibraryEstimatorClassBase
|
|
2
|
+
from hwcomponents.scaling import *
|
|
3
|
+
from hwcomponents import actionDynamicEnergy
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
# Original CSV contents:
|
|
7
|
+
# global_cycle_period,energy,area,n_instances,action
|
|
8
|
+
# 1e-9,0,0,1,read|update|leak|write|*
|
|
9
|
+
class DummyStorage(LibraryEstimatorClassBase):
|
|
10
|
+
"""
|
|
11
|
+
A dummy storage component. Has zero area, zero energy, and zero leakage power.
|
|
12
|
+
|
|
13
|
+
Parameters
|
|
14
|
+
----------
|
|
15
|
+
tech_node: float, optional
|
|
16
|
+
Technology node in meters. This is not used.
|
|
17
|
+
"""
|
|
18
|
+
component_name = "dummy_storage"
|
|
19
|
+
priority = 0.9
|
|
20
|
+
|
|
21
|
+
def __init__(self, tech_node: float | None = None):
|
|
22
|
+
super().__init__(leak_power=0.0, area=0.0)
|
|
23
|
+
self.tech_node: float = tech_node
|
|
24
|
+
|
|
25
|
+
@actionDynamicEnergy
|
|
26
|
+
def read(self) -> float:
|
|
27
|
+
"""
|
|
28
|
+
Returns the energy of one read operation in Joules. Energy is zero.
|
|
29
|
+
|
|
30
|
+
Returns
|
|
31
|
+
-------
|
|
32
|
+
float
|
|
33
|
+
Energy of one read operation in Joules
|
|
34
|
+
"""
|
|
35
|
+
return 0.0
|
|
36
|
+
|
|
37
|
+
@actionDynamicEnergy
|
|
38
|
+
def write(self) -> float:
|
|
39
|
+
"""
|
|
40
|
+
Returns the energy of one write operation in Joules. Energy is zero.
|
|
41
|
+
|
|
42
|
+
Returns
|
|
43
|
+
-------
|
|
44
|
+
float
|
|
45
|
+
Energy of one write operation in Joules
|
|
46
|
+
"""
|
|
47
|
+
return 0.0
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
# Original CSV contents:
|
|
51
|
+
# global_cycle_period,energy,area,n_instances,action
|
|
52
|
+
# 1e-9,0,0,1,read|update|leak|write|*
|
|
53
|
+
class DummyCompute(LibraryEstimatorClassBase):
|
|
54
|
+
"""
|
|
55
|
+
A dummy compute component. Has zero area, zero energy, and zero leakage power.
|
|
56
|
+
|
|
57
|
+
Parameters
|
|
58
|
+
----------
|
|
59
|
+
tech_node: float, optional
|
|
60
|
+
Technology node in meters. This is not used.
|
|
61
|
+
"""
|
|
62
|
+
component_name = "dummy_compute"
|
|
63
|
+
priority = 0.9
|
|
64
|
+
|
|
65
|
+
def __init__(self, tech_node: float | None = None):
|
|
66
|
+
super().__init__(leak_power=0.0, area=0.0)
|
|
67
|
+
self.tech_node: float = tech_node
|
|
68
|
+
|
|
69
|
+
@actionDynamicEnergy
|
|
70
|
+
def read(self) -> float:
|
|
71
|
+
"""
|
|
72
|
+
Returns the energy of one compute operation in Joules. Energy is zero.
|
|
73
|
+
|
|
74
|
+
Returns
|
|
75
|
+
-------
|
|
76
|
+
float
|
|
77
|
+
Energy of one compute operation in Joules
|
|
78
|
+
"""
|
|
79
|
+
return 0.0
|
|
80
|
+
|
|
81
|
+
@actionDynamicEnergy
|
|
82
|
+
def compute(self) -> float:
|
|
83
|
+
"""
|
|
84
|
+
Returns the energy of one compute operation in Joules. Energy is zero.
|
|
85
|
+
|
|
86
|
+
Returns
|
|
87
|
+
-------
|
|
88
|
+
float
|
|
89
|
+
Energy of one compute operation in Joules
|
|
90
|
+
"""
|
|
91
|
+
return 0.0
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
class DummyMemory(LibraryEstimatorClassBase):
|
|
95
|
+
"""
|
|
96
|
+
A dummy memory component. Has zero area, zero energy, and zero leakage power.
|
|
97
|
+
|
|
98
|
+
Parameters
|
|
99
|
+
----------
|
|
100
|
+
tech_node: float
|
|
101
|
+
Technology node in meters. This is not used.
|
|
102
|
+
"""
|
|
103
|
+
component_name = "dummy_memory"
|
|
104
|
+
priority = 0.9
|
|
105
|
+
|
|
106
|
+
def __init__(self, tech_node: float | None = None):
|
|
107
|
+
super().__init__(leak_power=0.0, area=0.0)
|
|
108
|
+
self.tech_node: float = tech_node
|
|
109
|
+
|
|
110
|
+
@actionDynamicEnergy
|
|
111
|
+
def read(self) -> float:
|
|
112
|
+
"""
|
|
113
|
+
Returns the energy of one read operation in Joules. Energy is zero.
|
|
114
|
+
|
|
115
|
+
Returns
|
|
116
|
+
-------
|
|
117
|
+
float
|
|
118
|
+
Energy of one read operation in Joules
|
|
119
|
+
"""
|
|
120
|
+
return 0.0
|
|
121
|
+
|
|
122
|
+
@actionDynamicEnergy
|
|
123
|
+
def write(self) -> float:
|
|
124
|
+
"""
|
|
125
|
+
Returns the energy of one write operation in Joules. Energy is zero.
|
|
126
|
+
|
|
127
|
+
Returns
|
|
128
|
+
-------
|
|
129
|
+
float
|
|
130
|
+
Energy of one write operation in Joules
|
|
131
|
+
"""
|
|
132
|
+
return 0.0
|
|
133
|
+
|
|
134
|
+
class DummyNetwork(LibraryEstimatorClassBase):
|
|
135
|
+
"""
|
|
136
|
+
A dummy network component. Has zero area, zero energy, and zero leakage power.
|
|
137
|
+
|
|
138
|
+
Parameters
|
|
139
|
+
----------
|
|
140
|
+
tech_node: float
|
|
141
|
+
Technology node in meters. This is not used.
|
|
142
|
+
"""
|
|
143
|
+
component_name = "dummy_network"
|
|
144
|
+
priority = 0.9
|
|
145
|
+
|
|
146
|
+
def __init__(self, tech_node: float | None = None):
|
|
147
|
+
super().__init__(leak_power=0.0, area=0.0)
|
|
148
|
+
self.tech_node: float = tech_node
|
|
149
|
+
|
|
150
|
+
@actionDynamicEnergy
|
|
151
|
+
def read(self) -> float:
|
|
152
|
+
"""
|
|
153
|
+
Returns the energy of one read operation in Joules. Energy is zero.
|
|
154
|
+
|
|
155
|
+
Returns
|
|
156
|
+
-------
|
|
157
|
+
float
|
|
158
|
+
Energy of one read operation in Joules
|
|
159
|
+
"""
|
|
160
|
+
return 0.0
|
|
161
|
+
|
|
162
|
+
@actionDynamicEnergy
|
|
163
|
+
def write(self) -> float:
|
|
164
|
+
"""
|
|
165
|
+
Returns the energy of one write operation in Joules. Energy is zero.
|
|
166
|
+
|
|
167
|
+
Returns
|
|
168
|
+
-------
|
|
169
|
+
float
|
|
170
|
+
Energy of one write operation in Joules
|
|
171
|
+
"""
|
|
172
|
+
return 0.0
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"""
|
|
2
|
+
@INPROCEEDINGS{9499856,
|
|
3
|
+
author={Yuan, Geng and Behnam, Payman and Li, Zhengang and Shafiee, Ali and Lin, Sheng and Ma, Xiaolong and Liu, Hang and Qian, Xuehai and Bojnordi, Mahdi Nazm and Wang, Yanzhi and Ding, Caiwen},
|
|
4
|
+
booktitle={2021 ACM/IEEE 48th Annual International Symposium on Computer Architecture (ISCA)},
|
|
5
|
+
title={FORMS: Fine-grained Polarized ReRAM-based In-situ Computation for Mixed-signal DNN Accelerator},
|
|
6
|
+
year={2021},
|
|
7
|
+
volume={},
|
|
8
|
+
number={},
|
|
9
|
+
pages={265-278},
|
|
10
|
+
doi={10.1109/ISCA52012.2021.00029}}
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
from hwcomponents_library.base import LibraryEstimatorClassBase
|
|
14
|
+
from hwcomponents.scaling import *
|
|
15
|
+
from hwcomponents import actionDynamicEnergy
|
|
16
|
+
from .isaac import IsaacDAC
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# Original CSV contents:
|
|
20
|
+
# tech_node,global_cycle_period,resolution,energy,area,n_instances,action
|
|
21
|
+
# 32nm,1e-9,4,0.22619,284.375,1,convert|read
|
|
22
|
+
# 32nm,1e-9,4,0,284.375,1,update|write|leak
|
|
23
|
+
# # Energy: 15.2*10^-3 W / (2.1*32*10^9 ADC BW) * 10 ^ 12 J->pJ
|
|
24
|
+
# # 15.2*10^-3 / (2.1*32*10^9) * 10 ^ 12
|
|
25
|
+
# # Area: 9100um^2 / 32
|
|
26
|
+
class FormsADC(LibraryEstimatorClassBase):
|
|
27
|
+
"""
|
|
28
|
+
The analog-digital-converter (ADC) from the FORMS paper.
|
|
29
|
+
|
|
30
|
+
Parameters
|
|
31
|
+
----------
|
|
32
|
+
tech_node: float
|
|
33
|
+
Technology node in meters.
|
|
34
|
+
resolution: int
|
|
35
|
+
Resolution of the ADC in bits.
|
|
36
|
+
"""
|
|
37
|
+
component_name = "forms_adc"
|
|
38
|
+
priority = 0.9
|
|
39
|
+
|
|
40
|
+
def __init__(self, tech_node: float, resolution: int = 4):
|
|
41
|
+
super().__init__(leak_power=0.0, area=284.375e-12)
|
|
42
|
+
self.tech_node: float = self.scale(
|
|
43
|
+
"tech_node",
|
|
44
|
+
tech_node,
|
|
45
|
+
32e-9,
|
|
46
|
+
tech_node_energy,
|
|
47
|
+
tech_node_area,
|
|
48
|
+
tech_node_leak,
|
|
49
|
+
)
|
|
50
|
+
self.resolution: int = self.scale(
|
|
51
|
+
"resolution", resolution, 4, pow_base(2), pow_base(2), pow_base(2)
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
@actionDynamicEnergy
|
|
55
|
+
def convert(self) -> float:
|
|
56
|
+
"""
|
|
57
|
+
Returns the energy of one ADC conversion in Joules
|
|
58
|
+
|
|
59
|
+
Returns
|
|
60
|
+
-------
|
|
61
|
+
float
|
|
62
|
+
Energy of one ADC conversion in Joules
|
|
63
|
+
"""
|
|
64
|
+
return 0.22619e-12
|
|
65
|
+
|
|
66
|
+
@actionDynamicEnergy
|
|
67
|
+
def read(self) -> float:
|
|
68
|
+
"""
|
|
69
|
+
Returns the energy of one ADC conversion operation in Joules
|
|
70
|
+
|
|
71
|
+
Returns
|
|
72
|
+
-------
|
|
73
|
+
float
|
|
74
|
+
Energy of one ADC conversion operation in Joules
|
|
75
|
+
"""
|
|
76
|
+
return 0.22619e-12
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class FormsDAC(IsaacDAC):
|
|
80
|
+
pass
|