我是一名 vhdl 初学者,需要帮助解决我的问题。
我有两个需要监控的信号。一个是 CHECK,另一个是 OK。
每次我要求检查时,我都应该得到好的结果(高或低)。
我需要连续监测6个连续的CHECK脉冲,并计数OK。
如果我有 6 OK(低),那么我需要产生输出(高),任何其他情况输出(低)。
我编写了一些代码,但无法产生上面想要的输出。但我首先有一个基本问题。
这可以在一个过程中完成吗?
--one process
if ...
reset clauses
elsif
count pulses and set a variable to 6
else
if variable = 6, produce output
end if;
或者我需要更多吗?
--first process
start counter on rising_edge of CHECK
-- second process
count pulses and set a signal some value (6)
-- third process
monitor signal and if =6, produce output
编辑:
这是我尝试过的代码,但失败了...将研究 FSM...
counter_operation:process (RESETn, CHECK, OK)
variable counter : unsigned (2 downto 0);
variable lost_count : unsigned (2 downto 0);
begin
-- if reset it asserted ensure counter is not running
if ( RESETn = '0') then
trip_signal <= '0';
lost_count := to_unsigned (0,3);
counter := to_unsigned (0,3);
-- run counter and perform actions
elsif (rising_edge(CHECK)) then
-- increment counter and limit maximum value
counter := counter+1;
if (counter > to_unsigned(6,3) ) then
counter := to_unsigned (0,3);
lost_count := to_unsigned (0,3);
end if;
-- check for first OK(LOW)
if (counter = to_unsigned(1,3)) then
if (OK = '0') then
lost_count := lost_count + to_unsigned (1,3);
else
lost_count := lost_count;
end if;
end if;
-- check for second consecutive OK(LOW)
if (counter = to_unsigned(2,3)) then
if (OK = '0') then
lost_count := lost_count + to_unsigned (1,3);
else
lost_count := lost_count;
end if;
end if;
-- check for third consecutive OK(LOW)
if (counter = to_unsigned(3,3)) then
if (OK = '0') then
lost_count := lost_count + to_unsigned (1,3);
else
lost_count := lost_count;
end if;
end if;
-- check for fourth consecutive OK(LOW)
if (counter = to_unsigned(4,3)) then
if (OK = '0') then
lost_count := lost_count + to_unsigned (1,3);
else
lost_count := lost_count;
end if;
end if;
-- check for fifth consecutive OK(LOW)
if (counter = to_unsigned(5,3)) then
if (OK = '0') then
lost_count := lost_count + to_unsigned (1,3);
else
lost_count := lost_count;
end if;
end if;
-- check for sixth consecutive OK(LOW)
if (counter = to_unsigned(6,3)) then
if (OK = '0') then
lost_count := lost_count + to_unsigned (1,3);
else
lost_count := lost_count;
end if;
end if;
-- check if we lost 6 consecutive
if (lost_count = to_unsigned (6,3)) then
trip_signal <= '1';
else
trip_signal <= '0';
end if;
end if;
end process counter_operation;
我这里肯定有问题,因为模拟前和模拟后不会产生相同的结果。 Pre-sim 似乎有效,但 post-sim 则无效。
编辑(2):
对于FSM来说,是这样的吗?
library IEEE;
use IEEE.std_logic_1164.all;
entity FSM_1 is
port (
CHECK : in std_logic;
CRC :in std_logic;
CLK : in std_logic;
RESETn :in std_logic;
OUT_SIG : out std_logic
);
end FSM_1;
architecture arch of FSM_1 is
-- signal, component etc. declarations
type TargetSeqStates is (IDLE, FIRST_CHECK, SECOND_CHECK, THIRD_CHECK, FOURTH_CHECK, FIFTH_CHECK, SIXTH_CHECK);
signal curr_st, next_st : TargetSeqStates;
begin
--------------------------------------------------------------------------------
-- Using the current state of the counter and the input signals, decide what the next state should be
--------------------------------------------------------------------------------
NxStDecode:process (CHECK, OK, curr_st)
begin
-- default next-state condition
next_st <= IDLE;
-- TODO...
-- TODO...
end process NxStDecode;
--------------------------------------------------------------------------------
-- At the desired clock edge, load the next state of the counter (from 1.) into the counter
-- create the current-state variables
--------------------------------------------------------------------------------
CurStDecode:process (CLK, RESETn)
begin
-- Clear FSM to start state
if (RESETn = '0') then
curr_st <= IDLE;
elsif (rising_edge(CLK)) then
curr_st <= next_st;
end if;
end process CurStDecode;
--------------------------------------------------------------------------------
-- Using the current state of the counter and the input signals, decide what the values of all output signals should be
--------------------------------------------------------------------------------
DecOutputs;process (curr_st)
begin
-- TODO....
-- TODO...
end process DecOutputs;
end arch;
我猜 TODO 部分依赖于状态图?
另外,我需要CLK吗?看来我需要改变状态,
在 CHECK 的上升沿,而不是 CLK。
最终编辑:
counter_operation:process (RESETn, CHECK, OK, CLK)
variable lost_counter : integer := 0;
variable last_CHECK : std_logic;
begin
if ( RESETn = '0') then
D_TRIP <= '0';
lost_counter := 0;
else
if (rising_edge(CLK)) then
if (CHECK /= last_CHECK) then
if (OK = '0') then
lost_counter := lost_counter + 1;
else
lost_counter := 0;
end if;
D_TRIP <= '0';
if (lost_counter = 6) then
D_TRIP <= '1';
lost_counter := 0;
end if;
end if;
last_CHECK := CHECK;
end if;
end if;
end process counter_operation;