std_logic_vector到整数转换vhdl

时间:2016-07-14 08:35:38

标签: vhdl

我遇到了转换问题/我读了很多类似的主题,但我的代码仍然没有工作。请你给我一些提示。 Quartus给我错误:

  

错误(10476):在true_dual_port_ram_single_clock.vhd(44)处的VHDL错误:标识符的类型" random_num_i"不同意它的用法" std_logic_vector"型

LIBRARY ieee;
USE ieee.std_logic_1164.all;
use IEEE.std_logic_signed.all;
use IEEE.std_logic_unsigned.all;
use IEEE.NUMERIC_STD.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;

entity write_ram is
  generic(width : integer := 32);
  port(clock_i  : IN  STD_LOGIC;
       we_w     : IN  STD_LOGIC;
       wr_addr  : IN  INTEGER RANGE 0 to 31;
       read_add : IN  INTEGER RANGE 0 to 31;
       q_out    : out STD_LOGIC_VECTOR(2 DOWNTO 0)
  );
end write_ram;

architecture rtl of write_ram is
  --- Component decalarartion
  component random is
    port(clk        : in  std_logic;
         random_num : out std_logic_vector(width - 1 downto 0) --output vector 
    );
  end component;

  component single_clock_ram is
    port(clock         : IN  STD_LOGIC;
         data          : IN  INTEGER RANGE 0 to 31;
         write_address : IN  INTEGER RANGE 0 to 31;
         read_address  : IN  INTEGER RANGE 0 to 31;
         we            : IN  STD_LOGIC;
         q             : OUT STD_LOGIC_VECTOR(2 DOWNTO 0)
    );
  end component;
  for all : random use entity work.random(rtl);
  for all : single_clock_ram use entity work.single_clock_ram(rtl);
  Signal random_num_i : INTEGER RANGE 0 to 31; --interanal signals
begin
  -- Component Instantiation

  C1 : random Port map(
      clk        => clock_i,
      --random_num <=to_integer(to_signed(random_num_i))
      random_num => random_num_i
    );
  random_num <= to_integer(to_signed(random_num_i)); -- error

  C2 : single_clock_ram
    Port map(
      clock         => clock_i,
      we            => we_w,
      read_address  => read_add,
      write_address => wr_addr,
      data          => random_num_i,
      q             => q_out
    );

end rtl;

2 个答案:

答案 0 :(得分:1)

首先,删除非标准库。

use IEEE.std_logic_signed.all;
use IEEE.std_logic_unsigned.all;
use IEEE.STD_LOGIC_ARITH.ALL;

仅保留std_logic_1164numeric_std

其他人引入了一堆重叠的声明,这使得很难确定发生了什么 - 如果同一个运算符有相同的参数和结果类型有多个声明,编译器会使它们全部不可见而不是选择一个任意一个。

然后,决定你要做什么。这目前是模糊和矛盾的。

(1)您有generic (width : integer :=32);和端口声明

random_num : out std_logic_vector (width-1 downto 0)

表示你正在处理32位字。

(2)你有一个范围整数:Signal random_num_i: INTEGER RANGE 0 to 31;,其中(a)应该是一个范围NATURAL,以便更清楚地表明负值是错误,并且(b)建议你正在处理5位字。

这是什么?你究竟想做什么?

在这里,你显然是想在端口映射中将它们连接在一起......

 C1: random Port map ( 
     clk => clock_i,
     --random_num <=to_integer(to_signed(random_num_i))
     random_num =>random_num_i
 );
 random_num <=to_integer(to_signed(random_num_i)); -- error

这里有很多问题。

1)像random_num =>random_num_i这样的简单端口映射要求双方都具有相同的类型。如果双方实际上是相同的类型,这将起作用:例如,如果您添加了信号声明

random_num_slv : std_logic_vector (width-1 downto 0);

然后端口映射random_num =>random_num_slv将起作用。现在,您可以在信号分配中转换为所需的类型random_num_i

random_num_i <= to_integer (unsigned(random_num_slv));

这仍然存在问题:32位输出可能会溢出5位整数。

虽然添加中间信号random_num_slv可能看起来效率低且冗余,但它可以保持设计的简洁性,这在处理不了解端口类型转换的工具时非常重要。

即使采用更清洁的方法,也要确保知道如何使用中间信号。当其他所有方法都失败时,它可以拯救你。

(2)注释掉的端口映射

 random_num <=to_integer(to_signed(random_num_i))
除了三件事之外,

将是这样做的方式...... (a)<=是一个信号分配,你需要=>一个n关联算子 (b)您将整数转换为整数,并使用它驱动std_logic_vector。那真的不行...... (c)组件端口是OUTPUT,因此您不应该首先驱动它。

你可能意味着什么

   to_integer(unsigned(random_num)) => random_num_i

如果您的工具正确支持端口映射中的转换,这将是最干净的方法。 注意:

  • 再次出现溢出问题,32位向量不适合5位整数。
  • 您可以通过转换unsigned而不是转换函数to_signed从std_logic_vector转换为有符号或无符号,因为它们是密切相关的类型。整数与这些“密切相关”,因此需要转换函数to_integer
  • 由于random_num_i声明不允许使用负数,请使用unsigned而不是signed

(3)现有的信号分配

random_num <=to_integer(to_signed(random_num_i)); -- error

再次包含多个错误。最大的问题是组件声明外部没有random_num端口可见。只需删除此行,您需要使用其中一个端口映射。

进一步考虑:

(1)某些类型的转换是不可避免的。但是,如果你做得太多,那通常会指向一个设计错误,比如在任何地方都使用std_logic_vector,即使对于像地址这样的地址来说也是不可避免的无符号整数,所以unsignednatural会是一个更好的选择。保持设计尽可能简单易读。我认为您在这里使用integer通常很好,但natural会更好(除非您需要负地址!)

(2)如果您正在添加类似width这样的通用的灵活性,请正确且一致地使用它 - 或者 - 检查它是否有效。

在此,如上所述,如果此实体使用width => 5进行实例化,则您的设计只能正常运行而不会出现意外。

因此,检查值并在不满足此前提条件时中止。

assert Width = 5 report "Width of " & natural'image(width) & " not supported!" 
   severity FAILURE;

或者使设计适用于通用的所有合理值,例如通过使其他数量以有效的方式依赖于它。例如:

   constant DEPTH : natural := 2**WIDTH - 1;
   signal random_num_i : natural range 0 to DEPTH;

依旧......

答案 1 :(得分:1)

您的问题不是MCVE,其中包含random和single_clock_ram的配置规范。您没有为它们提供实体声明和体系结构体(rtl)。

随着他们评论这个分析:

library ieee;
use ieee.std_logic_1164.all;
-- use ieee.std_logic_signed.all;  -- NOT USED
-- use ieee.std_logic_unsigned.all;  -- NOT USED
use ieee.numeric_std.all;
-- use ieee.std_logic_arith.all;  -- NOT USED

entity write_ram is
  generic (width:  integer := 32);
  port (clock_i:   in  std_logic;
        we_w:      in  std_logic;
        wr_addr:   in  integer range 0 to 31;
        read_add:  in  integer range 0 to 31;
        q_out:     out std_logic_vector(2 downto 0)
  );
end entity write_ram;

architecture rtl of write_ram is
  --- component declaration
  component random is
    port (clk:         in  std_logic;
         random_num:   out std_logic_vector(width - 1 downto 0) --output vector 
    );
  end component;

  component single_clock_ram is
    port (clock:          in  std_logic;
          data:           in  integer range 0 to 31;
          write_address:  in  integer range 0 to 31;
          read_address:   in  integer range 0 to 31;
          we:             in  std_logic;
          q:              out std_logic_vector(2 downto 0)
    );
  end component;
  -- for all:  random use entity work.random(rtl);
  -- for all:  single_clock_ram use entity work.single_clock_ram(rtl);
  signal random_num_i:  integer range 0 to 31; -- internal signals 
  signal random_num:   std_logic_vector(width - 1 downto 0); -- added
begin
  -- component instantiation

  c1:  random port map (
      clk        => clock_i,
      -- random_num <=to_integer(to_signed(random_num_i))
      -- random_num => random_num_i  -- DELETED
      random_num => random_num   -- ADDED
    );
  -- random_num <= to_integer(to_signed(random_num_i)); -- error DELETED
  random_num_i <= to_integer(signed(random_num));   -- ADDED

  c2:  single_clock_ram
    port map (
      clock         => clock_i,
      we            => we_w,
      read_address  => read_add,
      write_address => wr_addr,
      data          => random_num_i,
      q             => q_out
    );

end architecture rtl;

注意,有一个random_num std_logic_vector被声明连接到随机输出,它被转换为整数random_num_i,用作single_clock_ram数据的输入。 single_clock_ram的输出q看起来有点可疑,应该是整数还是更宽的std_logic_vector?