реклама на сайте
подробности

 
 
> Детектор наличия частоты., Гугл молчит. Не строить же велосипед.
MegaVolt
сообщение Jun 8 2015, 09:29
Сообщение #1


Знающий
****

Группа: Свой
Сообщений: 779
Регистрация: 3-01-05
Из: Минск
Пользователь №: 1 783



Нужно детектировать наличие частоты. Опорная частота присутствует.

Классика предлагает ставить счётчик и смотреть периодически что он насчитал. Так вот ищу решение для однобитного счётчика. Т.е. самый быстрый детектор.

Что то не могу правильно у гугла спросить. Неужели нет стандартного правильного решения для случая не кратных частот?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
MegaVolt
сообщение Jun 8 2015, 12:50
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 779
Регистрация: 3-01-05
Из: Минск
Пользователь №: 1 783



Короче наваял велосипед.

1. Детектит отсутствие клока в течении Alarm_Time тактов опорной частоты (за счёт синхронизатора выходной сигнал задержан на 2 такта относительно реально отсутствующей частоты. Т.е. частоты нет N тактов но об этом мы узнаём на N+2 такте)
2. Входная частота полностью асинхронная единственое условие Fвх < Fоп/2. Метастабильность учтена.
3. Единичный входной импульс считает наличием частоты.
4. На сигнал Not_Use нужно повесить таймспек на минимальную длинну. Для Xilinx MaxDelay.

Замечания и предложения приветствуются.

Код
----------------------------------------------------------------------------------
-- Company:
-- Engineer:
--
-- Create Date:    13:52:23 06/08/2015
-- Design Name:
-- Module Name:    Clock_Detector - Behavioral
-- Project Name:
-- Target Devices:
-- Tool versions:
-- Description:
--
-- Dependencies:
--
-- Revision:
-- Revision 0.01 - File Created
-- Additional Comments:
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity Clock_Detector is
    Generic (
      Alarm_time      : integer range 2 to 250000 := 4
    );
    Port ( ClkX : in  STD_LOGIC;
           Clk : in  STD_LOGIC;
           Detect : out  STD_LOGIC);
end Clock_Detector;

architecture Behavioral of Clock_Detector is

  function getlog2 (int : in integer) return integer is
    variable log2 : natural := 0;
  begin
    if (int = 0) then
      log2 := 0;
    elsif (int <= 2) then
      log2 := 1;
    else
      log2 := getlog2((int/2) + (int rem 2)) + 1;
    end if;
    return log2;
  end function getlog2;

constant Count_MSB         : natural := getlog2(Alarm_Time);
  
signal Not_Use :std_logic;
signal ClkX_Shift : std_logic;
signal ClkX_Shift1 : std_logic;
signal ClkX_Rise_Sync: std_logic;
signal Count :std_logic_vector(Count_MSB downto 0);
alias Overflow: std_logic is Count(Count_MSB);

begin

process (Clk)
begin  
   if (Clk'event and Clk = '1') then
     Not_Use <= ClkX;
     ClkX_Shift <= Not_Use;
     ClkX_Shift1 <= ClkX_Shift;
   end if;
end process;

ClkX_Rise_Sync <= not ClkX_Shift1 and ClkX_Shift;

process (Clk, ClkX_Rise_Sync)
begin
   if ClkX_Rise_Sync='1' then
      Count <= conv_std_logic_vector((2**Count_MSB-Alarm_Time),Count_MSB+1);
   elsif Clk='1' and Clk'event then
      if (not Overflow)='1' then
         Count <= Count + 1;
      end if;
   end if;
end process;

Detect <= not Overflow;

end Behavioral;


И ещё: чтобы эта дрянь не преобразовывала триггеры в сдвиговый регистр дописать вот это:

-- Synplify Pro: disable shift-register LUT (SRL) extraction
attribute syn_srlstyle : string;
attribute syn_srlstyle of NOT_USE : signal is "registers";
attribute syn_srlstyle of ClkX_Shift : signal is "registers";

-- Xilinx XST: disable shift-register LUT (SRL) extraction
attribute shreg_extract : string;
attribute shreg_extract of NOT_USE : signal is "no";
attribute shreg_extract of ClkX_Shift : signal is "no";
Go to the top of the page
 
+Quote Post
des00
сообщение Jun 8 2015, 13:26
Сообщение #3


Вечный ламер
******

Группа: Модераторы
Сообщений: 7 248
Регистрация: 18-03-05
Из: Томск
Пользователь №: 3 453



Цитата(MegaVolt @ Jun 8 2015, 19:50) *
2. .....единственое условие Fвх < Fоп/2......
3. Единичный входной импульс считает наличием частоты.

попса wink.gif но скорее всего, в ваших условиях, работать будет.


--------------------
Go to the top of the page
 
+Quote Post
MegaVolt
сообщение Jun 8 2015, 13:29
Сообщение #4


Знающий
****

Группа: Свой
Сообщений: 779
Регистрация: 3-01-05
Из: Минск
Пользователь №: 1 783



Цитата(des00 @ Jun 8 2015, 16:26) *
попса wink.gif но скорее всего, в ваших условиях работать будет.
C огромным интересом гляну на альтернативы. Желательно в том же объёме ресурсов. Готов смотреть на них даже в ссылках sm.gif

Хотя в чём проблема поделить входную частоту не понимаю sad.gif
Go to the top of the page
 
+Quote Post
des00
сообщение Jun 8 2015, 13:37
Сообщение #5


Вечный ламер
******

Группа: Модераторы
Сообщений: 7 248
Регистрация: 18-03-05
Из: Томск
Пользователь №: 3 453



Цитата(MegaVolt @ Jun 8 2015, 20:29) *
C огромным интересом гляну на альтернативы. Желательно в том же объёме ресурсов. Готов смотреть на них даже в ссылках sm.gif

Ресурсов больше, но и уровень контроля за частотой выше и любые частоты :
CODE

module clk_los_ctrl
#(
parameter int pREFFREQ_HZ = 48_000_000 ,
parameter int pFREQ_HZ = 48_000_000 ,
parameter int pPPM = 100
)
(
iclk ,
ireset ,
irefclk ,
olos
);

//------------------------------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------------------------------

input logic iclk ;
input logic ireset ;
input logic irefclk ;
output logic olos ;

//------------------------------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------------------------------

localparam int cCLK_CNT_W = clogb2(pFREQ_HZ);
localparam bit [63 : 0] cPPMFREQ = (pREFFREQ_HZ * pPPM)/1_000_000 ;
localparam int cREFCLK_CNT_W = clogb2(pREFFREQ_HZ + cPPMFREQ);

logic [cREFCLK_CNT_W-1 : 0] refclk_cnt;
logic refclk_window_start;
logic refclk_window_end;
logic refclk_window;
logic refclk_done;

logic clr;
logic clr_at_clk;

logic ppm_ok;

logic [cCLK_CNT_W-1 : 0] clk_cnt;
logic clk_cnt_done;
logic clk_cnt_done_at_ref_clk;
//------------------------------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------------------------------
// synthesis translate_off
initial begin : ini
refclk_cnt = '0;
refclk_window_start = '0;
refclk_window_end = '0;
refclk_window = '0;
refclk_done = '0;

clr = '0;
ppm_ok = '0;

clk_cnt = '0;
clk_cnt_done = '0;
end
// synthesis translate_on
//------------------------------------------------------------------------------------------------------
// count reference frequency
//------------------------------------------------------------------------------------------------------

always_ff @(posedge irefclk) begin
if (clr)
refclk_cnt <= '0;
else
refclk_cnt <= refclk_cnt + 1'b1;
//
// window
refclk_window_start <= (refclk_cnt == (pREFFREQ_HZ - cPPMFREQ - 2));
refclk_window_end <= (refclk_cnt == (pREFFREQ_HZ + cPPMFREQ - 2));

if (refclk_window_start)
refclk_window <= 1'b1;
else if (refclk_window_end)
refclk_window <= 1'b0;
//
// decision
{clr, refclk_done} <= {refclk_done, refclk_window_end};

if (refclk_window & clk_cnt_done_at_ref_clk)
ppm_ok <= 1'b1;
else if (refclk_done) begin
ppm_ok <= 1'b0;
olos <= ~ppm_ok;
end
end

//------------------------------------------------------------------------------------------------------
// synchronizers
//------------------------------------------------------------------------------------------------------

pulse_synchronizer
#(
.pLENGTH ( 3 )
)
clk_cnt_done_synchronizer // iclk -> irefclk
(
.clkin ( iclk ) , .resetin ( 1'b0 ) , .sin ( clk_cnt_done ) ,
.clkout ( irefclk ) , .resetout ( ) , .sout ( clk_cnt_done_at_ref_clk )
);

pulse_synchronizer
#(
.pLENGTH ( 3 )
)
clr_cnt__synchronizer // irefclk -> iclk
(
.clkin ( irefclk ) , .resetin ( 1'b0 ) , .sin ( clr ) ,
.clkout ( iclk ) , .resetout ( ) , .sout ( clr_at_clk )
);

//------------------------------------------------------------------------------------------------------
// count frequency
//------------------------------------------------------------------------------------------------------

always_ff @(posedge iclk) begin
if (clr_at_clk) begin
clk_cnt <= '0;
clk_cnt_done <= 1'b0;
end
else begin
clk_cnt <= clk_cnt + 1'b1;
clk_cnt_done <= (clk_cnt == (pFREQ_HZ-1));
end
end


endmodule



Цитата(MegaVolt @ Jun 8 2015, 20:29) *
Хотя в чём проблема поделить входную частоту не понимаю sad.gif

В наличии требования делать это руками, все это увеличивает NRE, что по началу кажется пустяком, но со временем понимаешь что это совсем не пустяк


--------------------
Go to the top of the page
 
+Quote Post
MegaVolt
сообщение Jun 9 2015, 06:21
Сообщение #6


Знающий
****

Группа: Свой
Сообщений: 779
Регистрация: 3-01-05
Из: Минск
Пользователь №: 1 783



Цитата(des00 @ Jun 8 2015, 16:37) *
Ресурсов больше, но и уровень контроля за частотой выше и любые частоты :
И время работы нехилое sad.gif
Мне нужен контроль за сбоями а не за самой частотой. Причём быстрый.
Цитата
В наличии требования делать это руками, все это увеличивает NRE, что по началу кажется пустяком, но со временем понимаешь что это совсем не пустяк

NRE это кто? По поводу требования делать руками... это же демка принципа а не финальная девайсина. Делитель дописать не проблема который в зависимости от заданных частот сам делит.

Хотя считать ppm в железе неожиданный подход sm.gif))
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th July 2025 - 22:45
Рейтинг@Mail.ru


Страница сгенерированна за 0.01432 секунд с 7
ELECTRONIX ©2004-2016