#3. FlipFlop(플립플롭)을 이용한 ShiftRegister 구현
논리회로설계실험(VHDL) 2020. 12. 24. 05:21
모바일 화면에서는 텍스트가 깨질 수 있습니다.
1-1. 배경이론(FlipFlop)
S-R 래치에서 클럭(Clock)이 포함된 형태로, 클럭값이 변할때만, 작동하는 회로로, 클럭값이 올라갈 때 작동하는 방식을 rising edge, 내려갈 때 작동하는 방식을 Falling edge라고 한다. 아래그림은 S-R FlipFlop의 회로도 이며, Rising edge 방식을 기준으로 만든 진리표이다. 앞의 SR래치와 값은 동일하지만, 클럭의 유무가 차이가 있다.
S-R Flipflop의 회로도
FlipFlop의 진리표
1-2. 배경이론(ShiftRegister)
FlipFlop을 여러 개 연결시켜, 값을 저장하는 회로가 Register이다. 그 중, 이번 실습은 shift Register을 구현한다. shift란 비트를 이동 하는것을 의미하는데 shift의 종류에는 3가지가 존재한다.3가지는 각각 circular, logical, arithmetic이며, 말로 설명하기 보다는 그림을 통해 이해하기 바란다.
1. circular shift (원형 시프트)
한비트씩 방향에 따라 움직이고, 마지막 비트가 처음 혹은 끝으로 이동한다.
circular shift의 동작방식 각각 right, left shift
2. logical shift (논리 시프트)
논리 shift이다. 단순히 비트를 좌, 우로 이동시키기만 하며, 이동시키고 남은 빈 자리에는 0을 채우는 방식으로 이루어진다. Circular shift와 마찬가지로, 부호비트(MSB)가 보존되지 않는다.
logical shift의 작동방식, 각각 right, left shift
3. Arithmetic shift(산술 시프트)
산술 shift이다. 앞의 두 shift와는 다르게 부호비트(MSB)가 보존된다. (오른쪽 shift일 경우), 왼쪽 shift의 경우엔 logical shift와 같은 방식으로 이루어진다.
arithmetic shift의 작동방식, 각각 right, left shift
2. ShiftRegister 코드
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity ShiftRegister is
Port ( clk : in STD_LOGIC; --포트구성(input) : clk, reset, enable 각각 1bit씩
reset : in STD_LOGIC;
enable : in STD_LOGIC;
Pi : in STD_LOGIC_VECTOR (3 downto 0); --포트구성(input) : parallel in (4bit)선언
mode : in STD_LOGIC_VECTOR (1 downto 0); --포트구성(input) : shift 방식을 결정해줄 mode 선언(2bit로 00,01,10,11 4가지 구성이 가능)
dir : in STD_LOGIC; --포트구성(input) : shift 방향성을 결정해줄 dir 선언(1bit, 0이면 right, 1이면 left)
Q : out STD_LOGIC_VECTOR (3 downto 0)); --포트구성(output) : Q 선언 (4bit)
end ShiftRegister;
architecture Behavioral of ShiftRegister is --아키텍쳐부분 시작, 내부신호 선언
signal in_Q : STD_LOGIC_VECTOR (3 downto 0); --내부신호 선언 in_Q
begin
Q <= in_Q; --내부신호가 출력값에 저장되도록 Q에 in_Q 대입
process(clk, reset) --process 시작, 실습에 주어진 조건에 맞추어 조건문을 쓴다.
begin
if(reset = '0') then --reset값이 0일때와 1일때로 나뉘는 조건문 시작
in_q <= "0000"; --reset값이 0일때의 동작, 내부신호 in_q에 0000(LOW)저장
elsif(clk ='1' and clk'event) then --reset값이 1인 상태에서, clk가 rising할 때의 조건문 시작
if(enable = '0') then --enable이 0일때와 1일때로 나뉘는 조건문 시작
in_q <= in_q; --enable이 0일때의 동작, 내부신호에 그대로 저장
elsif(mode = "00") then --enable이 1일때의 동작, mode의 상태에 따라 조건문 시작, mode가 00일때 Pi가 출력값으로 저장(내부신호에 저장하면 자동적으로 출력으로 나오게 된다.)
in_q <= Pi;
elsif(mode = "01") then --mode가 01일때 Circular shift 작동
if(dir = '0') then --Circular shift의 작동방향 결정(dir=0일때 Right, 1일때 Left),현재 right
in_q(2 downto 0) <= in_q(3 downto 1);
in_q(3) <= in_q(0);
else --Circular shift Left
in_q(3 downto 1) <= in_q(2 downto 0);
in_q(0) <= in_q(3);
end if; --dir에 대한 if문 종료
elsif(mode = "10") then --mode가 10일때 logical shift 작동
if(dir = '0') then --logical shift의 작동방향 결정(dir=0일때 Right, 1일때 Left),현재 right
in_q(2 downto 0) <= in_q(3 downto 1);
in_q(3) <= '0';
else --logical shift Left
in_q(3 downto 1) <= in_q(2 downto 0);
in_q(0) <= '0';
end if; --dir에 대한 if문 종료
elsif(mode = "11") then --mode가 11일때 arithmetic shift 작동
if(dir = '0') then --arithmetic shift의 작동방향 결정(dir=0일때 Right, 1일때 Left),현재 right
in_q(2 downto 0) <= in_q(3 downto 1);
in_q(3) <= in_q(3);
else --arithmetic shift Left
in_q(3 downto 1) <= in_q(2 downto 0);
in_q(0) <= '0';
end if; --if문 종료
end if; --enable과 mode에 대한 if문 종료
end if; --reset과 clk에 대한 if문 종료
end process; --process 종료
end Behavioral;
3. ShiftRegister TestBench코드
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
ENTITY ShiftRegister_TB IS
END ShiftRegister_TB;
ARCHITECTURE behavior OF ShiftRegister_TB IS
COMPONENT ShiftRegister
PORT( --포트 구성 입력값 : clk(1bit), reset(1bit), enable(1bit), Pi(4bit), mode(2bit), dir(1bit)
clk : IN std_logic;
reset : IN std_logic;
enable : IN std_logic;
Pi : IN std_logic_vector(3 downto 0);
mode : IN std_logic_vector(1 downto 0);
dir : IN std_logic;
Q : OUT std_logic_vector(3 downto 0) --포트 구성 출력값 : Q(4bit)
);
END COMPONENT;
--Inputs
signal clk : std_logic := '0'; --signal설정, 모든 값들이 0으로 초기화됩니다.
signal reset : std_logic := '0';
signal enable : std_logic := '0';
signal Pi : std_logic_vector(3 downto 0) := (others => '0');
signal mode : std_logic_vector(1 downto 0) := (others => '0');
signal dir : std_logic := '0';
--Outputs
signal Q : std_logic_vector(3 downto 0);
-- Clock period definitions
constant clk_period : time := 10 ns; --clk을 10ns의 주기로 설정
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: ShiftRegister PORT MAP (
clk => clk,
reset => reset,
enable => enable,
Pi => Pi,
mode => mode,
dir => dir,
Q => Q
);
-- Clock process definitions
clk_process :process --CLK process
begin
clk <= '0'; --clk에 0 대입
wait for clk_period/2; --0으로 바뀐뒤 5ns을 기다린다.
clk <= '1'; --clk에 1 대입
wait for clk_period/2; --1로 바뀐뒤 5ns을 기다린다.
end process;
-- Stimulus process
stim_proc: process --시간 뒤에 주석으로 달린값은 시간 누적값입니다.
begin
wait for 100 ns; --100ns
pi <= "1010"; --pi에 1010, enable에 1을 대입
enable <= '1';
wait for 50 ns;
reset <= '1'; --reset에 1, enable에 0을 대입
enable <= '0';
wait for 60 ns;
enable <= '1'; --enable에 1을 대입
wait for 100 ns;
pi <= "1011"; --pi 1011대입
wait for 40 ns;
mode <= "01"; --mode 01 대입
wait for 40 ns;
enable <= '0'; --enable 0대입
wait for 20 ns;
enable <= '1'; --enable 1대입
wait for 20 ns;
dir <= '1'; --dir 1대입
wait for 40 ns;
mode <= "10"; --mode 10, dir 0대입
dir <= '0'; --dir 0대입
wait for 20 ns;
dir <= '1'; --dir 1대입
wait for 20 ns;
mode <= "00"; --mode 00 pi에 1010 대입
pi <= "1010";
wait for 20 ns;
mode <= "11";
dir <= '0';
wait for 20 ns;
dir <= '1';
wait for 13 ns;
reset <= '0'; --reset 0대입, 초기화
wait for 100 ns;
wait for clk_period*10;
-- insert stimulus here
wait;
end process;
END;
#5. RAM/ROM (0) | 2021.03.08 |
---|---|
#4.Binary/Gray counter(이진,그레이 카운터) (0) | 2020.12.27 |
#2. 8 to 1 Multiplexer (0) | 2020.12.20 |
#1. Full adder(전가산기) (0) | 2020.10.22 |