Jump to content

    

помогите с оператором case и делением частоты

Всем доброго времени суток!

Помогите разобраться с оператором case и делителем частоты. Решил сделать делитель частоты,но такой,чтобы можно было изменять частоту при изменении некоторого 5 разрядного числа, назовем его fm1.

 

Может быть кому-то покажется странным, но вот мое творение для создания меандра:

нужно сделать так, чтобы при разных значениях fm1 выбирались разные значения переменной f15_1. Потом исходя из этого через выбранное количество отсчетов фронтов f50k формируются пички, и по ним в следующем процессе делается меандр.

frequency1Hz: process (f50k, fm1)
    variable f15: integer range 0 to 641:=0;
    variable f15_1: integer range 0 to 641:=0;
    begin
if Clr = '1' then
         f15_1:=0;
         f15:=0;
         freq15<='0'; 
        ELSIF true THEN
if rising_edge(f50k) THEN
if f15_1 = 0 then
case fm1 is              -- выбор значений f15_1 при разных значениях fm1 
        when "00000" =>
        f15_1 := 16;
        when "00010" =>
        f15_1 := 119;
        when "00011" =>
        f15_1 := 104;
        when "00100" =>
        f15_1 := 92;
        when "00101" =>
        f15_1 := 83;
        when "00110" =>
        f15_1 := 75;
        when "10110" =>
        f15_1 := 64;
        when "00111" =>
        f15_1 := 641;
        
  when others => null;
  end case;     
  end if;

  if f15=0 then           
        f15 := f15_1;  --присваиваем переменной выбранное значение
        freq15<='1';
           
  else
        f15:=f15-1;    -- отсчитываем назад до нуля и когда f15 снова станет 0, на длительность такта f50k появляется 1. 
        freq15<='0';
  end if;
  end if;
  end if;
     
    END PROCESS;
    
    freq15Hz: process (f50k) --делаем меандр
   begin
if clr='1' then
    f15<='0';

elsif true then
    if rising_edge (f50k) then
    if freq15='1' then
    if f15='0' then
    f15<='1';

elsif true then
    f15<='0';
end if;
end if;
end if;
end if;

end process;

 

Но все это к сожалению не работает. Пытаюсь все это реализовать на АPA300 в Libero. После синтеза и просмотра результата в ModelSim получается вот такая картина(.

 

Подскажите,пожалуйста,где ошибка,что не так, почему не работает!

 

Заранее благодарен)!

post-80654-1395069729_thumb.jpg

Share this post


Link to post
Share on other sites

Если честно не совсем понял где сигнал fm управляется в коде. Ннадо бы привести весь код программы(с читаемым форматированием).

 

Похоже что код написан так, что в некоторый момент выполняется условие перевода выхода fs в значение 1 и 0 одновременно.

Share this post


Link to post
Share on other sites
Всем доброго времени суток!

Помогите разобраться с оператором case и делителем частоты. Решил сделать делитель частоты,но такой,чтобы можно было изменять частоту при изменении некоторого 5 разрядного числа, назовем его fm1.

 

Может быть кому-то покажется странным, но вот мое творение для создания меандра:

нужно сделать так, чтобы при разных значениях fm1 выбирались разные значения переменной f15_1. Потом исходя из этого через выбранное количество отсчетов фронтов f50k формируются пички, и по ним в следующем процессе делается меандр.

 

 

Но все это к сожалению не работает. Пытаюсь все это реализовать на АPA300 в Libero. После синтеза и просмотра результата в ModelSim получается вот такая картина(.

 

Подскажите,пожалуйста,где ошибка,что не так, почему не работает!

 

Заранее благодарен)!

Добрый совет - избавляйтесь от конструкций if-then-else. Потеряетесь (потеряетесь к чертовой матери!). Читайте в поисковиках "автоматное программирование для начинающих".

Share this post


Link to post
Share on other sites
Если честно не совсем понял где сигнал fm управляется в коде. Ннадо бы привести весь код программы(с читаемым форматированием).

 

Похоже что код написан так, что в некоторый момент выполняется условие перевода выхода fs в значение 1 и 0 одновременно.

fm<=f15;

 

сигнал fm это и есть наш желанный меандр

Share this post


Link to post
Share on other sites
Если честно не совсем понял где сигнал fm управляется в коде. Ннадо бы привести весь код программы(с читаемым форматированием).

 

Похоже что код написан так, что в некоторый момент выполняется условие перевода выхода fs в значение 1 и 0 одновременно.

 

вот полный вариант

LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
LIBRARY IEEE;
USE IEEE.std_logic_unsigned.all;
use IEEE.STD_LOGIC_ARITH.ALL;


ENTITY SinTR IS
GENERIC
(
       koef : INTEGER 
                        := 2 
                      --:= 3 
                      --:= 1 
   );

PORT (

	TAKT       : in std_logic;
    strob      : in std_logic;
	sdvig      : in std_logic;
       data_serial: in std_logic;
       Clr        : in std_logic;

	fout       : out std_logic;
   	Dfm        : out std_logic;
       fmod_out     : out std_logic_vector (4 downto 0)

);

END SinTR;

ARCHITECTURE beh OF SinTR IS

signal fm1: std_logic_vector (4 downto 0) := ( others => '0' );
signal ff256 : std_logic_vector (3 downto 0);
signal freq2_5_1, f2_5, freq15, f15, f50k, freq50k, fm256, fm :std_logic := '0';
signal rs_s1, rs_s : std_logic_vector (41 downto 0):= (others => '0');

BEGIN
--	
--                <<  TAKT  >>  == 15 MHz
--сначала делаем меандр до частоты 2,5 MHz, из него формируем уже частоту f50k (50 kHz)
frequency2_5MHz: process (TAKT)
   variable f1: integer range 0 to koef :=0;
   begin
if Clr = '1' then
        f1 := 0;

       freq2_5_1<='0'; 
       ELSIF true THEN
	 IF rising_edge(TAKT) THEN
		 IF f1 = 0 THEN
			f1:=koef;
			freq2_5_1<='1';
		ELSIF true THEN
			f1:=f1-1;
			freq2_5_1<='0';
		END IF ;
	END IF;
	END IF ;
END PROCESS;

   freq2_5MHz: process (TAKT)
  begin
if clr='1' then
   f2_5<='0';

elsif true then
   if rising_edge (TAKT) then
   if freq2_5_1='1' then
   if f2_5='0' then
   f2_5<='1';

elsif true then
   f2_5<='0';
end if;
end if;
end if;
end if;

end process;
-- делаем частоту f50k
frequency50kHz: process (f2_5)
   variable f50k: integer range 0 to 25:=0;
   begin
if Clr = '1' then
        f50k := 0;

       freq50k<='0'; 
       ELSIF true THEN
	 IF rising_edge(f2_5) THEN
		 IF f50k = 0 THEN
			f50k:=25;
			freq50k<='1';
		ELSIF true THEN
			f50k:=f50k-1;
			freq50k<='0';
		END IF ;
	END IF;
	END IF ;
END PROCESS;

   freq50kHz: process (f2_5)
  begin
if clr='1' then
   f50k<='0';

elsif true then
   if rising_edge (f2_5) then
   if freq50k='1' then
   if f50k='0' then
   f50k<='1';

elsif true then
   f50k<='0';
end if;
end if;
end if;
end if;

end process;

Fout <= f50k;-- сигнал подаем на выходной порт



frequency1Hz: process (f50k, fm1) -- формируем частоту по тому же принципу, что и f50k, но добавляем case видимо как-то неправильно((
   variable f15: integer range 0 to 641:=0;
   variable f15_1: integer range 0 to 641:=0;
   begin
if Clr = '1' then
        f15_1:=0;
        f15:=0;
        freq15<='0'; 
       ELSIF true THEN
if rising_edge(f50k) THEN
if f15_1 = 0 then
case fm1 is

       when "00000" =>
       f15_1 := 16;
       when "00010" =>
       f15_1 := 119;
       when "00011" =>
       f15_1 := 104;
       when "00100" =>
       f15_1 := 92;
       when "00101" =>
       f15_1 := 83;
       when "00110" =>
       f15_1 := 75;
       when "10110" =>
       f15_1 := 64;
       when "00111" =>
       f15_1 := 641;

 when others => null;
 end case;     
 end if;

 if f15=0 then
       f15 := f15_1;
       freq15<='1';

 else
	f15:=f15-1;
	freq15<='0';
 end if;
 end if;
 end if;

END PROCESS;

   freq15Hz: process (f50k) --меандр 
  begin
if clr='1' then
   f15<='0';

elsif true then
   if rising_edge (f50k) then
   if freq15='1' then
   if f15='0' then
   f15<='1';

elsif true then
   f15<='0';
end if;
end if;
end if;
end if;

end process;


fm <= f15; --перезаписываем сигнал 
Dfm <= fm; --на выходной порт
                             -----------дальше для загрузки fm1
mr1_1 : PROCESS  ( strob  )		
BEGIN

 IF rising_edge(strob) THEN
			fm1<=rs_s1( 4 downto 0 );       
       END IF ;
END PROCESS;


fmod_out<=fm1;

msdvig : PROCESS  ( sdvig  )

BEGIN

 IF rising_edge(sdvig) THEN

           rs_s(41 downto 1)<=rs_s(40 downto 0);
		rs_s(0)<=data_serial;
           end if;

end process;




process (takt,clr,rs_s1) 
 begin    
  if clr = '1' then  
   rs_s1 <=( others => '0' ); 

  elsif (takt'event and takt = '1') then  
   rs_s1(41 downto 0) <= rs_s(41 downto 0);  

  end if;  
end process;  

END beh;

Share this post


Link to post
Share on other sites

с читабельным форматированием это значит примерно вот так:

 

LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
LIBRARY IEEE;
USE IEEE.std_logic_unsigned.all;
use IEEE.STD_LOGIC_ARITH.ALL;


ENTITY SinTR IS
GENERIC(
koef : INTEGER := 2 --:= 3 --:= 1
);

PORT (
TAKT		: in std_logic;
strob	   : in std_logic;
sdvig	   : in std_logic;
data_serial : in std_logic;
Clr		 : in std_logic;

fout		: out std_logic;
Dfm		 : out std_logic;
fmod_out	: out std_logic_vector (4 downto 0)
);

END SinTR;

ARCHITECTURE beh OF SinTR IS

signal fm1		  : std_logic_vector (4 downto 0) := ( others => '0' );
signal ff256		: std_logic_vector (3 downto 0);
signal freq2_5_1, f2_5, freq15, f15, f50k, freq50k, fm256, fm :std_logic := '0';
signal rs_s1, rs_s  : std_logic_vector (41 downto 0):= (others => '0');

BEGIN
-- 
-- << TAKT >> == 15 MHz
--сначала делаем меандр до частоты 2,5 MHz, из него формируем уже частоту f50k (50 kHz)
frequency2_5MHz: process (TAKT)
	variable f1: integer range 0 to koef :=0;
begin
	if Clr = '1' then
		f1 := 0;
		freq2_5_1<='0';
	ELSIF true THEN
		IF rising_edge(TAKT) THEN
			IF f1 = 0 THEN
				f1:=koef;
				freq2_5_1<='1';
			ELSIF true THEN
				f1:=f1-1;
				freq2_5_1<='0';
			END IF;
		END IF;
	END IF;
END PROCESS;

freq2_5MHz: process (TAKT)
begin
	if clr='1' then
		f2_5<='0';

	elsif true then
		if rising_edge (TAKT) then
			if freq2_5_1='1' then
				if f2_5='0' then
					f2_5<='1';

				elsif true then
					f2_5<='0';
				end if;
			end if;
		end if;
	end if;

end process;
-- делаем частоту f50k
frequency50kHz: process (f2_5)
	variable f50k: integer range 0 to 25:=0;
begin
	if Clr = '1' then
		f50k := 0;

		freq50k<='0';
	ELSIF true THEN
		IF rising_edge(f2_5) THEN
			IF f50k = 0 THEN
				f50k:=25;
				freq50k<='1';
			ELSIF true THEN
				f50k:=f50k-1;
				freq50k<='0';
			END IF;
		END IF;
	END IF;
END PROCESS;

freq50kHz: process (f2_5)
begin
	if clr='1' then
		f50k<='0';

	elsif true then
		if rising_edge (f2_5) then
			if freq50k='1' then
				if f50k='0' then
					f50k<='1';

				elsif true then
					f50k<='0';
				end if;
			end if;
		end if;
	end if;

end process;

Fout <= f50k;-- сигнал подаем на выходной порт

frequency1Hz: process (f50k, fm1) -- формируем частоту по тому же принципу, что и f50k, но добавляем case видимо как-то неправильно((
	variable f15: integer range 0 to 641:=0;
	variable f15_1: integer range 0 to 641:=0;
begin
	if Clr = '1' then
		f15_1:=0;
		f15:=0;
		freq15<='0';
	ELSIF true THEN
		if rising_edge(f50k) THEN
			if f15_1 = 0 then
				case fm1 is
					when "00000" =>
						f15_1 := 16;
					when "00010" =>
						f15_1 := 119;
					when "00011" =>
						f15_1 := 104;
					when "00100" =>
						f15_1 := 92;
					when "00101" =>
						f15_1 := 83;
					when "00110" =>
						f15_1 := 75;
					when "10110" =>
						f15_1 := 64;
					when "00111" =>
						f15_1 := 641;
					when others => null;
				end case;
			end if;
			if f15=0 then
				f15 := f15_1;
				freq15<='1';
			else
				f15:=f15-1;
				freq15<='0';
			end if;
		end if;
	end if;
END PROCESS;

freq15Hz: process (f50k) --меандр
begin
	if clr='1' then
		f15<='0';
	elsif true then
		if rising_edge (f50k) then
			if freq15='1' then
				if f15='0' then
					f15<='1';
				elsif true then
					f15<='0';
				end if;
			end if;
		end if;
	end if;
end process;


fm <= f15; --перезаписываем сигнал
Dfm <= fm; --на выходной порт
-----------дальше для загрузки fm1
mr1_1 : PROCESS ( strob )
BEGIN
	IF rising_edge(strob) THEN
		fm1<=rs_s1( 4 downto 0 );
	END IF;
END PROCESS;


fmod_out<=fm1;

msdvig : PROCESS ( sdvig )
BEGIN
	IF rising_edge(sdvig) THEN
		rs_s(41 downto 1)<=rs_s(40 downto 0);
		rs_s(0)<=data_serial;
	end if;
end process;

process (takt,clr,rs_s1)
begin
	if clr = '1' then
		rs_s1 <=( others => '0' );
	elsif (takt'event and takt = '1') then
		rs_s1(41 downto 0) <= rs_s(41 downto 0);
	end if;
end process;
END beh;

 

не ленитесь делать код читаемым.

 

Что касается самой проблемы, то возможно её решение в процессе mr1_1

BEGIN
    IF rising_edge(strob) THEN
        fm1<=rs_s1( 4 downto 0 );
    END IF;
END PROCESS;

 

fm1 загружается не синхронно относительно тактовой частоты f50k. Попробуйте так:

    mr1_1 : PROCESS (f50k)
    BEGIN
        IF rising_edge(f50k) THEN
            if strob = '1' then 
                fm1<=rs_s1( 4 downto 0 );
            end if;
        END IF;
    END PROCESS;

при этом сигнал strob импульсный длительностью в 1 такт клока f50k

Edited by des00

Share this post


Link to post
Share on other sites
с читабельным форматированием это значит примерно вот так:

 

К сожалению не помогло, теперь еще и fm1 не грузится(

post-80654-1395108854_thumb.jpg

Share this post


Link to post
Share on other sites
Всем доброго времени суток!

Помогите разобраться с оператором case и делителем частоты. Решил сделать делитель частоты,но такой,чтобы можно было изменять частоту при изменении некоторого 5 разрядного числа, назовем его fm1.

 

Может быть кому-то покажется странным, но вот мое творение для создания меандра:

нужно сделать так, чтобы при разных значениях fm1 выбирались разные значения переменной f15_1. Потом исходя из этого через выбранное количество отсчетов фронтов f50k формируются пички, и по ним в следующем процессе делается меандр.

 

 

Но все это к сожалению не работает. Пытаюсь все это реализовать на АPA300 в Libero. После синтеза и просмотра результата в ModelSim получается вот такая картина(.

 

Подскажите,пожалуйста,где ошибка,что не так, почему не работает!

 

Заранее благодарен)!

 

Приветствую :1111493779:

Прочел вопрос и проникся :crying:

Чтобы быть кратким, то совсем недавно писал я подобный модуль. Писал я на verilog, и по своей структуре у меня получился n-ое кол-во делителей опорной частоты и мультиплексор. Очень просто и сердито=))) А мультиплексор выбирал выход одного из необходимых делителей частоты. По сути выбирался коэффициент деления опорной частоты. Хотя на вход мультиплексора можно засунуть что угодно.

ЭТА ИНФОРМАЦИЯ К СВЕДЕНИЮ АВТОРА=)) Я не стал разбираться с Вашим написанным кодом, НО КАК-ТО УЖ МНОГО НАПИСАНО=)) Мне кажется можно упростить. Возможно я не прав, не судите строго=)))

Share this post


Link to post
Share on other sites
Приветствую :1111493779:

Прочел вопрос и проникся :crying:

Чтобы быть кратким, то совсем недавно писал я подобный модуль. Писал я на verilog, и по своей структуре у меня получился n-ое кол-во делителей опорной частоты и мультиплексор. Очень просто и сердито=))) А мультиплексор выбирал выход одного из необходимых делителей частоты. По сути выбирался коэффициент деления опорной частоты. Хотя на вход мультиплексора можно засунуть что угодно.

ЭТА ИНФОРМАЦИЯ К СВЕДЕНИЮ АВТОРА=)) Я не стал разбираться с Вашим написанным кодом, НО КАК-ТО УЖ МНОГО НАПИСАНО=)) Мне кажется можно упростить. Возможно я не прав, не судите строго=)))

Спасибо за информацию!Да, я согласен с Вами,что можно использовать N делителей частоты и мультиплексор, но как раз от этого и хочется уйти) А что если N будет настолько велико, что не хватит ресурсов ПЛИС?)

Не могли бы Вы поделиться кодом своего блока делителя частоты,вдруг это поможет?)спасибо))

Share this post


Link to post
Share on other sites
Спасибо за информацию!Да, я согласен с Вами,что можно использовать N делителей частоты и мультиплексор, но как раз от этого и хочется уйти) А что если N будет настолько велико, что не хватит ресурсов ПЛИС?)

Не могли бы Вы поделиться кодом своего блока делителя частоты,вдруг это поможет?)спасибо))

 

На глаза попадется, отправлю=)

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

 

А если от этого уйти, тогда можно взять одЫн счетчик и сбрасывать его, сравнивая с переменной заданной величиной. Т.о. шаг деления будет равен периоду дискретизации опорной частоты.

 

Если есть ограниченный набор каких-то фиксированных некоррелированных частот, тогда просто мультиплексируем их.

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

 

А что если N будет настолько велико, что не хватит ресурсов ПЛИС?)

А у Вас та как?????????????????????=)))))))))))))))))))

Или вы собираетесь торговать этим модулем=)?!

 

Тут можно извращаться по разному. Я предлагаю самое простое. Какая задача та у Вас? Если вы отметили, что

изменять частоту при изменении некоторого 5 разрядного числа

тогда у вас не более 32-х номиналов частот. У вас FPGA или CPLD?

Возьмите счетчик и сравнивайте его состояние с переменной величиной. Пусть он считает до 1... до 3 и т.д. В результате вы получите импульсную последовательность следующую с разной частотой.

Share this post


Link to post
Share on other sites
А если от этого уйти, тогда можно взять одЫн счетчик и сбрасывать его, сравнивая с переменной заданной величиной. Т.о. шаг деления будет равен периоду дискретизации опорной частоты.

Я так и пытаюсь сделать)сначала переменной присваиваю значение, которое выбирается из case,а затем работаю с выбранным значением. Как формируется меандр у меня: если переменная равно нулю,то ей присваивается значение N , и некому сигналу '1' на время равному одному такту опорной частоты. Затем происходит уменьшение N до нуля и все заново) и потом по 'пичкам' формируем меандр. Может быть и сложновато,но работало,пока не добавил case(( и где ошибка не вижу к сожалению...Помогите увидеть:)

 

Если есть ограниченный набор каких-то фиксированных некоррелированных частот, тогда просто мультиплексируем их.

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

Все частоты, которые хочется получить, формируются из опорной. Вся проблема,наверное,в неправильной работе case((

 

Если вы отметили, что

 

тогда у вас не более 32-х номиналов частот. У вас FPGA или CPLD?

Возьмите счетчик и сравнивайте его состояние с переменной величиной. Пусть он считает до 1... до 3 и т.д. В результате вы получите импульсную последовательность следующую с разной частотой.

Пытаюсь все это реализовать на Actel APA 300. 5 разрядное число приведено как пример.оно мб и больше)спасибо за ответы и советы:)

Share this post


Link to post
Share on other sites
Я так и пытаюсь сделать)сначала переменной присваиваю значение, которое выбирается из case,а затем работаю с выбранным значением. Как формируется меандр у меня: если переменная равно нулю,то ей присваивается значение N , и некому сигналу '1' на время равному одному такту опорной частоты. Затем происходит уменьшение N до нуля и все заново) и потом по 'пичкам' формируем меандр. Может быть и сложновато,но работало,пока не добавил case(( и где ошибка не вижу к сожалению...Помогите увидеть:)

 

 

Все частоты, которые хочется получить, формируются из опорной. Вся проблема,наверное,в неправильной работе case((

 

Там все проще=)) Ладно, ищите ошибку... если уверены что все именно так стоит оставить=)

 

Код там примитивный 10 - 20 строк=) Счетчик (5 разрядов) + компаратор + формирователь меандра (триггер с обратной связью через инвертор).

6 триггеров + логика.

 

А вы такой листинг программы залупили=))

 

ModelSim вам в таком случае в помощь=))

Share this post


Link to post
Share on other sites
Пытаюсь все это реализовать

видимо с помощью мультиплексора

when "00111" =>

f15_1 := 641;

 

when others => null;

end case;

 

when others => наверно желателен заданный период, отличный от нуля.

Share this post


Link to post
Share on other sites
Там все проще=)) Ладно, ищите ошибку... если уверены что все именно так стоит оставить=)

Поделитесь,пожалуйста,своим работающим кодом)буду очень признателен:)

Share this post


Link to post
Share on other sites
Поделитесь,пожалуйста,своим работающим кодом)буду очень признателен:)

На самом деле есть и более простой вариант...

У Вас:

-- << TAKT >> == 15 MHz

--сначала делаем меандр до частоты 2,5 MHz, из него формируем уже частоту f50k (50 kHz)

 

Берем двухпортовый блок памяти - это ОЗУ результатов и параметров. Определяем поля в ОЗУ, сколько битов под длительность пересчета, сколько под флаги, сколько под результат.

К нему счетчик адресов и АЛУ, которое вычитает код до нуля, а по нулю - перезагружается...

И крутим адреса по "кругу". А "круг" - это не более, чем 15M/2,5M или даже 15М/50К, т.е. там получится вполне достаточно тактов.

Делаем простой механизм, который считывает результат, вычитает 1 и записывает результат обратно в память. А при достижении 0 сигнал идет на триггер, соотв. номеру канала и его переключает в инверсное...

Далее остается только занести данные о периоде в ОЗУ и прорва таймеров начнет считать...

У меня в "Кратком Курсе" нечто подобное описано в главе о многопоточности...

 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this