하드웨어
모든 프로그램 언어가 그렇듯 c 언어랑 비스무리 합니다.
그렇다고 vhdl 문법을 c 처럼 사용 하면 예상치 못한 오류가 발생하기도 하는데요
그중 한가지 예를 들어 보겠습니다.
--------------------------------------------------- -- PROCESS1 ( CPLD_RST ) --------------------------------------------------- process( SW_1, SW_2 ,SW_5 )
begin if ( SW_5 = '0')then if(SW_1'event and SW_1 = '0')then SIG_LED0 <= '1'; end if;
if(SW_2'event and SW_2 = '0')then SIG_LED0 <= '0'; end if;
end if;
end process; |
위 코드는 스위치 1 이 low 일때 스위치 5 나 2 의 폴링엣지 발생시 sig_led0 를 키거나 끄는 동작을 기대하고 만든 코드 입니다.
c 문법적으로 봤을때 크게 문제가 없어 보이지만, 위 코드는 컴파일도 안됩니다.
해결방법을 알기 위해서는 vhdl 이 하드웨어 언어라는 점과, 클럭 입력으로 처리되는 저 코드가 어떤 회로로 합성되는지를 이해해야 합니다.
클럭 입력으로 동작되는 코드는 플립플롭이나 래치에 합성 됩니다.
래치나 플립플롭은 하나의 클럭을 가지며, 한비트의 정보를 저장 하는 회로 입니다.
그런데 위 코드 에서는 출력 SIG_LED0 의 상태를 두개의 클럭(SW_1에의한 클럭과, SW_2 에 의한 클럭) 에 매핑 시키려 하고 있기 때문에 오류가 발생 합니다.
이 코드를 동작 하도록 수정 하기 위해서는 아래와 같이 수정 해야 합니다.
--------------------------------------------------- -- PROCESS1 ( CPLD_RST ) --------------------------------------------------- process( SW_1, SW_5 )
begin if(SW_5'event and SW_5 = '0')then if ( SW_1 = '0')then SIG_LED0 <= '1'; end if;
if ( SW_1 = '0')then SIG_LED0 <= '0'; end if;
end if;
end process; |
또는
--------------------------------------------------- -- PROCESS1 ( CPLD_RST ) --------------------------------------------------- process( SW_1,SW_5 )
begin if(SW_5'event and SW_5 = '0')then if ( SW_1 = '0')then SIG_LED0 <= '1'; else SIG_LED0 <= '0'; end if;
end if;
end process; |
이렇게 하나의 클럭으로 처리 되도록 해 주어야 합니다.
한 비트의 출력을 제어 하므로 하나의 래치에 합성된다는 것을 염두해 두어야 합니다.
이런점이 c 언어나 기타 고급 언어와는 다른 차이점이 아닌가 생각 됩니다.
마지막으로 상관 없는 내용이지만. vhdl 문법중 쉬프트 시키는 방법을 간략히 정리해 봅니다.
SSL, SRL 과 같은 명령이 있다곤 하지만 안되는 경우가 있기 때문에 아래와 같이 하면 좋습니다.
좌측으로 3비트 쉬프트 시키기
TEMP := BUF; BUF(31 downto 0) <= TEMP(28 downto 0) & "000"; |
BUF 에 들어있는 값을 TEMP 에 저장하고, TEMP 의 0 ~ 28번 까지를 BUF 의 31 번 비트부터 채워넣고 마지막 세비트에 000 을 채원 넣는 식입니다.
우측으로 3비트 쉬프트 시키기
TEMP := BUF; BUF(31 downto 0) <= "000" & TEMP(31 downto 3); |
우측으로 쉬프트 시키기는 반대로 TEMP 의 31 ~ 3 까지의 데이터를 BUF의 31 번째 부터 세비트에 000 을 넣고 그뒤에 붙여 넣는 식입니다.
이 쉬프트 방법을 조금 응용 하면 비트의 루프를 만들 수 도 있습니다.
BUF(31 downto 0) <= BUF(30 downto 0)&BUF(31); |