Signed vs. Unsigned Typen in VHDL: Praktische Inzichten
Digitale ontwerpers vertrouwen op nauwkeurige rekenkunde binnen FPGA's en ASIC's. Een kernconcept is het onderscheid tussen signed en unsigned datatypes in VHDL.
Beide typen zijn gedefinieerd in de numeric_std package van de IEEE-bibliotheek. Hoewel veel ontwerpers nog steeds std_logic_arith gebruiken, is deze package geen IEEE-standaard en niet aanbevolen voor productieontwerpen.
In VHDL wordt een signed signaal geïnterpreteerd als een two's-complement getal, wat zowel positieve als negatieve waarden toestaat. Een unsigned signaal vertegenwoordigt alleen niet-negatieve waarden. Intern gebruikt de FPGA altijd two's-complement voor alle bit-vectoren, ongeacht het type dat u declareert.
| Bits | Unsigned Waarde | Signed Waarde |
|---|---|---|
| 011 | 3 | 3 |
| 010 | 2 | 2 |
| 001 | 1 | 1 |
| 000 | 0 | 0 |
| 111 | 7 | -1 |
| 110 | 6 | -2 |
| 101 | 5 | -3 |
| 100 | 4 | -4 |
Op het eerste gezicht kan deze mapping tegenstrijdig lijken, maar zodra u two's-complement begrijpt, is het gedrag voorspelbaar.
Het is belangrijk om te noteren dat het binaire resultaat van een rekenoperatie identiek is of de operandes nu signed of unsigned gedeclareerd zijn. Wat verandert is de interpretatie van dat resultaat.
Bijvoorbeeld, het optellen van twee 5-bit vectoren:
- Signed: 10001 + 00010 = 10011 (geïnterpreteerd als –13)
- Unsigned: 10001 + 00010 = 10011 (geïnterpreteerd als 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;
Testbench
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 simulatie-golf – Hex-waarden
Modelsim simulatie-golf – Decimale waarden
De twee screenshots tonen aan dat de onderliggende binaire resultaten identiek zijn ongeacht type. Het verschil ontstaat alleen wanneer de simulator de waarden weergeeft: in hex verschijnt hetzelfde bitpatroon, terwijl in decimaal signed-resultaten negatief kunnen lijken. Zorgvuldige type-afhandeling is essentieel bij FPGA-logica-ontwerp.
Als een deel van dit onderwerp onduidelijk blijft, mail ons via de sidebar contactlink. We helpen graag om signed en unsigned rekenkunde te meesteren.
| Meest Populaire Nandland Pagina's |
|---|
VHDL
- Verkeerslichten: Techniek, Geschiedenis en Toekomstige Innovaties
- Stroomsignaal-systemen: de 4–20 mA lus uitgelegd
- Signaalintegriteit Zekerstellen in High-Speed PCB-ontwerp
- LoRa Localisatie: Waarom Native Geolocatie Complexer Is Dan Het Lijkt
- Inleiding tot VHDL: Uw Eerste AND-poort Bouwen
- Uitgebreide Gids voor VHDL Type Conversies met Numeric_Std en Std_Logic_Arith
- VHDL Procedure Voorbeeld: Een Standard Logic Vector Incrementeren
- VHDL Records Gebruiken voor Schone, Herbruikbare FIFO-interfaces
- VHDL Variabelen Uitgelegd: Praktische Voorbeelden & Regels voor Betrouwbaar Ontwerp
- Formele verificatie van VHDL-modules met PSL meesteren
- Dynamische string-lijsten in VHDL: Best Practices & Voorbeeld