VHDL 类型转换签名为 std_logic_vector [英] VHDL typecast signed to std_logic_vector

查看:63
本文介绍了VHDL 类型转换签名为 std_logic_vector的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在查看 这个例子 和下面的答案,这是产生二进制补码的一个很好的解决方案:

I am looking at this example and below answer which is a nice solution to produce two's complement:

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 位减法器".代码如下所示:

I want to use the said example to have two's complement and then make a "16-bit subtractor". The code will look like the following:

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;

但是,我收到一条错误消息:错误:在 a 附近输入错误;当前类型 std_logic_vector;预期类型为无符号.

However, I am receiving an error saying: Error: type error near a; current type std_logic_vector; expected type unsigned.

请帮我解决这个问题.

推荐答案

既然没有人回答这个问题,也没有人反对,我来回答.

As nobody is answering this and nobody is down voting it, I will answer.

看错误

错误:在 a 附近输入错误;当前类型 std_logic_vector;预期类型为无符号.

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 就像错误所说.

What do you see? twoscomplement expects an unsigned, while a is std_logic_vector! Just like the error says.

std_logic_vectorunsigned 是两种不同的类型.由于 VHDL 是一种强类型语言,您不能只是将数据从一种类型转换为另一种类型.您需要使用类型转换.

std_logic_vector and unsigned are two separate types. As VHDL is a strongly typed language, you cannot just put the data from one type to another. You need to use type conversion.

对于不相关的类型,你应该实现一个类型转换函数.或者函数,如果你想要双向转换.例如

For unrelated types, you should implement a type conversion function. Or functions, if you want bidirectional conversion. E.g.

function (input : type_a) return type_b;

但在这种情况下,std_logic_vectorunsigned 具有相同的底层类型,std_logic.(std_ulogic 实际上自 VHDL-2008 以来我相信.)在这种情况下,您可以明确地从一种类型转换为另一种类型.例如

But in this case, std_logic_vector and unsigned have the same underlying type, std_logic. (std_ulogic actually since VHDL-2008 I believe.) In that case you can convert from one type to another explicitly. E.g.

    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 位,而不更改通用值.那不行.


Next, your not instantiating the twoscomplement component properly. The entity has a generic Nbits. By default you set it to 8. But in your architecture Behavioral of subtractor_16bit, you feed it with 16 bits, without changing the generic value. That doesn't work.

另外:twoscomplement 有两个端口:AY.但是在 subtractor_16bit 中,您开始使用 AC.这是糟糕的编码习惯.

Also: twoscomplement has two ports: A and Y. But in subtractor_16bit you start using A and C. That's bad coding practice.

最后,您可以删除 component 声明.只需从库中实例化实体.例如

Finally, you can drop the component declarations. Just instantiate the entities from the library. E.g.

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;

...

正如您在实体 twoscomplement 上看到的那样,端口 A 的大小为 NBit,端口Y大小为 NBit+1.那是因为您似乎想要保持 16 位值精度.所以在将无符号转换为有符号时,需要为符号添加第 17 位.因此,您的其余代码将需要修改!

As you see on your entity twoscomplement, port A has a size of NBits, and port Y has a size of NBits+1. That is because you seem to want to keep 16-bit value precision. So when converting unsigned to signed, you need to add a 17th bit for the sign. As a result, the rest of you code will need to be modified!

.... 但这可以通过不同的方式修复.我会教你一些关于二进制补码的知识:-a = not(a) + 1.

.... But this can be fixed a different way. I will learn you something about two's complement: -a = not(a) + 1.

证明(采用 4 位有符号精度):

Proof (Take 4 bits signed precision):

  • 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'
  • 0 = b'0000 => -0 is not(b'0000)+1 = b'1111'+1 = b'0000'
  • 7 = b'0111 => -7 is not(b'0111)+1 = b'1000'+1 = b'1001'
  • -6 = b'1010' => 6 is not(b'1010)+1 = b'0101'+1 = b'0110'

看到了吗?

那么现在我来为你解开谜题:

So now I will solve your puzzle for you:

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 行为...

You will still need to change/fix the cout and over behavior...

这篇关于VHDL 类型转换签名为 std_logic_vector的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆