2013-07-03 60 views

回答

19

如果作为签名的(2的补码)的8位值被解释,则一般与标准的VHDL转换方法是使用IEEE numeric_std库:

library ieee; 
use ieee.numeric_std.all; 

architecture sim of tb is 
    signal slv_8 : std_logic_vector(8 - 1 downto 0); 
    signal slv_16 : std_logic_vector(16 - 1 downto 0); 
begin 
    slv_16 <= std_logic_vector(resize(signed(slv_8), slv_16'length)); 
end architecture; 

因此,首先将std_logic_vector被转换转换为有符号值,然后应用调整大小,这将签署扩展有符号值,并且结果最终转换回std_logic_vector。

转换过程非常漫长,但具有通用性,即使目标长度稍后发生变化也能正常工作。

属性“长度简单地返回slv_16 std_logic_vector的长度,从而16.

对于无符号表示代替签字,它可以使用的代替unsignedsigned来完成,因此与此代码:

slv_16 <= std_logic_vector(resize(unsigned(slv_8), slv_16'length)); 
+0

我试图从16位调整到8位:resized_var1:= std_logic_vector(resize(unsigned(Kp)* unsigned(integration1)),8);我得到错误:“类型转换(对std_logic_vector)不能有聚合操作数。”为什么它不起作用? –

+0

因为,8应该在resize()的parens里面而不是std_logic_vector()。 –

4
architecture RTL of test is 
    signal s8: std_logic_vector(7 downto 0); 
    signal s16: std_logic_vector(15 downto 0); 
begin 
    s16 <= X"00" & s8; 
end; 
+0

什么是线5“X”是什么意思? –

+2

'x'表示“十六进制”。所以x“00”基本上是“00000000”二进制。 – Passepartout

+0

如果我想将“11111111”转换为“1111111111111111” –

2

为了完整起见,另一种方式是偶尔有用:

-- Clear all the slv_16 bits first and then copy in the bits you need. 
process (slv_8) 
begin 
    slv_16 <= (others => '0'); 
    slv_16(7 downto 0) <= slv_8; 
end process; 

我还没有我必须这样做才能回忆起来,但在更复杂的情况下,我需要这样做:将一些相关信号复制成更大,更复杂的记录是一次。

+1

符号扩展是用第一个赋值完成的:slv_16 <= (others => slv_8(7));' –

+0

这在功能上是正确的,但我认为如果你想要符号扩展,你应该使用正确的数字类型(即'签署'),然后使用'resize'函数 - 如你在你的回答中所建议的:) –

1

此处理,而无需修改零的宽度转换如果任std_logic_vector变化:

architecture RTL of test is 
    signal s8: std_logic_vector(7 downto 0); 
    signal s16: std_logic_vector(15 downto 0) := (others => '0'); 
begin 
    s16(s8'range) <= s8; 
end;