UVM & RTL/Verilog HDL

[Verilog HDL] CH7 구조적 프로시저 & 절차적 할당

Return 2022. 6. 14. 14:44

구조적 프로시저 

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할당을 위해 다음과 같은 일이 순차적으로 일어난다. 

1. clk의 상승 엣지에서 오른쪽의 각 변수들 in1,in2,in3, reg1의 값을 읽는 동작이 수행된다. 오른쪽의 수식은 계산을 하고, 시뮬레이터의 내부에 저장된다.

2. 각 할당문 내부에 선언된 지연에 의해 지정된 시간에 왼쪽의 변수에 쓰기 동작이 수행된다. reg1은 1단위 시간 후, reg2는 다음 클럭의 하강 엣지, reg3은 1단위 시간 후에 쓰기하도록 스케줄 됨

3. 스케줄된 시간 단계에서 쓰기 동작 수행. 내부 저장된 오른쪽 수식의 값이 왼쪽값으로 할당되기 때문에 쓰기 동작 명령이 수행되는 것은 중요하지 않다. reg3에 쓰기 연산이 수행되기 전 reg1에 새로운 값이 쓰였더라도 reg3에는 읽기 연산 후에 저장된 reg1의 이전값이 할당된다.

그러므로 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;
보기1에서 blocking문장을 사용할때 경쟁상태(race condition)가된다. 즉, a=b, b=a중 어느 것이 먼저 수행되는냐는 시뮬레이터의 실행 방법에 따라 달라진다. 그러므로 레지스터 a, b의 값은 바뀌지 않는다.
보기2에서 nonblocking문장은 경쟁상태를 없애준다. 클럭의 상승 엣지에서 모든 오른쪽 변수의 값은 읽기 동작을 하고, 오른쪽 수식의 값은 계산되고, 임시 변수에 저장된다. 쓰기 동작동안 임시 변수에 저장된 값이 왼쪽의 변수에 할당된다. 읽기와 쓰기 동작을 분리함으로써, 쓰기 명령이 수행되는 것에 개의치 않고 레지스터 a,b의 값을 정확하게 바꿀 수 있다.
always @(posedge clock) begin
    // 읽기 연산 
    temp_a = a;
    temp_b = b;
    // 쓰기 연산 
    a = temp_a;
    b = temp_b;
end
디지털 설계에서 blocking 할당 대신 nonblocking할당을 사용하는 것인 공통적인 사건 후에 동시에 데이터 전송이 일어나는 곳에서 사용할 것을 권한다. 그러한 경우에 최종 결과는 할당이 수행되는 순서에 영향을 받기 때문에, blocking할당은 경쟁 상태가 될 수 있다. nonblocking할당은 최종 결과가 할당을 수행한 후의 값에 영향을 받지 않기 때문에 동시에 데이터를 전송하는 모델로 사용하고는 한다.