플립플롭은 클럭의 양성 또는 음성 에지에서 입력 데이터를 캡처합니다. 중요한 점은 클럭 에지 이후 다음 클럭 에지까지 데이터에 무슨 일이 일어나든 출력에 반영되지 않는다는 것입니다. 반면 래치는 클럭 에지에서 캡처하지 않고, 인에이블 핀이 어서트되는 동안 출력이 입력을 따릅니다.
설계
이 예제에서는 세 개의 입력과 한 개의 출력을 가진 래치를 만듭니다. 입력 d는 0 또는 1이 될 수 있는 데이터를 나타내고, rstn은 액티브 로우 리셋, en은 입력 데이터가 출력으로 래치되도록 하는 인에이블입니다. 액티브 로우 리셋은 이 입력이 0이 되면 설계 요소가 리셋됨을 의미합니다. 출력 q의 값은 입력 d, en, rstn에 의해 결정됩니다.
module d_latch (
input d, // 데이터용 1비트 입력 핀
input en, // 래치 인에이블용 1비트 입력 핀
input rstn, // 액티브 로우 리셋용 1비트 입력 핀
output reg q // 데이터 출력용 1비트 출력 핀
);
// 이 always 블록은 en/rstn/d가 변경될 때마다 "항상" 트리거됨
// 리셋이 어서트되면 출력은 0
// 인에이블이 높으면 출력 q가 입력 d를 따름
always @ (en or rstn or d)
if (!rstn) q <= 0;
else if (en) q <= d;
endmodule
always 블록의 민감도 리스트에는 출력을 업데이트하는 데 필요한 모든 신호가 포함됩니다. 이 블록은 민감도 리스트의 신호 중 어느 것이든 값이 변경될 때마다 트리거됩니다. 또한 q는 en이 높을 때만 d의 값을 가지므로 포지티브 래치입니다.
회로도
테스트벤치
module tb_latch;
// 설계를 구동할 변수 선언
reg d;
reg en;
reg rstn;
reg [2:0] delay;
reg [1:0] delay2;
integer i;
// 설계 인스턴스화 및 TB 신호와 설계 포트 연결
d_latch dl0 (
.d (d),
.en (en),
.rstn (rstn),
.q (q)
);
// 이 initial 블록은 설계를 테스트하기 위한 자극을 형성
initial begin
$monitor ("[%0t] en=%0b d=%0b q=%0b", $time, en, d, q);
// 1. 테스트벤치 변수 초기화
d <= 0;
en <= 0;
rstn <= 0;
// 2. 리셋 해제
#10 rstn <= 1;
// 3. d와 인에이블을 랜덤하게 변경
for (i = 0; i < 5; i = i + 1) begin
delay = $random;
delay2 = $random;
#(delay2) en <= ~en;
#(delay) d <= i;
end
end
endmodule
테스트벤치가 신호를 더 랜덤하게 어서트/디어서트하도록 하기 위해, 0부터 7까지 값을 가질 수 있는 3비트 reg 변수 delay를 선언했습니다. 그런 다음 delay 변수를 사용하여 d와 en의 할당을 지연시켜 매 루프마다 다른 패턴을 얻습니다.