구조적 프로시저는 always와 initial이 있다.
이 두 문장은 행위 수준 모델링에서 가장 기본적인 문장이다.
Verilog는 C언어와는 다르게 병렬적으로 수행되는 프로그래밍언어이다. Verilog에서 각 always와 initial문은 각각 분리되어 수행된다. 각 수행은 시뮬레이션 시간 0에서 시작한다.
- initial 구문
initial 블록은 시간 0부터 시작하고, 시뮬레이션동안 한번만 실행되고, 다시는 수행되지 않는다.
여러개의 initial 블록이 있다면 각 블록은 시간 0에서 동시에 수행되고, 독립적으로 각자 실행을 마친다.
블록 내에 들어갈 행위수준 문장이 1개이면
initial
m=1'b0
라고 할 수 있지만, 행위수준 문장이 여러 줄이면 반드시 begin end문을 사용해야 한다.
initial
begin
#5 a=1'b1;
#25 b=1'b0;
변수들을 선언하고 초기화 할때 다음과 같이 사용할 수 있다.
reg clock;
initial clock = 0;
- always 구문
always문은 시간 0에서 시작하고, always 블록 내의 문장을 루프형식으로 연속하게 수행한다.
매 10 단위마다 반전시키는 클락을 만드는 코드
module clock_gen(output reg clock);
initial
clock = 1'b0;
always
#10 clock=~clock;
initial
#1000 $finish;
endmodule
- 절차적 할당
procedural assignments는 reg, integer, real, time변수 의 값을 갱신한다.
위 변수의 값에 경우 wire와 다르게 갱신되기 전까지 값이 변치 않고 유지된다. 6단원에서 배운 연속할당과 반대이다!!!
절차적 할당에는 두가지 형태가 있다.
블록킹(blocking) = "=" 를 사용
논블록킹(nonblocking) = "<=" 를 사용
이렇게 나눠지는 이유가 무엇일까? 바로 스케줄링 때문이다. 설계자가 스케줄링의 우선순위에 대해 정확하게 알지 못한다면 실수를 하기 때문이다.
이와 같은 베릴로그 코드가 있다고 생각해 보자.
initial
begin
a=1;
b=a;
end
위 그림처럼 blocking으로 선언을 하게 되면 순차적으로 실행이 되게 된다.
이런식으로 "="으로 선언된 구문은 blocking구문으로 이렇게 선언된 구문은 먼저 처리되기 전에는 다음 구문이 처리되는 것을 허용하지 않는다.
initial
begin
a<=1;
b<=a;
end
만일 다음과 같이 선언되어있다면 어떻게 될까? 동일 time에서 동시에 실행이 된다. 이렇게 실행이 된다면
a=1, b=x가 된다.
논블로킹 할당을 사용하는 이유는 무엇일까?
공통적인 사건이 일어난 후에, 여러개의 데이터를 동시에 전송하기 위해 사용된다.
always @(posedge clock)
a<=b;
always @(posedge clock)
b<=a;
이과 같은 코드가 있다면, 연산이 동시에 수행이 된다. but 읽어오는 연산을 진행한 다음 쓰기작업을 하기 때문에 이와 같은 경우에는 경쟁이 일어나지 않는다.
'HW > Verilog HDL' 카테고리의 다른 글
| 6. 데이터플로우 모델링 (0) | 2024.02.16 |
|---|