VHDL多个常量驱动器 [英] VHDL multiple constant drivers

查看:20
本文介绍了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     : 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;

然后是包:

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

package seven_segment_pkg is
-- Return a std_logic_vector ready for driving a number of 7-segment displays.
  function unsigned_to_seven_segment(value : unsigned; number_of_digits : integer; value_is_bcd : boolean)
    return std_logic_vector;
end;

package body seven_segment_pkg is

  function seven_seg_from_bcd_digit(bcd_digit : std_logic_vector(3 downto 0)) return std_logic_vector is
  begin
    case bcd_digit is
      --                   abcdefg
      when x"0"   => return "1000000";
      when x"1"   => return "1111001";
      when x"2"   => return "0100100";
      when x"3"   => return "0110000";
      when x"4"   => return "0011001";
      when x"5"   => return "0010010";
      when x"6"   => return "0000010";
      when x"7"   => return "1111000";
      when x"8"   => return "0000000";
      when x"9"   => return "0010000";
      when x"a"   => return "0001000";
      when x"b"   => return "0000011";
      when x"c"   => return "1000110";
      when x"d"   => return "0100001";
      when x"e"   => return "0000110";
      when x"f"   => return "1110001";
      when others => return "0000000";
    end case;
  end function;

  -- Return a vector ready for driving a series of 7-segment displays.
  function unsigned_to_seven_segment(
    value            : unsigned;
    -- Number of 7-segment displays (determines output vector width: W = 7*N)
    number_of_digits : integer;
    -- When true, treat the input value as a BCD number where every 4 bits hold one
    -- digit from 0 to A. When false, treat the input number as an unsigned integer.
    value_is_bcd     : boolean
    ) return std_logic_vector is

    variable segments      : std_logic_vector(number_of_digits*7-1 downto 0);
    variable bcd_quotient  : unsigned(value'range);
    variable bcd_remainder : unsigned(3 downto 0);
  begin

    if value_is_bcd then
      for i in 0 to number_of_digits-1 loop
        segments(i*7+6 downto i*7) := seven_seg_from_bcd_digit(
          std_logic_vector(value(i*4+3 downto i*4))
          );
      end loop;
    else
      bcd_quotient := value;
      for i in 0 to number_of_digits-1 loop
        bcd_remainder := resize(bcd_quotient mod 10, 4);
        bcd_quotient  := bcd_quotient / 10;
        segments(i*7+6 downto i*7) := seven_seg_from_bcd_digit(
          std_logic_vector(bcd_remainder)
          );
      end loop;

    end if;

    return segments;
  end function;

end package body;

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

如果我修改代码并插入

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

推荐答案

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

如果HEX0HEX1从进程中驱动,则在进程之前删除驱动程序。

这篇关于VHDL多个常量驱动器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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