Menu

Verilog 연산자: 산술, 비교, 논리, 조건

Verilog의 핵심 연산자 - 산술, 비교, 논리, 조건 ?: - 그리고 너비 혼합과 부호 처리의 규칙과 함정.

이 페이지에는 실행 가능한 에디터가 있습니다 - 편집하고 실행하면 결과를 바로 볼 수 있습니다.

Verilog에서 "연산자"가 의미하는 것

연산자는 신호를 담은 식을 받아 새로운 신호 식을 만듭니다. a + b는 하드웨어입니다 - synthesizer가 그것을 가산기로 만듭니다. a == b는 하드웨어입니다 - 비교기를 만듭니다. 이건 "실행되는 코드"가 아니라 모두 "연산자가 기술하는 회로"입니다.

연산자 메뉴 전체는 외울 만큼 작습니다. 이 문서는 산술, 비교, 논리, 조건 연산자를 다룹니다. Bitwise and Reduction은 직접적인 소프트웨어 대응이 없는 비트 레벨 연산자를 다룹니다.

산술: + - * / %

알아 둘 세 가지.

  1. 나눗셈은 정수 나눗셈입니다. 7/23이지 3.5가 아닙니다. Verilog에는 float 타입이 없습니다(엄밀히는 real이 있지만 시뮬레이션 전용).
  2. 나눗셈과 modulo는 하드웨어에서 비쌉니다. /4는 괜찮지만(synthesizer가 right shift로 변환), 런타임 가변 n에 대한 /n은 여러 사이클짜리 나눗셈기를 만들고 보통은 원하지 않는 결과입니다.
  3. Overflow는 wrap됩니다. N비트 부호 없는 두 값을 더해 N비트를 넘으면 N비트로 잘립니다. carry를 잡고 싶다면 결과를 한 비트 더 넓게 선언하세요.
wire [7:0] a, b;
wire [8:0] sum = a + b;   // 9비트 sum이 carry out을 잡음

비교: == != < > <= >=

여섯 비교 연산자 모두 단일 비트 결과를 반환합니다: 참이면 1, 거짓이면 0, 피연산자 중 어느 쪽이든 xz 비트가 있으면 x. x/z 케이스를 다루려면 ===!==(case-equality 연산자)에 손을 뻗으세요. X and Z Values에서 다룹니다.

여기서 <=는 비교 연산자(less-than-or-equal)입니다. 같은 문자가 procedural block 안에서는 또한 non-blocking assignment(q <= d)를 의미합니다. 문맥으로 구분합니다: 식 안이면 비교이고, 대입되는 값의 왼쪽에 있으면 대입입니다. 겹침이 혼란스럽지만 파서에게는 모호하지 않습니다.

논리: && || !

논리 연산자는 피연산자를 boolean(non-zero는 true, 0은 false)으로 다루고 단일 비트 결과를 만듭니다.

내재화해야 할 핵심 구분: 논리 &&는 비트와이즈 &가 아닙니다.

4'b1100 && 4'b0011   // 1 (둘 다 non-zero, logical AND는 true)
4'b1100 &  4'b0011   // 4'b0000 (양쪽에서 1인 비트 위치가 없음)

|||도 마찬가지. if 조건과 ?: 술어에는 logical을, 비트 위치별 AND/OR가 필요할 때는 비트와이즈를 쓰세요.

&&||는 C 의미의 short-circuit입니다: 결과가 왼쪽에서 이미 결정되면 오른쪽이 평가되지 않습니다. 이건 포인터나 함수 호출을 검사하는 testbench에서 의미가 있고, 모든 게 어차피 병렬로 일어나는 synthesis 가능한 RTL에서는 거의 의미가 없습니다.

조건 연산자: ?:

ternary는 mux와 조건 식을 만드는 최고의 친구입니다.

cond ? a : b 패턴은 하드웨어에서 1비트 select의 2-to-1 멀티플렉서입니다. 체인은 3-, 4-way select까지는 괜찮지만, 그 이상은 Case Statementcase 문이 훨씬 읽기 좋습니다.

?: 연산자는 가끔만 오버라이드하는 기본값을 register에 주는 표준 방법이기도 합니다.

next_value = update ? new_data : next_value;

너비 규칙: 초보자의 함정

산술 연산자의 너비 규칙은 악명 높게 놀랍습니다. 짧은 버전.

  • 결과의 너비는 입력 너비들의 최댓값입니다.
  • 결과가 더 넓은 곳에 대입되면 zero-extension(부호 있다면 sign-extension)됩니다.
  • 중간 계산의 너비도 결과 너비입니다, 즉 중간에서 overflow가 일어납니다.

첫 곱셈은 피연산자 너비가 둘 다 8비트여서 결과 너비도 8비트이고 40000이 들어맞지 않아 overflow합니다. 두 번째는 a를 명시적으로 넓힌 뒤 곱했기에 동작합니다.

수정 라인 기법.

  • concatenation 연산자 {8'b0, a}로 zero-extension.
  • $unsigned(a) 또는 $signed(a)로 해석을 영향.
  • 의심스러우면 중간 식을 더 넓은 너비로 cast.

연산자 우선순위

표를 외울 필요는 없지만 몇 가지 규칙에 의존하게 됩니다.

  • *, /, %+, -보다 강하게 결합.
  • 비교는 논리(&&, ||)보다 강하게 결합.
  • 조건 연산자 ?:는 매우 낮은 우선순위 - 큰 식 안에서 보통 분기에 괄호가 필요.
  • 의심스러우면 괄호. 시뮬레이터는 글자 수로 청구하지 않습니다.
out = (mode == 2'd0) ? a + b : a - b;   // 괄호로 더 명확

다음에 볼 내용

소프트웨어 사촌처럼 보이는 연산자는 모두 다뤘습니다. 다음 문서 - Bitwise and Reduction - 은 직접적인 소프트웨어 대응이 없는 연산자를 다룹니다: 비트별 AND/OR/XOR과, 전체 vector를 단일 비트로 줄이는 reduction 형태.

자주 묻는 질문

Verilog는 어떤 연산자를 지원하나요?

Verilog에는 네 가지 큰 연산자 가족이 있습니다: 산술(+, -, *, /, %), 비교(==, !=, <, >, <=, >=), 논리(&&, ||, !), 그리고 비트와이즈/reduction(&, |, ^, ~, ~&, ~|, ~^). 거기에 shift 연산자(<<, >>, <<<, >>>), concatenation {}, replication {N{...}}, 그리고 조건 연산자 ?:가 있습니다.

Verilog에서 &&와 &의 차이는?

&&는 논리 AND - 각 피연산자를 boolean(0 또는 non-zero)으로 다루고 1비트 결과를 반환합니다. &는 비트와이즈 AND - 비트를 위치별로 짝짓습니다. 4'b1100 && 4'b00111(둘 다 non-zero)이고, 4'b1100 & 4'b00114'b0000입니다. 조건에는 &&, 비트 레벨 연산에는 &.

Verilog에서 나눗셈은 어떻게 동작하나요?

정수 나눗셈입니다 - 소수 부분이 버려집니다. 7 / 23이지 3.5가 아닙니다. % 연산자는 나머지를 줍니다: 7 % 21입니다. 0으로 나누면 시뮬레이션에서 x(unknown)가 됩니다. 두 연산자 모두 기술적으로는 synthesis 가능하지만 FPGA와 ASIC에서 매우 크고 느린 하드웨어를 만들어 냅니다 - 제수가 2의 거듭제곱이 아니라면 synthesis 가능한 경로에서 피하세요.

Verilog의 조건 연산자란?

?:는 C에서 가져온 ternary 또는 조건 연산자입니다. cond ? a : bcond가 true(non-zero)이면 a로, 아니면 b로 평가됩니다. mux와 비슷한 로직에 가장 많이 쓰는 구문입니다: out = sel ? in1 : in0는 2-to-1 mux를 만듭니다. ?: 체인은 더 큰 mux를 만들지만 두 입력을 넘어서면 보통 case가 더 명확합니다.

Coddy programming languages illustration

Coddy로 코딩 배우기

시작하기