Jump to content

    
Sign in to follow this  
jenya7

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

Recommended Posts

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

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 не изменяется. Что тут не так?

Edited by jenya7

Share this post


Link to post
Share on other sites

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

Тут будет защелка для 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;

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

Share this post


Link to post
Share on other sites
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 не генерируется.

Edited by jenya7

Share this post


Link to post
Share on other sites
11 минут назад, jenya7 сказал:

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

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

Share this post


Link to post
Share on other sites
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  показывает.

Edited by jenya7

Share this post


Link to post
Share on other sites

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

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;

 

Edited by jenya7

Share this post


Link to post
Share on other sites

Я для проверки сгенерировал на 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 генерирует частоты с погрешностью?

Edited by jenya7

Share this post


Link to post
Share on other sites
39 минут назад, jenya7 сказал:

 

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

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

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

 

Share this post


Link to post
Share on other sites
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 задающего осцилятора...надо посмотреть.

Edited by jenya7

Share this post


Link to post
Share on other sites

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

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

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

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

 

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

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this