工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Industrial programming >> VHDL

VHDL での符号付きと符号なし

すべてのデジタル デザイナーは、FPGA または ASIC 内での演算の仕組みを理解する必要があります。そのための最初のステップは、符号付きおよび符号なしの信号タイプがどのように機能するかを理解することです。 numeric_std には符号付きと符号なしの型が存在します ieee ライブラリの一部であるパッケージ。数学演算を実行するために頻繁に使用される別のパッケージ ファイルがあることに注意してください:std_logic_arith .ただし、std_logic_arith は ieee がサポートする公式のパッケージ ファイルではないため、デジタル デザインでの使用は推奨されません。

タイプ signed として定義されているシグナル ツールがこの信号を正または負のいずれかに解釈することを意味します。タイプ unsigned として定義されているシグナル 信号が正のみであることを意味します。内部的に、FPGA は 2 の補数 を使用します。 表現。たとえば、3 ビットの信号は次の表に従って解釈できます。

ビット 符号なし値 符号付き値 011 3 3 010 2 2 001 1 1 000 0 0 111 7 -1 110 6 -2 101 5 -3 100 4 -4

あなたはまだ混乱していますか?これは直感的ではありません。うまくいけば物事を解決する例を見てみましょう。以下のファイルは、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 進数で表示する場合、一部は負の数値として解釈されます。符号付きおよび符号なしの型を使用する場合は、十分に注意する必要があります。このトピックをもう少しよく理解していただければ幸いです。これは多くのデジタル デザイナーが苦労している領域だと思います。完全に理解していないことがあれば、サイドバーの連絡先リンクからメールを送ってください。明確にするよう努めます。


最も人気のある Nandland ページ

VHDL

  1. チュートリアル - VHDL の紹介
  2. VHDL 変換の例
  3. プロシージャ ステートメント - VHDL の例
  4. レコード - VHDL の例
  5. 変数 - VHDL の例
  6. 現在の信号システム
  7. 信号機
  8. LoRaローカリゼーション
  9. PSL を使用した VHDL でのフォーマル検証
  10. VHDL で文字列のリストを作成する方法
  11. シグナルインテグリティとPCB