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 시뮬레이션 웨이브 출력 값은 16진수로 표시됨
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를 만드는 데는 좋습니다. 하드웨어 설명 언어로 디지털 논리