순차회로
논리게이트의 조합으로만 구성되는 조합논리회로의 Verilog 모델링에 관해 살펴보았고 이제부터는 순차회로의 Verilog 모델링을 살펴보자. 순차회로는 현재 인가되고 있는 입력뿐 아니라 과거의 입력과 회로에 기억된 상태값에 의해 출력이 결정되는 회로를 총칭한다. 따라서 순차회로는 과거의 입력이나 현재 상태값을 저장하는 기억소자(래치,플립플롭)와 조합논리회로로 구성된다.
순차회로는 동장방식에 따라 동기식 비동기식으로 구분된다. 동기식 순차회로는 회로를 구성하는 모든 플립플롭이나 래치들이 하나의 공통 클럭신호에 의해 동작하도록 구성된 회로를 말하며, 따라서 모든 플립플롭이나 래치들이 동일한 시점에 자신의 상태를 변화시킨다. 반면 비동기식 순차회로는 플립플롭이나 래치들이 서로 다른 클록신호에 의해 동작하도록 구성된 회로이며, 각 플립플롭들은 서로 다른 시점에 상태변화를 일으킨다. 일반적으로 대부분의 디지털 시스템은 동기식 방식을 기본으로 하고 있다.
디지털 시스템 설계에는 데이터 레지스터, 시프트 레지스터, 계수기, 직렬-병렬 변환기, 유한상태머신(FSM), 주파수 분주기, 펄스 발생기 등 다양한 종류의 순차회로가 사용된다. 이들 순차회로에는 클럭신호에 의해 동작하는 래치 또는 플립플롭이 기본적으로 포함된다.
래치와 플립플롭의 동작은 always구문 내부에 if 조건문을 이용하여 모델링될 수 있다. Edge-triggered플립플롭은 event제어 연산자 @와 전이 검출 수식어인 posedge 또는 negedge를 사용하여 if 조건문으로 모델링 될 수 있다.
★ 래치와 플립플롭
순차회로를 구성하는 저장소자는 동작방식에 따라 래치와 플립플롭으로 구분된다. 래치는 클록신호의 레벨(0또는 1)에 따라 동작하는 저장소자이며, 플립플롭은 클럭신호의 상승 또는 하강엣지에 동기되어 동작하는 저장소자이다.
★ D래치
D래치는 클록신호의 레벨(0또는1)에 따라 입력 D가 출력으로 통과되거나 또는 출력 Q의 값이 유지되는 동작을 수행한다. 클록신호의 레벨에 따라 동작하므로 level-sensitive D래치라고도 한다. D래치는 동작방식에 따라 positive level-sensitive 방식과 negative level-sensitive방식으로 구분된다. 위 그림은 positive level-sensitive D래치의 동작을 보이고 있다. 클록신호가 1인 기간에는 입력 D가 출력Q로 전달되며, 0인 기간에는 입력이 출력에 영향을 미치지 않고 출력 Q가 유지되는 동작을 한다.
positive level-sensitive D래치는 다음과 같이 모델링될 수 있다. always문의 감지신호목록에 clock과 d입력이 모두 포함되어야 하며, 클럭신호가 1인 동안에 입력 d가 출력 q로 전달되는 동작이 if(clock)조건문으로 표현된다. 클럭신호가 0인 동안에는 입력 d가 출력 q에 영향을 미치지 않아야 하므로 if 조건문에 else블록이 사용되지 않는다. 만약 else블록이 사용되면 래치가 아닌 조합논리회로로 동작하게 된다.
module dlatch(clk,d,q);
input clk, d;
output reg q;
always @(*) begin
if(clk) q=d;
end
endmodule
▣ TESTBENCH
module tb_dlatch;
reg clk,d;
wire q;
dlatch u0(clk,d,q);
always
#10 clk = ~clk;
initial begin
clk=1'b0;
d = 1'b0;
end
always begin
#15 d=1'b1; #20 d=1'b0;
#10 d=1'b1; #10 d=1'b0;
#10 d=1'b1; #15 d=1'b0;
end
endmodule
셋과 리셋 기능을 갖는 래치회로도 유사한 방법으로 모델링될 수 있다. 다음 코드는 active-low리셋을 갖는 positive level- sensitive D 래치의 모델링이다. 리셋 신호가 0인동안 래치의 출력을 0으로 만들기 위해 조건문이 사용되었다.
module dlatch_rst(rst,clk,d,q);
input rst,clk,d;
output reg q;
always@(*)begin
if(!rst) q=1'b0;
else if(clk) q = d;
end
endmodule
▣ TESTBENCH
module tb_dlatch_rst;
reg rst, clk, d;
wire q;
dlatch_rst u0(rst,clk,d,q);
always
#10clk = ~clk;
initial begin
clk =1'b0;
rst =1'b0;
d =1'b0;
#20 d=1'b1;
#40 rst=1'b1;
#15 d=1'b0; #20 d=1'b1;
end
endmodule
래치가 포함된 순차회로의 Verilog모델링에서 blocking할당문을 사용하는 경우와 nonblocking 할당문을 사용하는 경우의 차이점을 살펴본다. 다음코드는 if조건문에 else가 없으므로 래치가 포함된 순차회로로 동작한다. if조건문 내부에 2개의 blocking할당문이 포함되어있다. blocking할당문은 문장이 나열된 순서에 의해 실행되므로 ,첫번째 blocking할당문의 실행에 의해 reg m값이 변경되고, 변경된 m이 두번째 blocking할당문의 실행에 영향을 미친다. 두번째 blocking할당문 우변의 m은 변경된 현재의 값이 되므로, reg m은 래치가 아닌 단순 NOR게이트의 출력이 되며, 2번째 blcoking할당문의 reg y만 래치의 출력이 된다. (합셩결과 1개의 래치가 생성되었다.)
module latch_blk(en,a,b,c,y);
input en,a,b,c;
output reg y;
always@(*)begin
if(en) begin
m = ~(a|b);
y = ~(m&c);
end
end
endmodule
module latch_blk(en,a,b,c,y);
input en,a,b,c;
output reg y;
always@(*)begin
if(en) begin
m <= ~(a|b);
y <= ~(m&c);
end
end
endmodule
밑의 합성결과의 차이를 보듯이 래치가 포함된 순차회로의 모델링에서 blocking과 nonblocking은 커다란 차이를 갖는다. 래치가 1개 포함된 회로와 2개 포함된 회로는 전혀 다른 회로이므로, 설계자가 의도하는 회로가 구현될 수 있도록 올바른 구문을 사용해야 한다.
★ Filp Flop
Edge trigger D F/F의 모델링을 위해서는 다음과 같이 always구문에 event제어 연산자@와 엣지 검출 수식어인 posedge, negedge를 사용해서 클럭신호의 에지를 검출한다. 클럭신호의 에지에서만 동작하므로 always블록의 event 목록에는 클럭신호만 포함시키고, 데이터 입력신호는 포함하지 않는다. (단, 비동기식 set,reset을 갖는 F/F의 경우에는 set과 reset신호도 함께 포함시켜야한다.
// clock의 상승에지 검출
always @(posedge clk)
// clock의 하강에지 검출
always @(negedge clk)
Edge trigger D F/F이 q와q_bar 출력을 갖는 경우의 Verilog모델링에대해 살펴보자.
1. 두개의 nonblocking 할당문을 통해 q와q_bar를 생성하는 경우. (좋지 않은 모델링)
module dff(clk,d,q,q_bar);
input clk,d;
output reg q,q_bar;
always@(posedge clk)begin
q<=d;
q_bar<=~d;
end
endmodule
2. 두개의 blocking할당문을 통해 q와q_bar를 생성하는 경우.(좋지 않은 모델링)
module dff(clk,d,q,q_bar);
input clk,d;
output reg q,q_bar;
always@(posedge clk)begin
q=d;
q_bar=~d;
end
endmodule
always구문 내부에 두 개의 nonblocking,blocking 할당문을 통해 q,q_bar를 생성하는데 q,q_bar가 모두 플립플롭의 출력이 되며, 두개의 플립플롭이 합성된다. 두 경우 모두 클럭의 상승에지에서 동작하고 q_bar는 q의 반전값을 출력하므로, 컽으로 보기에 회로는 올바르게 동작하지만, 1비트의 정보를 저장하기 위하여 2개의 플립플롭을 사용하는것은 비효율적이다.
위의 두 코드가 2개의 플립플롭을 생성하는 이유는 always블록 내에서 신호q와 q_bar를 생성하기 때문이다. 따라서 한 개의 플립플롭을 생성하기 위해서는 다음과 같은 코드로 always블록에서 출력 q만 생성하고, q_bar는 always블록 밖에서 assign구문으로 생성해야한다.
module dff_good(clk,d,q,q_bar);
input clk,d;
output reg q;
output q_bar;
always@(posedge clk)begin
q <= d;
end
assign q_bar = ~q;
endmodule
★ 동기식 Set, Rest을 갖는 D 플립플롭
동작방식에 따라 동기식과 비동기식으로 구분되며, set/reset신호가 0일때 동작하는 active-low방식과 1일 때 동작하는 active-high 방식으로 구분된다. 다음코드는 active-low리셋을 갖는 D F/F의 모델링이다. 동기식 리셋을 위해 always에 posedge clk만 포함시키며, rst_n은 포함되지 않는다. always내부에서 if조건문을 이용해 active-low 리셋 동작이 구현된다.
module dff_sync_rst(clk,d,rst_n,q,qb);
input clk,d,rst_n;
output reg q;
output qb;
assign qb = ~q;
always@(posedge clk)begin
if(!rst_n) q <= 1'b0;
else q <= d;
end
endmodule
★ 비동기식 Set, Rest을 갖는 D F/F
다음은 비동기식 acitve-low 리셋을 갖는 D 플립플롭의 모델링이다. 비동기식 리셋을 위해 always 블록의 event에 posedge clk 와 negedge rst_n 되어야 하며, 이에 클럭신호의 상승에지와 무관하게 리셋신호 rst_n의 하강엣지가 검출되면 리셋동작이 일어나게된다.
module dff_async_rst(clk,d,rst_n,q,qb);
input clk,d,rst_n;
output reg q;
output qb;
assign qb = ~q;
always@(posedge clk or negedge rst_n)begin
if(!rst_n) q <= 1'b0;
else q <= d;
end
endmodule
★F/F이 포함된 순차회로의 Verilog modeling에서 blocking, nonblocking 할당문의 차이
다음 코드는 always구문의 @(posedge clk)에 의해 플립플롭이 포함된 순차회로로 동작한다. blocking 할당문은 문장이 나열된 순서에 따라 실행되는 순차적 흐름을 가지므로, 첫 번째와 두 번째 blocking 할당문의 실행에 의해 reg m과n의 값이 변경되고, 변경된 m과 n이 세 번째 blocking할당문의 실행에 영향을 미친다. 따라서 세 번째 blocking할당문 우변의 m과 n은 변경된 현재의 값이 되므로, reg m과 n은 단순 NAND게이트와 OR게이트의 출력이 되며, 세번째 blocking 할당문의 reg y만 플립플롭의 출력이 된다. 즉, 1개의 플립플롭만이 출력이 된다. (합성 결과 참고)
module seq_blk(clk,a,b,c,d,e,y);
input clk,a,b,c,d,e;
output y;
reg m,n,y;
always@(posedge clk)begin
m = ~(a&b);
n = c|d;
y = ~(m|n|e);
end
endmodule
동일하게 always구문의 @(posedge clk)에 의해 플립플롭이 포함된 순차회로로 동작한다. always 블록 내부에 3개의 nonblocking할당문이 포함되어 있으며 순차적 흐름에 대한 blocking없이 정해진 할당 스케줄에 의해 값이 할당된다. begin-end 블록 내 nonblocking할당문들은 우변이 동시에 평가된 후, 할당 스케쥴(이 예에서는 문장의 나열 순)에 따라 좌변의 객체에 값이 할당된다.
따라서, 첫 번째와 두 번째 nonblocking할당문에서 좌변의 m과 n에 대한 할당이 일어나기 이전의 m과 n의 값이 세번째 nonblocking할당문 우변의 평가에 사용된다. 결국 nonblocking할당문 좌변의 객체 m,n,y는 할당이 이루어지기 이전의 값을 유지하고 있어야 하므로 이들은 플립플롭의 출력이 된다.즉, 3개의 플립플롭이 생성되었다. (합성 결과 확인)
module seq_nonblk(clk,a,b,c,d,e,y);
input clk, a,b,c,d,e;
output y;
reg m,n,y;
always@(posedge clk)begin
m = ~(a&b);
n = c|d;
y = ~(m|n|e);
end
endmodule
위의 두 예제에서 보듯이 플립플롭이 포함된 순차회로의 모델링에서 blocking 할당문과 nonblocking할당문은 커다란 차이를 보인다. 플립플롭이 1개 포함된 회로와 3개 포함된 회로는 전혀 다른회로이므로, 설계자가 의도하는 회로가 구현될 수 있도록 올바른 구문을 사용해야된다.
'UVM & RTL > Verilog HDL' 카테고리의 다른 글
[26] Verilog HDL 순차회로에서 blocking할당문과 nonblocking할당문 (0) | 2022.03.05 |
---|---|
[25] Verilog HDL 순차회로 설계과제 (LATCH, FILP FLOP) (0) | 2022.03.05 |
[23] Verilog HDL 순차회로 설계과제 (COMPARATOR, TRI-STATE) (0) | 2022.03.05 |
[22] Verilog HDL 조합회로 구현 (COMPARATOR, TRI-STATE) (0) | 2022.03.05 |
[21] Verilog HDL 조합회로 설계과제 (Decoder, Encoder) (1) | 2022.03.05 |
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!