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