VHDL での符号付きと符号なし
すべてのデジタル デザイナーは、FPGA または ASIC 内での演算の仕組みを理解する必要があります。そのための最初のステップは、符号付きおよび符号なしの信号タイプがどのように機能するかを理解することです。 numeric_std には符号付きと符号なしの型が存在します ieee ライブラリの一部であるパッケージ。数学演算を実行するために頻繁に使用される別のパッケージ ファイルがあることに注意してください:std_logic_arith .ただし、std_logic_arith は ieee がサポートする公式のパッケージ ファイルではないため、デジタル デザインでの使用は推奨されません。
タイプ signed として定義されているシグナル ツールがこの信号を正または負のいずれかに解釈することを意味します。タイプ unsigned として定義されているシグナル 信号が正のみであることを意味します。内部的に、FPGA は 2 の補数 を使用します。 表現。たとえば、3 ビットの信号は次の表に従って解釈できます。
あなたはまだ混乱していますか?これは直感的ではありません。うまくいけば物事を解決する例を見てみましょう。以下のファイルは、signed unsigned がどのように機能するかをテストします。理解する必要があるのは、信号が署名済みまたは未署名として定義されているかどうかは 定義されていないということです。 実際のバイナリ計算の実行方法に影響します。
例:2 つの符号付きベクトル 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 シミュレーション波形の出力値は 10 進数で表示
上記の 2 つのモデルシムのスクリーンショットを比較してください。最初に、結果 の数学関数は、16 進数で表した場合とまったく同じです。 解釈です 異なる結果の。これは、下のスクリーンショットを見るとわかります。 Modelsim が結果を 10 進数で表示する場合、一部は負の数値として解釈されます。符号付きおよび符号なしの型を使用する場合は、十分に注意する必要があります。このトピックをもう少しよく理解していただければ幸いです。これは多くのデジタル デザイナーが苦労している領域だと思います。完全に理解していないことがあれば、サイドバーの連絡先リンクからメールを送ってください。明確にするよう努めます。
VHDL