Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: генератор ПСП (m-последовательности) на XC9536
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Работаем с ПЛИС, области применения, выбор
8-)
Доброе время суток. Помогите чайнику решить проблему, pls.
Никак не могу понять в чём проблема. Провожу моделирование в modelsim - всё работает. Прошиваю XC9536 - не работает. Вот код на vhdl:

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 instantiating
---- any Xilinx primitives in this code.
library UNISIM;
use UNISIM.VComponents.all;

entity counter is
Port ( CLK : in std_logic;
DOUT : out std_logic_vector(7 downto 0));
end counter;

architecture Behavioral of counter is
signal regA: std_logic_vector(8 downto 0);
signal flag: std_logic;
begin

process (CLK)
begin

if (CLK'event and CLK='1') then

if flag = '1' then
regA <= (regA(4) xor regA(0)) & regA(8 downto 1);

DOUT(0) <= regA(0);
DOUT(1) <= regA(1);
DOUT(2) <= regA(2);
DOUT(3) <= regA(3);
DOUT(4) <= regA(4);
DOUT(5) <= regA(5);
DOUT(6) <= regA(8);
DOUT(7) <= regA(7);
else
flag <= '1';
regA(0) <= '1';
regA(1) <= '1';
regA(2) <= '1';
regA(3) <= '1';
regA(4) <= '1';
regA(5) <= '1';
regA(6) <= '1';
regA(7) <= '1';
regA(8) <= '1';
end if;
end if;
end process;

end Behavioral;

После прошивания микросхемы все сигналы DOUT имеют низкий уровень.
Laptop
вполне логично, у тебя ведь не определены значения регистров по умолчанию, надо ввести цепь начального сброса и не мучаться с flag и конечно присвоение вроде DOUT(0) <= regA(0) необходимо вынести за процесс иначе получишь задержку в один такт.
впрочем и шины лучше присваивать сразу без индексов DOUT <= regA;
в общем причина в том что у тебя по включению сразу flag = 1, а regA = "000000000" smile.gif
удачи в освоениииsmile.gif
sazh
Никакого ресета (в глобальном смысле) для работоспособности счетчика не надо.
Ясно дело, не корректна схемная реализация.
VHDL не знаю. Работаю в Quartuse
Выдается ошибка при синтезе:
Error (10481): VHDL Use Clause error at counter.vhd(9): design library "UNISIM" does not contain primary unit "VComponents"
Сделал так:
--library UNISIM;
--use UNISIM.VComponents.all;
Получил предупреждение:
Warning: Reduced register "flag" with stuck data_in port to stuck value VCC
По включению питания триггер flag устанавливается в ноль. Только вот на d входе триггера 1, по этому при включенной опции по умолчанию
Power-up don’t care синтезатор игнорирует этот триггер (считает его за константу), выбрасывает часть схемы и благодаря этому на выходе все нули.
Если отключить минимизацию Power-up don’t care, все работает, как? Вам виднее.
Резюме. Схема некорректна в части формирования сигнала триггером flag.
Victor®
Странный какой-то у Вас генератор M-последовательности...
А где регистр сдвига? Или это какая-то "необычная" реализация?
И еще, совет - используйте отдельный сброс

to sazh по поводу
--library UNISIM;
--use UNISIM.VComponents.all;
это библиотеки под XILINX :-), а Вы работаете в QUARTUS
vitus_strom
Каким софтом собираете проект, посмотрите к нему сервис пак, потому как 7 версия софта работает не корректно с ЦПЛД...
:-)
to Laptop: Тогда вопрос такой: Почему если убрать строчку

regA <= (regA(4) xor regA(0)) & regA(8 downto 1);

то регистр regA инициализируется (regA="111111111") ?

to Victor®: так строчка

regA <= (regA(4) xor regA(0)) & regA(8 downto 1);

и выполняет сдвиг всех значений регистра. Таким образом определяются Shift Registers в Code Templates (WebPack ISE 4.1).

P.S. Спасибо за ваши ответы.
sazh
To Victor
//И еще, совет - используйте отдельный сброс//
Хочу еще раз акцентировать. В нормальной схеме (если не нужны конкретные установки регистров в нужный момент времени) отдельный сброс только вреден. (Меня всегда умиляла кнопочка сброс на макетках с микроконтроллерами). В данном случае сброс на тригггер flag действительно сделает эту схему независимой от установок синтезатора. И больше ничего. Как была схема некорректной так и останется. Внешний сброс источник всех сбоев. И в данной схеме он не нужен. По дешифрации состояния все нули загружать в регистр константу все 1.
Victor®
Цитата(:-) @ Dec 16 2005, 13:51) *
to Victor®: так строчка
regA <= (regA(4) xor regA(0)) & regA(8 downto 1);
и выполняет сдвиг всех значений регистра. Таким образом определяются Shift Registers в Code Templates (WebPack ISE 4.1).


Блин, спутал AHDL и VHDL операторы wacko.gif
vitus_strom
Предлагаю модифицировать код следующим образом:

process (CLK)
begin

if (CLK'event and CLK='1') then

if flag = '1' then
flag <= flag;
regA <= (regA(4) xor regA(0)) & regA(8 downto 1);
DOUT(7 downto 0) <= regA(7) & regA(8) & regA(5 downto 0);
else
flag <= '1';
regA(8 downto 0) <= (others => '1');
DOUT(7 downto 0) <= DOUT(7 downto 0); --Например
end if;
end if;
end process;

end Behavioral;

писать в одной ветке сигнал и не писать его в другой значит оставлять ее на откуп синтезатору, а что он там насинтезит одному разработчику известно, ну еще может что то про Это в стандарте написано.
Но проой бывают такие неприятности что и найти сложно....
Victor®
Цитата(sazh @ Dec 16 2005, 14:21) *
To Victor
//И еще, совет - используйте отдельный сброс//
Хочу еще раз акцентировать. В нормальной схеме (если не нужны конкретные установки регистров в нужный момент времени) отдельный сброс только вреден. (Меня всегда умиляла кнопочка сброс на макетках с микроконтроллерами). В данном случае сброс на тригггер flag действительно сделает эту схему независимой от установок синтезатора. И больше ничего. Как была схема некорректной так и останется. Внешний сброс источник всех сбоев. И в данной схеме он не нужен. По дешифрации состояния все нули загружать в регистр константу все 1.


В СИСТЕМЕ должет быть сброс\инициализация для приведение в нормальное состояние после сбоя. Только не убеждайте меня, что несбоящих систем не бывает smile.gif Ну не будете же Вы ездить, например, на необслуживаемый объект, чтобы питание перебросить... А watchdog - поможет. И все узлы, входящие в систему должны иметь возможность сброс\инициализации без обесточивания...
И еще не согласен, что внешний сброс - источник всех сбоев, его надо правильно проектировать....
disel
Я когда-то делал универсальный генератор m-последовательностей следующим образом:

library IEEE;
use IEEE.STD_LOGIC_1164.all;
use IEEE.STD_LOGIC_ARITH.all;


entity GaloisPRNG is
generic(
PN : std_logic_vector := O"325"
);
port(
CLK : in STD_LOGIC;
PRN : in STD_LOGIC;
Q : out STD_LOGIC
);
end GaloisPRNG;


architecture rtl of GaloisPRNG is

function calcN (P : std_logic_vector) return natural is
variable tN : natural;
begin
tN := 0;
for i in P'Length-1 downto 0 loop
if P(i) = '1' then
tN := i;
end if;
end loop;
return P'Length - tN - 1;
end;

constant N : natural := calcN(PN);
signal A, X : STD_LOGIC_VECTOR(N-1 downto 0);
constant P : STD_LOGIC_VECTOR (N downto 0) := PN (PN'Length-N-1 to PN'Length-1);

begin

A(N-1) <= X(0);

process ( X )
begin
for i in N-2 downto 0 loop
if P(i+1) = '0' then
A(i) <= X(i+1);
elsif P(i+1) = '1' then
A(i) <= X(i+1) xor X(0);
end if;
end loop;
end process;

process ( CLK, PRN )
begin
if PRN = '0' then
X <= ( others => '1' );
elsif CLK'event and CLK = '1' then
X <= A;
end if;
end process;

Q <= X(0);

end rtl;

Задаешь нужный полином (PN) и получаешь желаемый генератор.
8-)
Спасибо всем за ответы. Проблема, наконец, решилась. Всё дело было в начальной инициализации. Поменял её на другой вариант и всё заработало. Вот такие чудеса. Вот что получилось, если кому интересно:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity counter is
Port ( CLK : in std_logic;
DOUT : inout std_logic_vector(7 downto 0));
end counter;

architecture Behavioral of counter is
signal regA: std_logic_vector(8 downto 0);
signal count : integer range 0 to 2;
begin

process (CLK)
begin
if (CLK'event and CLK='1') then
if count = 2 then--причём если указать "count=1", то ничего не заработает
regA <= (regA(4) xor regA(0)) & regA(8 downto 1);
-- DOUT(7 downto 0) <= not regA(7 downto 0);
DOUT <= ( not regA(2) ) & DOUT(7 downto 1);
else--теперь здесь инициализация. Хотя выглядит грубовато...
count <= count + 1;
regA(8 downto 0) <= (others => '1');
DOUT(7 downto 0) <= (others => '1');
end if;
end if;
end process;

end Behavioral;

Вот только интересно: почему же не работает при "count=1" ...
evgeniy_s
Проверил Ваш код на Aldec'е - никаких проблем не обнаружил, всё моделируется и при count=1, и при count=2. Вы на какой системе моделируете, если опять в этом глючном моделсиме - то дело, скорее всего, в нём?
maksya
На лицо явные признаки классического последовательного программирования. Отрекитесь Вы от него, ну хотя бы на время проектирования на VHDL. Забудьте про флаги, вспомните про триггеры! Теперь по порядку...

Насчет инициализации содержимого регистра, т.е. о начальном значении, которое по сути и определяет M-последовательность: Триггер есть сущность, способная находиться в одном из допустимых устойчивых состояний (в простейшем случае 0 или 1). Стало быть необходимо задавать начальное значение самостоятельно (входы асинхронной установки/сброса) или надеять на волю всевышних электротехнических сил. Вот мне интересно, в каком состоянии будет ваш регистр после включения питания? В testbench'е при работе с ModelSim'ом небось задавали начальное значение. А кто за вас будет этим заниматься при реальной работе?..

Вы же аппаратуру проектируете. Так и опирайтесь на неё при разработке. А ежели фантазии не хватает представить во что выльется Ваш код, то используйте RTL Viewer.

Вот Я тут накидал ваш ПСП за минут 5:

Код

LIBRARY IEEE;
    USE IEEE.std_logic_1164.all;

ENTITY psp IS
PORT(       clk : in std_logic;
          reset : in std_logic;
     init_value : in std_logic_vector(8 downto 0); -- начальное значение; задается вне блока
           dout : out std_logic);
END psp;

ARCHITECTURE rus OF psp IS

   SIGNAL reg: std_logic_vector(8 downto 0); -- это, собственно сдвигающий регистр

BEGIN

process(clk, reset, init_value)
begin
   if reset = '1' then
      reg <= init_value;
   elsif rising_edge(clk) then
      reg <= (reg(4) xor reg(0)) & reg(8 downto 1);
   end if;
end process;

dout <= reg(0);

END rus;


Еще по поводу counter'а хотел сказать. Пустяк конечно, но в каком, извините за выражение, месте вы там счетчик увидели? Теория ПСП, основанная на M-последовательностях, реализуется с помощью сдвиговых регистров, а не счетчиков. Счетчики конечно строятся из тех же триггеров, но назначение этих цифровых устройств различны. А иначе стали бы давать им различные имена?

Чуть не забыл, если Я правильно помню курс "Методы защиты информации", то генератор ПСП на каждом такте (шаге алгоритма для программиста будет, наверное, понятней) выдает 1 бит. Если же выдается число, то такая штука носит название - генератор псевдослучайных чисел.

P.S.: И поудаляй свои ники-смайлики.
sazh
Действительно, интересно. Обсудили Вашу проблему со всех сторон.
Вам даже выкатили готовую мегафункцию формирователя псевдослучайной последовательности.
И что у вас на выходе. Неужели у вас нет под рукой RTL просмотрщика, чтобы посмотреть что Вы напроектировали. Ведь наверняка получили кучу замечаний. И не устранили.
Основа Вашей схемы – один регистр и элементы XOR. Инициализация может быть только двумя способами
Или с помощью внешнего сигнала установки начального значения на этом регистре, или с помощью дешифрации состояния регистра по включению и синхронной загрузки в регистр нужного начального значения. Если хотите защититься от сбоев, продешифрируйте запрещенные состояния вашего полинома и грузите по сбою нужное состояние в регистр. Хотите простробировать полученную шину, поставьте на выходе просто регистр.
Что касается схемотехники, нужно с умом использовать схемные решения, которые используются в ограниченном интервале времени и всего один раз (Например по включению питания выработать интервал определенной длительности ( то что Вы называете инициализацией)) и потом на выходе всегда какой то неизменный уровень. Без установок синтезатора не обойтись. По умолчанию такие куски схем игнорируются синтезатором. А значит и выбрасывается та часть схемы, которая управляется этим триггером (константной) или в Вашем случае счетчиком. Вы же уже второй раз напоролись на это. "count=1".
Что касается элементов BIDIR. Они могут использоваться только совместно с шинными формирователями по третьему состоянию. Хотя вообще не понятно, зачем здесь двунаправленная шина.
8-)
to evgeniy_s:
Моделировал я действительно в ModelSim. И в нём-то как раз всё работает и при count=1, и при count=2. А вот когда прошивал XC9536, то ПЛИС правильно работала только при count=2 (или большем значении).

to maksya:
Полностью согласен с тем, что необходимо задавать начальное значение регистров (триггеров). В данном случае у меня стояла задача проинициализировать регистр без подачи в ПЛИС внешних сигналов. Кстати осмелюсь заявить, что при включении питания все триггеры будут иметь значение '0'. По крайней мере при проектировании ПЛИС XC9536 в WebPack ISE 4.1. Согласен с тем, что это спорное утверждение, но у меня это происходит именно так - проверял несколько раз. И в ModelSim не задавал начальные значения.
Счетчик здесь используется НЕ ДЛЯ ГЕНЕРАЦИИ ПСП, а для того чтобы правильно выполнялась начальная инициализация. В исходном варианте она не выполнялась правильно. И второй мой вопрос состоял как раз в том, почему исходный вариант не работает (насколько я понимаю варинт когда "count=1" - эквивалентен исходному). А теперь и ещё один появился: Насколько корректно проводить инициализацию триггеров без подачи в ПЛИС внешних сигналов?

P.S.
улыбка - лучшее лекарство от всего!
От улыбки хмурый день светлей.
8-)
Пока писал ответ - sazh всё подробно объяснил. Замечу только, что использовал BIDIR в "DOUT : inout std_logic_vector(7 downto 0)" потому, что этот регистр DOUT используется как для чтения так и для записи (" DOUT <= ( not regA(2) ) & DOUT(7 downto 1);").

Еще раз хочу поблагодарить всех за ценные советы и примеры.
Laptop
Кстати насчет inout, лучше завести отдельный сигнал, иначе можешь получить чтение с пинов и сопутствующие глюки.
Просадишь выходной сигнал нагрузкой и получишь при считывании не то что ожидал...
Laptop
Цитата(:-) @ Dec 16 2005, 12:51) *
to Laptop: Тогда вопрос такой: Почему если убрать строчку

regA <= (regA(4) xor regA(0)) & regA(8 downto 1);

то регистр regA инициализируется (regA="111111111") ?

Тут ведь все от синтезатора зависит, он может использовать разные элементы для синтеза различных конструкций. А разные элементы могут иметь различное начальное состояние. Тем более гарантии что начальное состояние по включении будет именно такое никто не даст. Если нужна гарантия, то ставь сброс по питанию, причем лучше с формирователем длительности, стандартные супервизоры есть со временем около 300 мс.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.