EmbDev.net

Forum: FPGA, VHDL & Verilog VHDL: counter checking


von maestros (Guest)


Rate this post
0 useful
not useful
I want to detect a external signal connection to a CPLD (only connected 
or not connected). My system clock is 1MHz and external signal is 4KHz. 
I have developed a logic that will detect rising edge of external signal 
and start a counter. If the counter is counting then external signal is 
connected and if the counter is not counting then external signal is not 
connected. I write the code but its not working, what is the problem? I 
am beginner in VHDL. Please help, How to check a counter running in 
vhdl?
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity SYNC_detection1 is
Port (  SYNC        : in  STD_LOGIC;
            CLK     : in  STD_LOGIC;
            EDGE        : out  STD_LOGIC;
            OUTPUT  : out  STD_LOGIC;
            BITSOUT : out  STD_LOGIC_VECTOR (3 downto 0)
                );
end SYNC_detection1;

architecture workingarchi of SYNC_detection1 is

signal SYNC_reg : std_LOGIC := '0';
signal SYNC_edge : std_LOGIC := '0';
signal TEMP : std_LOGIC := '0';
signal counter : STD_LOGIC_VECTOR (3 downto 0);

begin

SYNC_edge_p : process(CLK) 
begin
    if (rising_edge(CLK)) then
        SYNC_reg <= SYNC;
    end if;
end process;

SYNC_edge <= not SYNC_reg and SYNC;

counter_p: process(CLK) 
begin
    if (rising_edge(CLK)) then
        if SYNC_edge = '1' then
            counter <= counter + 1; 
                if (counter = "0000") then
                TEMP <= '1';
                end if;
        end if;
    end if;
end process;

OUTPUT <= TEMP;
BITSOUT <= counter;
EDGE <= SYNC_edge;
end workingarchi;

: Edited by Moderator
von Lothar M. (lkmiller) (Moderator)


Rate this post
0 useful
not useful
maestros wrote:
> use ieee.numeric_std.all;
> use IEEE.STD_LOGIC_UNSIGNED.ALL;
Never ever both together!
By ignoring this hint you will encounter some fairly strange errors due 
to multiple defined data types.

> I write the code but its not working, what is the problem? I am
> beginner in VHDL.
What do you expect? What does the code instead? How do you see that? 
What does your testbench look like?

> If the counter is counting then external signal is connected and if the
> counter is not counting then external signal is not connected.
A external signal is always connected in some way. Only its value 
changes. So do you mean "high" and "low" or '1' and '0'?

BTW:
The signal TEMP is only set once. Afterwards its never reset. That looks 
kind of strange...

BTW2:
Pls read the manual above each text box and use the [ vhdl ] tags for 
your code:
Reply
Rules — please read before posting
    Post long source code as attachment, not in the text
    :
Formatting options
    [vhdl]VHDL code[/vhdl]
    :

: Edited by Moderator
von maestros (Guest)


Rate this post
0 useful
not useful
Hi Lothar M., Thanks for your immediate reply and guidance. I will 
change my code accordingly. This is a part of my entire code written 
separately for easy understanding.

You said it correctly. A external signal is always connected in some 
way. In my case, when external signal is disconnected... the CPLD input 
pin is pulled 'high' and when the external signal is connected the CPLD 
will get 3.9KHz square wave as input. I want to create a 'status' for 
external signal weather it is connected or not by giving high or low 
repectively on CPLD pin.

Since it is incomplete code, i have not simulated the testbench. I stuck 
in the counter condition checking. How to check the counter running or 
counter stop, so that i can generate proper output. Please help.

von Lothar M. (lkmiller) (Moderator)


Attached files:

Rate this post
0 useful
not useful
maestros wrote:
> the CPLD input pin is pulled 'high' and when the external signal is
> connected the CPLD will get 3.9KHz square wave as input. I want to
> create a 'status' for external signal weather it is connected or not by
> giving high or low repectively on CPLD pin.
So the most easy way would be to check wether there is a change on the 
square-input now and then.

What I would do is nearly the same like you did:
Count up a counter with each system clock.
When the counter reaches a time of a little bit more than 1/(2*4kHz) = 
125µs = 125 system clock cycles  (lets assume here that the square 
signal is a perfect 50:50 square, otherwise it would be a rectangle and 
the time must be longer...) then there is no signal at the square input, 
so set "NoSignal" output is '1'.
Then check the square input for changes. When a change occures, reset 
the counter and additionally set the "NoSignal" output to '0'.

All in all it looks like this:
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std.all;

entity SYNC_det is
Port (  CLK      : in  STD_LOGIC;
        Square   : in  STD_LOGIC;
        SquareDetected : out  STD_LOGIC := '0'
                );
end SYNC_det;

architecture arch of SYNC_det is

   signal sqsr : std_LOGIC_vector(1 downto 0) := "11"; -- shift register for edge detection, default value: external pullup
   signal cnt : integer range 0 to 127 := 0;

begin

   counter_p: process(CLK) 
   begin
       if (rising_edge(CLK)) then

            -- never ever use a async input without sync'ing it to the system clock!
           sqsr <= sqsr(0)&Square;
           
           -- check for edges 
           if sqsr="10" or sqsr="01" then -- edge on SQUARE
               cnt <= 0;
               SquareDetected <= '1';
           else                               
               if cnt<127 then            -- count to highest value     
                   cnt <= cnt + 1; 
               else
                   SquareDetected <= '0'; -- end of counter reached --> timeout, no more edges 
               end if;
           end if;

       end if;
   end process;

end arch;

And the description above togehter with this testbench...
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;

 
ENTITY tb_sd IS
END tb_sd;
 
ARCHITECTURE behavior OF tb_sd IS 

    COMPONENT SYNC_det
    PORT(
         CLK : IN  std_logic;
         Square : IN  std_logic;
         SquareDetected : OUT  std_logic
        );
    END COMPONENT;
    
   signal CLK : std_logic := '0';
   signal Square : std_logic := '1';

   signal sq    :  std_logic := '1'; -- default value = 'high' due to pullup
   signal sqen  :  std_logic := '1';

   signal SquareDetected : std_logic;

BEGIN
   uut: SYNC_det PORT MAP (
          CLK => CLK,
          Square => Square,
          SquareDetected => SquareDetected
        );

   clk  <= not clk after 500 ns;   -- 1MHz system clock
   
   sq   <= not sq after 125 us;    -- 4kHz square wave 
   sqen <= not sqen after 2250 us; -- enable for the square wave signal
   Square <= sq and sqen;

END;
... results in the waveform in the screenshot. Looks ok for me... ;-)

: Edited by Moderator
von maestros (Guest)


Rate this post
0 useful
not useful
Hello Lothar M., Your code is perfectly  working, I have tested it on 
hardware also. Thanks a lot for your help and prompt reply.

von Lothar M. (lkmiller) (Moderator)


Attached files:

Rate this post
0 useful
not useful
maestros wrote:
> Your code is perfectly  working, I have tested it on hardware also.
Nice to hear.
A hint: check out the symmetry of your square wave. When its changing a 
little bit from 50:50 to 48:52, then you will get short spikes on the 
SquareDetected output, because there is only a little margin on the 
counter (from 125 to 127). See WF_SD_DC48.PNG for that.
To get this waveform I changed the test bench a little to invoke the 
duty cycle in the 4kHz signal:
   :
   constant dc : real := 0.48;
   :
BEGIN
   :
   process begin
      sq <= '1';
      wait for dc * 250 us;
      sq <= '0';
      wait for (1.0-dc) * 250 us;
   end process;
   :

To be much more tolerant there it would be best to increase the top 
value of the counter to 255:
   :
   signal cnt : integer range 0 to 255 := 0;
   :
               if cnt<255 then            -- count to highest value
   :
The reaction to detect a missing 4kHz square wave signal is then delayed 
by  129us. See WF_SD_DC48_cnt255.PNG at around 2.2ms.

: Edited by Moderator

Reply

Entering an e-mail address is optional. If you want to receive reply notifications by e-mail, please log in.

Rules — please read before posting

  • Post long source code as attachment, not in the text
  • Posting advertisements is forbidden.

Formatting options

  • [c]C code[/c]
  • [avrasm]AVR assembler code[/avrasm]
  • [vhdl]VHDL code[/vhdl]
  • [code]code in other languages, ASCII drawings[/code]
  • [math]formula (LaTeX syntax)[/math]




Bild automatisch verkleinern, falls nötig
Note: the original post is older than 6 months. Please don't ask any new questions in this thread, but start a new one.