Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: ПЛИС непонятно работает, хотя в симуляторе всё как надо
Форум разработчиков электроники ELECTRONIX.ru > Программируемая логика ПЛИС (FPGA,CPLD, PLD) > Работаем с ПЛИС, области применения, выбор
enzaime
В общем штука такая в процессе изучения ПЛИС заметил вот какую вещь: по мере уменьшения емкости чипа (total logic elements) начинаются всякие странные вещи. Например, там где должна быть 1 там 0 и наоборот.
Я сделал тестовый проект, в котором виден этот эффект. Использую плату CoreEP4CE10 c ПЛИС EP4CE10F17C8 и тактовым генератором на 50 МГц

Реализуется следующее:
n параллельных процессов в которых m раз выполняется * и /

проц 1: *,/
проц 2: *,/ *,/
проц 3: *,/ *,/ *,/ *,/
проц 4: *,/ *,/ *,/ *,/ *,/
проц 5: *,/ *,/ *,/ *,/ *,/ *,/
и т.д.

каждая ветка описывается так:

Код
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_misc.all;
entity vetka is    
     generic(n:natural:= 10);
     port(
     clk : in STD_LOGIC;
     a: in std_logic_vector(15 downto 0);  
     r:out std_logic;
     chisl:out std_logic
         );
end vetka;

--}} End of automatically maintained section

architecture arch of vetka is

function vetv (a: std_logic_vector) return std_logic_vector is
variable c: std_logic_vector(29 downto 0);    
begin
  c := x"000"&"00"&a;
  for i in 1 to n loop    
      c := conv_std_logic_vector(conv_integer©*conv_integer©,30);
      c := conv_std_logic_vector(conv_integer©/conv_integer(c(7 downto 0)),30);  
  end loop;
  return c;
end;    
function merg (d: std_logic_vector) return std_logic is
variable c: std_logic:='0';    
begin

  for i in 0 to 29 loop    
      c := c or d(i);
  end loop;
  return c;
end;
signal d:std_logic_vector(29 downto 0):=x"0000000"&"00";
signal st:std_logic_vector(3 downto 0):=x"0";        

begin                    
    r <= or_reduce(d);
    chisl <= merg(d);
    process(clk)
    begin        
        if(rising_edge(clk)) then    
            
            if(st = x"0") then
                d <= vetv(a);
                st <= x"1";
            end if;
            
            if(st = x"1") then
                st <= x"0";
                d <= conv_std_logic_vector(0,30);
            end if;               
            
        end if;
    end process;

     -- enter your statements here --

end arch;

функция or-reduce(d) регистрирует изменение сигнала d, изменяя своё значение на противоположное при каждом изменении сигнала d.

далее генерируются n процессов длины m

Код
library IEEE;
use IEEE.STD_LOGIC_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
entity gabage is
     generic(m:natural:=5);
     port(
          clk : in STD_LOGIC;  
          etalon: out std_logic;    
         a: in std_logic_vector(15 downto 0);
         vetv : out STD_LOGIC_vector(m downto 0);
         rez: out std_logic_vector(m downto 0);
         alls: out std_logic
         );
end gabage;

--}} End of automatically maintained section

architecture arch of gabage is
signal etst:std_logic_vector(3 downto 0):=x"0";      
signal et:std_logic:='0';
signal vrez:std_logic_vector(m downto 0);
component vetka is    
     generic(n:natural:= 10);
     port(
     clk : in STD_LOGIC;
     a: in std_logic_vector(15 downto 0);  
     r:out std_logic;
     chisl:out std_logic
         );
end component;    

function merg (d: std_logic_vector) return std_logic is
variable c: std_logic:='0';    
begin
  c := d(0);
  for i in 1 to m loop    
      c := c and d(i);
  end loop;
  return c;
end;
begin                    
    
    vetv <= vrez;
    etalon <= et;  
    alls <= merg(vrez);
G0: for i in 0 to m generate
    k1:vetka  
        generic map(n => i)
        port map(
        clk => clk,      
        a => a,
        r => vrez(i),
        chisl => rez(i)
        );
end generate;
    process(clk)
    begin        
        if(rising_edge(clk)) then              
            
            if(etst = x"0") then
                et <= '1';
                etst <= x"1";
            end if;            
            
            if(etst = x"1") then
                et <= '0';
                etst <= x"0";
            end if;    
            
        end if;
    end process;
    

     -- enter your statements here --

end arch;

В общем сначала я думал увидеть задержку выполнения операций для каждого процесса, сравнивая r и etalon увидеть какое-то отставание на каждой ветви от эталона (etalon).
Сигнал alls объединение сигналов готовности через функцию логическое И

Да и главный файл:
Нажмите для просмотра прикрепленного файла

Выходная частота pll 200 МГц входная 50 МГц

Вот так это дело работает в симуляторе modelsim (gate level), например, для 8 веток

Нажмите для просмотра прикрепленного файла
Смотрел работу в чипе с помощью логического анализатора, работающего на частоте 200 МГц (частота выходных сигналов 100 МГц)

Если генерировать для 4 ветвей, то всё работает как надо ( правда каких-то задержек я не увидел, возможно, неправильно смотрел)
отчёт компилятора
Нажмите для просмотра прикрепленного файла
Вот что отображает логический анализатор
Нажмите для просмотра прикрепленного файла
Но если сгенерировать для 8 ветвей, то что-то непонятное происходит картинка сильно отличается от того, что в симуляторе. Сигналы готовности n должны быть равномерными с частотой 100 МГЦ, но по факту бывает так что высокий уровень несколько тактов не сменяется низким, хотя в коде нигде такого не прописано
Нажмите для просмотра прикрепленного файла
отчёт компилятора
Нажмите для просмотра прикрепленного файла
Я как-то не понимаю почему это происходит. Тоесть понятно что я что-то делаю не так, но вот что именно не понимаю
Может кто сталкивался с чем-то подобным?
Вот ссылка с проектом на яндекс диске https://yadi.sk/d/FEwjHm0G3EwbyD
andrew_b
Извините, я не буду смотреть проект.
Два вопроса:
1. Вы как-то констрейните ваш проект?
2. Что значит "функция or-reduce(d) регистрирует изменение сигнала d, изменяя своё значение на противоположное при каждом изменении сигнала d"? Как вы это делаете? Я всю жизнь думал, что триггер описать функцией нельзя.
litv
"Я как-то не понимаю почему это происходит. Тоесть понятно что я что-то делаю не так, но вот что именно не понимаю
Может кто сталкивался с чем-то подобным? a14.gif "
Вы из программистов что-ли?
Поменьше выкладывайте своих странных исходников - они нам не нужны.
Дело в Ваших очень слабых знаниях по ПЛИС на данный момент.

1)Начните с простых блоков.
Douglas_Smith HDL CHIP design.
Счетчики сумматоры. Без всяких for.
2)Научитесь что бы они работали сихронно.
3)Моделирование <> это не проект ПЛИС.
4)Научитесь писать временные ограничения на трассировку ПЛИС.
5)Научитесь выжимать из них максимальную тактовую частоту для ПЛИС.

Только потом приходите на форум и рассказывайте что ПЛИС оказывается не работает(ну у меня такое на первом курсе было).
AVR
Боюсь не смогу помочь с такой проблемой новичка, но абсолютно уверяю: ПЛИС работает предсказуемо при любом объеме логики, если конечно задать для проекта верные констрейны.
andrewkrot
Попробуйте уменьшить частоту в 10 раз и сравните результат
enzaime
Цитата
Только потом приходите на форум и рассказывайте что ПЛИС оказывается не работает(ну у меня такое на первом курсе было).

Да я ПЛИС не обвиняю) Знаю, что сам виноват) Да и где просить совета как не в сообществе у людей, которые шарят?
Цитата
1)Начните с простых блоков.
Douglas_Smith HDL CHIP design.
Счетчики сумматоры. Без всяких for.

Насчёт for: почему нельзя применять, если это синтезируемая конструкция языка? (как ,например, использование типа real - несинтезируемой конструкции, используемого для симуляции ) И чего это тогда без циклов писать? Писать что-то вроде машины состояний? Это же с ума сойти можно и вообще крыша поехать может
Цитата
3)Моделирование <> это не проект ПЛИС.
А как же тогда быть, если, например, пишешь прошивку, а ПЛИС под рукой нет, как тогда отлаживать?

Цитата
Извините, я не буду смотреть проект.
Два вопроса:
1. Вы как-то констрейните ваш проект?
2. Что значит "функция or-reduce(d) регистрирует изменение сигнала d, изменяя своё значение на противоположное при каждом изменении сигнала d"? Как вы это делаете? Я всю жизнь думал, что триггер описать функцией нельзя.

Я и не настаивал, на просмотре проекта)
Констрейнить значит задавать временные ограничения? Нет, не задаю(
А почему они не учитываются как-то там автоматически? Я ведь задаю, что частота 200 МГц (в модуле pll), да и в процессе разводки мне никаких ошибок не выдаёт. По типу: так мол и так для такой частоты проект развести не удаётся. Да и косвенно я указал ограничение, задав частоту 200 МГц, т.е. я хочу чтобы в каждом процессе по восходящему фронту операции выполнялись не менее, чем за 5 нс, а тут ещё какие-то констрейны прописывать надо? Моя не понимат(
Насчёт второго: да фиг знает, это функция из библиотеки ieee.std_logic_misc.all; на форуме stackoverflow http://stackoverflow.com/questions/2897338...rray-of-vectors тут чувак, наверно умный, чёт объясняет про неё
Цитата
Попробуйте уменьшить частоту в 10 раз и сравните результат

Да я интуитивно понимаю что такое может быть, если операция не успевает выполняться за отведенное время, поэтому уменьшение частоты скорее всего устранит проблему. Нет щас возможности проверить( Но почему мне среда не бросает в лицо никаких ошибок? По типу: так мол 200 МГц слишком много для реализации такой логики. А наоборот всё компилирует и файл прошивки создаётся и типа заливай и всё будет ок, а на деле шляпа какая-то выходит(
lexx
Констрейнить - значит выбрать порт тактового сигнала и четко задать его частотут (период и скважность), а также описать задержки по всем in/out портам.
Если частота четко не указано, то что-то на выходе может и получится, но это ерунда. Симуляция будет работать в любом случае, ей все-равно на частоты, поскольку фукция идеальна с точки зрения задержек.
Timmy
Цитата(enzaime @ Mar 3 2017, 23:30) *
Да я интуитивно понимаю что такое может быть, если операция не успевает выполняться за отведенное время, поэтому уменьшение частоты скорее всего устранит проблему. Нет щас возможности проверить( Но почему мне среда не бросает в лицо никаких ошибок? По типу: так мол 200 МГц слишком много для реализации такой логики. А наоборот всё компилирует и файл прошивки создаётся и типа заливай и всё будет ок, а на деле шляпа какая-то выходит(

Среда "бросает в лицо" предупреждение о неполностью оконстрейненом проекте. И ещё, вероятно, о неоконтрейненом клоке. Но вы же не обращаете внимания на подобные мелочиsm.gif.
andrew_b
Цитата(enzaime @ Mar 3 2017, 23:30) *
Насчёт второго: да фиг знает, это функция из библиотеки ieee.std_logic_misc.all; на форуме stackoverflow http://stackoverflow.com/questions/2897338...rray-of-vectors тут чувак, наверно умный, чёт объясняет про неё
Ну так or_reduce -- это простое многовходовое ИЛИ, а совсем не то, что вы написали:
Цитата
функция or-reduce(d) регистрирует изменение сигнала d, изменяя своё значение на противоположное при каждом изменении сигнала d
Golikov A.
Цитата
Насчёт for: почему нельзя применять, если это синтезируемая конструкция языка? (как ,например, использование типа real - несинтезируемой конструкции, используемого для симуляции ) И чего это тогда без циклов писать? Писать что-то вроде машины состояний? Это же с ума сойти можно и вообще крыша поехать может


это синтезируемая, но не так как вам кажется конструкцияsm.gif
Ее надо воспринимать как сокращенная запись. То есть он равносилен просто записи N раз друг за другом тела фора. А дальше так как все происходит одновременно фор просто превращается в больщущую параллельную конструкцию.

И да, чтобы создать цикл в "програмистском" смысле надо делать подобие конечного автомата, хоть и простого, но надо...

Цитата
А почему они не учитываются как-то там автоматически? Я ведь задаю, что частота 200 МГц (в модуле pll)

А откуда плис знает, что вы знаетеsm.gif? PLL это штука которая задает умножитель, делитель и следит за опорной частотой, но знать эту частоту PLL не надо. Когда вы его вставляли вы ему сообщили клок, но вы сообщили его не PLL модулю, а визарду для расчета параметров. Так что блок просто задал коэффициенты и пошел работать, ему в целом все равно сколько вы на вход потом подадите. Он сделает кратный выход и все.
Теперь надо частоту сообщить еще и анализатору времянок, чтобы он ее кратно распространил на проект. Для этого надо задать констраин с периодом входного клока. А дальше в 80% случаев действительно все произойдет автоматически.
Нюансы есть когда поступают внешние асинхронные сигналы, когда у вас несколько клоков, когда вам надо делать мультициклы и т.п. Но думаю вам пока хватит и просто обконстраинить входной клок.



Еще, на уровне интуиции, мне кажется что вы переоцениваете полученные возможности. Вы понимаете что время за которое сигнал доходит от одного блока до друго внутри ПЛИС все время разное? Оно сильно меняется от температуы и питания. Инструменты по созданию схемы проверяют что этот +- вкладывается в ворота клока, но не более. То есть фактически у вас разрешение задания времянок - это период клока.
Надеюсь вы это понимаете.
enzaime
Цитата
Боюсь не смогу помочь с такой проблемой новичка, но абсолютно уверяю: ПЛИС работает предсказуемо при любом объеме логики, если конечно задать для проекта верные констрейны.

А предсказуемо, значит так как в симуляции? Или предсказуемо означает с учётом большого опыта?
Как новичку понять что будет работать, а что нет?
И можно ли как-то просимулировать констрейны? В vhdl, например, есть оператор latency, нужно как-то с ним писать код, чтобы учитывать временные ограничения?
Цитата
Среда "бросает в лицо" предупреждение о неполностью оконстрейненом проекте. И ещё, вероятно, о неоконтрейненом клоке. Но вы же не обращаете внимания на подобные мелочиsm.gif.

Да действительно что-то там было про клок, но я особо внимания не обратил) Вот если бы за каждый варнинг било бы током, я бы начал суетиться и подозревать что что-то не так)
Цитата
Еще, на уровне интуиции, мне кажется что вы переоцениваете полученные возможности. Вы понимаете что время за которое сигнал доходит от одного блока до друго внутри ПЛИС все время разное? Оно сильно меняется от температуы и питания. Инструменты по созданию схемы проверяют что этот +- вкладывается в ворота клока, но не более. То есть фактически у вас разрешение задания времянок - это период клока.
Надеюсь вы это понимаете.

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

Чего так сложно-то??? sad.gif
iosifk
Цитата(enzaime @ Mar 4 2017, 12:47) *
И можно ли как-то просимулировать констрейны? В vhdl, например, есть оператор latency, нужно как-то с ним писать код, чтобы учитывать временные ограничения?

Давайте уточним про симуляцию. Вы что именно симулировали? RTL или добавляли в проект sdf-файл задержек, полученный после размещения проекта в кристалле?
enzaime
Цитата
Давайте уточним про симуляцию. Вы что именно симулировали? RTL или добавляли в проект sdf-файл задержек, полученный после размещения проекта в кристалле?

Давайте) Конечно же без всяких там sdf файлов, только RTL) Я видел, что в меню симуляции в квартусе есть 2 вида: RTL и ещё какая-то (щас посмотреть не могу). Я запускал их обе, но каких-то явных различий не заметил. А sdf файл никакой я не писал и не подключал. Как-то так
iosifk
Цитата(enzaime @ Mar 4 2017, 13:54) *
Давайте) Конечно же без всяких там sdf файлов, только RTL)

Ну так что же Вы от RTL хотите? Он же не понимает, что задержки Вам все портят, констрейнов нет, компилятор живет спойно, Вы ругаете ПЛИСы, а все остальные в недоумении...
enzaime
Цитата
Ну так что же Вы от RTL хотите? Он же не понимает, что задержки Вам все портят, констрейнов нет, компилятор живет спойно, Вы ругаете ПЛИСы, а все остальные в недоумении...

Сам знаю, что я виноват, но вот потихоньку разбираюсь)
Я вспомнил, второй вид симуляции в quartus называется modelsim gate-level simulation. Это уже симуляция почти как на устройстве? И туда надо как-то подключать sdc файл? И будет ли эта симуляция показывать отличные результаты от RTL симуляции, если sdc файл написан неверно (неправильно заданы констрейны) сейчас к сожалению нет возможности это проверить(
dvladim
Цитата(enzaime @ Mar 4 2017, 14:23) *
Сам знаю, что я виноват, но вот потихоньку разбираюсь)

У вас каша в голове. Возьмите хотя бы tutorial от Квартуса и почитайте.
Вкратце последовательность такая: вы пишете RTL код и отлаживаете его в симуляторе.
Затем добавляете временные ограничения (SDC) и синтезируете. Получаете выходной нетлист (vo в Квартусе), файл задержек (SDF) и кучу отчетов.
Можете посмотреть блок схему после синтеза или после размещения - улучшает понимание во что превратилось то, что вы написали в исходниках.
Смотрите отчеты синтеза - обратить внимание на latch, отчеты временного анализа.
Если все устраивает и нет отрицательных slack-ов то всё будет работать на железе.
Выходной нетлист с задержками можете промоделировать - это и будет соответствовать реальному поведению схемы.
PS. расширения я писал для Верилога, для ВХДЛ расширения будут другие.
Flood
Цитата(enzaime @ Mar 4 2017, 12:47) *
Чего так сложно-то??? sad.gif


Ну, сложно - понятие относительное.
В языке C, бывает, нужно выделить память перед тем как начать ей пользоваться и освободить по окончании. По сравнению с, допустим, питоном, это сложно?

ПЛИСоводство - область в целом гораздо менее развитая, чем "обычное" мейнстримовое программирование, а оттого более сложная и менее удобная для программиста. Языки кривоваты, редакторов нормальных почти нет, компиляция занимает часы и может закончиться провалом таймингов. Что ни делай с кодом - сотни варнингов, практически все тулчейны глубоко проприетарные, и т. п. Короче, хардкор.
И это в то время, когда для программистов давным-давно редактор уже чуть ли не сам пишет код, линтер подчеркивает ошибки во время написания, а компилятор переспрашивает, "а вы точно хотите использовать присваивание под if?".

Возможно, ситуация несколько сдвинется в связи с современным хайпом аппаратных ускорителей и общим ростом популярности ПЛИСов. Но достижение того уровня удобства, к которому привыкли сегодняшние программисты, в среде ПЛИСов займет еще многие годы, если вообще будет достигнуто.

Также, пресловутый рост популярности приводит к тому, что к написанию кода для ПЛИС подключается все больше людей из среды обычного процедурного программирования. Привычка писать императивный код плохо ложится на ПЛИС (точнее, никак), часто из-за непонимания принципа работы последних. Тут нужна перестройка мышления в сторону функционального программирования.

С другой стороны, старики ПЛИСоводства, пришедшие из чистой электроники и привыкшие в свое время еще к схемотехническому вводу, также часто имеют закостеневшее мышление и избегают использовать в своем коде какие-то абстракции, считая, что синтезатор не разберется и лучше избегать любых сложных конструкций. Такие люди свысока посматривают на написанный программистом код и возмущаются: "кто так пишет?", "не отсинтезируется", "откуда ситнезатору знать, что это память?", "не соберется", и т.п. А код внезапно нормально синтезируется и успешно собирается sm.gif

Так что одной правды здесь нет.
Golikov A.
На пальцах:
каждый элемент в схеме, каждое соединение создает задержечку сигнала.
Когада вы симулите RTL вы симулите идеальный вариант без задержечек вообще. Если у вас есть опты, то в 99% случаев этой симуляции хватит вам чтобы предсказать как поведет себя ПЛИС. После какого-то порога постсинтез симмуляцию уже и делать то перестаешь.

Кроме опыта вам нужна еще помщь синтезатора, плейсера и тому подобных утилит. Для этого им нужны констраины, им надо объяснить какие у них есть вводные по времени. Самый основной констраин это период клока. Утилиты размещая элементы учитывают все задержечки и строют схему так чтобы сигнал от элемента до элемента доходил за период клока при любых раскладах температуры и питания. Это гарантия что синхронные схемы после этого заработают ровно как в симуляторе.

После того как схема построена вы можете поглядеть на то что там получилось для этого симулятору нужен еще один файл с этими задержчеками, тот самый sdf файл. Симмулятор вам будет рисовать сигналы добавляя задержечки из sdf файла. Если файл будет не верный то и графики будут не верные, но к счастью этот файл пишите не вы, а его вам даст инструментsm.gif.

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

Но как я и написал выше при правильных констраинах, некотором опыте, вам понадобиться только первый шаг симмуляции RTL.
enzaime
Во!!! Всё как надо разъяснили, я аж всё понял, чего да как) Всем спасибо)
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.