Altifigence Academy

24 / 63 · 개념

조합 RTL: 모든 경로에서 출력 대입하기

조건 연산자와 always_comb로 같은 함수를 표현하고, 출력 대입을 빠뜨려 latch가 생기는 경우를 찾습니다.

조합회로는 현재 입력으로 출력이 결정됩니다

MUX멀티플렉서 선택 신호에 따라 여러 입력 중 하나를 출력으로 연결하는 조합회로입니다. 선택 비트와 입력 번호의 대응을 명세해야 합니다. 자세히 보기를 가장 직접적으로 쓰는 방법은 assign y = sel ? b : a;입니다. 여러 출력을 함께 계산할 때는 always_comb를 사용할 수 있습니다.

SystemVerilog
always_comb begin
  y = a;
  if (sel) y = b;
end

기본값을 먼저 대입했기 때문에 sel이 0인 경로도 정의되어 있습니다. 반대로 if (sel) y = b;만 남겨 놓으면 sel=0일 때 과거 y를 유지해야 하므로 순수 조합 함수가 아닙니다. 도구의 경고를 무시하거나 always_comb라는 키워드만 믿어서는 안 됩니다.

y=a를 기본값으로 둔 뒤 sel=1일 때만 b를 선택하는 코드는 아래 회로와 같은 0/1 조합 동작을 합니다. sel=0인 입력에서도 출력이 반드시 결정됩니다.

기본 대입이 덮는 두 경로

y = sel ? b : a

절차형 문법을 소프트웨어 실행 순서로만 읽지 않기

조합 블록에서는 일반적으로 blocking 대입 =으로 임시 결과를 계산합니다. 같은 블록에서 먼저 대입한 결과를 아래 식이 읽는다면 그 두 계산은 하나의 조합 경로로 이어집니다. 순차 레지스터레지스터 여러 비트의 상태를 저장하는 회로입니다. 이 과정의 동기식 레지스터는 클록 에지에서 정해진 입력을 저장합니다. 자세히 보기 갱신에 사용하는 nonblockingnonblocking 순차 RTL에서 <=로 표현하는 대입입니다. 우변을 평가한 뒤 갱신을 예약하므로 같은 에지의 레지스터들이 이전 상태를 기준으로 계산할 수 있습니다. 자세히 보기 대입 <=와 역할을 구분하세요.

SystemVerilog
always_comb begin
  next_y = sel ? b : a;
  inverted_y = ~next_y;
end

출력 하나를 여러 블록에서 구동하지 않는 것도 기본 규칙입니다. 모듈을 나눌수록 각 신호를 어느 블록이 단독으로 구동하는지 인터페이스에서 확인해야 합니다.

선택할 두 데이터의 비트 폭을 먼저 맞춥니다

8비트와 12비트를 선택한다면 y의 폭과 부호 확장을 명시하세요. 암묵적 확장이 의도대로 되는지 파형에서 확인하는 데 그치지 말고, 설계 단계에서 입력 범위를 정해야 합니다. 0/1 모델 밖에서 sel이 X일 때의 조건 연산자 의미는 단순 if와 다를 수 있으므로, 이 과정의 2상태 모델에서 얻은 결과를 모든 4상태 동작에 그대로 적용해서는 안 됩니다.

직접 생각해 보기

always_comb 안에 if(en) y=d;만 있습니다. 이것을 enable이 없을 때 0을 출력하는 조합회로로 바꾸려면 어떻게 작성하나요?

해설 보기

블록 시작에서 y를 0으로 대입하고 en이 1일 때 d로 덮어쓰거나, assign y = en ? d : 0에 해당하는 폭이 명확한 표현을 사용합니다. en=0일 때 이전 값을 유지하는 기능은 레지스터나 latch의 동작으로 따로 정의해야 하며, 0을 출력하는 기능과 다릅니다.

선택은 이 브라우저에만 적용됩니다. 언제든 푸터에서 변경할 수 있습니다.