구조적 프로시저
Verilog에는 두 가지 구조적 프로시저 always와 initial이 있다. 이 두 문장은 행위 수준 모델링에서 가장 기본적인 문장이다. 모든 행위 수준 문장은 반드시 구조적 프로시저 문장 안에 나타난다. 두 구문은 중첩될 수 없으며 각 always와 initial문이 분리되어 독립적으로 수행된다.
★ 규칙4 : always, initial의 LHS는 무조건 reg형이다.
initial문
initial블록은 시간 0에서 시작하고, 시뮬레이션동안 한 번만 수행되고, 다시는 수행되지 않는다. 만약 여러 개의 initial 블록이 있으면, 각 블록은 시간 0에서 동시에 수행되고, 다른 블록과 상관없이 독립적으로 실행을 마친다. 여러 개의 행위 수준 문장은 반드시 키워드 begin과 end문을 사용해 묶어야한다.
// always, initial구문은 병렬적으로 실행됨.
module stimulus;
reg x,y,a,b,m;
initial begin
m = 1'b0;
#5 a = 1'b1;
#25 b = 1'b0;
end
initial begin
#10 x = 1'b0;
#25 y = 1'b1;
end
initial
#50 $finish;
endmodule
always문
always문은 시간0에서 시작하고 always블록 내의 문장을 루프 형식으로 연속되게 수행한다. 디지털 회로의 연속적으로 반복되는 활동의 블록을 모델링하기 위해 사용된다.
module clock_gen(
output reg clock;
);
initial
clock = 1'b0;
always
#10 clock = ~clock;
initial
#1000 $finish;
endmodule
절차적 할당
절차적 할당은 reg, integer, real, time변수의 값을 갱신한다. 변수에 할당된 값은 절차적 할당 방법으로 다른 값이 갱신되기 전까지 변치 않고 유지된다. blokcing방법, nonblocking방법 두가지가 있다.
blocking 문장
순차적 블록에 열거된 순서대로 수행된다. blocking 문장은 병렬 처리 블록내의 문장이 실행되는 것을 허용한다.
reg x, y, z;
reg [15:0] reg_a, reg_b;
integer count;
// 모든 행위수준문장은 반드시 initailm always블록 안에 있어야한다.
initial begin
x = 0; y = 1; z = 1; // y=1은 x=0문장이 수행된 뒤에만 수행될 수 있다.
count = 0;
reg_a = 16'b0; reg_b = reg_a;
#15 reg_a[2] = 1'b1;
#10 reg_b[15:13] = {x,y,z};
count = count +1;
end
위의 예제에서 y = 1문장은 x = 0문장이 수행된 뒤에만 수행될 수 있다. 특정 블록내의 행위는 만약 블록킹 문장이 사용되었다면, 문장은 순차적으로 수행될 수 있기 때문에 한 begin-end문 내에서 순차적으로 수행된다. 즉, count = count + 1문장은 맨 마지막에 수행되고, 각 문장이 수행되는 시뮬레이션 시간은 다음과 같다.
- x = 0문에서 reg_b = reg_a문 사이의 모든 문장은 단위 시간 0에 수행된다.
- reg_a[2] = 0 문장은 단위시간 15에 수행된다.
- reg_b[15:13] 문장은 단위시간 25에 수행된다.
- count = count +1 문장은 단위시간 25에 수행된다.
nonblocking 문장
순차적 블록내 앞선 문장이 끝나지 않아도 할당 스케줄링을 할 수 있게 해준다. <= 기호는 논블록킹 할당을 지정하는데 사용된다.
reg x, y, z;
reg [15:0] reg_a, reg_b;
initial begin
x=0;y=1;z=1;
count = 0;
reg_a = 16'b0; reg_b = reg_a;
reg_a[2] <= #15 1'b1;
reg_b[15:13] <= #10 {x,y,z};
count << count + 1;
end
- reg_a[2] = 0 은 15단위 시간 후에 수행되도록 스케줄되어 있다.
- reg_b[15:13] = {x,y,z}는 10단위 시간 후에 수행되도록 스케줄되어 있다.
- count = count + 1이 지연 없이 수행되도록 스케줄되어 있다.
nonblocking 할당 응용
앞서 nonblocking 할당의 동작을 설명했다. 디지털 디자인에서 nonblocking할당을 왜 사용하는지를 이해하는것이 중요하다. 공통적인 사건이 일어난 후에 여러 개의 데이터를 동시에 전송하기 위한 방법으로 주로 사용된다.
// 클럭의 상승 모서리에 3개의 데이터가 동시에 전송됨.
always @(posedge clock) begin
reg <= #1 in1;
reg2 <= @(negedge clock) in2 ^ in3;
reg3 <= #1 reg1; // reg1의 이전값
end
각 클럭의 상승 엣지마다 nonblocking할당을 위해 다음과 같은 일이 순차적으로 일어난다.
그러므로 reg1,reg2,reg3의 최종값은 할당이 수행되는 명령어에 독립적이다. 다음은 경쟁 조건(race condition)을 제거하기 위한 nonblocking구문의 예이다.
// 보기 1: 동시에 수행되는 blocking 문장을 가진 always블록
always @(posedge clock)
a = b;
always @(posedge clock)
b = a;
// 보기 2: 동시에 수행되는 nonblocking문장을 가진 always블록
always @(posedge clock)
a <= b;
always @(posedge clock)
b <= a;
always @(posedge clock) begin
// 읽기 연산
temp_a = a;
temp_b = b;
// 쓰기 연산
a = temp_a;
b = temp_b;
end
'UVM & RTL > Verilog HDL' 카테고리의 다른 글
[Verilog HDL] CH7 조건문, 다중분기 (0) | 2022.06.14 |
---|---|
[Verilog HDL] CH7 타이밍 제어 (0) | 2022.06.14 |
[Verilog HDL] CH6 연산자 (0) | 2022.06.14 |
[Verilog HDL] CH6 dataflow 모델링 (0) | 2022.06.14 |
[Verilog HDL] CH4 모듈과 포트 (0) | 2022.06.14 |
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!