2017-06-15 19 views
0

VHDLの32ビット乗算器の記録ロジックを実装しようとしています。さらに、入力ビットベクトル(x_in)は再符号化されるため、1つの余分な入力「1」があります。 「1」が'1'の場合は、出力はでなければなりません。「1」が'0'の場合は、の2倍にする必要があります。また、 "neg"が高い場合、出力を反転する必要があります。ここに私のVHDLコードです:VHDLコードの混乱

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.std_logic_unsigned.all; 
use IEEE.std_logic_arith.all; 

package test is 
    function toString(v : std_logic_vector) return string; 
    function toString(b : std_logic) return string; 
end package; 

package body test is 
    function toString(b : std_logic) return string is 
     variable str : string(1 to 3); 
     begin 
      str := std_logic'image(b); 
      return "" & str(2); 
    end toString; 

    function toString(v : std_logic_vector) return string is 
     variable str : string(1 to 1); 
     variable strOut : string(1 to v'length); 
     begin 
      for i in 1 to v'length loop 
       str := toString(v(i-1)); 
       strOut(v'length - i + 1) := str(1); 
      end loop; 
      return strOut; 
    end toString; 
end test; 

私が実行します。

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.std_logic_unsigned.all; 
use ieee.std_logic_arith.all; 
use work.sum_vector_pkg.all; 

entity tb_multipleGenerator is 

end entity tb_multipleGenerator; 

architecture logic of tb_multipleGenerator is 

    component multipleGenerator 
     generic(
      constant WIDTH : integer := 32 
     ); 
     port(
      x_in  : in std_logic_vector(31 downto 0); 
      one  : in std_logic_vector(15 downto 0); 
      multiple : out partial_sum_array 
     ); 
    end component; 

    signal x_tb  : std_logic_vector(31 downto 0); 
    signal one_tb  : std_logic_vector(15 downto 0); 
    signal multiple_tb : partial_sum_array; 

begin 
    process begin 
     x_tb <= x"00000000"; 
     one_tb <= x"0000"; 
     wait for 200 ns; 
     x_tb <= x"00001111"; 
     one_tb <= x"0011"; 
     wait; 
    end process; 

    u_mult: multipleGenerator 
     generic map (
      WIDTH => 32 
     ) 
     port map (
      x_in  => x_tb, 
      one  => one_tb, 
      multiple => multiple_tb 
     ); 
end architecture logic; 

私は次のパッケージを使用していた出力を確認するには:

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.std_logic_unsigned.all; 
use IEEE.std_logic_arith.all; 

package sum_vector_pkg is 
    type partial_sum_array is array (0 to 15) of std_logic_vector(32 downto 0); 
end package; 

library ieee; 
use ieee.std_logic_1164.all; 
use ieee.std_logic_unsigned.all; 
use IEEE.std_logic_arith.all; 
use work.sum_vector_pkg.all; 
use work.test.all; 

entity multipleGenerator is 
    generic(
      constant WIDTH : integer := 32 
    ); 
    port(
     x_in  : in std_logic_vector(WIDTH - 1 downto 0); 
     one  : in std_logic_vector(WIDTH/2 - 1 downto 0); 
     multiple : out partial_sum_array 
    ); 
end entity multipleGenerator; 

architecture logic of multipleGenerator is 
    signal sum : std_logic_vector(WIDTH downto 0); 

begin 
    gen : for i in 0 to WIDTH/2 - 1 generate 
     process (one,sum,x_in) is begin 
      case one(i) is 
       when '0' => sum <= x_in & '0'; -- twice x_in 
       when '1' => sum <= '0' & x_in; -- same as x_in 
       when others => sum <= x"00000000" &'0'; 
      end case; 
      multiple(i) <= sum; 
      report "The sum is " & toString(sum) & " one(i) is " & toString(one(i)) & " x_in is " & toString(x_in); 
     end process; 
    end generate; 
end architecture logic; 

私は、次のテストベンチでそれを実行しています上記のコードは'X'の出力になります。ここにサンプル出力があります:

Time: 200 ns Iteration: 2 Region: /tb_multiplegenerator/u_mult/gen(12) 
# ** Note: The sum is 0000000000000000000XX00XX00XX00XX one(i) is 0 x_in is 00000000000000000001000100010001 
# Time: 200 ns Iteration: 2 Region: /tb_multiplegenerator/u_mult/gen(13) 
# ** Note: The sum is 0000000000000000000XX00XX00XX00XX one(i) is 0 x_in is 00000000000000000001000100010001 
# Time: 200 ns Iteration: 2 Region: /tb_multiplegenerator/u_mult/gen(14) 
# ** Note: The sum is 0000000000000000000XX00XX00XX00XX one(i) is 0 x_in is 00000000000000000001000100010001 
# Time: 200 ns Iteration: 2 Region: /tb_multiplegenerator/u_mult/gen(15) 

誰かがこのコードが機能していない理由を説明してください。

+0

[最小限、完全で検証可能な例](https://stackoverflow.com/help/mcve)はどうですか?関数bv_negateでパッケージmlite_packをダミーにし、テストベンチを提供することができました。最低でも、失敗時に1とnegの明確な値を提供し、それらの報告書がどのように生成されるかを示しました。あなたの問題は、あなたが提供したもので複製することはできません。 – user1155120

+0

@ user1155120私は質問を更新し、テストベンチも提供しました。見てください、今すぐ複製可能でなければなりません。 – sarthak

+1

コードで生成された「合計は...」出力はどこですか? – mkrieger1

答えて

2

問題は既にmultipleGeneratorエンティティにあります。シグナルsumを定義します。これは、generateステートメントで再利用し続けます。ただし、これらの割り当てはVHDLで並行して行われます。したがって実際にはsumに16個のドライバを割り当てています!

実際にはsumは必要ありません。

あなたのコードのクリーンアップ(となってVHDL 2008)

std_logic_vector_vector_pkg.vhd:

library ieee; 
use ieee.std_logic_1164.all; 

package std_logic_vector_vector_pkg is 
    type std_logic_vector_vector is array (natural range <>) of std_logic_vector; 
end package; 

converter_pkg.vhd

library ieee; 
use ieee.std_logic_1164.all; 

package converter_pkg is 
    function to_string(slv : std_logic_vector) return string; 
end package; 

package body converter_pkg is 
    function to_string(slv : std_logic_vector) return string is 
     variable output : string(1 to slv'length) := (others => 'X'); 
     variable i_o : positive := 1; 
    begin 
     for i_s in slv'high downto slv'low loop 
      output(i_o) := std_logic'image(slv(i_s))(2); 
      i_o := i_o + 1; 
     end loop; 
     return output; 
    end function; 
end package body; 

multipleGenerator.vhd

library ieee; 
use ieee.std_logic_1164.all; 
use work.std_logic_vector_vector_pkg.all; 
use work.converter_pkg.all; 

entity multipleGenerator is 
    generic(
     WIDTH : integer := 32 
    ); 
    port(
     x_in  : in std_logic_vector(WIDTH - 1 downto 0); 
     one  : in std_logic_vector(WIDTH/2 - 1 downto 0); 
     multiple : out std_logic_vector_vector(0 to WIDTH/2 - 1)(WIDTH downto 0) 
    ); 
end entity; 

architecture rtl of multipleGenerator is 
begin 
    gen : for i in 0 to WIDTH/2 - 1 generate 
     multiple(i) <= '0' & x_in when one(i)='1' else x_in & '0'; 
    end generate; 

    process(one) 
    begin 
     for i in 0 to WIDTH/2 - 1 loop 
      report "The sum is " & to_string(multiple(i)) & 
       " one(" & integer'image(i) & ") is " & std_logic'image(one(i)) & 
       " x_in is " & to_string(x_in); 
     end loop; 
    end process; 
end architecture; 

multipleGenerator_tb.vhd

library ieee; 
use ieee.std_logic_1164.all; 
use work.std_logic_vector_vector_pkg.all; 

entity multipleGenerator_tb is end entity; 

architecture behavioral of multipleGenerator_tb is 
    signal b  : std_logic_vector(31 downto 0); 
    signal one  : std_logic_vector(15 downto 0); 
    signal multiple : std_logic_vector_vector(0 to one'length-1)(x'length downto 0); 
begin 
    process 
    begin 
     x <= (others => '0'); 
     one <= (others => '0'); 
     wait for 200 ns; 
     x <= x"00001111"; 
     one <= x"0011"; 
     wait; 
    end process; 

    u_mult: entity work.multipleGenerator 
     generic map (
      WIDTH => x'length 
     ) 
     port map (
      x_in  => x, 
      one  => one, 
      multiple => multiple 
     ); 
end architecture;