VHDL
모든 디지털 디자이너는 수학이 FPGA 또는 ASIC 내부에서 어떻게 작동하는지 이해해야 합니다. 이를 위한 첫 번째 단계는 부호 있는 신호 유형과 부호 없는 신호 유형이 작동하는 방식을 이해하는 것입니다. numeric_std에 서명된 유형과 서명되지 않은 유형이 있습니다. ieee 라이브러리의 일부인 패키지. 수학 연산을 수행하는 데 자주 사용되는 또 다른 패키지 파일이 있습니다. std_logic_arith . 그러나 std_logic_arith는 공식 ieee 지원 패키지 파일이 아니므로 디지털 디자인에 사용하지 않는 것이 좋습니다.
signed 유형으로 정의된 신호 이는 도구가 이 신호를 양수 또는 음수로 해석한다는 것을 의미합니다. unsigned 유형으로 정의된 신호 신호가 양수일 것임을 의미합니다. 내부적으로 FPGA는 2의 보수를 사용합니다. 대표. 예를 들어, 3비트 신호는 아래 표에 따라 해석될 수 있습니다.
아직 혼란스러우신가요? 이것은 직관적이지 않습니다! 희망적으로 상황을 정리할 예를 살펴보겠습니다. 아래 파일은 서명되지 않은 서명이 작동하는 방식을 테스트합니다. 이해해야 할 것은 신호가 서명 또는 서명되지 않은 것으로 정의되든 그렇지 않든 않습니다. 실제 이진 수학이 수행되는 방식에 영향을 줍니다.
예:두 개의 부호 있는 벡터 10001 + 00010의 경우 답은 여전히 10011이지만 해석입니다. 결과가 다릅니다.
부호가 없는 경우 답(10011)은 19를 나타냅니다.
서명된 케이스의 경우 답(10011)은 -13을 나타냅니다.
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity signed_unsigned is port ( i_rst_l : in std_logic; i_clk : in std_logic; i_a : in std_logic_vector(4 downto 0); i_b : in std_logic_vector(4 downto 0) ); end signed_unsigned; architecture behave of signed_unsigned is signal rs_SUM_RESULT : signed(4 downto 0) := (others => '0'); signal ru_SUM_RESULT : unsigned(4 downto 0) := (others => '0'); signal rs_SUB_RESULT : signed(4 downto 0) := (others => '0'); signal ru_SUB_RESULT : unsigned(4 downto 0) := (others => '0'); begin -- Purpose: Add two numbers. Does both the signed and unsigned -- addition for demonstration. This process is synthesizable. p_SUM : process (i_clk, i_rst_l) begin if i_rst_l = '0' then -- asynchronous reset (active low) rs_SUM_RESULT <= (others => '0'); ru_SUM_RESULT <= (others => '0'); elsif rising_edge(i_clk) then ru_SUM_RESULT <= unsigned(i_a) + unsigned(i_b); rs_SUM_RESULT <= signed(i_a) + signed(i_b); end if; end process p_SUM; -- Purpose: Subtract two numbers. Does both the signed and unsigned -- subtraction for demonstration. This process is synthesizable. p_SUB : process (i_clk, i_rst_l) begin if i_rst_l = '0' then -- asynchronous reset (active low) rs_SUB_RESULT <= (others => '0'); ru_SUB_RESULT <= (others => '0'); elsif rising_edge(i_clk) then ru_SUB_RESULT <= unsigned(i_a) - unsigned(i_b); rs_SUB_RESULT <= signed(i_a) - signed(i_b); end if; end process p_SUB; end behave;
테스트벤치:
library ieee; use ieee.std_logic_1164.all; entity example_signed_unsigned_tb is end example_signed_unsigned_tb; architecture behave of example_signed_unsigned_tb is --Registers signal r_CLK : std_logic := '0'; signal r_RST_L : std_logic := '0'; signal r_A : natural := 0; signal r_B : natural := 0; signal r_A_SLV : std_logic_vector(4 downto 0) := (others => '0'); signal r_B_SLV : std_logic_vector(4 downto 0) := (others => '0'); constant c_CLK_PERIOD : time := 10 ns; component example_signed_unsigned is port ( i_rst_l : in std_logic; i_clk : in std_logic; i_a : in std_logic_vector(4 downto 0); i_b : in std_logic_vector(4 downto 0) ); end component example_signed_unsigned; begin i_DUT: example_signed_unsigned port map ( i_rst_l => r_RST_L, i_clk => r_CLK, i_a => r_A_SLV, i_b => r_B_SLV ); clk_gen : process is begin r_CLK <= '0' after c_CLK_PERIOD/2, '1' after c_CLK_PERIOD; wait for c_CLK_PERIOD; end process clk_gen; process begin r_RST_L <= '0'; wait for 20 ns; r_RST_L <= '1'; wait for 20 ns; r_A_SLV <= "01001"; r_B_SLV <= "00110"; wait for 20 ns; r_A_SLV <= "10001"; r_B_SLV <= "00110"; wait for 20 ns; r_A_SLV <= "10001"; r_B_SLV <= "00001"; wait for 20 ns; r_A_SLV <= "10001"; r_B_SLV <= "00010"; wait for 20 ns; r_A_SLV <= "11111"; r_B_SLV <= "00001"; wait for 20 ns; r_A_SLV <= "00000"; r_B_SLV <= "00001"; wait for 20 ns; wait; end process; end behave;
Modelsim 시뮬레이션 웨이브 출력 값은 DECIMAL로 표시
위의 두 modelsim 스크린샷을 비교하십시오. 처음에는 결과가 수학 함수의 16진수로 표현될 때 정확히 동일합니다. 해석입니다. 결과가 다릅니다. 이는 하단 스크린샷을 보면 알 수 있습니다. Modelsim이 결과를 10진수로 표시할 때 일부는 음수로 해석됩니다. 서명된 유형과 서명되지 않은 유형을 사용할 때는 매우 주의해야 합니다! 이 주제를 조금 더 잘 이해하시기 바랍니다. 이것은 많은 디지털 디자이너가 어려움을 겪는 영역인 것 같습니다. 따라서 완전히 이해하지 못하는 부분이 있으면 사이드바에 있는 연락처 링크를 통해 저에게 이메일을 보내주시면 더 명확하게 설명하도록 노력하겠습니다.
VHDL
이전 자습서에서 For-Loop를 사용하여 정수 범위를 반복하는 방법을 배웠습니다. 그러나 고정된 정수 범위보다 루프를 더 자세히 제어하려면 어떻게 해야 할까요? 이를 위해 While 루프를 사용할 수 있습니다. While 루프는 테스트하는 표현식이 true로 평가되는 한 계속해서 동봉된 코드를 반복합니다. . 따라서 While-Loop는 얼마나 많은 반복이 필요한지 미리 알 수 없는 상황에 적합합니다. 이 블로그 게시물은 기본 VHDL 자습서 시리즈의 일부입니다. While 루프의 구문은 다음과 같습니다. while <
간단히 말해 VHDL은 디지털 회로 설계에 사용되는 컴퓨터 언어입니다. 저는 VHDL을 Java 또는 C++와 같은 보다 일반적인 다른 프로그래밍 언어와 구별하기 위해 컴퓨터 언어라는 용어를 사용합니다. 그러나 VHDL은 프로그래밍 언어입니까? 예, 그렇습니다. 컴퓨터 프로그램을 만들 때 아무 소용이 없는 프로그래밍 언어입니다! VHDL은 이벤트 구동 병렬 프로그래밍 언어입니다. 컴퓨터의 CPU가 실행할 수 있는 프로그램을 만드는 데는 적합하지 않지만 실제 CPU를 만드는 데는 좋습니다. 하드웨어 설명 언어로 디지털 논리