-
[Verilog][기초문법] 타이밍 제어카테고리 없음 2022. 1. 6. 21:32
3가지의 타이밍 제어방법이 있다
1 딜레이에 기반한 제어
2 event를 이용한 제어
3 level sensitive 제어
1. 딜레이 기반의 타이밍 제어는 다시 3가지가 있다
- 정규할당 지연 또는 관성지연 (regular delay control)
'timescale 1ns/1ps reg a, b; // 정규지연 initial begin a = 0; b = 1; #10 a = 1; // 10ns 후에 할당 #(a+b) a = b; // 2ns 후에 할당 #(1:3:5) a = 1; // min : typ : max end명시된 딜레이 후에 a 값에 할당이 된다.
딜레이는 숫자, 변수 모두 사용이 가능하다.
프리머티브와 마찬가지로 min : typical : max 형식도 지원된다.
정규지연은 딜레이가 지나야 해당 문장이 실행이 된다. 즉 문장이 블로킹 된다.
해당 딜레이가 지나기 전에 b의 값이 바뀐다면, 그 바뀐 값이 a에 할당된다.
- 내부할당 지연 또는 전파지연 (intra assignment delay control)
'timescale 1ns/1ps reg a, b; // 내부할당 지연 initial begin a = 0; b = 1; a = #(10) 1; // 10ns 후에 할당 a = #(15) b; end정규할당 지연과 마찬가지로 딜레이엔 숫자, 변수 등이 올 수 있다.
정규지연과 차이점이라면
각 문장들이 블로킹 되지 않고 실행이 된다. 다만 최종적인 값을 할당하는 것만 지연이 될 뿐이다.
따라서 위의 코드에선 a = #(10) 1; a = #(15) b; 2개의 문장이 동시에 실행이 된다.
10ns 후에 1이 할당되고 5ns 후에 b가 할당된다.
딜레이가 지나기 전에 b의 값이 변하더라도 a에 할당되는 값은 변하지 않는다.
- 제로딜레이
'timescale 1ns/1ps reg a, b; // 내부할당 지연 initial begin a = 0; b = 0; a = #(0) 1; #(0) b = 1; end간혹 딜레이값에 0을 주는 경우가 있는데 이는 딜레이없이 할당하는 것과는 다르다.
베릴로그 시뮬레이션은 time slot 단위로 계산이 되는데 각 time slot 내부에서도 문장을 실행하는 순서가 정해져있다.
time slot은 다시 time region 으로 나눠져서 해당 시간대에서 계산되어야할 문장들의 순서가 정해진다.
딜레이가 0이라도 딜레이 없이 바로 할당하는 문장과는 다른 time region에서 계산이 된다. 그래서 결과를 예측하기가 힘들다.
시뮬레이터의 계산순서를 정확히 알지 않는다면, zero delay는 쓰지 않는것을 권한다.
2. event를 이용한 제어
베릴로그에서 event 는 어떤 값의 변화를 뜻한다.
event를 이용한 제어는 3가지 방법이 있다.
- 정규사건 제어
@(posedge clk) q <= d; @(clk) q <= d; q <= @(posedge clk) d; // 여러개의 event ORing 할 수 있다. always @(a, b, d, d) begin out = in; end // sensitivity list 를 *으로 대체 가능하다. always @(*) begin out = a ? b|c|d : e&f&g; end@ 키워드를 사용하여 신호가 할당되는 타이밍을 제어할 수 있다.
event 제어도 정규지연, 할당지연 두가지 방법으로 적용 가능하다.
@() 내부에 여러개의 변수를 넣을 수 있다. 괄호 안에 있는 신호들을 sensitivity list 라고 한다.
콤마 대신에 or 를 쓸 수 있다.
sensitivity list에 넣어야할 신호들이 너무 많을경우 @* 또는 @(*) 으로 대체할 수 있다.
해당 블럭내부의 어떠한 신호라도 변화가 있으면 구동된다.
- named event 제어
event recieve; // event 정의 always @(posedge clk) begin if (last_data) ->recieve; // recieve 이벤트를 trigger 한다. end // recieve 이벤트가 trigger 되면 동작한다 always @(recieve) begin Q <= d; endnamed event 정의를 위해 event 키워드를 제공한다.
이벤트를 구동하려면 ->event_name 형태로 trigger 한다.
- level sensitive 제어
always begin wait (enable == 1'b1) count <= #(10) count + 1'b1; end준위구동 제어라고 하는데 어떤 조건이 참이 될때 까지 기다렸다가 문장/블럭을 실행한다.
이를 위해 wait() 함수가 제공된다.
조건이 참이 아니라면 다음 문장실행이 블로킹 된다.