带启动的VHDL有限状态机计数器

带启动的VHDL有限状态机计数器,vhdl,counter,Vhdl,Counter,我对vhdl非常陌生,我正在尝试学习如何使用vhdl进行FSM。 现在我需要一个代码,在一个固定的计数值之后,它会给我一个脉冲,以便启动第二个FSM块。我有一个循环信号每100千赫,我需要计数,并释放这个信号后,一个固定数量的计数。 实际上它是自由运行的,每次它看到这个信号,它就开始计数,但实际上我想添加一个开始信号,所以它必须在看到这个开始信号后开始计数 目前,我的工作代码是: library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.numeri

我对vhdl非常陌生,我正在尝试学习如何使用vhdl进行FSM。 现在我需要一个代码,在一个固定的计数值之后,它会给我一个脉冲,以便启动第二个FSM块。我有一个循环信号每100千赫,我需要计数,并释放这个信号后,一个固定数量的计数。 实际上它是自由运行的,每次它看到这个信号,它就开始计数,但实际上我想添加一个开始信号,所以它必须在看到这个开始信号后开始计数

目前,我的工作代码是:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.ALL;

entity counter is
Port (
    signal_in : in STD_LOGIC := '0'; --segnale di start
    clk : in  STD_LOGIC; --clock di ingresso
    reset  : in  STD_LOGIC; --ff reset
    signal_out: out STD_LOGIC; --gate in uscita
    count_val: in std_logic_vector (7 downto 0);
    start : in STD_LOGIC := '0'


   );
end counter;

architecture behavioral of counter is
type state_type is (idle, count_up);
signal state : state_type;

begin
process (reset, clk, signal_in, start)
variable index : integer :=0;
variable countlen: integer;
variable count_v: std_logic;
variable countlen2 : std_logic;

begin

 countlen := to_integer(unsigned(count_val))-1;



if reset = '1' then  
  count_v := '0';
  index := 0;
  state <= idle;

else
--if start = '1' and
    --if rising_edge(clk) then
    if rising_edge(signal_in) then
    case state is
      when idle =>
        count_v :='0';
        index := 0;
        if (signal_in = '1') then
          state <= count_up;
          else
          state <= idle;
        end if;


      when count_up =>
        if(index < countlen) then
        state <=count_up;
        index := index + 1;
       elsif
        index = countlen then
        count_v := '1';
        state <=idle; 
        end if;        



      when others => null;
    end case;



  end if;
   end if;  

  signal_out <= count_v;

  end process; 


  end Behavioral;
任何尝试使用start=1的cose都将停止计数。 请问有人有什么建议吗

问候


富尔维奥

欢迎光临。您的规格不是100%清楚。信号输入和启动之间有什么区别?根据您的代码和您的解释,它们似乎都起到了启动作用

此外,您的代码还有一些奇怪的地方:

您的进程似乎是一个同步进程,带有异步重置。其灵敏度列表应仅包含时钟和复位。其主体应为:

process(clk, reset)
    <variable declarations>
begin
    <NOTHING HERE>
    if reset = '1' then
        <reset code>
    elsif rising_edge(clk) then
        <regular code>
    end if;
    <NOTHING HERE>
end process;
请注意,这实际上是时钟时钟的同步。我怀疑您犯了一个非常常见的错误:当断言signal_in时,您想增加计数器,因此您或多或少地决定将signal_in用作时钟。这不是一个真正的同步和安全的设计。在真正安全的同步设计中,您不使用逻辑信号作为时钟。你有很好的识别时钟,你只使用这些作为时钟。在您的情况下,只有一个时钟:clk。如果要在断言逻辑信号时同步执行某些操作,请等待时钟上升沿,然后测试逻辑信号并采取适当的操作。

感谢您的支持。 是的,重点是我需要对信号进行截取或计数。 该信号的宽度为50-100ns,并以100kHz的频率重复。 所以在我看来,这个信号将进入信号进入。我的FPGA是一款Actel proasic3,时钟为40 MHz。 在我的设置中,此信号将始终打开,但我不希望FSM在看到中的第一个信号时开始计数,但仅当我发送指示计数数的开始信号时。事实上,他们问我是否有可能将这个信号抽取到65000个计数,所以我肯定需要使用16位向量,而不是8位向量。 异步复位是在这里,我需要在数据记录的中间重置整个FSM。< /P> 希望现在更清楚这段代码应该做什么


对于Old fart,是的,事实上,所有来自fpga外部的信号都将首先与带有fpga时钟的简单2 ff同步器同步

,正如注:不相关的(也称为异步输入信号)应首先同步,然后才能与时钟安全地使用它们。
process (clk, reset)
    variable index: natural range 0 to 255;
begin
    if reset = '1' then
        state      <= idle;   
        signal_out <= '0';
        index      := 0;
    elsif rising_edge(clk) then
        case state is
            when idle =>
                signal_out <= '0';
                index      := 0;
                if start = '1' then
                    state <= count_up;
                end if;
            when others =>
                if signal_in = '1' then
                    if index = to_integer(unsigned(count_val)) - 1 then
                        state      <= idle;
                        signal_out <= '1';
                    else
                        index := index + 1;
                    end if;
                end if;
        end case;
    end if;
end process;