I am a vhdl begginner, and in need of help for my problem. I have 2 signals that i need to monitor. One is CHECK and the other OK. Every time i ask for a CHECK, I should get OK (HIGH or LOW). I need to monitor contantly 6 consecutive CHECK pulses, and count the OK. If i have 6 OK (LOW) then i need to produce the output (HIGH), any other case output (LOW). I have writen some code that does not produce the wanted output above. But i have a fundamental question first. can this be done in one process?
--one process
if ...
reset clauses
elsif
count pulses and set a variable to 6
else
if variable = 6, produce output
end if;
or do i need more?
--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
EDIT: Here is the code i tried, but failed... will look into 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;
I definetely have something wrong in here, because pre and post simulation do not produce the same results. Pre-sim seems to work, but post-sim does not.
EDIT (2): for the FSM, something like this?
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;
I guess the TODO parts are dependent of the state diagram? Also, do I need the CLK? It seems that I need to change state, on rising_edge of CHECK, not CLK.
Final Edit:
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;