Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: помогите с оператором case и делением частоты
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Работаем с ПЛИС, области применения, выбор
gethan
Всем доброго времени суток!
Помогите разобраться с оператором 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 получается вот такая картина(.

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

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

Похоже что код написан так, что в некоторый момент выполняется условие перевода выхода fs в значение 1 и 0 одновременно.
tdocs.su
Цитата(gethan @ Mar 17 2014, 19:25) *
Всем доброго времени суток!
Помогите разобраться с оператором case и делителем частоты. Решил сделать делитель частоты,но такой,чтобы можно было изменять частоту при изменении некоторого 5 разрядного числа, назовем его fm1.

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


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

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

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

Добрый совет - избавляйтесь от конструкций if-then-else. Потеряетесь (потеряетесь к чертовой матери!). Читайте в поисковиках "автоматное программирование для начинающих".
gethan
Цитата(cerg19 @ Mar 17 2014, 19:47) *
Если честно не совсем понял где сигнал fm управляется в коде. Ннадо бы привести весь код программы(с читаемым форматированием).

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

fm<=f15;

сигнал fm это и есть наш желанный меандр
gethan
Цитата(cerg19 @ Mar 17 2014, 19:47) *
Если честно не совсем понял где сигнал fm управляется в коде. Ннадо бы привести весь код программы(с читаемым форматированием).

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


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

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;
cerg19
с читабельным форматированием это значит примерно вот так:

CODE
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
gethan
Цитата(cerg19 @ Mar 18 2014, 05:43) *
с читабельным форматированием это значит примерно вот так:


К сожалению не помогло, теперь еще и fm1 не грузится(
Dmitriyspb
Цитата(gethan @ Mar 17 2014, 19:25) *
Всем доброго времени суток!
Помогите разобраться с оператором case и делителем частоты. Решил сделать делитель частоты,но такой,чтобы можно было изменять частоту при изменении некоторого 5 разрядного числа, назовем его fm1.

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


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

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

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


Приветствую 1111493779.gif
Прочел вопрос и проникся crying.gif
Чтобы быть кратким, то совсем недавно писал я подобный модуль. Писал я на verilog, и по своей структуре у меня получился n-ое кол-во делителей опорной частоты и мультиплексор. Очень просто и сердито=))) А мультиплексор выбирал выход одного из необходимых делителей частоты. По сути выбирался коэффициент деления опорной частоты. Хотя на вход мультиплексора можно засунуть что угодно.
ЭТА ИНФОРМАЦИЯ К СВЕДЕНИЮ АВТОРА=)) Я не стал разбираться с Вашим написанным кодом, НО КАК-ТО УЖ МНОГО НАПИСАНО=)) Мне кажется можно упростить. Возможно я не прав, не судите строго=)))
gethan
Цитата(Dmitriyspb @ Mar 18 2014, 06:37) *
Приветствую 1111493779.gif
Прочел вопрос и проникся crying.gif
Чтобы быть кратким, то совсем недавно писал я подобный модуль. Писал я на verilog, и по своей структуре у меня получился n-ое кол-во делителей опорной частоты и мультиплексор. Очень просто и сердито=))) А мультиплексор выбирал выход одного из необходимых делителей частоты. По сути выбирался коэффициент деления опорной частоты. Хотя на вход мультиплексора можно засунуть что угодно.
ЭТА ИНФОРМАЦИЯ К СВЕДЕНИЮ АВТОРА=)) Я не стал разбираться с Вашим написанным кодом, НО КАК-ТО УЖ МНОГО НАПИСАНО=)) Мне кажется можно упростить. Возможно я не прав, не судите строго=)))

Спасибо за информацию!Да, я согласен с Вами,что можно использовать N делителей частоты и мультиплексор, но как раз от этого и хочется уйти) А что если N будет настолько велико, что не хватит ресурсов ПЛИС?)
Не могли бы Вы поделиться кодом своего блока делителя частоты,вдруг это поможет?)спасибо))
Dmitriyspb
Цитата(gethan @ Mar 18 2014, 08:24) *
Спасибо за информацию!Да, я согласен с Вами,что можно использовать N делителей частоты и мультиплексор, но как раз от этого и хочется уйти) А что если N будет настолько велико, что не хватит ресурсов ПЛИС?)
Не могли бы Вы поделиться кодом своего блока делителя частоты,вдруг это поможет?)спасибо))


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

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

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

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

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

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

тогда у вас не более 32-х номиналов частот. У вас FPGA или CPLD?
Возьмите счетчик и сравнивайте его состояние с переменной величиной. Пусть он считает до 1... до 3 и т.д. В результате вы получите импульсную последовательность следующую с разной частотой.
gethan
Цитата(Dmitriyspb @ Mar 18 2014, 08:47) *
А если от этого уйти, тогда можно взять одЫн счетчик и сбрасывать его, сравнивая с переменной заданной величиной. Т.о. шаг деления будет равен периоду дискретизации опорной частоты.

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

Цитата(Dmitriyspb @ Mar 18 2014, 08:47) *
Если есть ограниченный набор каких-то фиксированных некоррелированных частот, тогда просто мультиплексируем их.
Если есть возможность пользоваться опорной частотой, тогда можно реализовать на основе счетчика.

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

Цитата(Dmitriyspb @ Mar 18 2014, 08:47) *
Если вы отметили, что

тогда у вас не более 32-х номиналов частот. У вас FPGA или CPLD?
Возьмите счетчик и сравнивайте его состояние с переменной величиной. Пусть он считает до 1... до 3 и т.д. В результате вы получите импульсную последовательность следующую с разной частотой.

Пытаюсь все это реализовать на Actel APA 300. 5 разрядное число приведено как пример.оно мб и больше)спасибо за ответы и советыsm.gif
Dmitriyspb
Цитата(gethan @ Mar 18 2014, 09:33) *
Я так и пытаюсь сделать)сначала переменной присваиваю значение, которое выбирается из case,а затем работаю с выбранным значением. Как формируется меандр у меня: если переменная равно нулю,то ей присваивается значение N , и некому сигналу '1' на время равному одному такту опорной частоты. Затем происходит уменьшение N до нуля и все заново) и потом по 'пичкам' формируем меандр. Может быть и сложновато,но работало,пока не добавил case(( и где ошибка не вижу к сожалению...Помогите увидетьsm.gif


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


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

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

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

ModelSim вам в таком случае в помощь=))
sazh
Цитата(gethan @ Mar 18 2014, 08:42) *
Пытаюсь все это реализовать

видимо с помощью мультиплексора
when "00111" =>
f15_1 := 641;

when others => null;
end case;

when others => наверно желателен заданный период, отличный от нуля.
gethan
Цитата(Dmitriyspb @ Mar 18 2014, 09:44) *
Там все проще=)) Ладно, ищите ошибку... если уверены что все именно так стоит оставить=)

Поделитесь,пожалуйста,своим работающим кодом)буду очень признателенsm.gif
iosifk
Цитата(gethan @ Mar 18 2014, 11:00) *
Поделитесь,пожалуйста,своим работающим кодом)буду очень признателенsm.gif

На самом деле есть и более простой вариант...
У Вас:
-- << TAKT >> == 15 MHz
--сначала делаем меандр до частоты 2,5 MHz, из него формируем уже частоту f50k (50 kHz)

Берем двухпортовый блок памяти - это ОЗУ результатов и параметров. Определяем поля в ОЗУ, сколько битов под длительность пересчета, сколько под флаги, сколько под результат.
К нему счетчик адресов и АЛУ, которое вычитает код до нуля, а по нулю - перезагружается...
И крутим адреса по "кругу". А "круг" - это не более, чем 15M/2,5M или даже 15М/50К, т.е. там получится вполне достаточно тактов.
Делаем простой механизм, который считывает результат, вычитает 1 и записывает результат обратно в память. А при достижении 0 сигнал идет на триггер, соотв. номеру канала и его переключает в инверсное...
Далее остается только занести данные о периоде в ОЗУ и прорва таймеров начнет считать...
У меня в "Кратком Курсе" нечто подобное описано в главе о многопоточности...
Dmitriyspb
Цитата(iosifk @ Mar 18 2014, 14:14) *
На самом деле есть и более простой вариант...


Я бы его назвал скорее АЛЬТЕРНАТИВНЫЙ вариант rolleyes.gif

P.S. Интересный способ
Zerg1
Вот так не проще?

CODE

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.std_logic_arith.all;
USE ieee.std_logic_unsigned.all;
use IEEE.NUMERIC_STD.ALL;

entity main is
GENERIC(
count_width : INTEGER := 8
);

Port ( clk_in : in STD_LOGIC;
f15_1 : in STD_LOGIC_VECTOR(4 DOWNTO 0);
fm1 : out STD_LOGIC);
end main;

architecture Behavioral of main is

signal count : STD_LOGIC_VECTOR(count_width-1 DOWNTO 0) := CONV_STD_LOGIC_VECTOR(0, count_width);
signal temp_clk_out : STD_LOGIC := '0';

begin

p1: process(clk_in, count)
begin
if rising_edge(clk_in) then
if f15_1 = CONV_STD_LOGIC_VECTOR(0, 5) then
temp_clk_out <= clk_in;
else
if count /= (f15_1-1) then
count <= count + '1';
else
count <= CONV_STD_LOGIC_VECTOR(0, count_width);
end if;

if count = CONV_STD_LOGIC_VECTOR(1, count_width) then
temp_clk_out <= '1';
else
temp_clk_out <= '0';
end if;
end if;
end if;
end process;

fm1 <= temp_clk_out;

end Behavioral;
gethan
Цитата(Zerg1 @ Mar 19 2014, 13:01) *
Вот так не проще?

CODE

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.std_logic_arith.all;
USE ieee.std_logic_unsigned.all;
use IEEE.NUMERIC_STD.ALL;

entity main is
GENERIC(
count_width : INTEGER := 8
);

Port ( clk_in : in STD_LOGIC;
f15_1 : in STD_LOGIC_VECTOR(4 DOWNTO 0);
fm1 : out STD_LOGIC);
end main;

architecture Behavioral of main is

signal count : STD_LOGIC_VECTOR(count_width-1 DOWNTO 0) := CONV_STD_LOGIC_VECTOR(0, count_width);
signal temp_clk_out : STD_LOGIC := '0';

begin

p1: process(clk_in, count)
begin
if rising_edge(clk_in) then
if f15_1 = CONV_STD_LOGIC_VECTOR(0, 5) then
temp_clk_out <= clk_in;
else
if count /= (f15_1-1) then
count <= count + '1';
else
count <= CONV_STD_LOGIC_VECTOR(0, count_width);
end if;

if count = CONV_STD_LOGIC_VECTOR(1, count_width) then
temp_clk_out <= '1';
else
temp_clk_out <= '0';
end if;
end if;
end if;
end process;

fm1 <= temp_clk_out;

end Behavioral;

не работает почему-то((((
Zerg1
У меня вот что рисует:
gethan
Цитата(Zerg1 @ Mar 19 2014, 21:51) *
У меня вот что рисует:

Немножко не так: при f15_1=6 получается,что 5 периодов clock_in fm1 принимает значение 0 и всего лишь один период clock_ina. А нужно, чтобы скважность была 50%. 3 периода clock_ina fm1 должно принимать значение '1' и 3 периода значение '0'. Может появится новое решение? rolleyes.gif
Спасибо за советы))
Zerg1
Тогда вот так
CODE

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.std_logic_arith.all;
USE ieee.std_logic_unsigned.all;
use IEEE.NUMERIC_STD.ALL;

entity main is
GENERIC(
count_width : INTEGER := 8
);

Port ( clk_in : in STD_LOGIC;
wr_fm15_1 : in STD_LOGIC;
fm15_1 : in STD_LOGIC_VECTOR(4 DOWNTO 0);
fm1 : out STD_LOGIC);
end main;

architecture Behavioral of main is

signal count : STD_LOGIC_VECTOR(count_width-1 DOWNTO 0) := CONV_STD_LOGIC_VECTOR(0, count_width);
signal temp_clk_out : STD_LOGIC := '0';
signal temp_fm15_1 : STD_LOGIC_VECTOR(4 DOWNTO 0);

begin

p1 : process(wr_fm15_1, count)
begin
if rising_edge(wr_fm15_1) then
temp_fm15_1(4 DOWNTO 0) <= '0' & fm15_1(4 downto 1);
end if;
end process;


p2 : process(clk_in, count)
begin
if rising_edge(clk_in) then
case conv_integer(temp_fm15_1) is
when 0 => temp_clk_out <= clk_in;
when 1 => temp_clk_out <= not temp_clk_out;
when others =>
if count /= (temp_fm15_1-1) then
count <= count + '1';
else
count <= CONV_STD_LOGIC_VECTOR(0, count_width);
end if;
END CASE;
if count = CONV_STD_LOGIC_VECTOR(1, count_width) then
temp_clk_out <= not temp_clk_out;
end if;
end if;
end process;

fm1 <= temp_clk_out;

end Behavioral;


Добавился еще один сигнал "wr_fm15_1" по которому происходит смена коэффициента деления.

Вот результат:
gethan
Цитата(gethan @ Mar 17 2014, 19:25) *
Всем доброго времени суток!
Помогите разобраться с оператором case и делителем частоты. Решил сделать делитель частоты,но такой,чтобы можно было изменять частоту при изменении некоторого 5 разрядного числа, назовем его fm1.

Может быть кому-то покажется странным, но вот мое творение для создания меандра:
нужно сделать так, чтобы при разных значениях fm1 выбирались разные значения переменной f15_1. Потом исходя из этого через выбранное количество отсчетов фронтов f50k формируются пички, и по ним в следующем процессе делается меандр.
CODE
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 получается вот такая картина(.

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

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

Может кто-нибудь поможет отыскать ошибку и понять почему именно так не работает?) Пожалуйста))))
Dmitriyspb
Цитата(gethan @ Mar 20 2014, 21:22) *
Может кто-нибудь поможет отыскать ошибку и понять почему именно так не работает?) Пожалуйста))))


Запускайте Modelsim и смотрите smile3046.gif
gethan
Написал вот такой код: там два процесса. Сначала делаем один меандр, потом по второму формируем другой.

CODE

frequancy8khz: process( f2_5) --частота f2_5 ранее сформированная частота из тактовой
variable f8k: integer range 0 to 19 := 0;
begin
IF clr ='1' THEN
f8k:=0;
ELSIF rising_edge( f2_5 ) THEN
IF f8k=0 THEN
f8k:=19;
else
f8k:=f8k-1;
end if;

IF f8k>9 THEN
freq8k<='1';

else
freq8k<='0';
end if;
end if;

end process;

f8k<=freq8k;

frequency15Hz_10: process (f8k)
variable f15_10: integer range 0 to 11 :=0;
BEGIN
if clr ='1' THEN
f15_10:=0;
ELSIF rising_edge( f8k ) THEN
if f15_10=0 THEN
f15_10:=11;
else
f15_10:=f15_10-1;

end if;

IF f15_10>6 THEN
freq15_10<='1';
else
freq15_10<='0';

end if;
end if;

END PROCESS;


Два одинаковых процесса,НО!!!!
почему-то в одном (в первом процессе для частоты f8k) количество rising_edge(f2_5) считается правильно, т.е. по 10 на нулевое значение и на единичное значение сигнала freq8k. А во втором процессе почему то считает ровно в 2 раза меньше, чем указано.
Как так? Помогите понять,почему так!?)
На рисунке сигнал dfm1 - это переназванный сигнал f15_10, который должен отсчитывать по 6 rising_edge сигнала f256out1(f8k). Но он отсчитывает только по 3, в два раза меньше,чем надо.(( В чем дело,не пойму! Помогите,пожалуйста!;)
sazh
Цитата(gethan @ Mar 23 2014, 16:09) *
Написал вот такой код: там два процесса. Сначала делаем один меандр, потом по второму формируем другой.

Посмотрите в RTL что у Вас получилось.
Если б выложили файлы с тестбенчем, может кто и проанализировал. Как два взаимосвязанных счетчика реализовать.
Ох уж этот VHDL. Пора наверное что то подправить в консерватории.
Maverick
Цитата(sazh @ Mar 24 2014, 05:31) *
Ох уж этот VHDL. Пора наверное что то подправить в консерватории.

Старая поговорка гласит - "На вкус и цвет товарищей нет"
смысл затевать очередной халивар?
sazh
Цитата(Maverick @ Mar 24 2014, 07:07) *
Старая поговорка гласит - "На вкус и цвет товарищей нет"
смысл затевать очередной халивар?



Это не халивар. Это Глас вопиющего в пустыне.
И на меня не надо обращать внимание. Хотите уважительного отношения к своему языку. Пропагандируйте.
Учите. Подсказывайте. Вопрошающему.
Еще немного и VHDL из действительно качественного языка описания аппаратуры превратится в птичий язык.
(Это когда люди не понимают, что делают, используя тот или иной инструмент)
Maverick
Цитата(sazh @ Mar 24 2014, 06:29) *
Это не халивар. Это Глас вопиющего в пустыне.
...Хотите уважительного отношения к своему языку. Пропагандируйте.

пропаганды я не вел, не веду и не буду вести. Я не вижу в этом смысла...
andrew_b
Цитата(gethan @ Mar 23 2014, 17:09) *
Написал вот такой код
Извините, но читать ваш адски отформатированный код нет никакого желания. Если вас это форматирование устраивает, то ради бога. Но если вы хотите, чтобы вам помогли, начните с элементарного: сделайте код выглядящим нормально. Как говорится, "макет должен быть красивым, а не соответствовать местности".
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.