디지털 전자공학에서 시프트 레지스터는 한 플롭의 출력 핀 q가 다음 플롭의 데이터 입력 핀(d)에 연결된 플립플롭의 캐스케이드입니다. 모든 플롭이 같은 클럭으로 동작하므로 시프트 레지스터에 저장된 비트 배열이 한 위치씩 시프트됩니다. 예를 들어, 초기값이 10110인 5비트 우측 시프트 레지스터의 입력이 0으로 연결되면 다음 패턴은 01011, 그 다음은 00101이 됩니다.
설계
이 시프트 레지스터 설계는 다섯 개의 입력과 하나의 n비트 출력을 가지며, parameter MSB를 사용하여 시프트 레지스터의 폭을 나타냅니다. n이 4면 4비트 시프트 레지스터가 되고, n이 8이면 8비트 시프트 레지스터가 됩니다.
이 시프트 레지스터의 주요 특징:
en 핀으로 활성화/비활성화 가능
dir로 좌측/우측 시프트 방향 제어 가능
rstn을 로우로 당기면 시프트 레지스터 리셋, 출력은 0
d 핀으로 시프트 레지스터의 입력 데이터 값 제어 가능
module shift_reg #(parameter MSB=8) (
input d, // 시프트 레지스터의 첫 번째 플롭으로 들어갈 데이터 입력 선언
input clk, // 시프트 레지스터의 모든 플롭에 클럭 입력 선언
input en, // 시프트 레지스터 온/오프용 인에이블 입력 선언
input dir, // 좌측 또는 우측 시프트 방향 입력 선언
input rstn, // 레지스터를 기본값으로 리셋하는 입력 선언
output reg [MSB-1:0] out // 레지스터의 모든 플롭 현재 값을 읽기 위한 출력 선언
);
// 이 always 블록은 클럭의 상승 에지에서 "항상" 트리거됨
// 블록에 진입하면 먼저 리셋이 0인지 확인하고, 예이면 레지스터 리셋
// 아니면 시프트 레지스터가 인에이블되었는지 확인
// 아니오 => 이전 출력 유지. 예이면 요청된 방향에 따라 시프트
always @ (posedge clk)
if (!rstn) out <= 0;
else begin
if (en)
case (dir)
0 : out <= {out[MSB-2:0], d};
1 : out <= {d, out[MSB-1:1]};
endcase
else out <= out;
end
endmodule
하드웨어 회로도
테스트벤치
테스트벤치는 이 시프트 레지스터의 기능을 검증하는 데 사용됩니다. 설계는 최상위 module에 인스턴스화되고 입력들은 다양한 값으로 구동됩니다. 각 입력에 대한 설계 동작은 출력 핀 out에서 관찰할 수 있습니다.
module tb_sr;
parameter MSB = 16; // [선택] 시프트 레지스터의 비트 수를 나타내는 파라미터
reg data; // 설계의 d-입력을 구동할 변수 선언
reg clk; // 설계에 클럭을 구동할 변수 선언
reg en; // 설계에 인에이블을 구동할 변수 선언
reg dir; // 시프트 레지스터의 시프트 방향을 구동할 변수 선언
reg rstn; // 설계에 리셋을 구동할 변수 선언
wire [MSB-1:0] out; // 설계 출력에서 값을 캡처할 wire 선언
// MSB를 전달하여 설계(16비트 시프트 레지스터) 인스턴스화하고 TB 신호와 연결
shift_reg #(MSB) sr0 (
.d (data),
.clk (clk),
.en (en),
.dir (dir),
.rstn (rstn),
.out (out)
);
// 클럭 생성: 주기 = 20ns, 주파수 => 50MHz
always #10 clk = ~clk;
// 시간 0에 변수들을 기본값으로 초기화
initial begin
clk <= 0;
en <= 0;
dir <= 0;
rstn <= 0;
data <= 'h1;
end
// 설계를 검증하기 위해 메인 자극 구동
initial begin
// 1. 리셋 어서트 후 일정 시간 뒤 디어서트
rstn <= 0;
#20 rstn <= 1;
en <= 1;
// 2. 7클럭 동안 데이터 핀에 번갈아 값 구동
repeat (7) @ (posedge clk) data <= ~data;
// 4. 시프트 방향 변경 후 7클럭 동안 데이터 핀에 번갈아 값 구동
#10 dir <= 1;
repeat (7) @ (posedge clk) data <= ~data;
// 5. 다음 7클럭 동안 아무것도 구동하지 않고 dir에 따라 시프트만 허용
repeat (7) @ (posedge clk);
// 6. 시뮬레이션 종료
$finish;
end
// 이 변수들의 값을 모니터링하여 로그파일에 출력하여 디버깅
initial $monitor ("rstn=%0b data=%b, en=%0b, dir=%0b, out=%b", rstn, data, en, dir, out);
endmodule
아래 로그에서 시프트 레지스터가 인에이블된 시간은 녹색으로, 시프트 방향이 변경된 시간은 노란색으로, 데이터 입력 핀이 일정한 시간은 파란색으로 하이라이트되어 있습니다.