| Author |
Message |
suquid29
Joined: 02 May 2008 Posts: 16
|
17 Jul 2008 11:50 How to know if clock is toggling? |
|
|
|
Hi,
I'm designing a module that measures frequency of unknown clock. I've done it simply by counting edges on a known period of time window (with proper synchronization of course).
But before that, I need to check if its toggling... How can I do that?
I though of OR between clk and NOT(clk), but is not a good idea because there is a small period of time (t_pd of NOT) that they are both low...
Any good ideas?
Thanks!
|
|
| Back to top |
|
 |
Black Jack
Joined: 02 Dec 2003 Posts: 217 Helped: 10 Location: UKRAINE
|
17 Jul 2008 13:01 Re: How to know if clock is toggling? |
|
|
|
| suquid29 wrote: |
Hi,
I'm designing a module that measures frequency of unknown clock. I've done it simply by counting edges on a known period of time window (with proper synchronization of course).
But before that, I need to check if its toggling... How can I do that?
I though of OR between clk and NOT(clk), but is not a good idea because there is a small period of time (t_pd of NOT) that they are both low...
Any good ideas?
Thanks! |
Hi!
This will work.
| Code: |
library IEEE;
use IEEE.std_logic_1164.ALL;
use IEEE.std_logic_arith.ALL;
use IEEE.std_logic_unsigned.ALL;
entity Bit_rate_sinc is
port
(
reset_n : in std_logic; -- Asyhch. Reset
data_in : in std_logic; -- Input Data Stream
sys_clk : in std_logic; -- System Clock (Data Input Oversampling)
data_out : out std_logic; -- Output Data Stream
-- (Sinchronous with sys_clk)
rise_edge_det : out std_logic;
fall_edge_det : out std_logic;
edge_det : out std_logic
);
end Bit_rate_sinc;
architecture Behavioral of Bit_rate_sinc is
signal data_sync : std_logic_vector (3 downto 0);
signal rise_edge_det_i : std_logic;
signal fall_edge_det_i : std_logic;
begin
------------------------------------------------------------------------
-- Sync. Input Data with sys_clk --
------------------------------------------------------------------------
INPUT_DATA_SYNC_PRC: process (sys_clk, reset_n)
begin
if (reset_n = '0') then
data_sync <= (others => '0');
elsif rising_edge (sys_clk) then
data_sync <= data_sync(2 downto 0) & data_in;
end if;
end process INPUT_DATA_SYNC_PRC;
------------------------------------------------------------------------
-- Detect Rising and Falling Edges --
------------------------------------------------------------------------
rise_edge_det_i <= '1' when data_sync(3 downto 2) = "01" else '0';
fall_edge_det_i <= '1' when data_sync(3 downto 2) = "10" else '0';
rise_edge_det <= rise_edge_det_i;
fall_edge_det <= fall_edge_det_i;
edge_det <= rise_edge_det_i OR fall_edge_det_i;
data_out <= data_sync(3);
end Behavioral;
|
you can use edge_det as enable signal for counter like
| Code: |
| cnt_ena <= edge_det AND time_base; |
where time_base - signal width 1 s
Last edited by Black Jack on 17 Jul 2008 13:12; edited 1 time in total |
|
| Back to top |
|
 |
j_andr
Joined: 30 Mar 2008 Posts: 90 Helped: 15 Location: europe
|
17 Jul 2008 13:01 Re: How to know if clock is toggling? |
|
|
|
| suquid29 wrote: |
| /.../I need to check if its toggling/.../ |
may be - connect your unknown clock to the clk port of FF,
the D port to '1', and reset the FF at the init state;
if the output of the FF is '1' that means the flip-flop
has seen at least one positive slope of the clock ...
--
|
|
| Back to top |
|
 |
suquid29
Joined: 02 May 2008 Posts: 16
|
18 Jul 2008 10:56 Re: How to know if clock is toggling? |
|
|
|
| Black Jack wrote: |
you can use edge_det as enable signal for counter like
| Code: |
| cnt_ena <= edge_det AND time_base; |
where time_base - signal width 1 s |
I'm not sure I've fully understood what you mean.... Can you please explain again?
Thanks !
And one more question: I'm using a clock i don't know if exist as a clock for a process. If it suddenly stops, I can get the wrong status. right?
|
|
| Back to top |
|
 |
Black Jack
Joined: 02 Dec 2003 Posts: 217 Helped: 10 Location: UKRAINE
|
18 Jul 2008 11:17 Re: How to know if clock is toggling? |
|
|
|
| suquid29 wrote: |
| Black Jack wrote: |
you can use edge_det as enable signal for counter like
| Code: |
| cnt_ena <= edge_det AND time_base; |
where time_base - signal width 1 s |
I'm not sure I've fully understood what you mean.... Can you please explain again?
Thanks !
And one more question: I'm using a clock i don't know if exist as a clock for a process. If it suddenly stops, I can get the wrong status. right? |
I`m sorry. You need count only rise or fall edges. So right code is...
| Code: |
| cnt_ena <= rise_edge_det AND time_base; |
From your counting clock (for example sys_clk = 32.768 MHz) you can
get 1 sec. pulses (time_base) dividing by 2*32768000 with counter.
Next step - count cnt_ena pulses with additional counter
You can connect cnt_ena with clock input of counter or better
connect cnt_ena with enable input of counter and sys_clk
with clock input.
So ... for 1 sec time interval you count number of pulses equal to frequency.
|
|
| Back to top |
|
 |
sree205
Joined: 13 Mar 2006 Posts: 417 Helped: 30
|
19 Jul 2008 8:51 How to know if clock is toggling? |
|
|
|
| Assuming there is a clock in ur module and if u need to check if an incoming signal is toggling or not, use a posedge or negedge detector circuit to find out. Its possible to use that as an enable to start the counter to judge the frequency of the incoming signal.
|
|
| Back to top |
|
 |
Zerox100
Joined: 01 Mar 2003 Posts: 320 Helped: 10
|
19 Jul 2008 10:28 Re: How to know if clock is toggling? |
|
|
|
It's part of my project. i have edited it for you. It will be useful.
THX
code and testbench:
library ieee;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_1164.all;
entity uart_rx_tb is
end uart_rx_tb;
architecture TB_ARCHITECTURE of uart_rx_tb is
-- Component declaration of the tested unit
component uart_rx
port(
rst : in std_logic;
clk_in : in std_logic;
serial_in : in std_logic;
rdy : out std_logic;
clr : in std_logic;
Parallel_out : out std_logic_vector(7 downto 0) );
end component;
-- Stimulus signals - signals mapped to the input and inout ports of tested entity
signal rst : std_logic;
signal clk_in : std_logic:='0';
signal serial_in : std_logic;
signal clr : std_logic;
-- Observed signals - signals mapped to the output ports of tested entity
signal rdy : std_logic;
signal Parallel_out : std_logic_vector(7 downto 0);
begin
UUT : uart_rx
port map (
rst => rst,
clk_in => clk_in,
serial_in => serial_in,
rdy => rdy,
clr => clr,
Parallel_out => Parallel_out
);
clk_in <= not clk_in after 670 ps;
rst <= '1', '0' after 12 ns;
serial_in <= '1', '0' after 40 ns, '1' after 100 ns, '0' after 120 ns;
clr <= '0';
end TB_ARCHITECTURE;
configuration TESTBENCH_FOR_uart_rx of uart_rx_tb is
for TB_ARCHITECTURE
for UUT : uart_rx
use entity work.uart_rx(behav1);
end for;
end for;
end TESTBENCH_FOR_uart_rx;
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY UART_RX IS
PORT (
RST : IN STD_LOGIC;
CLK_IN : IN STD_LOGIC;
SERIAL_IN : IN STD_LOGIC;
RDY : OUT STD_LOGIC;
CLR : IN STD_LOGIC;
PARALLEL_OUT : OUT STD_LOGIC_VECTOR (7 DOWNTO 0)
);
END UART_RX;
ARCHITECTURE BEHAV1 OF UART_RX IS
SIGNAL COUNTER1 :STD_LOGIC_VECTOR (3 DOWNTO 0);
SIGNAL DET_CLK, DET_CLK_INT : STD_LOGIC;
BEGIN
PROCESS (RST, CLK_IN)
BEGIN
IF RST='1' THEN
COUNTER1 <= "1111" AFTER 1 NS;
RDY <= '0';
ELSIF CLK_IN='1' AND CLK_IN'EVENT THEN
IF DET_CLK_INT='1' THEN
COUNTER1 <= "0000" AFTER 1 NS;
RDY <= '1';
ELSE
IF COUNTER1="1111" THEN
RDY <= '0';
ELSE
COUNTER1 <= COUNTER1 +1 AFTER 1 NS;
RDY <= '1';
END IF;
END IF;
END IF;
END PROCESS;
INPUTCLK2 :PROCESS (RST, DET_CLK, SERIAL_IN)
BEGIN
IF RST ='1' OR DET_CLK='1' THEN
DET_CLK_INT <= '0';
ELSIF SERIAL_IN='0' AND SERIAL_IN'EVENT THEN
DET_CLK_INT <= '1';
END IF;
END PROCESS;
OUTPUTCLK2 :PROCESS (RST, CLK_IN)
BEGIN
IF RST ='1' THEN
DET_CLK <= '0';
ELSIF CLK_IN='1' AND CLK_IN'EVENT THEN
DET_CLK <= DET_CLK_INT;
END IF;
END PROCESS;
END BEHAV1;
|
|
| Back to top |
|
 |
Black Jack
Joined: 02 Dec 2003 Posts: 217 Helped: 10 Location: UKRAINE
|
21 Jul 2008 10:17 Re: How to know if clock is toggling? |
|
|
|
| Zerox100 wrote: |
It's part of my project. i have edited it for you. It will be useful.
THX
code and testbench:
library ieee;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_1164.all;
entity uart_rx_tb is
end uart_rx_tb;
architecture TB_ARCHITECTURE of uart_rx_tb is
-- Component declaration of the tested unit
component uart_rx
port(
rst : in std_logic;
clk_in : in std_logic;
serial_in : in std_logic;
rdy : out std_logic;
clr : in std_logic;
Parallel_out : out std_logic_vector(7 downto 0) );
end component;
-- Stimulus signals - signals mapped to the input and inout ports of tested entity
signal rst : std_logic;
signal clk_in : std_logic:='0';
signal serial_in : std_logic;
signal clr : std_logic;
-- Observed signals - signals mapped to the output ports of tested entity
signal rdy : std_logic;
signal Parallel_out : std_logic_vector(7 downto 0);
begin
UUT : uart_rx
port map (
rst => rst,
clk_in => clk_in,
serial_in => serial_in,
rdy => rdy,
clr => clr,
Parallel_out => Parallel_out
);
clk_in <= not clk_in after 670 ps;
rst <= '1', '0' after 12 ns;
serial_in <= '1', '0' after 40 ns, '1' after 100 ns, '0' after 120 ns;
clr <= '0';
end TB_ARCHITECTURE;
configuration TESTBENCH_FOR_uart_rx of uart_rx_tb is
for TB_ARCHITECTURE
for UUT : uart_rx
use entity work.uart_rx(behav1);
end for;
end for;
end TESTBENCH_FOR_uart_rx;
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY UART_RX IS
PORT (
RST : IN STD_LOGIC;
CLK_IN : IN STD_LOGIC;
SERIAL_IN : IN STD_LOGIC;
RDY : OUT STD_LOGIC;
CLR : IN STD_LOGIC;
PARALLEL_OUT : OUT STD_LOGIC_VECTOR (7 DOWNTO 0)
);
END UART_RX;
ARCHITECTURE BEHAV1 OF UART_RX IS
SIGNAL COUNTER1 :STD_LOGIC_VECTOR (3 DOWNTO 0);
SIGNAL DET_CLK, DET_CLK_INT : STD_LOGIC;
BEGIN
PROCESS (RST, CLK_IN)
BEGIN
IF RST='1' THEN
COUNTER1 <= "1111" AFTER 1 NS;
RDY <= '0';
ELSIF CLK_IN='1' AND CLK_IN'EVENT THEN
IF DET_CLK_INT='1' THEN
COUNTER1 <= "0000" AFTER 1 NS;
RDY <= '1';
ELSE
IF COUNTER1="1111" THEN
RDY <= '0';
ELSE
COUNTER1 <= COUNTER1 +1 AFTER 1 NS;
RDY <= '1';
END IF;
END IF;
END IF;
END PROCESS;
INPUTCLK2 :PROCESS (RST, DET_CLK, SERIAL_IN)
BEGIN
IF RST ='1' OR DET_CLK='1' THEN
DET_CLK_INT <= '0';
ELSIF SERIAL_IN='0' AND SERIAL_IN'EVENT THEN
DET_CLK_INT <= '1';
END IF;
END PROCESS;
OUTPUTCLK2 :PROCESS (RST, CLK_IN)
BEGIN
IF RST ='1' THEN
DET_CLK <= '0';
ELSIF CLK_IN='1' AND CLK_IN'EVENT THEN
DET_CLK <= DET_CLK_INT;
END IF;
END PROCESS;
END BEHAV1; |
Hi!
I think that this code isn`t synthesizable.
For example,
| Code: |
...
COUNTER1 <= "1111" AFTER 1 NS;
...
|
|
|
| Back to top |
|
 |
Zerox100
Joined: 01 Mar 2003 Posts: 320 Helped: 10
|
21 Jul 2008 12:53 Re: How to know if clock is toggling? |
|
|
|
It's fully synthesizable with some simulation issues. Synthesis tools ignores timing and delay constrains.
Compile it. It's great!
|
|
| Back to top |
|
 |
mehrzad321
Joined: 14 Feb 2008 Posts: 7
|
22 Jul 2008 11:06 How to know if clock is toggling? |
|
|
|
you can simply detect rising edge and falling edge of a given signal by register it and then compare it with one cycle delayed version:
if rising_edge(clk) then
sig_1 <= sig;
if (sig = '1' and sig_1 = '0') then
--- rising edge of sig
end if;
if (sig = '0' and sig_1 = '1') then
--- falling edge of sig
end if;
end if;
That is it!
|
|
| Back to top |
|
 |