我是vhdl begginner,需要帮助解决我的问题。 我有2个信号需要监测。一个是CHECK,另一个是OK。 每次我要求检查时,我都应该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;
我definetely有什么错在这里,是因为之前和之后做模拟不会产生相同的结果。 Pre-sim似乎可以工作,但是后sim不能。
对于FSM编辑(2): ,这样的事情?
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的rising_edge上改变状态 ,而不是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;
我看到两个答案都是指CLK信号,这是否意味着我不能在没有CLK的情况下监视信号?我虽然我可以使用CHECK作为参考,并计数确定。马丁,感谢您对我的原始代码的评论,请告诉我为什么它不起作用?缺乏CLK? – sparkyT
非常感谢您的信息,我已经更新了我的代码与您的建议(如果我理解得很好),它的工作原理,但我没有得到的东西。 lost_counter = 6,每输出一个连续的第三个丢失位,lost_counter = 9,每四分之一,依此类推... – sparkyT
刚刚意识到我在Final Edit中强制设计的方式,我正在计算和递增检查信号。上升计数为1,下降沿计数为2。所以要检测6个零位,我需要我的计数为12. – sparkyT