Освоение знаковых и беззнаковых типов в VHDL: практические инсайты
Цифровые проектировщики полагаются на точную арифметику внутри ПЛИС и ASIC. Ключевая концепция — различие между знаковыми (signed) и беззнаковыми (unsigned) типами данных в VHDL.
Оба типа определены в пакете numeric_std библиотеки IEEE. Хотя многие проектировщики все еще используют std_logic_arith, этот пакет не является стандартом IEEE и не рекомендуется для производственных проектов.
В VHDL знаковый сигнал интерпретируется как число в дополнительном коде, позволяя как положительные, так и отрицательные значения. Беззнаковый сигнал представляет только неотрицательные значения. Внутри ПЛИС всегда используется дополнительный код для всех битовых векторов, независимо от объявленного типа.
| Биты | Беззнаковое значение | Знаковое значение |
|---|---|---|
| 011 | 3 | 3 |
| 010 | 2 | 2 |
| 001 | 1 | 1 |
| 000 | 0 | 0 |
| 111 | 7 | -1 |
| 110 | 6 | -2 |
| 101 | 5 | -3 |
| 100 | 4 | -4 |
На первый взгляд это отображение может показаться контр интуитивным, но как только вы понимаете дополнительный код, поведение становится предсказуемым.
Важно отметить, что бинарный результат арифметической операции идентичен, будь операнды объявлены как знаковые или беззнаковые. Меняется только интерпретация этого результата.
Например, сложение двух 5-битных векторов:
- Знаковое: 10001 + 00010 = 10011 (интерпретируется как –13)
- Беззнаковое: 10001 + 00010 = 10011 (интерпретируется как 19)
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 p_SUM : process (i_clk, i_rst_l) begin if i_rst_l = '0' then 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; p_SUB : process (i_clk, i_rst_l) begin if i_rst_l = '0' then 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 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 simulation wave – Hex values
Modelsim simulation wave – Decimal values
Два скриншота демонстрируют, что базовые бинарные результаты идентичны независимо от типа. Разница возникает только когда симулятор отображает значения: в hex один и тот же битовый паттерн появляется, а в десятичном знаковые результаты могут быть отрицательными. Тщательная обработка типов критична при проектировании логики ПЛИС.
Если какая-либо часть этой темы остается неясной, пожалуйста, напишите нам через контактную ссылку в боковой панели. Мы рады помочь вам освоить знаковую и беззнаковую арифметику.
| Самые популярные страницы Nandland |
|---|
VHDL
- Введение в VHDL: создание вашего первого И-шлюза
- Полное руководство по преобразованию типов в VHDL с Numeric_Std и Std_Logic_Arith
- Пример процедуры VHDL: инкремент std_logic_vector
- Использование записей (Records) в VHDL для чистых, повторно используемых интерфейсов FIFO
- Переменные в VHDL: практические примеры и правила для надежного дизайна
- Токовые сигнальные системы: стандарт 4–20 мА подробно
- Светофоры: инженерия, история и будущие инновации
- Локализация LoRa: почему нативная геолокация сложнее, чем кажется
- Создание списков строк в VHDL: лучшие практики и пример
- Обеспечение целостности сигнала в высокоскоростном дизайне PCB