728x90
행위 수준 모델링
행위 수준 모델링
- 행위 수준 모델링이란 회로도나 논리식을 고려하지 않고 회로의 기능적 측면을 고려하는 동작(행위) 수준의 설계방법이다.
- 행위 수준 모델링을 위해서는 앞에서 설명한 조합논리회로 설계에 사용하는 연속 할당문(assign문) 외에도 순차논리회로 설계를 위한 절차형 할당문의 이해 필요
절차형 할당문
- 절차형 할당문은 레지스터 자료형(reg, integer, real 등)의 값을 할당하며, 절차형 할당문에 의해 값이 갱신될 때까지 할당된 값을 유지
- 절차형 할당문은 always, initial, task, function 등의 절차 구문과 함께 사용
- 블록킹(blocking, '=') 대입문과 논블록킹(nonblocking'<=') 대입문으로 구분
- 실행 흐름이 절차 구문 내의 할당문(블록킹 또는 논블록킹 대입문)에 도달했을 때 할당을 위한 이벤트 발생
- 반면 연속 할당문은 할당을 위한 문장의 실행에 의해서가 아니라 할당기호(=) 오른쪽 수식의 값 변화에 의해 왼쪽 네트에 값이 할당되는 점이 다르다.
always문
always문
- always문은 행위 수준 모델링의 가장 기본이 되는 구문
- 논리 합성, 즉 실제 하드웨어 구현이 가능
- 조합논리회로와 순차논리회로의 모델링에 모두 사용되며, 시뮬레이션을 위한 테스트벤치 작성에도 사용
- always문은 module이 실행되는 동안 always 블록 내의 문장을 루프 형식으로 반복 수행
- 따라서 타이밍 제어와 관련된 표현에 유용하게 사용
- 표현 형식
always @(sensitivity_list) //마지막에 세미콜론이 없음
begin
blocking or nonblocking 대입문;
if, case문 등;
end
- 사용 예
module sample (a, b, out1, out2);
input a, b;
output out1, out2;
reg out1, out2;
always @(a or b) //a 또는 b 신호가 변화할 떄마다 아래 begin ~ end가 실행
begin
//이벤트 신호 a 또는 b의 값이 변화하면 레지스터 out1과 out2에 각각 1과 0을 할당(블록킹 대입문)
out1 = 1'b1;
out2 = 1'b0;
end
- always문 사용 시 주의 사항
- always문의 사용 형식은 예약어 always 다음에 @(sensitivity_list)을 기술, 마지막에 세미콜론(;) 없음을 주의
- always문은 sensitivity_list의 이벤트 신호들 중 하나라도 값이 변화할 때마다 내부의 동작(행위) 수준 문장들이 실행
- always @(sensitivity_list)와 하나 또는 여러 개의 내부 동작(행위) 수준 문장들로 구성된 블록은 'always 블록'이라고 함
- always 블록에서 여러 개의 내부 동작(행위) 수준 문장들이 사용될 경우 begin~end 블록으로 묶어 표현
- always @(*) 또는 always *
- always @(sensitivity_list)는 sensitivity_list에 정의된 신호의 변화가 있을 때 내부 문장이 실행
- always @(*) 또는 always *는 always 블록 내 모든 신호의 변화가 있을 때 내부 문장들 실행
- 하나의 module 내에 여러 개의 always 블록 포함 가능
- 각각의 always 블록들은 연속 할당문과 마찬가지로 동시에 실행
- sensitivity_list에 나열된 신호들 중 하나 이상의 신호가 변화하게 되면 always 블록 내부의 begin~end 블록이 실행
- 이때 begin~end 블록 내에 사용된 블록킹 대입문(=) 또는 논블록킹 대입문(<=)에 따라 실행 방식이 달라짐.
- always 블록의 동작은 일종의 레지스터이므로 always 블록 내에서 할당문 왼쪽 신호들은 반드시 레지스터(reg)형으로 선언
initial 문
initial문
- module이 실행되는 동안 무한히 반복되는 always문과 달리 initial 문은 한 번만 실행
- always문과 마찬가지로 begin~end 내에 여러 절차형 문장들로 구성되는 initial 블록 구성
- initial 내부의 절차형 문장들은 순차적으로 실행
- initial 블록은 일반적으로 초기화, 모니터링, 파형, 그리고 전체 실행 시 단 한 번만 수행되어야 하는 과정에 사용
- 표현 형식
initial begin
blocking or nonblocking 할당문;
end
- 사용 예
module sample (a, b, out1, out2);
input a, b;
output out1, out2;
reg out1, out2; //아래 initial 블록의 왼쪽 할당 신호 out1, out2를 레지스터형 선언
initial
begin
out1 = 1'b0; //레지스터 out1에 초기값 0할당
out2 = 1'b1; //레지스터 out2에 초기값 0할당
end
endmodule
절차적 할당문(blocking과 non-blocking)
절차적 할당문
- 절차적 할당문은 순차적 할당문이라고도 하며 블록킹 대입문과 논블록킹 대입문이 있음.
- 연속 할당문과 달리 할당을 위한 예약어 assign을 사용하지 않음.
- reg, integer 등의 레지스터형 변수(신호)의 값을 할당할 때 사용
- 절차형 할당문에 의해 값이 할당된 레지스터형 변수들은 다음 절차형 할당문에 의해 값이 갱신될 때까지 현재 할당된 값을 유지
- 레지스터 변수에 값을 할당할 때, 레지스터의 비트 수에 비해 할당하고자 하는 비트 수가 클 경우 할당 값의 하위 비트의 값들이 선택, 반대의 경우 레지스터의 상위 비트에 0이 채워짐.
- 표현 형식
out = a & b; //블록킹 대입문
out <= a | b; //논블록킹 대입문
- 사용 예
module sample (a, b, out1, out2);
input a, b;
output out1, out2;
reg out1, out2;
always @ (a or b)
begin
out1 = a & b; //블록킹 대입문
out2 <= a | b; //논블록킹 대입문
end
endmodule
블록킹 대입문(blocking assignment)
- 블록킹 대입문은 begin~end로 묶인 블록에 열거된 순서대로 실행
- 하나의 대입이 끝나고 다음 대입이 순차적으로 이루어짐(지연 발생)
- 하나의 대입이 끝나지 않았다면 blocking되어 있음 -> 다음 대입문으로 넘어가지 못 함.
- 예시
/* case 1 */
reg [3:0] a, b, c, d;
always @(posedge clk)
begin
c = b; //1번 동작
b = a; //2번 동작
a = d; //3번 동작
end
//1번 동작이 끝난 후 2번 동작, 2번 동작이 끝난 후 3번 동작
//처리 전 초기값 : a = 5, b = 3, c = 10, d = 2
//처리 후 변경값 : a = 2, b = 5, c = 3, d = 2
/* case 2 */
reg [3:0] a, b, c, d;
always @(posedge clk)
begin
a = d; //1번 동작
c = b; //2번 동작
b = a; //3번 동작
end
//1번 동작이 끝난 후 2번 동작, 2번 동작이 끝난 후 3번 동작
//처리 전 초기값 : a = 5, b = 3, c = 10, d = 2
//처리 후 변경값 : a = 2, b = 2, c = 3, d = 2
논블록킹 대입문(nonblocking assignment)
- 순차적 블록 내에 열거된 순서와 무관하게 지연없이 할당
- 대입문 오른쪽의 할당이 완전히 끝난 후 병렬적으로 왼쪽에 할당
- 일반적으로 순차논리회로를 설계할 떄는 기술 순서와 상관없는 논블록킹 대입문의 사용이 적절
- 논블록킹 대입문에 사용되는 <= 연산자는 관계연산자의 작거나 같다와 같은 기호 사용
- <= 연산자가 수식에서 사용되면 관계연산자, 논블록킹 할당의 문장에서는 할당(대입) 연산자로 해석
- 예시
/* case1 */
reg [3:0] a, b, c, d;
always @(posedge clk)
begin
c <= b; //1번 동작
b <= a; //2번 동작
a <= d; //3번 동작
end
//1번 동작, 2번 동작, 3번 동작의 오른쪽에 할당이 먼저 일어난 후 동시에 왼쪽에 할당된다.
//처리 전 초기값 : a = 5, b = 3, c = 10, d = 2
//처리 후 변경값 : a = 2, b = 5, c = 3, d = 2
/* case2 */
reg [3:0] a, b, c, d;
always @(posedge clk)
begin
a <= d; //1번 동작
c <= b; //2번 동작
b <= a; //3번 동작
end
//1번 동작, 2번 동작, 3번 동작의 오른쪽에 할당이 먼저 일어난 후 동시에 왼쪽에 할당된다.
//동시에 할당되기 떄문에 기술 순서가 변해도 결과는 case1과 case2가 똑같다.
//처리 전 초기값 : a = 5, b = 3, c = 10, d = 2
//처리 후 변경값 : a = 2, b = 5, c = 3, d = 2
결론
- 블록킹 대입문은 기술 순서에 따라 다른 결과를 가져오지만, 논블록킹 대입문은 기술순서와 무관하게 같은 결과를 가져온다.
- always문과 initial문 내에 할당 변수(레지스터)가 하나만 있을 경우 블록킹 대입문과 논블록킹 대입문 중 어떤 대입문을 사용하더라도 동일한 결과를 갖게 됨.
- 그러나 추루 always/initial문을 수정하게 될 경우를 고려하여 논블록킹 대입문을 사용하는 것이 좋음.
- 이 글은 "따라하면서 배우는 디지털 시스템 설계 및 응용 with Verilog HDL"을 기반으로 작성했음을 알립니다.
'verilog > 이론' 카테고리의 다른 글
[verilog] verilog의 추상화 수준 모델링 방법(1)(게이트 수준 : and, or, nand, nor, xor,3-state gate primitive, 데이터 플로우 수준 : 연속 할당문, 절차형 할당문) (2) | 2023.11.27 |
---|---|
[verilog] verilog의 연산자(2)(비트단항 논리연산자, 관계 연산자, 시프트 연산자, 조건 연산자, 결합 연산자, 반복 연산자) (2) | 2023.11.21 |
[verilog] verilog의 연산자(1)(산술연산자, 논리연산자, 비트단위 논리연산자) (2) | 2023.11.15 |
[verilog] 벡터(vector)와 배열(array) (0) | 2023.11.13 |
[verilog] verilog의 자료형 (0) | 2023.11.11 |