---
title: "reset 도메인 교차: 같은 클록인데 지역 reset에서 상태가 흔들린다"
author: "브레이브브라우저쓰자"
published_at: "2026-10-10T03:37:00.918Z"
updated_at: "2026-10-05T23:53:49.215Z"
tags: ["reset 도메인 교차"]
canonical_url: "https://ariser.io/@writer_a9817d5a8de0/reset-%EB%8F%84%EB%A9%94%EC%9D%B8-%EA%B5%90%EC%B0%A8-%EA%B0%99%EC%9D%80-%ED%81%B4%EB%A1%9D%EC%9D%B8%EB%8D%B0-%EC%A7%80%EC%97%AD-reset%EC%97%90%EC%84%9C-%EC%83%81%ED%83%9C%EA%B0%80-%ED%9D%94%EB%93%A4%EB%A6%B0%EB%8B%A4"
ai_assisted: true
---

# reset 도메인 교차: 같은 클록인데 지역 reset에서 상태가 흔들린다

이 글은 AI가 활용됐습니다.

[원문](https://ariser.io/@writer_a9817d5a8de0/reset-%EB%8F%84%EB%A9%94%EC%9D%B8-%EA%B5%90%EC%B0%A8-%EA%B0%99%EC%9D%80-%ED%81%B4%EB%A1%9D%EC%9D%B8%EB%8D%B0-%EC%A7%80%EC%97%AD-reset%EC%97%90%EC%84%9C-%EC%83%81%ED%83%9C%EA%B0%80-%ED%9D%94%EB%93%A4%EB%A6%B0%EB%8B%A4)

송신 레지스터와 수신 레지스터가 같은 클록을 쓴다. 데이터 경로의 setup·hold도 만족한다. 그런데 송신 블록만 reset했을 때 수신 쪽 상태가 가끔 틀어진다. 데이터 CDC 검사만 보았다면 놓치기 쉬운 경계다. **reset 도메인 교차는 클록 관계가 아니라, reset이 상태를 비동기적으로 바꾸는 경로와 그 변화를 받는 상태의 관계를 분석한다.**

reset 도메인은 같은 초기화 사건을 공유하는 상태의 범위다. 클록 도메인과 꼭 일치하지 않는다. 같은 클록에서 어떤 레지스터는 지역 reset으로 초기화되고 다른 레지스터는 계속 동작할 수 있다. 반대로 여러 클록 영역이 하나의 전원 초기화 reset을 공유하기도 한다.

## 같은 클록의 데이터가 클록 밖에서 바뀐다

가상의 10ns 주기 클록에서 송신 FF의 출력 ready가 1이라고 하자. 수신 FF는 다음 10ns 에지에 ready를 샘플링한다. 그런데 송신 블록의 비동기 reset이 9.9ns에 활성화되어 ready를 0으로 만든다.

이 변화는 송신 클록 에지가 만들지 않았다. 정상 동작의 launch edge에서 계산한 데이터 경로 조건만으로 10ns 수신 에지에 대한 안정성을 보장할 수 없다. reset-to-Q와 배선 지연을 거쳐 전이가 수신 에지 근처에 도착하면 수신 FF의 setup·hold 조건을 건드릴 수 있다.

수신 쪽은 reset되지 않고 계속 동작한다는 조건이 중요하다. 양쪽 전체가 초기화 상태로 들어가 외부 거래도 금지되는 전원 초기화와, 한 블록만 재시작하는 지역 reset은 다르게 분석해야 한다. reset 이름이 같거나 초기값이 같다는 사실만으로 안전성이 정해지지 않는다.

[PULP의 CDC reset controller 설명](https://github.com/pulp-platform/common_cells/blob/master/src/cc_cdc_reset_ctrlr.sv)은 다른 영역에 비동기 clear를 그대로 전달할 때 주변 회로에서 reset assertion이 준안정성을 유발할 수 있다는 문제를 다룬다. reset의 해제만 동기화하는 일반적인 구조와 reset이 활성화될 때의 데이터 변화는 별도의 사건이다.

## 해제를 동기화했는데도 assertion은 남는다

많은 reset synchronizer는 비동기 assertion과 동기 deassertion을 사용한다. reset을 풀 때 기능 상태가 클록에 맞춰 출발하도록 만드는 구조다. 하지만 외부 reset이 활성화되면 출력 reset도 즉시 내려가도록 설계되어 있다.

따라서 송신 출력은 assertion 순간 클록과 무관하게 초기값으로 바뀔 수 있다. 수신 쪽이 계속 움직이는 설계에서 “reset synchronizer가 있으므로 송신 출력은 항상 동기 신호”라는 결론은 틀린다. 정상 동작의 출력 갱신과 reset에 의한 출력 갱신을 따로 보아야 한다.

원문의 [2-phase CDC reset 조건](https://github.com/pulp-platform/common_cells/blob/master/src/cc_cdc_2phase.sv)도 전원 초기화와 warm reset을 구분하며, deassertion synchronizer가 assertion에 의한 reset-domain 위험까지 없애지 않는다고 설명한다. 사용 모듈이 허용하는 reset 범위를 확인하는 것이 먼저다.

## 한 비트 안정화와 여러 상태의 정합성은 다르다

ready 한 비트가 바뀌는 경로라면 적절한 수신 동기화가 한 요소가 될 수 있다. 하지만 주소, valid, 카운터 상태가 각각 다른 시각에 초기값으로 바뀌면 단일 비트 synchronizer만으로 거래의 관계를 보존할 수 없다.

예를 들어 송신의 payload는 0으로 초기화되었는데 수신은 이전 valid=1을 한 사이클 더 본다고 하자. 수신 값은 모두 안정적이어도 이전 거래 표시로 초기화된 payload를 소비한다. 이것은 아날로그적인 준안정성만 찾는 검사로 충분히 설명되지 않는다. 어떤 거래를 어떤 reset 경계에서 유효하다고 해석하는지도 확인해야 한다.

그래서 대책은 경로의 의미에 따라 달라진다. 상대에게 전달하는 상태를 안전한 수준으로 유지하거나, 초기화 전에 거래를 격리하거나, 양쪽에서 동기 clear를 협상하는 방식이 가능하다. 갑작스러운 비동기 reset에서는 “나중에 격리했다”는 사실로 이미 샘플링된 거래를 되돌릴 수 없으므로, 격리가 언제 효력을 갖는지까지 설계해야 한다.

어떤 방법도 이름만으로 모든 경로를 해결하지 않는다. 예를 들어 격리가 data만 막고 valid는 그대로 두면 잘못된 거래를 만들 수 있다. 수신 reset을 함께 넣는 방식도 reset 배포와 해제 순서, 외부에 남은 거래에 대한 조건이 필요하다.

## reset 관계를 표로 적으면 숨은 경계가 보인다

작은 블록부터 다음과 같은 표를 만들 수 있다. 이것은 분석 예이며 실제 칩의 분류 결과가 아니다.

| 경로 | 송신의 reset | 수신의 reset | 확인할 사건 |
|---|---|---|---|
| 지역 ready→항상 동작 제어기 | local reset | 전원 초기화만 | local assertion 때 출력 전이 |
| payload와 valid→다른 블록 | local reset | 별도 local reset | 초기화 중 거래 조합과 순서 |
| 상태→같이 초기화되는 상태 | 같은 전원 reset | 같은 전원 reset | reset 도착·해제 관계와 사용 금지 구간 |

같은 클록인지부터 지우지 말고 reset이 언제 독립적으로 발생할 수 있는지를 기록한다. 소프트웨어 요청, watchdog, 전원 관리, 테스트 모드가 서로 다른 reset을 만들 수 있다면 각 사건에서 살아남는 수신 상태가 달라진다.

검증 자극도 정상 시작에만 reset을 넣어서는 부족하다. 입력 수락 직전, 출력이 stall된 동안, 확인이 돌아오는 중에 reset을 적용하고 상대가 어떤 결과를 볼 수 있는지 검사한다. RTL 파형의 정상 논리값 확인과 물리적인 reset-to-data 경로 검사는 서로 보완해야 한다.

처음의 수신 오류는 같은 클록을 쓰는 두 FF 사이에서도 생겼다. reset이 송신의 상태를 클록 밖에서 바꾸었기 때문이다. **reset 도메인 교차를 볼 때의 질문은 “클록이 같은가” 다음에 “한쪽이 초기화되는 동안 다른 쪽은 무엇을 계속 믿는가”다.** 그 답에 맞춰 안정화와 거래 격리의 책임을 정해야 지역 reset이 전체 시스템의 상태를 흔들지 않는다.

