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 在这个过程中,错误从何而来? 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”语句中使用了。

除了糟糕的同步描述之外,还有糟糕的编码风格:)

首先,如果要描述计数器,就不应该在流程中使用变量。因此,使用架构区域中声明的信号

二,。 决定要用于计数器的信号类型:无符号或整数。我建议不签名

三,。 信号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等等

那么,它应该是什么样子呢

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