ZASADA 0 January 25, 2014 Posted January 25, 2014 · Report post Я знаю людей, которые прекрасно понимают, как и что происходит внутри ПЛИС, успешно выполняют свою работу, но при этом считают, что то, что они описывают на HDL, тем не менее, программа может такие люди и есть, но они не приходят на этот форум с одинаковыми с вопросами "почему у меня не работает". в основе большой части создаваемых новых тем лежит именно непонимание каким именно образом набор буковок на HDL превращается в железо. более того, есть довольна большая группа писателей, гордящихся своим незнанием, им не интересно знать чем триггер отличается от защелки, безразлично как устроенна логическая ячейка. Они свято верят в умный компилятор/синтезатор и бесконечные размеры современных ПЛИС. Quote Share this post Link to post Share on other sites More sharing options...
SM 9 January 25, 2014 Posted January 25, 2014 · Report post Попутный вопрос: вот то, что компания nVidia предлагает в качестве расширений к ЯП С для поддержки технологии CUDA, - это "язык программирования" или HDL? :) ЯП, так как в результате, после всех компиляций, ЭТО предполагает исполнение на их исполняющем устройстве - графическом акселераторе, а не превращается в электрическую схему соединений транзисторов. Все, что исполняется каким либо устройством - это программы, все, что превращается в схему соединений и взаимодействия каких либо элементов, это описание устройства. Да, можно одним и тем же языком представить и то, и это (даже русским - "пойди туда, принеси это" - программа, "бочка, соединенная шлангом с краном" - описание устройства) - все зависит лишь от конкретного частного случая применения языка и того, что будет физически в конечном результате. Quote Share this post Link to post Share on other sites More sharing options...
dxp 113 January 25, 2014 Posted January 25, 2014 · Report post ЯП, так как в результате, после всех компиляций, ЭТО предполагает исполнение на их исполняющем устройстве - графическом акселераторе, а не превращается в электрическую схему соединений транзисторов. Все, что исполняется каким либо устройством - это программы, все, что превращается в схему соединений и взаимодействия каких либо элементов, это описание устройства. Да, можно одним и тем же языком представить и то, и это (даже русским - "пойди туда, принеси это" - программа, "бочка, соединенная шлангом с краном" - описание устройства) - все зависит лишь от конкретного частного случая применения языка и того, что будет физически в конечном результате. В таком случае, когда вы пишете для имплементации в ПЛИС, вы тоже никакую схему не создаёте, схему давным-давно создала фирма-разработчик и производитель ПЛИС, т.е. эта схема там аппаратно существует, а вы лишь только настраиваете коммутацию и (в случае FPGA) инициализируете массивы памяти (блоки памяти и LUT'ы). По вашему подходу вывод, что HDL'ем пользуются только разработчики самой ПЛИС и прочих ASIC'ов, а у остальных ЯП, а не HDL. :) Процессы работы с CUDA весьма сходны с тем, что происходит в ПЛИС - тоже конфигурируется готовая схема из набора одинаковых блоков, разница том, что сама структура более "крупногранулированная" и блоки более узкоспециализированные, приспособленные для выполнения нескольких конкретных операций - это обусловлено целевой задачей - обработка определённых потоков данных. может такие люди и есть, но они не приходят на этот форум с одинаковыми с вопросами "почему у меня не работает". в основе большой части создаваемых новых тем лежит именно непонимание каким именно образом набор буковок на HDL превращается в железо. более того, есть довольна большая группа писателей, гордящихся своим незнанием, им не интересно знать чем триггер отличается от защелки, безразлично как устроенна логическая ячейка. Они свято верят в умный компилятор/синтезатор и бесконечные размеры современных ПЛИС. Основная масса таких людей с такими вопросами сюда не обращается, т.к. такой нубский уровень лежит гораздо ниже их уровня понимания как концепций программирования, так и особенностей различных имплементаций, начиная от виртуальной машины HDL симулятора и заканчивая аппаратной реализацией в виде комбинационной и последовательностной (регистровой) логики. Quote Share this post Link to post Share on other sites More sharing options...
Golikov 0 January 25, 2014 Posted January 25, 2014 · Report post Засада на меня намекал:)... иногда пренебрежение к программистам не дает оценить сложность их вопросов:) Чтобы вам было еще сложнее расскажу что есть такая штука MPI - это расширение языка С на уровне библиотек, которая заставляет процессорный кластер абсолютно параллельно выполнять программу. Все процессоры вместе выполняют одну программу строчка за строчкой, но параллельно. По началу бошку рвет нереально, а потом привыкаешь. когда я использую HDL я могу его использовать двумя способами: 1. Я хочу получить какую-то известную мне схему и языком описываю так чтобы получилась именно она (я так понимаю подход SM) 2. Я хочу получить от схему необходимую мне функциональность, и мне абсолютно феолетово на какие страдания пойдет синтезатор. Признаюсь, чаще я иду по 2 пути, и потому для меня Verilog язык программирования, им я задаю желаемый мне функционал. Иногда я иду и по 1 пути, но только когда по 2 пути мне идти дорого: если я не влезаю в кристалл, или в частоту, тогда начинаю ковыряться что там да как. 1 путь работает всегда, 2 путь раньше практически всегда не работал, мне передавали мучения людей которые создавали схемы на самых первых ПЛИС. Сейчас стоимость ресурса ПЛИС неуклонно падает, и 2 путь начинает работать чаще и чаще. И вот тут самое главное: второй путь абстрактный, написав на нем модуль один раз, я могу переносить его на разные кристаллы. К примеру вот мне тут совершенно случайно стало известно что на современных ПЛИС нет модулей которые выдают Z, но к счастью синтезатор это знал, и опираясь на мое описание функционала сформировал правильную схему. И мне все равно что он там поставил, функционал поддержан, ресурсов хватило. Естественно если бы моей целью было именно создание Z на выходе, я потерпел бы неудачу. Язык С# тоже идет по этому пути. Результатом компиляции являются не конкретные инструкции. Все для того чтобы успевать за сменой процессоров и систем. Программы на С# гораздо более живучие и легче переносятся с одной версии виндов на другую. Quote Share this post Link to post Share on other sites More sharing options...
ZASADA 0 January 25, 2014 Posted January 25, 2014 · Report post и в результате 2 пути мы видим проекты с кривой времянкой, с трудом впихиваемые в огромные плис. и программы под винду с 1 кнопкой и 1 менюшкой, безбожно тормозящие на самом мощном железе. конечно хорошо, что мы дожили до плис с миллионами ячеек и нет нужды экономить каждую из них. но и писать абстрактные проекты нельзя, надо представлять что именно мы хотим получить и помогать синтезатору, описывая схему понятными ему конструкциями. Quote Share this post Link to post Share on other sites More sharing options...
dxp 113 January 25, 2014 Posted January 25, 2014 · Report post Вряд ли путь 2 можно считать хорошим. Если проект достаточно серьёзный/сложный, путь 2 почти никогда не работает или работает плохо. Это касается не только HDL, ПЛИС, но и любого программирования - для получения достойного результата всегда надо понимать, как это работает. Путь 1 при наличии достаточного уровня владения темой реализуется простым следованием немногочисленному набору правил - например, в области плисоводства это понимание, во что синтезируется та или иная языковая конструкция, синхронный дизайн, соблюдение правил перехода сигналов между разными клоковыми доменами (может, ещё что-то забыл). Это не так сложно запомнить и следовать этому. А вот несоблюдение приведёт к неприятностям, которые избыток ресурсов ПЛИС вряд ли скомпенсирует. Но хочется отметить, что выбор между путь 1 и путь 2 не имеет никакого отношения к тому, является ли HDL языком программирования. Выбор между путь 1 и путь 2 - это тщательный, взвешенный подход vs. экстенсивный путь, это относится практически к любой области. HDL vs ЯП тут ортогонально. Quote Share this post Link to post Share on other sites More sharing options...
2inltd 0 January 25, 2014 Posted January 25, 2014 (edited) · Report post Ну и наконец Вы уже достаточно долго возитесь с этой задачкой про светодиод - не находите?? Вот вам готовая логика зажигания: reg led; always @(posedge clock or posedge reset) begin if (reset) led <= #1 1'h0; else if (on) led <= #1 1'h1; else if (off) led <= #1 1'h0; end Обратите внимание, что в проекте появился reset! Вам остается сформировать сигналы on и off как результат выделения положительного и отрицательного фронта Даю их в качестве схемы - переведите в Verilog сами. Я же говорил, что знаю как сделать по другому и что бы работало. вот например: always @ (pin) begin if (pin === 1) begin led = 1; end if (pin === 0) begin led = 0; end end Может не очень хорошо написано, но работает (и даже без клока). А меня интересовал именно тот первоначальный пример и в первом же ответе мне объяснили в чём дело. кстати можно писать always @(posedge pin or negedge pin) begin end счетчик внутри можно сделать, можно даже внешним пином помахать с кучей варнингов... .... вот добились своего, теперь сижу и думаю, а как получился счетчик который работает по обоим фронтам? Раньше я такой фигней не страдал, и спокойно делал делители на нечетную частоту.... Если написать "always @(posedge pin or negedge pin)", компилятор выдаёт ошибку Error (10239): Verilog HDL Always Construct error at test.v(9): event control cannot test for both positive and negative edges of variable "pin" А вот если сделать счётчик по принципу как я писал выше, то можно условно считать, что он работает по обоим фронтам. Edited January 25, 2014 by 2inltd Quote Share this post Link to post Share on other sites More sharing options...
Golikov 0 January 25, 2014 Posted January 25, 2014 · Report post Не надо путать абстрактные проекты и проекты с плохой архитектурой. Можно написать класс с функцией сортировки, и ему будет все равно какой тип данных он сортирует. Но в тоже время в этом классе можно реализовать сортировку пузырьком. Сделав первое без второго, можно проиграть в эффективности против класса который сортирует конкретный тип, но в поддержке кода и переносимости будет огромный выигрыш. А теперь представьте что вы делаете не серию на 10 лет, а единичные приборы с тиражом сотня - две, основная стоимость которых время выхода на рынок. 2 фронт можно так использовать if(CLK_PREDEVIDER == 0) always @(posedge Bus2IP_Clk or negedge Bus2IP_Clk) begin MASTER_CLK_task(); end else always @(posedge Bus2IP_Clk) begin MASTER_CLK_task(); end //процедура формирование сигналов для выходного мастерклока task MASTER_CLK_task; begin if ( Bus2IP_Resetn == 1'b0 ) //сброс схемы begin MCLK <= 1'b0; INV_MCLK <= 1'b1; mclk_devider <= 0; end else begin if(mclk_devider < MCLK_DEVIDER_VAL) //выдерживаем паузу mclk_devider <= mclk_devider + 1; else //пауза выдержана меняем состояние клока begin mclk_devider <= 0; //сбрасываем счетчик MCLK <= ~MCLK; INV_MCLK <= ~INV_MCLK; end end end endtask дальше синал MCLK и INV_MCLK вышли на ружу через DDR. Кстати интересный факт, если бы я думал о том как это сделано в железе, я бы такое не написал, счетчик на 2 фронтах я по умолчанию не знаю. Но умный синтезатор что-то заменил, и вуаля... П.С. Нужно это для деления клока на нечетное число со скважностью 50% Quote Share this post Link to post Share on other sites More sharing options...
iosifk 3 January 25, 2014 Posted January 25, 2014 · Report post Не надо путать абстрактные проекты и проекты с плохой архитектурой. Кстати интересный факт, если бы я думал о том как это сделано в железе, я бы такое не написал, счетчик на 2 фронтах я по умолчанию не знаю. Но умный синтезатор что-то заменил, и вуаля... Остается только выяснить, реализуются ли MASTER_CLK_task() в железе... Quote Share this post Link to post Share on other sites More sharing options...
Джеймс 5 January 25, 2014 Posted January 25, 2014 · Report post Я же говорил, что знаю как сделать по другому и что бы работало. вот например: always @ (pin) begin if (pin === 1) begin led = 1; end if (pin === 0) begin led = 0; end end Ничего вы не знаете. Вы хоть понимаете что вы написали?? Вот что: assign led = pin; Синтезатор cделал провод . Про-вод. А не регистр. Да, провод работает без clock-а, это вы верно заметили. Всё, я заканчиваю дискуссию. Зря я время потратил, "2inltd". Quote Share this post Link to post Share on other sites More sharing options...
Golikov 0 January 25, 2014 Posted January 25, 2014 · Report post Остается только выяснить, реализуются ли MASTER_CLK_task() в железе... хм... вот вы сказали и я подумал... А вдруг я его правда только симулировал... В реальном проекте частота четная, и там по одному фронту все работает. И я вот что-то сейчас не помню запускал ли я в железе на нечетной частоте... Но это корка для микроблайза, я ее имплементил точно до передачи в железо, но на какой частоте блин не помню... буду силы проверю, может чудес то и нет). Ненавистники программистов готовьте дудки, похоже я правда облажался:)... Quote Share this post Link to post Share on other sites More sharing options...
2inltd 0 January 25, 2014 Posted January 25, 2014 · Report post Ничего вы не знаете. Вы хоть понимаете что вы написали?? Вот что: assign led = pin; Провод cделал синтезатор. Про-вод. А не регистр. Да, провод работает без clock-а, это вы верно заметили. Всё, я заканчиваю дискуссию. Зря я время потратил, "2inltd". 1. По сути весь пример и является assign led = pin;. И это только пример, сама программа была другая, это только принцип задумки. 2. Первая задумка была почему 2 always не могут выдать разные значения в 1 провод. и как я уже говорил я получил ответ. и как я уже говорил я не знал что always является триггером защёлкой. иначе не задавал бы таких глупых вопросов. 3. Вторая задумка была (она появилась в основном в процессе жизни темы), чтобы программа работала и по нарастанию и по спаду (это только пример, что я написал "led = 1;" и "led = 0;". Здесь могут быть какие-нибудь инструкции выбора, математические функции и другой нормальный код). И условно можно считать, что это будет срабатывать и по переднему и по заднему фронтам. как-то так. Quote Share this post Link to post Share on other sites More sharing options...
Golikov 0 January 25, 2014 Posted January 25, 2014 · Report post многим тяжело даются абстрактно сформулированные задачи, а потом мы почему то виноваты что они тему читали... Я так понимаю реально работа по 2 фронтам возможно только как в DDR, типа 2 линии защелок, одна защелкивает данные по одному фронту, другая по другому, и какая-то схема потом анализирует оба сигнала по одному из фронтов или же на частоте сильно большей, полученной с ПЛЛ. наверное пора признать что все таки не представляя кухни внутри ПЛИС эффективной разработки пока вести не получится... еще есть варианта сдвинуть клок на четверть периода и поксорить его с исходником, тогда эта штука будет давать на каждый фронт восходящий и все получится...%) Quote Share this post Link to post Share on other sites More sharing options...
Джеймс 5 January 25, 2014 Posted January 25, 2014 · Report post if(mclk_devider < MCLK_DEVIDER_VAL) //выдерживаем паузу mclk_devider <= mclk_devider + 1; А давайте я вам в двух словах объясню как task работает при синтезе? Эта конструкция используется чтобы сократить работу (грубо говоря, писанину..) если есть код, который используется в разных местах. Посмотрите страницы 48-49 в Книге (раздел 2.2.3) http://books.google.ru/books?id=j1EFsHlqEg...zed&f=false Или вот код с синтезируемым task, который я приводил около года назад http://electronix.ru/forum/index.php?showt...t&p=1154353 Ваш фрагмент кода внутри task выше ("выдерживаем паузу") работает вообще не по clock-у. Quote Share this post Link to post Share on other sites More sharing options...
Golikov 0 January 26, 2014 Posted January 26, 2014 · Report post А давайте я вам в двух словах объясню как task работает при синтезе? Эта конструкция используется чтобы сократить работу (грубо говоря, писанину..) если есть код, который используется в разных местах. Спасибо капитан очевидность, отчасти так он и использовался в примере, только кроме механической писанины, есть еще общая читаемость кода, так он тоже использовался. Ваш фрагмент кода внутри task выше ("выдерживаем паузу") работает вообще не по clock-у. почему? Можно подробнее что имеется ввиду? Quote Share this post Link to post Share on other sites More sharing options...