无法解析 net "clk_1hz" 的多个常量驱动程序
Can't resolve multiple constant drivers for net "clk_1hz"
!!编辑!!
好的,在学习了几个教程之后,我现在正在尝试创建一个类似的过程,我按下一个按钮来改变 LED 闪烁的频率,但这次使用多路复用器。现在的问题是标题中的错误,Error (10028): Can't resolve multiple constant drivers for net "clk_1hz"。现在我已经阅读了这里所有不同的帖子,但我似乎无法识别我做错了什么......我明白它告诉我我正在将多个不同的来源分配给 "clk_1hz" 和 "clk_4hz",但它告诉我这是在代码的端口映射中发生的。我的印象是端口映射相当于 "soldering" 不同组件的输入和输出?
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity blinking_led is
port(
clk_50mhz : in std_logic ;
btn_one : in std_logic;
green_led : out std_logic
);
end entity;
architecture behave of blinking_led is
component MUXii
port(
a : in std_logic;
b : in std_logic;
sel : in std_logic;
z : out std_logic
);
end component;
component PLLii
port(
clk : in std_logic;
y : out std_logic;
x : out std_logic
);
end component;
signal clk_1hz : std_logic ;
signal clk_4hz : std_logic ;
signal scaler : integer range 0 to 25000000 ;
signal scaler_2 : integer range 0 to 12500000 ;
signal LED : std_logic ;
signal a, b, z, sel, y, x : std_logic;
begin
Multiplexer_process : process( a, b, sel, z)
begin
if(sel = '1') then
z <= a;
else
z <= b;
end if;
end process Multiplexer_process;
PLL_1_4_Hz : PLLii port map (
clk => clk_50mhz,
y => clk_1hz,
x => clk_4hz
);
MUX1 : MUXii port map (
a => clk_1hz,
b => clk_4hz,
sel => btn_one,
z => LED
);
green_led <= LED;
clk_1_4_hz_process : process( clk_50mhz )
begin
if(rising_edge(clk_50mhz)) then
if (scaler < 25000000) then
scaler <= scaler + 1 ;
clk_1hz <= '0';
else
scaler <= 0;
clk_1hz <= '1';
end if;
if (scaler_2 < 12500000) then
scaler_2 <= scaler_2 + 1 ;
clk_4hz <= '0';
else
scaler_2 <= 0;
clk_4hz <= '1';
end if;
end if;
end process clk_1_4_hz_process;
end behave;
编辑!!
所以我设法摆脱了我遇到的一些问题,所以现在代码是...
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity PLL is port(
clk : in std_logic;
y : out std_logic;
x : out std_logic
);
end PLL;
architecture behaviour of PLL is
signal scaler : integer range 0 to 25000000 ;
signal scaler_2 : integer range 0 to 12500000 ;
signal clk_1hz : std_logic ;
signal clk_4hz : std_logic ;
begin
clk_1_4_hz_process : process( clk )
begin
if(rising_edge(clk)) then
if (scaler < 25000000) then
scaler <= scaler + 1 ;
clk_1hz <= '0';
x <= clk_1hz;
else
scaler <= 0;
clk_1hz <= '1';
x <= clk_1hz;
end if;
if (scaler_2 < 12500000) then
scaler_2 <= scaler_2 + 1 ;
clk_4hz <= '0';
y <= clk_4hz;
else
scaler_2 <= 0;
clk_4hz <= '1';
y <= clk_4hz;
end if;
end if;
end process;
end behaviour;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity MUX2to1 is port(
A : in std_logic;
B : in std_logic;
Sel : in std_logic;
Z : out std_logic
);
end MUX2to1;
architecture behavior of MUX2to1 is
begin
MUX2to1_p : process (Sel, A, B)
begin
if (Sel = '1') then
Z <= A;
else
Z <= B;
end if; -- note that *end if* is two words
end process;
end behavior;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity Com_Connect is port(
clk_50mhz : in std_logic;
btn_one : in std_logic;
green_led : out std_logic
);
end Com_Connect;
Architecture behaviour of Com_Connect is
component PLL
port(
clk : in std_logic;
y : out std_logic;
x : out std_logic
);
end component PLL;
component MUX2to1
port(
A : in std_logic;
B : in std_logic;
Sel : in std_logic;
Z : out std_logic
);
end component MUX2to1;
signal wire_one, wire_two : std_logic;
begin
PLL1 :PLL port map (
clk => Clk_50mhz,
y => wire_one,
x => wire_two
);
MUX2to1_1 : MUX2to1 port map (
A => wire_two,
B => wire_one,
Sel => btn_one,
Z => green_led
);
end;
虽然这没有错误,但它不起作用(没有任何反应,没有 LED 亮起,模拟是空白等)并且它确实有几个警告,例如
警告 (15714):某些引脚的 I/O 分配不完整。有关详细信息,请参阅 I/O 分配警告报告
严重警告 (332148):不满足时序要求
第一个我不明白,因为它指的是我知道我已经映射到引脚分配模块中的 LED。
第二个对我来说有点神秘,仍在努力弄清楚。有没有人有任何网站推荐或书籍可以帮助我更好地掌握这些基础知识?
伙计们干杯!
每个 process
中的第一个语句应该是 if rising_edge (clk)
,以便该进程中的所有内容都被视为寄存器。如果没有这个,您就是在告诉 FPGA 软件将内容视为组合逻辑或锁存器。
这里概述了 FPGA 软件用来决定它是生成寄存器、锁存器还是组合逻辑的规则:
寄存器:进程中的每个赋值只在时钟边沿触发(例如if rising_edge (clk)
)。
组合逻辑:进程总是分配给它的所有输出。输入不包括任何时钟信号。
闩锁:其他任何东西,例如一个信号并不总是分配。
通常您应该避免使用会产生闩锁的代码。它们不能很好地工作(如果有的话)。您的 LED
输出是由锁存器生成的,因为它并不总是被分配。
您的编辑完全改变了问题。以后请不要这样做。
现在你的思路好像是对的,但是还是有一些问题。
首先,您没有显示 mux 和 pll 组件的实现,尽管我可以根据它们的名称猜出它们的作用。您看到多个驱动程序的原因是因为您的组件正在做与您的进程相同的事情,并且组件和进程都试图驱动慢速时钟和 LED 输出。删除您的组件;仅这些过程就足够了。
您的多路复用器进程中使用的信号名称与别处使用的信号名称不匹配。
您的“1Hz”时钟将 运行 为 2Hz。
慢速时钟的占空比将为 1:12-2500 万,因为在整个慢速周期中,只有一个 50MHz 周期的慢速时钟变高。您需要 1:1 或 50% 的占空比。您可以通过在计数器过期时切换慢时钟来实现。请注意,这也会将频率减半,因此您的 1Hz 时钟实际上为 1Hz,但 4Hz 将变为 2Hz。
如果您更改为切换并希望它在模拟中工作,您将需要设置默认值,或定义重置行为并在模拟中重置。您应该模拟您编写的所有内容!
编辑:跟进您的更新:
- 你已经正确地进入了一个只有组件的模型(尽管额外的
可能是 1-liner 的多路复用器的样板不是我的首选
风格),但你的大问题仍然是占空比真的,
真的很低。太低以至于你的 LED 不会闪烁足够长的时间
人眼能看出来。
- 不正确的频率问题仍然存在。
- I/O 警告不是由您的 VHDL 直接引起的,因为引脚分配
那里没有处理。
- 因为这是一个很慢的简单设计,所以你真的不需要
太担心时机了。你可能还没有给它任何
时序限制,这就是为什么它说它不符合时序。如果
你曾经继续做更复杂的数字逻辑或与
更高的频率(100+ MHz),适当的约束和满足
时机变得很重要。
我还有一些挑剔的地方,但并不是真正的错误:
- 您名为
PLL
的组件不是 PLL,它只是一个时钟分频器。
更准确地说,它是一个计数器。大多数 FPGA,除了实际的
锁相环,具有时钟分频器,其工作方式类似于
织物内计数器,但经过加固以更快地运行并连接到
高速时钟所需的专用时钟路由。
- 您的
Com_Connect
架构是
结构上写的,不是行为上的,尽管你给它起了名字
behaviour
.
!!编辑!!
好的,在学习了几个教程之后,我现在正在尝试创建一个类似的过程,我按下一个按钮来改变 LED 闪烁的频率,但这次使用多路复用器。现在的问题是标题中的错误,Error (10028): Can't resolve multiple constant drivers for net "clk_1hz"。现在我已经阅读了这里所有不同的帖子,但我似乎无法识别我做错了什么......我明白它告诉我我正在将多个不同的来源分配给 "clk_1hz" 和 "clk_4hz",但它告诉我这是在代码的端口映射中发生的。我的印象是端口映射相当于 "soldering" 不同组件的输入和输出?
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity blinking_led is
port(
clk_50mhz : in std_logic ;
btn_one : in std_logic;
green_led : out std_logic
);
end entity;
architecture behave of blinking_led is
component MUXii
port(
a : in std_logic;
b : in std_logic;
sel : in std_logic;
z : out std_logic
);
end component;
component PLLii
port(
clk : in std_logic;
y : out std_logic;
x : out std_logic
);
end component;
signal clk_1hz : std_logic ;
signal clk_4hz : std_logic ;
signal scaler : integer range 0 to 25000000 ;
signal scaler_2 : integer range 0 to 12500000 ;
signal LED : std_logic ;
signal a, b, z, sel, y, x : std_logic;
begin
Multiplexer_process : process( a, b, sel, z)
begin
if(sel = '1') then
z <= a;
else
z <= b;
end if;
end process Multiplexer_process;
PLL_1_4_Hz : PLLii port map (
clk => clk_50mhz,
y => clk_1hz,
x => clk_4hz
);
MUX1 : MUXii port map (
a => clk_1hz,
b => clk_4hz,
sel => btn_one,
z => LED
);
green_led <= LED;
clk_1_4_hz_process : process( clk_50mhz )
begin
if(rising_edge(clk_50mhz)) then
if (scaler < 25000000) then
scaler <= scaler + 1 ;
clk_1hz <= '0';
else
scaler <= 0;
clk_1hz <= '1';
end if;
if (scaler_2 < 12500000) then
scaler_2 <= scaler_2 + 1 ;
clk_4hz <= '0';
else
scaler_2 <= 0;
clk_4hz <= '1';
end if;
end if;
end process clk_1_4_hz_process;
end behave;
编辑!!
所以我设法摆脱了我遇到的一些问题,所以现在代码是...
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity PLL is port(
clk : in std_logic;
y : out std_logic;
x : out std_logic
);
end PLL;
architecture behaviour of PLL is
signal scaler : integer range 0 to 25000000 ;
signal scaler_2 : integer range 0 to 12500000 ;
signal clk_1hz : std_logic ;
signal clk_4hz : std_logic ;
begin
clk_1_4_hz_process : process( clk )
begin
if(rising_edge(clk)) then
if (scaler < 25000000) then
scaler <= scaler + 1 ;
clk_1hz <= '0';
x <= clk_1hz;
else
scaler <= 0;
clk_1hz <= '1';
x <= clk_1hz;
end if;
if (scaler_2 < 12500000) then
scaler_2 <= scaler_2 + 1 ;
clk_4hz <= '0';
y <= clk_4hz;
else
scaler_2 <= 0;
clk_4hz <= '1';
y <= clk_4hz;
end if;
end if;
end process;
end behaviour;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity MUX2to1 is port(
A : in std_logic;
B : in std_logic;
Sel : in std_logic;
Z : out std_logic
);
end MUX2to1;
architecture behavior of MUX2to1 is
begin
MUX2to1_p : process (Sel, A, B)
begin
if (Sel = '1') then
Z <= A;
else
Z <= B;
end if; -- note that *end if* is two words
end process;
end behavior;
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity Com_Connect is port(
clk_50mhz : in std_logic;
btn_one : in std_logic;
green_led : out std_logic
);
end Com_Connect;
Architecture behaviour of Com_Connect is
component PLL
port(
clk : in std_logic;
y : out std_logic;
x : out std_logic
);
end component PLL;
component MUX2to1
port(
A : in std_logic;
B : in std_logic;
Sel : in std_logic;
Z : out std_logic
);
end component MUX2to1;
signal wire_one, wire_two : std_logic;
begin
PLL1 :PLL port map (
clk => Clk_50mhz,
y => wire_one,
x => wire_two
);
MUX2to1_1 : MUX2to1 port map (
A => wire_two,
B => wire_one,
Sel => btn_one,
Z => green_led
);
end;
虽然这没有错误,但它不起作用(没有任何反应,没有 LED 亮起,模拟是空白等)并且它确实有几个警告,例如
警告 (15714):某些引脚的 I/O 分配不完整。有关详细信息,请参阅 I/O 分配警告报告
严重警告 (332148):不满足时序要求
第一个我不明白,因为它指的是我知道我已经映射到引脚分配模块中的 LED。 第二个对我来说有点神秘,仍在努力弄清楚。有没有人有任何网站推荐或书籍可以帮助我更好地掌握这些基础知识?
伙计们干杯!
每个 process
中的第一个语句应该是 if rising_edge (clk)
,以便该进程中的所有内容都被视为寄存器。如果没有这个,您就是在告诉 FPGA 软件将内容视为组合逻辑或锁存器。
这里概述了 FPGA 软件用来决定它是生成寄存器、锁存器还是组合逻辑的规则:
寄存器:进程中的每个赋值只在时钟边沿触发(例如
if rising_edge (clk)
)。组合逻辑:进程总是分配给它的所有输出。输入不包括任何时钟信号。
闩锁:其他任何东西,例如一个信号并不总是分配。
通常您应该避免使用会产生闩锁的代码。它们不能很好地工作(如果有的话)。您的 LED
输出是由锁存器生成的,因为它并不总是被分配。
您的编辑完全改变了问题。以后请不要这样做。 现在你的思路好像是对的,但是还是有一些问题。
首先,您没有显示 mux 和 pll 组件的实现,尽管我可以根据它们的名称猜出它们的作用。您看到多个驱动程序的原因是因为您的组件正在做与您的进程相同的事情,并且组件和进程都试图驱动慢速时钟和 LED 输出。删除您的组件;仅这些过程就足够了。
您的多路复用器进程中使用的信号名称与别处使用的信号名称不匹配。
您的“1Hz”时钟将 运行 为 2Hz。 慢速时钟的占空比将为 1:12-2500 万,因为在整个慢速周期中,只有一个 50MHz 周期的慢速时钟变高。您需要 1:1 或 50% 的占空比。您可以通过在计数器过期时切换慢时钟来实现。请注意,这也会将频率减半,因此您的 1Hz 时钟实际上为 1Hz,但 4Hz 将变为 2Hz。
如果您更改为切换并希望它在模拟中工作,您将需要设置默认值,或定义重置行为并在模拟中重置。您应该模拟您编写的所有内容!
编辑:跟进您的更新:
- 你已经正确地进入了一个只有组件的模型(尽管额外的 可能是 1-liner 的多路复用器的样板不是我的首选 风格),但你的大问题仍然是占空比真的, 真的很低。太低以至于你的 LED 不会闪烁足够长的时间 人眼能看出来。
- 不正确的频率问题仍然存在。
- I/O 警告不是由您的 VHDL 直接引起的,因为引脚分配 那里没有处理。
- 因为这是一个很慢的简单设计,所以你真的不需要 太担心时机了。你可能还没有给它任何 时序限制,这就是为什么它说它不符合时序。如果 你曾经继续做更复杂的数字逻辑或与 更高的频率(100+ MHz),适当的约束和满足 时机变得很重要。
我还有一些挑剔的地方,但并不是真正的错误:
- 您名为
PLL
的组件不是 PLL,它只是一个时钟分频器。 更准确地说,它是一个计数器。大多数 FPGA,除了实际的 锁相环,具有时钟分频器,其工作方式类似于 织物内计数器,但经过加固以更快地运行并连接到 高速时钟所需的专用时钟路由。 - 您的
Com_Connect
架构是 结构上写的,不是行为上的,尽管你给它起了名字behaviour
.