Verilog assign 문 완전 해설: 연속 할당으로 조합 논리 구현하기
wire 타입 신호는 연속적으로 값을 구동해야 합니다. 브레드보드에서 전선이 배터리 전압을 계속 전달하는 것과 같습니다. Verilog에서 이 개념을 구현하는 것이 assign 문(연속 할당)입니다.
assign 문법
assign = [drive_strength] [delay] ;
- LHS: 스칼라/벡터 넷 또는 넷의 결합 (절대
reg 불가)
- RHS: 상수, 신호 표현식, 레지스터, 함수 호출 가능
- 드라이브 강도/지연: 데이터플로 모델링용, 합성 시 대부분 무시
- 동작: RHS 피연산자 중 하나라도 값 변경 시 LHS 즉시 업데이트 (항상 활성)
기본 규칙
- LHS는 넷 타입만 허용 (
wire, tri 등)
- RHS는 레지스터, 함수 호출 포함 가능
- RHS 변경 시마다 LHS 재평가 (이벤트 드리븐)
- 여러
assign이 같은 넷을 구동하면 다중 드라이버 → x 발생 위험
예제 1: 간단한 AND 게이트
module and_gate (input a, b, output out);
assign out = a & b;
endmodule
합성 시 2입력 AND 게이트로 구현.
예제 2: 다채로운 assign 활용 패턴
module xyz (input [3:0] x, input y, output [4:0] z);
wire [1:0] a; wire b;
// Case 1: 결합(concatenation)으로 5비트 생성 → 5비트 출력에 할당
assign z = {x, y}; // z = {x[3:0], y}
// Case 2: 부분 선택에 할당 → 나머지 비트 Hi-Z
assign z[3:1] = {x, y}; // z[4], z[0] = Z
// Case 3: 상수 비트 추가 구동
assign z[3:1] = {x, y}; assign z[4] = 1; // z[0]만 Z
// Case 4: 같은 비트 중복 구동 (값 동일 → 경합 없음)
assign z[3:1] = {x, y}; assign z[3] = 0; // OK
// Case 5: 같은 비트 중복 구동 (값 다름 → X 발생)
assign z[3:1] = {x, y}; assign z[3] = 1; // z[3] = X
// Case 6: RHS 부분 선택
assign z = {x[1:0], y}; // z[4:2] = 0
// Case 7: LHS 부분만 구동
assign z[2:0] = {x[1:0], y}; // z[4:3] = Z
// Case 8: 복제 연산자
assign z = {3{y}}; // {y, y, y} → 3비트 후 0 패딩
// Case 9: LHS 결합
assign {a, b} = {x, y}; // a=2비트, b=1비트 → RHS 하위 3비트 매핑
// Case 10: LHS 순서 변경
assign {b, a} = {x, y}; // 매핑 순서 달라짐
endmodule
reg 변수에 assign 불가
reg는 값 저장 능력이 있어 연속 구동 불필요. reg는 always/initial 블록에서만 할당 가능.
암시적 연속 할당 (Implicit Continuous Assignment)
wire [1:0] a;
assign a = x & y; // 명시적
wire [1:0] a = x & y; // 암시적 (선언 시 할당)
조합 논리 설계 패턴
module combo (input a, b, c, d, output o);
assign o = ~((a & b) | (c ^ d));
endmodule
입력 변경 시마다 출력 즉시 업데이트 → 순수 조합 논리에 적합. 순차 소자(플립플롭)와 달리 클럭 에지 불필요.
시뮬레이션 파형 특징
- 입력이
x인 동안 출력도 x
- 입력 안정화 후 조합 논리 지연 시간 이후 출력 확정
- 글리치(glitch) 발생 가능 → 동기식 설계에서 주의
핵심: assign 문은 합성 가능한 조합 논리의 기본 빌딩 블록입니다.