【问题标题】:How to convert 8 bits to 16 bits in VHDL?如何在 VHDL 中将 8 位转换为 16 位?
【发布时间】:2013-07-01 08:23:37
【问题描述】:

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

【问题讨论】:

    标签: vhdl


    【解决方案1】:

    如果8位值被解释为有符号(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));
    

    【讨论】:

    • 我试图从 16 位调整到 8 位为: resized_var1 :=std_logic_vector(resize(unsigned(Kp)*unsigned(integration1)),8);我收到错误消息:“类型转换(到 std_logic_vector)不能有聚合操作数。”为什么它不起作用?
    • 因为 ,8 应该在 resize() 的括号内,而不是 std_logic_vector()。
    • 我认为重要的是要注意调整大小不会改变数值。调整到更大的向量时,左侧会添加零
    • @Damo:只有当 resize 使无符号类型更长时,您的评论才是正确的。如果 resize 用于使无符号或有符号类型更短,则 MSB 会被截断,这会改变值,如果 resize 用于使有符号值更长,则使用符号 (MSB) 进行填充,而不是 0。
    【解决方案2】:
    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;
    

    【讨论】:

    • 第 5 行中的“X”是什么意思?
    • “x”代表“十六进制”。所以x“00”基本上是“00000000”二进制。
    • 如果我想将“11111111”转换为“1111111111111111”
    • 等一下,你是想一直添加一个,还是只在数字为“负数”时添加?如果是前者,你应该做s16 &lt;= x"ff" &amp; s8s16 &lt;= (7 downto 0 =&gt; '1') &amp; s8。如果是后者,你应该拉出 s8 的第 7 位,并将第二个语句中的 '1' 替换为那个。
    • 这实际上是一个错误的答案,对于负面信号,那么在这个扩展之后你最终会得到一个错误的信号。
    【解决方案3】:

    如果任何一个 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】:

      为了完整起见,还有另一种偶尔有用的方法:

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

      对于我能回忆起来的向量,我不必这样做,但在更复杂的情况下我需要这样做:只需将一些相关信号复制到更大、更复杂的记录中就可以了。

      【讨论】:

      • 并且签名扩展是通过第一个分配为slv_16 &lt;= (others =&gt; slv_8(7));完成的
      • 这在功能上是正确的,但我认为如果你想要符号扩展,你应该使用正确的数字类型(即signed),然后使用resize 函数 - 正如你在你的回答中提出:)
      【解决方案5】:

      借助新发布的 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)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-08-18
        • 2012-10-11
        • 2012-07-01
        • 2014-10-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多