Vhdl 多常数驱动程序

Vhdl 多常数驱动程序,vhdl,Vhdl,我正在尝试修改一个源代码,用于使用开关和十六进制显示进行求和(例如)和其他数学函数 这是主要代码: library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.seven_segment_pkg.all; entity Switch7Segment is port ( SW : in std_logic_vector(9 downto 0); HEX0 :

我正在尝试修改一个源代码,用于使用开关和十六进制显示进行求和(例如)和其他数学函数

这是主要代码:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.seven_segment_pkg.all;

entity Switch7Segment is
  port (
    SW       : in  std_logic_vector(9 downto 0);
    HEX0     : out std_logic_vector(6 downto 0);
    HEX1     : out std_logic_vector(6 downto 0);
    HEX2     : out std_logic_vector(6 downto 0);
    HEX3     : out std_logic_vector(6 downto 0);
    KEY      : in  std_logic_vector(3 downto 0);
    CLOCK_50 : in  std_logic
    );
end entity Switch7Segment;

architecture behavior of Switch7Segment is
  signal segments1 : std_logic_vector(13 downto 0);
  signal segments2 : std_logic_vector(13 downto 0);
  signal segmentsR : std_logic_vector(13 downto 0);  -- Range changed from 27 downto 0 to allow compile
  signal input1    : integer;
  signal input2    : integer;
  signal result    : unsigned(31 downto 0);  -- Range added to allow compile
  signal temp      : integer;
begin

  input1 <= to_integer(unsigned(SW(4 downto 0)));
  input2 <= to_integer(unsigned(SW(9 downto 5)));

  segments1 <= unsigned_to_seven_segment(value => unsigned(SW(4 downto 0)), number_of_digits => 2, value_is_bcd => false);
  segments2 <= unsigned_to_seven_segment(value => unsigned(SW(9 downto 5)), number_of_digits => 2, value_is_bcd => false);

  HEX1 <= segments1(13 downto 7);
  HEX0 <= segments1(6 downto 0);
  HEX3 <= segments2(13 downto 7);
  HEX2 <= segments2(6 downto 0);

  process(CLOCK_50)
  begin
    if (CLOCK_50' EVENT and CLOCK_50 = '1' AND KEY(0) = '1') then
      temp      <= input1+input2;
      result    <= to_unsigned(integer(temp), result'length);
      segmentsR <= unsigned_to_seven_segment(value => unsigned(result), number_of_digits => 2, value_is_bcd => false);
      HEX1      <= segmentsR(13 downto 7);
      HEX0      <= segmentsR(6 downto 0);
    end if;
  end process;

end architecture;
我认为有一个错误,那就是目前我从未在这里签名,结果的长度。如果我们编译这个VHDL代码,Quartus会告诉我们该函数用于13个元素,而不是27个元素。但是我没有看到解决它的障碍…我的问题是关于输出(HEX0…HEX3)

如果我修改代码并插入

 signal segmentsR: std_logic_vector(13 downto 0);
我解决了长度问题,但我将看到错误10028(多个常量驱动程序)。
如果我理解正确,我就不能在同一个向量上两次赋值,两个不同的值或类似的东西是正确的吗?也许我总是像C++程序员一样思考。我认为,如果我使用时钟,问题将得到解决,但不是真的…

问题是,在进程之前和进程中都有
HEX0
HEX1
的驱动程序,但在典型的合成代码中,任何信号/端口都只能从一个位置驱动


如果进程中驱动了
HEX0
HEX1
,则在进程之前删除驱动程序。

从概念上讲,多驱动程序错误意味着您的行为代码(请记住:VHDL描述了电路如何工作)无法合成。或者,如果你有非常特殊的合成代码,它会给你意想不到的结果

根据我的经验,当我以未定义的行为编写代码时会出现此错误——例如,如果在两个进程中,我根据某个条件修改同一变量(例如,X),那么硬件可能会运行到未定义的状态,在这两个条件都满足的情况下——该如何修改变量?如果你熟悉比赛条件或相互排斥,这看起来应该很熟悉。硬件语言不容易支持互斥等,因此它们会警告您,不会让您做坏事

在您的情况下,我认为您可以通过为顶级端口指定默认值来澄清代码并简化事情,如下所示:

entity Switch7Segment is
port (
    SW       : in  std_logic_vector(9 downto 0);
    HEX0     : out std_logic_vector(6 downto 0);
    HEX1     : out std_logic_vector(6 downto 0) := (others => '0');
    HEX2     : out std_logic_vector(6 downto 0) := (others => '0');
    HEX3     : out std_logic_vector(6 downto 0);
    KEY      : in  std_logic_vector(3 downto 0);
    CLOCK_50 : in  std_logic
);
end entity Switch7Segment;
这为实体提供了默认值。创建实体的任何内容都可以提供与默认值不同的值。请在此处阅读更多信息:

看起来您的默认值更复杂(基于函数的输入)。在这种情况下,我要么(1)更改接口以便调用者提供信息,要么(2)在包中编写函数和常量,并使用函数/常量作为默认值


另一种可能的解决方案是使用泛型和默认值。这将允许您在默认值中使用SW字段的位。(即:类似于HEX2:out std_logic_vector(6到0):=(SW(xx到yy),其中SW在泛型端口中定义)

多个驱动程序的问题与互斥或竞争完全不同。多个驱动程序没有时间概念,因此没有竞争条件。多个驱动程序意味着两个物理电路试图同时连续地改变电路节点的电压。这是一个电气问题。当您开始谈论呼叫者时实体的默认值很明显,您不理解编程语言和硬件描述语言之间的区别。我使用caller是指实例化实体和设置端口的任何地方。我应该说端口的默认值,而不是默认实体,这是一个输入错误对于多个驱动程序,如果您来自软件背景,软件中的互斥可以作为硬件中多个驱动程序的有用类比。软件中的互斥可以保护共享资源免受多线程/进程不良影响。防止寄存器中的多个驱动程序(例如)防止您提到的电气故障。
entity Switch7Segment is
port (
    SW       : in  std_logic_vector(9 downto 0);
    HEX0     : out std_logic_vector(6 downto 0);
    HEX1     : out std_logic_vector(6 downto 0) := (others => '0');
    HEX2     : out std_logic_vector(6 downto 0) := (others => '0');
    HEX3     : out std_logic_vector(6 downto 0);
    KEY      : in  std_logic_vector(3 downto 0);
    CLOCK_50 : in  std_logic
);
end entity Switch7Segment;