Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

FPGA event detection FSM

Status
Not open for further replies.

shaiko

Advanced Member level 5
Joined
Aug 20, 2011
Messages
2,644
Helped
303
Reputation
608
Reaction score
297
Trophy points
1,363
Activity points
18,302
Below, is a code for an event detecor inplemented on an FPGA.
The design has an input vector called: "events"
and a steady state value for that vector - called "default_events_vector".
If "events" and "default_events_vector" aren't equal, it means that an event has accured.
This immidiatly changes the state of the asynchronous FSM and switches on an external DSP.

What do you think of the design ?
Any noticeable issues?

Code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity event_detector is 
    generic ( event_vector_width : positive := 26 ) ;
	port
	(
		rst ,
		dsp_off : in std_logic ;
		events : in unsigned ( event_vector_width - 1 downto 0 ) ; 		
		dsp_on : buffer std_logic 
	) ;
end entity;		        

architecture synthesizable_event_detector of event_detector is	
	
	type fsm_states is
	( 
		fsm_idle_state_0 ,
		fsm_on_state_1 
	) ; 
																										
	constant default_events_vector : unsigned ( event_vector_width - 1 downto 0 ) := "11100111110001111111111111" ; 															
	signal fsm_state : fsm_states ;
	signal event_flag : std_logic ;
	
begin   
	
	event_detecion: process 
	(
		events ,
		event_flag
	) is 
	begin
		for i in 0 to event_vector_width - 1 loop 
			if events ( i ) /= default_events_vector ( i ) then
				event_flag <= '1' ;
			else 
				event_flag <= '0' ;
			end if ;
		end loop ;
	end process event_detecion ;
		
	asynchronous_fsm : process 
	(
		dsp_on ,
		rst ,
		fsm_state ,
		event_flag ,
		dsp_off 
	) is
	begin
	
		if rst = '0' then 	
			dsp_on <= '0' ; 
			fsm_state <= fsm_idle_state_0 ;	
		else
		
			case fsm_state is
			
				when fsm_idle_state_0 =>
					
					if event_flag = '1' then					
						fsm_state <= fsm_on_state_1 ;	
						dsp_on <= '1' ;	
					end if ;		
			
				when fsm_on_state_1 =>
				
					if dsp_off = '1' then 							
						dsp_on <= '0' ;	
						fsm_state <= fsm_idle_state_0 ;	
					end if ;					
	
			end case ;
			
		end if ;
		
	end process asynchronous_fsm ;			
	
end architecture synthesizable_event_detector ;
 

According to the description, you're intending to compare all input bits. Presently, only the highest input bit is evaluated.

Apart from this point, it's much text for a basically simple logic: A comparator followed by an RS latch. It's function reduces to:
Code:
process(rst, events, dsp_off )
begin
if rst = '0' then
  dsp_on  <= '0' ;
elsif events /= default_events_vector then
  dsp_on  <= '1' ;
elsif dsp_off = '1' then 
  dsp_on  <= '0' ;
end if;
end;

It can only work, if events is known to be glitch-free.
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
Presently, only the highest input bit is evaluated.
Why?

I want this code to compare all bits...What should I change to make it work ?
 

Why?

I want this code to compare all bits...What should I change to make it work ?

Signals only take the last assignment given to them
In your loop, it sets the event_flag based on the last bit of the vector, not the entire array (because the last loop iteration overrides the other iterations)
I suggest you set up an array of signals (one for each bit in the compare array) and then and the result into a single event bit.
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
You see, there's a reason why I whose the loop statement.
The actual code is a little more complex...some of the envent vector bits may be masked by an internal masking register.

Code:
		for i in 0 to event_vector_width - 1 loop 
			if EVENT_DETECTOR_EVENTS_I ( i ) /= default_events_vector ( i ) then
				event_flag <= '1' ;
				if mask_vector ( i ) = '0' then
					unmasked_event_flag <= '1' ;
				else
					unmasked_event_flag <= '0' ;
				end if ;
			else 
				event_flag <= '0' ;
			end if ;
		end loop ;
	end process event_detecion ;

I want any event to be detected while only an "unmasked_event_flag" to cause a wakeup.
Any idea how to make it in a loop ?
 

The problem of the more complex code is just the same. The result is only reflecting the state of EVENT_DETECTOR_EVENTS_I(event_vector_width - 1). If you want to use a for..loop iteration, you need to break the loop after a match.

Also the complex expression can be evaluated for all bits at once.
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
How can I break the for loop ?
Is there a break statement like in C ?

Code:
		for i in 0 to event_vector_width - 1 loop 
			if EVENT_DETECTOR_EVENTS_I ( i ) /= default_events_vector ( i ) then
				event_flag <= '1' ;
				if mask_vector ( i ) = '0' then
					unmasked_event_flag <= '1' ;
				else
					unmasked_event_flag <= '0' ;
				end if ;
			else 
				event_flag <= '0' ;
			end if ;
		end loop ;
	end process event_detecion ;
 

Code:
if mask_vector ( i ) = '0' then
  unmasked_event_flag <= '1' ;
  exit;
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
Can you please show me where exactly I shoult assert the "exit" statement in the code below

Code:
for i in 0 to event_vector_width - 1 loop -- where should the "exit" statement (or statements) be placed ?
	if EVENT_DETECTOR_EVENTS_I ( i ) /= default_events_vector ( i ) then
		event_flag <= '1' ;
		if mask_vector ( i ) = '0' then
			unmasked_event_flag <= '1' ;
		else
			unmasked_event_flag <= '0' ;
		end if ;
	else 
		event_flag <= '0' ;
	end if ;
end loop ;
 

are you just looking for 1 bit to match? or all?
If its 1 bit - put it where mask_vector is checked for '0';

If its all, you need to redesign it like I said with an array of event flags which are then anded together.
 

If you are seting different flags in the for .. loop, you can code the event also as sequential or:
Code:
event_flag <= '0';
for ... loop
  event_flag <= event_flag or condition;
end loop;
 

TrickyDicky,

Allow me to elaborate.
I have an input event vector ( "events" ) - if this vector deviates from it's default values ( "default_events" ) - I want the signal "any_event_detected" to stobe '1'.
I have another vector called "unmasked_event_detected" - this one must strobe '1' when an unmasked event is detected ( not just any envent ).

Suppose the event vector is only 3 bits long:

Code:
any_event_detected <= '1' when events /= default_events ;
	
unmasked_event_detected <= '1' when									                                             
             ( ( events ( 0 ) /= default_events ( 0 ) ) and ( mask_vector ( 0 ) = '0' ) ) or 
             ( ( events ( 1 ) /= default_events ( 1 ) ) and ( mask_vector ( 1 ) = '0' ) ) or 
	( ( events ( 2 ) /= default_events ( 2 ) ) and ( mask_vector ( 2 ) = '0' ) ) 		
	     else '0' ;

Now, I want to do the above with a generic for loop.
Qestion is - what will be the exact syntax for that loop
 

Instead of setting the event flags directly in the loop, set variables that you clear before the loop and test after the loop.

If you want to use "exit" you need one loop for each event flag, but I think the "exit" solution have a higher risk for confusion of the synthesis tool.

---------- Post added at 20:44 ---------- Previous post was at 20:42 ----------

You can set the event flags directly in the loop if you clear them before the loop only.
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
std_match,

You seem to understand what I want to do.
I'll much appriciate if you show me the exact syntax to achieve that.
Thanks
 

but I think the "exit" solution have a higher risk for confusion of the synthesis tool.
I never noticed confusion of a synthesis tools with these rather trivial behavioral constructs. My main concern would be 1. code readability and 2. shortness, as far as the first objective isn't thwarted.

If you prefer the for ... loop solution with exit, you need two separate loops. My favourite solution is
Code:
event_flag <= or_reduce((events XOR default_events_vector) AND NOT mask_vector);
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
FvM,

what does "or_reduce" do ?
Is it a standart function ?
 

shaiko said:
I'll much appreciate if you show me the exact syntax to achieve that.


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
event_flag <= '0' ;
unmasked_event_flag <= '0' ;
for ... loop
    if EVENT_DETECTOR_EVENTS_I ( i ) /= default_events_vector ( i ) then
        event_flag <= '1' ;
        if mask_vector ( i ) = '0' then
            unmasked_event_flag <= '1' ;
        end if ;
    end if ;
end loop ;

 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
or_reduce() is from Synopsys "IEEE".std_logic_misc. It's a reduction or function, ORing all bits of a bit vector.
In VHDL 2008, the reduction operation is achieved with an extended syntax
std_logic_var <= OR std_logic_vector_var
 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
Instead of setting the event flags directly in the loop, set variables that you clear before the loop and test after the loop.

that would work quite nice:


Code VHDL - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
process(input)
  variable temp : boolean;
begin
 
temp := false;
 
  for i in 0 to 15 loop
    temp := temp or (input(i) = MY_TESTER(i) );
  end loop;
 
  if temp then
    event_flag <= '1';
  else
    event_flag <= '0';
  end if;
end process;

 
  • Like
Reactions: shaiko

    shaiko

    Points: 2
    Helpful Answer Positive Rating
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top