2017-06-15 168 views
0

我正試圖在VHDL中實現一個32位乘法器的記錄邏輯。此外,輸入位矢量(x_in)被重新編碼,它有一個額外的輸入「1」。意圖是當「一」是'1'輸出應該是x_in否則如果「一」是'0',它應該是兩次x_in。如果「負」高,則輸出必須反轉。這是我的VHDL代碼:VHDL代碼混淆

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 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; 

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弄糟了包milite_pack並提供了一個測試臺。在最低限度爲失敗時提供一個明確的價值,並且顯示如何生成這些報告報表。您的問題無法用您提供的內容複製。 – 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;