Перейти к содержанию
    

Посчитать пульсы за период.

На пин приходят пульсы. Мне их надо посчитать за определенный период.

entity FCOUNTER is
  port(
    RST			:in std_logic; 
    CLK        :in std_logic;
  	
    FREQ_IN    :in std_logic;               
	PERIOD     :in  Std_logic_vector(15 downto 0)  := X"03E8"; --1000
    COUNTER    :out Std_logic_vector(31 downto 0) 
    
  );
end FCOUNTER;


architecture STRUCTURE of FCOUNTER is

signal ms_clock :std_logic := '0';
signal reset :std_logic := '0';
signal f_count : std_logic_vector(31 downto 0) := (others=>'0');
signal ms_count : std_logic_vector(15 downto 0) := (others=>'0');
signal count : std_logic_vector(31 downto 0) := (others=>'0');

signal clk1 : std_logic := '0';
signal clk2 : std_logic := '0';
signal clk3 : std_logic := '0';
signal clk4 : std_logic := '0';

begin

clk3 <= not clk1 and clk2;

process(FREQ_IN, reset)
begin 

    if (rising_edge(FREQ_IN)) then
        f_count <= f_count + '1';
    end if;
	 
	 if (reset = '1') then
	    COUNTER <= f_count; --ticks per period
		 f_count <= (others=>'0');
	 end if;


end process;


process(CLK) --100 Mhz
begin

    if (rising_edge(CLK)) then
	 
	    count <= count + '1'; 
		 
		               --49999
		if (count = X"0000C34F") then  --50000 - 500us
		    count <= (others=>'0');
		    ms_clock <= not ms_clock; --tick 500us
		end if;
		
		if (clk3 = '1') then
		    ms_count <= ms_count + '1'; 
		 
		    if (ms_count = PERIOD) then  --milliseconds
		        ms_count <= (others=>'0');
			     reset <= '1';
		    end if;
	  
		end if;
		
		if (reset = '1') then  --do it one clock
		    reset <= '0';
		end if;
		
    end if;		
	 
end process;


process(CLK) 
begin
    clk1 <= ms_clock;
	clk2 <= clk1;
end process;


end STRUCTURE;

Смотрю на Сигнал Тап reset не изменяется. Что тут не так?

Изменено пользователем jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Странно все как-то сделано...

Тут будет защелка для COUNTER, FREQ_IN по идее синтезатор должен будет завести на клоковый вход регистра, хотя он вряд ли заводится с пина, предназначенного для тактирования. Про асинхронность сброса - отдельный вопрос.

Quote

process(FREQ_IN, reset)
begin 

    if (rising_edge(FREQ_IN)) then
        f_count <= f_count + '1';
    end if;
	 
	 if (reset = '1') then
	    COUNTER <= f_count; --ticks per period
		 f_count <= (others=>'0');
	 end if;


end process;

Для чего тут процесс вообще и CLK в списке чувствительности в частности?

Quote

process(CLK) 
begin
    clk1 <= ms_clock;
	clk2 <= clk1;
end process;

В общем, я бы предложил сначала избавиться от всех неоднозначных моментов в коде и использовать синхронную обработку, а потом уже тестировать код на железе и оценивать результаты

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В каком симуляторе Вы моделировали ?

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

6 minutes ago, Flip-fl0p said:

В каком симуляторе Вы моделировали ?

 

Смотрю в Альтере в Сигнал Тап.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

18 minutes ago, Tausinov said:

В общем, я бы предложил сначала избавиться от всех неоднозначных моментов в коде и использовать синхронную обработку, а потом уже тестировать код на железе и оценивать результаты

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

 

я конечно перемудрил. так проще

process(FREQ_IN, reset)
begin 

    if (FREQ_IN'event and FREQ_IN = '1') then
        f_count <= f_count + '1';
    end if;
	 
	 if (reset = '1') then
	    COUNTER <= f_count; --ticks per period
		 f_count <= (others=>'0');
	 end if;


end process;

process(CLK) --100 Mhz
begin

    if (rising_edge(CLK)) then
	 
	    count <= count + '1'; 
		               --99999
		if (count = X"0001869F") then  --100000 - 1ms
		    count <= (others=>'0');
		    ms_count <= ms_count + '1'; 
		end if;
		 
		if (ms_count = PERIOD) then  --milliseconds
		    ms_count <= (others=>'0');
			 reset <= '1';
		end if;
	  
		if (reset = '1') then  --do it one clock
		    reset <= '0';
		end if;
		
    end if;		
	 
end process;

правда тоже не работает. reset не генерируется.

Изменено пользователем jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

11 минут назад, jenya7 сказал:

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

Делать надо не так как Вы хотите, а как правильно. Уже много раз говорилось, что самописные модули надо сперва отлаживать в симуляторе. Но Вы упорно игнорируете эти советы. А потом снова создание тему, что у Вас что-то не работает. Может пора уже поменять стиль разработки ? Ps. Простите за опечатки, пишу с телефона.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 hour ago, Flip-fl0p said:

Делать надо не так как Вы хотите, а как правильно. Уже много раз говорилось, что самописные модули надо сперва отлаживать в симуляторе. Но Вы упорно игнорируете эти советы. А потом снова создание тему, что у Вас что-то не работает. Может пора уже поменять стиль разработки ? Ps. Простите за опечатки, пишу с телефона.

мне казалось, что это настолько тривиальная задача, миллион раз реализованная, что сейчас за 5 минут получу решение. иногда приятно ошибиться.

 

сделал такой вот тестбенч

 

entity f_count_tb is
end f_count_tb;


ARCHITECTURE behavior OF f_count_tb IS 

component FCOUNTER is
  port(
    RST			:in std_logic; 
  	 CLK        :in std_logic;
  	
    FREQ_IN    :in std_logic;               
	 PERIOD     :in  Std_logic_vector(15 downto 0)  := X"03E8"; 
    COUNTER    :out Std_logic_vector(31 downto 0) 
    
  );
end component;

constant clk_period : time := 20 ns;
constant freq_period : time := 10 ns;

signal counter   : std_logic_vector(31 downto 0);
signal pulse_in  : std_logic;
signal clk       : std_logic;

begin

U_TEST_FREQ : FCOUNTER
port map
(
    RST => '0',
	 CLK => clk,
	 
	 FREQ_IN => pulse_in,
	 PERIOD => X"0008",
	 COUNTER => counter
);


clk_process :process
begin

	clk <= '0';
	wait for clk_period/2;
	clk <= '1';
	wait for clk_period/2;
	
end process;

process
begin

	pulse_in <= '0';
	wait for freq_period/2;
	pulse_in <= '1';
	wait for freq_period/2;
	
end process;


end;

 

ок. вижу сигналы clk и pulse_in в моделсим. но FREQ_IN и f_count на нуле. сигнал тап хоть f_count  показывает.

Изменено пользователем jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Так Вы ресет не подали....

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У FCOUNTER топ порт RST не используется в архитектуре, потому модуль остаётся в ресете.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

вобщем в таком варианте все правильно считается

process(FREQ_IN, reset)
begin 

    if (FREQ_IN'event and FREQ_IN = '1') then
        f_count <= f_count + '1';
    end if;
	 
	 if (reset = '1') then
	    --COUNTER <= f_count; --ticks per period
		 f_count <= (others=>'0');
	 end if;


end process;

process(CLK) --100 Mhz
begin

    if (rising_edge(CLK)) then
	 
	    count <= count + '1'; 
		               --99999
		if (count = X"0001869F") then  --100000 - 1ms
		    count <= (others=>'0');
		    ms_count <= ms_count + '1'; 
		end if;
		 
		if (ms_count = PERIOD) then  --milliseconds
		    ms_count <= (others=>'0');
			 
			 COUNTER <= f_count; --ticks per period
			 
			 reset <= '1';
		end if;
	  
		if (reset = '1') then  --do it one clock
		    reset <= '0';
		end if;
		
    end if;		
	 
end process;

 

Изменено пользователем jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я для проверки сгенерировал на PLL частоты и вывожу их на наружные пины (FREQ_OUT1, FREQ_OUT2, FREQ_OUT3)  и подключаю перемычкой на FREQ_IN.

Резальтат измерений

60 000 000 - 59 999 840

100 000 000 - 99 999 840

120 000 000 - 119 999 990

Но народ не устраивает точность измерения (хотят максимум +\- 5ppm).

Может PLL генерирует частоты с погрешностью?

Изменено пользователем jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

39 минут назад, jenya7 сказал:

 

А каков pmm у опоры ?

Сделайте правильно cdc. 

С каких ножек fpga выходит клок. С каких заходит ? Не все ножки правильно применять в качестве клокоаых.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

14 minutes ago, Flip-fl0p said:

А каков pmm у опоры ?

Сделайте правильно cdc. 

С каких ножек fpga выходит клок. С каких заходит ? Не все ножки правильно применять в качестве клокоаых.

 

Так нет опоры. Задача померять асинхронно. Пины взял посто которые было удобно использовать.

 

--in entity
FREQ_IN  : in std_logic;     --AB3
FREQ_OUT1 : out std_logic;    --Y3
FREQ_OUT2 : out std_logic;    --Y4
FREQ_OUT3 : out std_logic;    --Y5

--in architecture

FREQ_OUT1 <= clk_120M;
FREQ_OUT2 <= clk_100M;
FREQ_OUT3 <= clk_60M;
                    
                    
U_PLL : pll 
port map
(
	 inclk0 => MAX10_CLK2_50,
	 c0	  => clk_100M,
	 c1	  => clk_120M,
	 c2	  => clk_150M,
	 c3	  => clk_60M
);

 

ааа. ppm задающего осцилятора...надо посмотреть.

Изменено пользователем jenya7

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Уточню замечание

15 минут назад, Flip-fl0p сказал:

Сделайте правильно cdc. 

У вас f_count считается на частоте FREQ_IN, а защелкивается в регистр COUNTER на частоте CLK.

 

И что за хитровывернутость с сигналом reset?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...