If statement 在这个过程中,错误从何而来? IEEE库; 使用IEEE.STD_LOGIC_1164.ALL; 使用IEEE.NUMERIC_STD.all; 实体reset40是 端口(时钟:标准_逻辑中--50MHz CIKIS:输出标准逻辑 ); 结束复位40; reset40的体系结构是 信号A:std_逻辑; 开始 进程(时钟)-第20行 变量fcounter:无符号(24到0); 变量计数器_A:整数范围0到40:=0; 开始 如果上升沿(时钟),则 fcounter:=fcounter+1; 如果结束; A
除了糟糕的同步描述之外,还有糟糕的编码风格:) 首先,如果要描述计数器,就不应该在流程中使用变量。因此,使用架构区域中声明的信号 二,。 决定要用于计数器的信号类型:无符号或整数。我建议不签名 三,。 信号A不在灵敏度列表中。但是,将A添加到进程的灵敏度列表中并不是解决方案,因为在一个进程中使用两个不同的时钟(时钟和A)是(A)每个合成工具都不支持的,(b)糟糕的编码风格=>所以对使用第二个时钟的第二个计数器使用第二个进程 四,。 您在“if rising_edge(…)then”语句中使用了。合成工具将为括号中给出的信号推断(新)时钟信号。因此,您的描述将导致异步描述,这也是不好的样式。一种好的方式是从启用第二个计数器(计数器A)的fcounter(x)导出时钟启用信号。计数器A也与主时钟“时钟”同步 五,。 fcounter没有init值,尽管它是一个寄存器 六,。 为什么fcounter有25位?您只使用了7位。 除此之外,在fcounter(6)中使用位6将产生一个除以128(2^7)的时钟。 使用fcounter(0)表示输出f/2的切换触发器。fcounter(1)->f74等等 那么,它应该是什么样子呢If statement 在这个过程中,错误从何而来? IEEE库; 使用IEEE.STD_LOGIC_1164.ALL; 使用IEEE.NUMERIC_STD.all; 实体reset40是 端口(时钟:标准_逻辑中--50MHz CIKIS:输出标准逻辑 ); 结束复位40; reset40的体系结构是 信号A:std_逻辑; 开始 进程(时钟)-第20行 变量fcounter:无符号(24到0); 变量计数器_A:整数范围0到40:=0; 开始 如果上升沿(时钟),则 fcounter:=fcounter+1; 如果结束; A,if-statement,vhdl,fpga,If Statement,Vhdl,Fpga,除了糟糕的同步描述之外,还有糟糕的编码风格:) 首先,如果要描述计数器,就不应该在流程中使用变量。因此,使用架构区域中声明的信号 二,。 决定要用于计数器的信号类型:无符号或整数。我建议不签名 三,。 信号A不在灵敏度列表中。但是,将A添加到进程的灵敏度列表中并不是解决方案,因为在一个进程中使用两个不同的时钟(时钟和A)是(A)每个合成工具都不支持的,(b)糟糕的编码风格=>所以对使用第二个时钟的第二个计数器使用第二个进程 四,。 您在“if rising_edge(…)then”语句中使用了。
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.all;
entity reset40 is
Port ( CLOCK : in STD_LOGIC; --50MHz
CIKIS : out STD_LOGIC
);
end reset40;
architecture Behavioral of reset40 is
signal A:std_logic;
begin
process(CLOCK) --line20
variable fcounter: unsigned(24 downto 0);
variable counter_A:integer range 0 to 40:=0;
begin
if rising_edge (CLOCK) then
fcounter := fcounter+1;
end if;
A<=fcounter(6); --fa=fclock/2^6
if ((rising_edge (A)) and (counter_A/=40)) then
counter_A:= counter_A+1;
CIKIS<=A;
else
CIKIS<='0';
end if;
end process;
end Behavioral;
体系结构[…]
[...]
信号计数器:无符号(6到0):=(其他=>0');
信号计数器_a:无符号(5到0):=(其他=>“0”);
开始
进程(时钟)
贝因
如果上升沿(时钟),则
--我正在为计数器溢出使用一个以上的位,这将重置fcounter
如果(f计数器(6)=“1”),则
f计数器“0”);
其他的
fcounter您的基本错误是,进程中的所有代码只需在时钟上升沿上运行。这是因为目标芯片只有触发器可以在一条边上响应
您编写的流程对以下行引起的时钟的变化非常敏感:
input <= '0';
--input <= any_signal;
process(clock)
begin
if rising_edge(clock) then
if (reset = '1') then
pulse_train <= (others => '1');
else
pulse_train <= pulse_train(pulse_train'high - 1 downto 0) & input;
end if;
end if;
end process;
output <= pulse_train(pulse_train'high);
因此,它对两个时钟边缘都很敏感
然后将部分代码放入
process(clock)
这将活动限制在上升边缘,这是好的。不幸的是,代码的其余部分超出了if
子句的范围,因此被描述为在时钟的每一个边缘上运行,无论是上升还是下降。在模拟中,这将是好的,但合成器找不到任何可以这样做的触发器,因此产生了错误
其他需要注意的事项-您需要以某种方式重置或初始化计数器。或者使用复位信号,以便在复位信号高的任何时候,计数器都被设置回全零。或者使用初始化语句
您可以不用它们进行纯合成,因为当FPGA启动时,sythesiser会(在没有初始化或重置代码的情况下)自动将计数器设置为全零。这是一个糟糕的形式,虽然:
- 它在模拟中不起作用,模拟是至关重要的。你可能还没有意识到这一点,但你最终会意识到的李>
- 如果您将代码移植到另一个无法神奇地初始化东西的架构,那么在启动时计数器中会随机出现1和0。这可能重要,也可能不重要,但最好避免做出决定
非常感谢您感兴趣的回答。这对我会有用的。我想做一个脉冲序列,它由40个连续的1s组成,用于硬复位IC。另外,我想能够调整它的频率,因为IC的频率边界。感谢您的回复。抱歉,但没有任何理由避免变量@MartinThompson因为有一种用VHDL描述事物的方法并不意味着你应该使用它!特别是对于VHDL初学者来说,变量并不是一个好的选择。@Paebbels避免使用支持良好的语言功能,这些功能可以实现更干净的代码和更高的抽象性,而没有很好的理由,从本质上说,无论是初学者还是非初学者!“不幸的是,您的代码的其余部分不在if子句的范围内,因此被描述为在时钟的每一个边缘上运行,无论是上升还是下降。”但是如何操作呢?我只使用上升边。我是如何跳出if子句的?你最好使用一个if上升沿(clk),然后并将所有其他内容放在里面。否则合成器可能无法识别它(因为它使用“模板匹配”在代码中找到合适的结构)
process(clock)
if rising_edge(clock) then