如何在VHDL中将8位转换为16位?

时间:2013-07-03 15:01:39

标签: vhdl

我有来自ADC转换器的输入信号,即8位(std_logic_vector(7 downto 0))。我必须将它们转换为16位信号(std_logic_vector(15 downto 0)),以便对16位系统进行16位信号处理。

5 个答案:

答案 0 :(得分:26)

如果8位值被解释为signed(2的补码),则通用和标准的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转换为有符号值,然后应用resize,将签名扩展签名值,结果最终转换回std_logic_vector。

转换相当冗长,但其优势在于它是通用的,即使稍后更改目标长度也能正常工作。

属性'length只返回slv_16 std_logic_vector的长度,因此为16。

对于无符号表示而非签名,可以使用unsigned代替signed来完成,因此使用以下代码:

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

答案 1 :(得分:6)

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;

答案 2 :(得分: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;

对于我能记得的矢量,我没有必要这样做,但我在更复杂的情况下需要这样做:将一些相关信号复制到更大,更复杂的记录中是一次。

答案 3 :(得分: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;

答案 4 :(得分:1)

使用新发布的VHDL-2019标准,您可以完成

larger_vec <= extend(shorter_vec);

其中extend是如下定义的函数

function extend(vec : std_logic_vector) return target_vec of std_logic_vector is
  variable result : std_logic_vector(target_vec'length - 1 downto 0) := (others => '0');
begin
  assert vec'length <= target_vec'length report "Cannot extend to shorter vector";
  result(vec'length - 1 downto 0) := vec;
  return result;
end function;

工具支持仍然有限,但是至少有一个模拟器支持(Riviera-PRO)。