[SRAM-PIM Core Circuit] Design 256x1 Analog CIM
"256x1 Analog CIM"
1. Introduction
Cell Array Size가 256x1이므로 256개의 Input이 256개의 Weight가 MAC 연산을 통해 1개의 4-bit Digital 값을 출력
· WL_BL (Wordline)
Bit-Cell의 문을 여닫는 Switch 제어 신호
Weight 데이터를 Bit-Cell에 새로 쓰거나 저장된 값을 읽어올 때 이 신호를 High 시켜 Tr On(평소 연산 수행 시 Low로 Tr Off)
· BL/BLB
Bit-Cell에 실제로 밀어 넣을 Weight 데이터가 지나다니는 데이터 Bus
이 셀에 Weight '+1'을 저장하고 싶다면 주변 회로에서 BL=1/BLB=0 전압을 걸어둔 상태로 WL_BL 문을 Open
→ 내부 Node VL=1/VR=0으로 설정(Weight '-1'을 저장하고 싶다면 반대로 BL=0/BLB=1 → VL=0/VR=1)
· VL/VR
SRAM Bit-Cell 내부에서 Weight 데이터가 머무르는 저장 공간
VL/VR은 항상 반대되는 상호 반전 상태 유지
Weight '+1'인 경우(VL=1/VR=0) : VL=1이므로 왼쪽 Tr ON → MWL로 들어온 신호가 Capacitor를 통과해 MBL로 전달
Weight '-1'인 경우(VL=0/VR=1) : VR=1이므로 오른쪽 Tr ON → MWLB로 들어온 신호가 Capacitor를 통과해 MBL로 전달
· MWL/MWLB
오직 MAC 연산을 수행하기 위해 입력 데이터를 전달하는 전용 신호선
2. Operation
① 연산 시작 전, MWL/MWLB를 Vrst(0.5VDR)인 0.4V로 Pre-Charge
② 입력 데이터 구분 (+1/-1)
'+1' 입력 : MWL = VDR로 상승/MWLB = Vss로 하강
'-1' 입력 : MWL = Vss로 하강/MWLB = VDR로 상승
③ Weight 데이터 구분 (+1/-1)
'+1' Weight (MWL Tr On)
· '+1' 입력 : MWL = VDR로 상승 → MBL 전압 상승 (곱셈 결과 +1)
· '-1' 입력 : MWL = Vss로 하강 → MBL 전압 하강 (곱셈 결과 -1)
'-1' Weight (MWLB Tr On)
· '+1' 입력 : MWLB = Vss로 하강 → MBL 전압 하강 (곱셈 결과 -1)
· '-1' 입력 : MWLB = VDR로 상승 → MBL 전압 상승 (곱셈 결과 +1)
④ 곱셈 결과를 누적한 값이 11단계 Flash ADC를 통해 4-bit Digital로 변환
3. Architecture
<Comparator>
MBL > Vref → out = 1 / MBL < Vref → out = 0
이전에 설계한 Flash ADC 사용 시 MBL과 Vref를 비교기에 동시에 직접 연결하면 비교기가 0/1을 판별하며 강하게 켜지고 꺼질 때 발생하는 Switching Noise가 MBL로 역류하여 영향을 줌
∴ C3SRAM 논문에서 제시한 Comparator 방식을 사용하여 계산 시 연결을 끊어 MBL로 역류하여 영향을 주는 것을 방지
<Edge Detector>
낮은 Bit 자리의 값이 a, 높은 Bit 자리의 값이 b로 인가a=1, b=0인 경우 out=1 / a=1, b=1인 경우 out=0이 되어 경계값 찾기
4. Setting & Result
[('Sum = 0' Input) x ('+1' Weight)]
<('Sum = 0' Input) x ('+1' Weight)>
<'Sum = 0'일 때의 MBL 전압>
rst0가 Low로 떨어질 때 MBL과 Capacitor 사이의 Switch가 Off 되어 이 순간의 MBL 전압이 Capacitor에 영구적으로 갇힘→ rst0가 Low인 순간의 전압이 Vref와 비교
<Step of Vref>
'Sum = 0'일 때 MBL 전압이 약 0.385V이므로 이를 중간점으로 잡고 30mV 간격으로 11단계를 나눔<'Sum = 0'일 때의 MBL 전압과 Vref>
[('Sum = +50' Input) x ('+1' Weight)]
Vref6 < MBL < Vref7 → result = 0111
[(Random Input) x (Random Weight)]
<(Random Input) x (Random Weight)>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | import random ROWS = 256 COLS = 1 V_RST = 0.385 # Sum=0일 때의 기준 전압 V_UNIT = 0.0013 # 셀 하나당 전압 변화량 {(+50 = 0.450V) - (0 = 0.385V)} / 50 # ADC 전압 단계 V_STEPS = [0.25, 0.28, 0.31, 0.34, 0.37, 0.40, 0.43, 0.46, 0.49, 0.52] # 데이터 생성 (Input: -1, 0, 1 / Weight: -1, 1) inputs = [random.choice([-1, 0, 1]) for _ in range(ROWS)] weights = [[random.choice([-1, 1]) for _ in range(COLS)] for _ in range(ROWS)] # --- [SPICE Stimuli 출력] --- print("*" * 65) print(" [1] SPICE STIMULI (DIFFERENTIAL + ZERO INPUT)") print("*" * 65) print("\n# --- 차동 입력 ---") for i, inp in enumerate(inputs): if inp == 1: print(f"vmwl{i:<4} MWL<{i}> 0 pwl(0 0.4 15n 0.4 15.1n 0.8)") print(f"vmwlb{i:<3} MWLB<{i}> 0 pwl(0 0.4 15n 0.4 15.1n xvss)") elif inp == -1: print(f"vmwl{i:<4} MWL<{i}> 0 pwl(0 0.4 15n 0.4 15.1n xvss)") print(f"vmwlb{i:<3} MWLB<{i}> 0 pwl(0 0.4 15n 0.4 15.1n 0.8)") else: # Input 0 case print(f"vmwl{i:<4} MWL<{i}> 0 pwl(0 0.4 15n 0.4 15.1n 0.4)") print(f"vmwlb{i:<3} MWLB<{i}> 0 pwl(0 0.4 15n 0.4 15.1n 0.4)") print("\n# --- 초기 가중치 (.ic) ---") for r in range(ROWS): for c in range(COLS): cell_idx = r * COLS + c if weights[r][c] == 1: print(f".ic v(VL<{cell_idx}>)=xvdd v(VR<{cell_idx}>)=xvss") else: print(f".ic v(VL<{cell_idx}>)=xvss v(VR<{cell_idx}>)=xvdd") # --- [Step 기준 결과 예측] --- print("\n" + "*" * 50) print(" EXPECTED RESULTS (USER DEFINED STEP CRITERIA)") print("*" * 50) def classify_adc(v_mbl): # <Step Of Vref> 기준에 따른 분류 로직 for code, threshold in enumerate(V_STEPS): if v_mbl < threshold: return code return 10 # 0.52V 이상일 경우 표의 마지막 값인 1010(Code 10) 출력 adc_results = [] for c in range(COLS): dot_sum = sum(inputs[r] * weights[r][c] for r in range(ROWS)) # 물리적 전압 계산: 초기전압 + (누적합 * 단위전압) predicted_v = V_RST + (dot_sum * V_UNIT) code = classify_adc(predicted_v) adc_results.append(code) print(f"Sum={dot_sum:>4} | Voltage={predicted_v:.4f}V | Code={code:>2}") | cs |
<Python Code for Random Input & Random Weight>
'Sum = 0'일 때 MBL 전압은 0.385V, 'Sum = +50'일 때 MBL 전압은 0.450V→ 기준 전압 = 0.385V, 전압 변화량 = {(+50 = 0.450V) - (0 = 0.385V)} / 50
5. Reference
▶ C3SRAM
https://hecess.blogspot.com/2026/01/sram-pim-core-circuit-study-c3sram-paper.html
댓글
댓글 쓰기