以下代码是Xilinx ISE 14.7中的VDHL模块,用于计算去抖按钮(iXXX),测试它们是否达到最大值,并输出"值"对于将在7段LED上显示的std_logic_vector(oXXX)的每个累计输入(显示多路复用器和逻辑未显示)。复位(clrXX)是电路板上的开关(Digilent Spartan 3)。
在XILINX ISE中尝试合成或检查语法时,出现以下错误:
Xst:528 - Multi-source in Unit <BSO_cnt> on signal <Mcount_oOUT_s_cy<0>>;
this signal is connected to multiple drivers.
Xst:528 - Multi-source in Unit <BSO_cnt> on signal <Mcount_oOUT_s_lut<1>>;
this signal is connected to multiple drivers.
Xst:528 - Multi-source in Unit <BSO_cnt> on signal <Mcount_oBALL_s_cy<0>>;
this signal is connected to multiple drivers.
Xst:528 - Multi-source in Unit <BSO_cnt> on signal <Mcount_oBALL_s_lut<1>>;
this signal is connected to multiple drivers.
Xst:528 - Multi-source in Unit <BSO_cnt> on signal <Mcount_oBALL_s_lut<2>>;
this signal is connected to multiple drivers.
Xst:528 - Multi-source in Unit <BSO_cnt> on signal <Mcount_oSTRIKE_s_cy<0>>;
this signal is connected to multiple drivers.
Xst:528 - Multi-source in Unit <BSO_cnt> on signal
<Mcount_oSTRIKE_s_lut<1>>; this signal is connected to multiple drivers.
我该如何解决这个问题?我对VHDL很新,不知道从哪里开始。
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity BSO_cnt is
Port ( iBALL : in STD_LOGIC;
iSTRIKE : in STD_LOGIC;
iOUT : in STD_LOGIC;
clrBS : in STD_LOGIC;
clrOUT : in STD_LOGIC;
CLK : in STD_LOGIC;
oBALL : out STD_LOGIC_VECTOR (2 downto 0);
oSTRIKE : out STD_LOGIC_VECTOR (1 downto 0);
oOUT : out STD_LOGIC_VECTOR (1 downto 0));
end BSO_cnt;
architecture Behavioral of BSO_cnt is
SIGNAL iBALL_s : STD_LOGIC;
SIGNAL iSTRIKE_s : STD_LOGIC;
SIGNAL iOUT_s : STD_LOGIC;
SIGNAL oBALL_s : STD_LOGIC_VECTOR(2 DOWNTO 0);
SIGNAL oSTRIKE_s : STD_LOGIC_VECTOR(1 DOWNTO 0);
SIGNAL oOUT_s : STD_LOGIC_VECTOR(1 DOWNTO 0);
Begin
oBALL <= oBALL_s;
oSTRIKE <= oSTRIKE_s;
oOUT <= oOUT_s;
BALL_PROCESS: PROCESS(CLK)
BEGIN
IF rising_edge(CLK) THEN
IF (clrBS = '1') THEN
oBALL_s <= (OTHERS => '0');
ELSIF (iBALL_s /= iBALL) THEN
IF (iBALL = '1') THEN
iBALL_s <= iBALL;
oBALL_s <= STD_LOGIC_VECTOR(UNSIGNED(oBALL_s) + 1);
IF (oBALL_s = "100") THEN
oBALL_s <= (OTHERS => '0');
oSTRIKE_s <= (OTHERS => '0');
END IF;
END IF;
ELSE
iBALL_s <= iBALL;
END IF;
END IF;
END PROCESS;
STRIKE_PROCESS: PROCESS(CLK)
BEGIN
IF rising_edge(CLK) THEN
IF (clrBS = '1') THEN
oSTRIKE_s <= (OTHERS => '0');
ELSIF (iSTRIKE_s /= iSTRIKE) THEN
IF (iSTRIKE = '1') THEN
iSTRIKE_s <= iSTRIKE;
oSTRIKE_s <= STD_LOGIC_VECTOR(UNSIGNED(oSTRIKE_s) + 1);
IF (oSTRIKE_s = "11") THEN
oSTRIKE_S <= (OTHERS => '0');
oBALL_s <= (OTHERS => '0');
oOUT_s <= (OTHERS => '0');
END IF;
END IF;
ELSE
iSTRIKE_s <= iSTRIKE;
END IF;
END IF;
END PROCESS;
OUT_PROCESS: PROCESS(CLK)
BEGIN
IF rising_edge(CLK) THEN
IF (clrOUT = '1') THEN
oOUT_s <= (OTHERS => '0');
ELSIF (iOUT_s /= iOUT) THEN
IF (iOUT = '1') THEN
iOUT_s <= iOUT;
oOUT_s <= STD_LOGIC_VECTOR(UNSIGNED(oOUT_s) + 1);
IF (oOUT_s = "11") THEN
oOUT_s <= (OTHERS => '0');
oBALL_s <= (OTHERS => '0');
oSTRIKE_s <= (OTHERS => '0');
END IF;
END IF;
ELSE
iOUT_s <= iOUT;
END IF;
END IF;
END PROCESS;
end Behavioral;
答案 0 :(得分:0)
您的问题可能与您从多个进程中驱动信号(oSTRIKE_s
,oBALL_s
,oOUT_s
)这一事实有关。把它想象成短路(当不同的过程不同意价值时,你期望什么价值?)。
为什么它不会在编译和/或模拟时产生错误?
由于大多数人不了解多驱动器问题,解析功能和已解析的VHDL类型(即许多VHDL程序员甚至教师),您总是使用STD_LOGIC
类型具有内置分辨率功能,可计算多个驱动过程的结果值。它的工作原理(通常会提供很多X
值)...仅用于模拟。如果您使用了未解析的类型(STD_ULOGIC
),那么在编译或模拟时会出现错误,因为这些类型不支持多种驱动情况。
为什么它在综合中不起作用?
您的合成器会尝试在您的目标(Spartan FPGA)的可用硬件资源上映射您的设计。 偶然你的目标没有配备可用于实现虚假设计的三态缓冲区。所以合成器会引发错误。我写的是偶然因为,如果它是另一个能够实现这个目标的目标,你可以对它进行编程并...融合它,这要归功于你的短路。有些东西可能会在你迟到之前阻止你,但你永远不会知道......毕竟你很幸运。
该怎么做?
STD_LOGIC
和STD_LOGIC_VECTOR
。也就是说,设计中任何时候所有进程都以'Z'
(高阻抗)驱动信号,除了最多一个驱动强值('0'
或'1'
)的信号。在大多数情况下,您不希望这样做,您必须使用STD_ULOGIC
和STD_ULOGIC_VECTOR
。如果您的老师坚持要求您使用STD_LOGIC
和STD_LOGIC_VECTOR
,请将其发送给我。答案 1 :(得分:0)
终于搞定了!问题是多个进程将值分配给同一信号。这就是我纠正错误的方法:
注意标志信号{Bmax_s,Smax_s和Omax_s}。它们由一个进程使用,以向其他进程指示它已达到其最大计数。然后,每个时钟周期,每个进程使用一个或多个标志来决定是否清除,或者在OUT_PROCESS增量的情况下,输出信号和/或更新其自己的标志。
现在每个信号只由一个进程分配!
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity BSO_cnt is
Port ( inBALL : in STD_LOGIC;
inSTRIKE : in STD_LOGIC;
inOUTS : in STD_LOGIC;
inclrBS : in STD_LOGIC;
inclrOUT : in STD_LOGIC;
CLK : in STD_LOGIC;
outBALL : out STD_LOGIC_VECTOR (1 downto 0);
outSTRIKE : out STD_LOGIC_VECTOR (1 downto 0);
outOUTS : out STD_LOGIC_VECTOR (1 downto 0));
end BSO_cnt;
architecture Behavioral of BSO_cnt is
--inputs
SIGNAL inBALL_s : STD_LOGIC;
SIGNAL inSTRIKE_s : STD_LOGIC;
SIGNAL inOUTS_s : STD_LOGIC;
--outputs
SIGNAL outBALL_s : STD_LOGIC_VECTOR(1 DOWNTO 0);
SIGNAL outSTRIKE_s : STD_LOGIC_VECTOR(1 DOWNTO 0);
SIGNAL outOUTS_s : STD_LOGIC_VECTOR(1 DOWNTO 0);
--max count flags
SIGNAL maxBALL : STD_LOGIC;
SIGNAL maxSTRIKE : STD_LOGIC;
SIGNAL maxOUTS : STD_LOGIC;
begin
--assign signals to module outputs
outBALL <= outBALL_s;
outSTRIKE <= outSTRIKE_s;
outOUTS <= outOUTS_s;
--count ball pushes & update ball counter
BALL_PROCESS: PROCESS(CLK)
BEGIN
--wait for postive edge of clock
IF rising_edge(CLK) THEN
--check for clear ball/strike switch
IF (inclrBS = '1') THEN
outBALL_s <= (OTHERS => '0');
--check for any max count flags
ELSIF (maxSTRIKE = '1') OR (maxBALL = '1') OR (maxOUTS = '1') THEN
--clear ball count
outBALL_s <= (OTHERS => '0');
--clear ball max count flag
maxBALL <= '0';
--check for change of ball button state
ELSIF (inBALL_s /= inBALL) THEN
--if pressed
IF inBALL = '1' THEN
inBALL_s <= inBALL;
-- check for walk
IF (outBALL_s = "11") THEN
--set flag
maxBALL <= '1';
ELSE
--increment ball counter
outBALL_s <= STD_LOGIC_VECTOR(UNSIGNED(outBALL_s) + 1);
END IF;
--if released
ELSE
inBALL_s <= inBALL;
END IF;
END IF;
END IF;
END PROCESS;
--Count strike pushes, and update strike counter
STRIKE_PROCESS: PROCESS(CLK)
BEGIN
--wait for positive edge of clock
IF rising_edge(CLK) THEN
--check for clr ball/strike switch
IF inclrBS = '1' THEN
outSTRIKE_s <= (OTHERS => '0');
--check for any max counts reached & update strike count
ELSIF (maxSTRIKE = '1') OR (maxBALL = '1') OR (maxOUTS = '1') THEN
outSTRIKE_s <= (OTHERS => '0');
--reset flag
maxSTRIKE <= '0';
--check for strike button state change
ELSIF (inSTRIKE_s /= inSTRIKE) THEN
--if pressed increment strike count
IF inSTRIKE = '1' THEN
inSTRIKE_s <= inSTRIKE;
--check for strikeout
IF (outSTRIKE_s = "10") THEN
--set flag
maxSTRIKE <= '1';
ELSE
--increment strike count
outSTRIKE_s <= STD_LOGIC_VECTOR(UNSIGNED(outSTRIKE_s) + 1);
END IF;
--if released
ELSE
inSTRIKE_s <= inSTRIKE;
END IF;
END IF;
END IF;
END PROCESS;
--Count out pushes, and update out counter
OUT_PROCESS: PROCESS(CLK)
BEGIN
--wait for positive clock edge
IF rising_edge(CLK) THEN
--check for clear out switch
IF inclrOUT = '1' THEN
outOUTS_s <= (OTHERS => '0');
--check for max out count
ELSIF maxOUTS = '1' THEN
outOUTS_s <= (OTHERS => '0');
--clear flag
maxOUTS <= '0';
--check for strikeout
ELSIF maxSTRIKE = '1' THEN
--check for max outs
IF (outOUTS_s = "10") THEN
--set max outs flag
maxOUTS <= '1';
ELSE
--increment outs
outOUTS_s <= STD_LOGIC_VECTOR(UNSIGNED(outOUTS_s) + 1);
END IF;
--check if button has changed states
ELSIF (inOUTS_s /= inOUTS) THEN
--if pressed
IF inOUTS = '1' THEN
inOUTS_s <= inOUTS;
--check for change of inning
IF (outOUTS_s = "10") THEN
maxOUTS <= '1';
ELSE
--increment outs
outOUTS_s <= STD_LOGIC_VECTOR(UNSIGNED(outOUTS_s) + 1);
END IF;
--if released
ELSE
inOUTS_s <= inOUTS;
END IF;
END IF;
END IF;
END PROCESS;
end Behavioral;
以下是来自测试台的模拟输出的图像,该测试台重置并增加球和球。罢工直到3次罢工......
对我的第一个VHDL项目来说不错:D