2017-09-23 81 views
0

我在看this example和下面的回答這是一個很好的解決方案,以產生兩個的補:VHDL類型轉換籤訂std_logic_vector

library ieee; 
use ieee.numeric_std.all; 
entity twoscomplement is 
    generic 
    (
    Nbits : positive := 8 
); 
    port 
    ( 
    A : in unsigned (Nbits-1 downto 0); 
    Y : out signed (Nbits downto 0) 
); 
end entity twoscomplement; 

architecture a1 of twoscomplement is 
begin 
    Y <= -signed(resize(A, Y'length)); 
end architecture; 

我想使用上述例子有補,然後做一個「16位減法器「。該代碼將如下所示:

library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 
use IEEE.NUMERIC_STD.ALL; 

entity subtractor_16bit is 
    Port ( a  : in STD_LOGIC_VECTOR(15 downto 0); 
      b  : in STD_LOGIC_VECTOR(15 downto 0); 
      cin : in STD_LOGIC; 
      sum : out STD_LOGIC_VECTOR(15 downto 0); 
      cout : out STD_LOGIC; 
      over : out STD_LOGIC 
      ); 
end subtractor_16bit; 

architecture Behavioral of subtractor_16bit is 

component fulladder_16bit is 
    Port (
      a  : in STD_LOGIC_VECTOR(15 downto 0); 
      b  : in STD_LOGIC_VECTOR(15 downto 0); 
      cin : in STD_LOGIC; 
      sum : out STD_LOGIC_VECTOR(15 downto 0); 
      cout : out STD_LOGIC; 
      over : out STD_LOGIC 
     ); 
end component; 

component twoscomplement is 
    Port (
     A : in unsigned (15 downto 0); 
     C : out signed (15 downto 0) 
     ); 
end component; 

signal n1 : STD_LOGIC_VECTOR(15 downto 0); 

begin 

    twoscomplement_1: twoscomplement port map (a => a ,c => n1); --ERROR 
    fulladder_16bit_1: fulladder_16bit port map (a => a, b => n1, sum => sum , cin => cin, cout => cout, over => over); 

end Behavioral; 

不過,我收到一個錯誤說: 錯誤:錯誤類型附近;當前類型std_logic_vector;預期類型無符號。

請幫我解決這個問題。

+2

至少有三個錯誤可見無[最小,完整和可驗證的示例](https://stackoverflow.com/help/mcve)。在'兩個端口映射中(a => a,c => n1); --ERROR'。 C中的兩個元素被聲明爲有符號類型,而n1被定義爲類型std_logic_vector。 A和C的大小有一個默認的通用值,這裏沒有修改,分別是長度8和9,而A的長度是16,長度是C.通用需要被傳遞並且n1的長度被調整。二的補碼也可以在沒有結構元素的表達式中執行。 – user1155120

+0

只需查看'twoscomplement'的實現,就可以看到類型轉換的示例... – JHBonarius

+1

'type_conversion :: = type_mark(expression)*顯式*類型轉換*是在*緊密相關的類型*之間轉換的表達式。當且僅當類型具有相同的維度和元素類型緊密相關時,兩個數組類型緊密相關。一種類型與其本身密切相關。 IEEE Std 1076-2008 9.3.6類型轉換。數組類型signed和std_logic_vector具有相同的元素基類型。 – user1155120

回答

1

由於沒有人回答這個問題,沒有人投票,我會回答。

查看錯誤

Error: type error near a; current type std_logic_vector; expected type unsigned.

看看現在的實體subtractor_16bit

[...] 
entity subtractor_16bit is 
    Port ( a  : in STD_LOGIC_VECTOR(15 downto 0); 
[...] 
    component twoscomplement is 
     Port (
      A : in unsigned (15 downto 0); 
[...] 
    twoscomplement_1: twoscomplement port map (a => a ,c => n1); 
[...] 

你看到了什麼? twoscomplement預計unsigned,而astd_logic_vector就像錯誤說的那樣。

std_logic_vectorunsigned是兩種不同的類型。由於VHDL是強類型語言,因此不能只將數據從一種類型轉換爲另一種類型。你需要使用類型轉換。

對於不相關的類型,您應該實現一個類型轉換函數。或功能,如果你想雙向轉換。例如。

function (input : type_a) return type_b; 

但是,在這種情況下,std_logic_vectorunsigned具有相同的基礎類型,std_logic。 (std_ulogic,因爲我相信VHDL-2008。) 在這種情況下,您可以明確地從一種類型轉換爲另一種類型。例如。

signal a_u : unsigned(y downto 0); 
    signal a_slv : std_logic_vector(y downto 0); 
begin 
    a_u <= unsigned(a_slv); 

接下來,你不能正確實例化twoscomplement組件。該實體具有通用的Nbits。默認情況下,您將其設置爲8.但是在subtractor_16bit的體系結構Behavioral中,可以使用16位進行填充,而不更改通用值。這是行不通的。

另外:twoscomplement有兩個端口:AY。但在subtractor_16bit中,您開始使用AC。這是不好的編碼習慣。


最後,您可以刪除component聲明。只是從庫中實例化實體。例如。

twoscomplement_1: entity work.twoscomplement [...] 

所以,subtractor_16bit應該是這個樣子:

library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 

entity subtractor_16bit is 
    Port (
     a  : in STD_LOGIC_VECTOR(15 downto 0); 
     b  : in STD_LOGIC_VECTOR(15 downto 0); 
     cin : in STD_LOGIC; 
     sum : out STD_LOGIC_VECTOR(15 downto 0); 
     cout : out STD_LOGIC; 
     over : out STD_LOGIC 
     ); 
end entity; 

architecture structural of subtractor_16bit is 
    use IEEE.NUMERIC_STD.ALL; 
    signal n1 : signed(a'range); 
begin 
    twoscomplement_1: entity work.twoscomplement 
     generic map(
      NBits => a'length 
      ) 
     port map (
      a => unsigned(a), 
      y => n1 
      ); 
    fulladder_16bit_1: entity work.fulladder_16bit 
     port map (
      a => a, 
      b => std_logic_vector(n1), 
      sum => sum, 
      cin => cin, 
      cout => cout, 
      over => over 
      ); 
end architecture; 

...

然而,這仍然無法正常工作。

當你對你的實體twoscomplementA的大小爲NBits端口,端口Y的大小爲NBits+1看到。這是因爲你似乎想要保持16位值的精度。因此,在將無符號轉換爲帶符號時,您需要爲符號添加第17位。結果,你的其他代碼將需要修改!

....但是這可以用不同的方法修復。我會向你學習一些關於補碼的內容:-a = not(a) + 1

證明(以4個比特精度簽署):

  • 0 = B'0000 => -0是not(b'0000)+1 = b'1111'+1 = b'0000'
  • 7 = b'0111 => -7是not(b'0111)+1 = b'1000'+1 = b'1001'
  • -6 = b'1010' => 6是not(b'1010)+1 = b'0101'+1 = b'0110'

看到了嗎?

所以現在我會解決你的難題給你:

library IEEE; 
use IEEE.STD_LOGIC_1164.ALL; 

entity subtractor_16bit is 
    Port (
     a  : in STD_LOGIC_VECTOR(15 downto 0); 
     b  : in STD_LOGIC_VECTOR(15 downto 0); 
     sum : out STD_LOGIC_VECTOR(15 downto 0); 
     cout : out STD_LOGIC; 
     over : out STD_LOGIC 
     ); 
end entity; 

architecture structural of subtractor_16bit is 
begin 
    fulladder_16bit_1: entity work.fulladder_16bit 
     port map (
      a => a, 
      b => not(b), 
      sum => sum, 
      cin => '1', 
      cout => cout, 
      over => over 
      ); 
end architecture; 

你仍然需要改變/修復coutover行爲......

相關問題