ZASADA 0 25 января, 2014 Опубликовано 25 января, 2014 · Жалоба Я знаю людей, которые прекрасно понимают, как и что происходит внутри ПЛИС, успешно выполняют свою работу, но при этом считают, что то, что они описывают на HDL, тем не менее, программа может такие люди и есть, но они не приходят на этот форум с одинаковыми с вопросами "почему у меня не работает". в основе большой части создаваемых новых тем лежит именно непонимание каким именно образом набор буковок на HDL превращается в железо. более того, есть довольна большая группа писателей, гордящихся своим незнанием, им не интересно знать чем триггер отличается от защелки, безразлично как устроенна логическая ячейка. Они свято верят в умный компилятор/синтезатор и бесконечные размеры современных ПЛИС. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SM 0 25 января, 2014 Опубликовано 25 января, 2014 · Жалоба Попутный вопрос: вот то, что компания nVidia предлагает в качестве расширений к ЯП С для поддержки технологии CUDA, - это "язык программирования" или HDL? :) ЯП, так как в результате, после всех компиляций, ЭТО предполагает исполнение на их исполняющем устройстве - графическом акселераторе, а не превращается в электрическую схему соединений транзисторов. Все, что исполняется каким либо устройством - это программы, все, что превращается в схему соединений и взаимодействия каких либо элементов, это описание устройства. Да, можно одним и тем же языком представить и то, и это (даже русским - "пойди туда, принеси это" - программа, "бочка, соединенная шлангом с краном" - описание устройства) - все зависит лишь от конкретного частного случая применения языка и того, что будет физически в конечном результате. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 58 25 января, 2014 Опубликовано 25 января, 2014 · Жалоба ЯП, так как в результате, после всех компиляций, ЭТО предполагает исполнение на их исполняющем устройстве - графическом акселераторе, а не превращается в электрическую схему соединений транзисторов. Все, что исполняется каким либо устройством - это программы, все, что превращается в схему соединений и взаимодействия каких либо элементов, это описание устройства. Да, можно одним и тем же языком представить и то, и это (даже русским - "пойди туда, принеси это" - программа, "бочка, соединенная шлангом с краном" - описание устройства) - все зависит лишь от конкретного частного случая применения языка и того, что будет физически в конечном результате. В таком случае, когда вы пишете для имплементации в ПЛИС, вы тоже никакую схему не создаёте, схему давным-давно создала фирма-разработчик и производитель ПЛИС, т.е. эта схема там аппаратно существует, а вы лишь только настраиваете коммутацию и (в случае FPGA) инициализируете массивы памяти (блоки памяти и LUT'ы). По вашему подходу вывод, что HDL'ем пользуются только разработчики самой ПЛИС и прочих ASIC'ов, а у остальных ЯП, а не HDL. :) Процессы работы с CUDA весьма сходны с тем, что происходит в ПЛИС - тоже конфигурируется готовая схема из набора одинаковых блоков, разница том, что сама структура более "крупногранулированная" и блоки более узкоспециализированные, приспособленные для выполнения нескольких конкретных операций - это обусловлено целевой задачей - обработка определённых потоков данных. может такие люди и есть, но они не приходят на этот форум с одинаковыми с вопросами "почему у меня не работает". в основе большой части создаваемых новых тем лежит именно непонимание каким именно образом набор буковок на HDL превращается в железо. более того, есть довольна большая группа писателей, гордящихся своим незнанием, им не интересно знать чем триггер отличается от защелки, безразлично как устроенна логическая ячейка. Они свято верят в умный компилятор/синтезатор и бесконечные размеры современных ПЛИС. Основная масса таких людей с такими вопросами сюда не обращается, т.к. такой нубский уровень лежит гораздо ниже их уровня понимания как концепций программирования, так и особенностей различных имплементаций, начиная от виртуальной машины HDL симулятора и заканчивая аппаратной реализацией в виде комбинационной и последовательностной (регистровой) логики. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 25 января, 2014 Опубликовано 25 января, 2014 · Жалоба Засада на меня намекал:)... иногда пренебрежение к программистам не дает оценить сложность их вопросов:) Чтобы вам было еще сложнее расскажу что есть такая штука MPI - это расширение языка С на уровне библиотек, которая заставляет процессорный кластер абсолютно параллельно выполнять программу. Все процессоры вместе выполняют одну программу строчка за строчкой, но параллельно. По началу бошку рвет нереально, а потом привыкаешь. когда я использую HDL я могу его использовать двумя способами: 1. Я хочу получить какую-то известную мне схему и языком описываю так чтобы получилась именно она (я так понимаю подход SM) 2. Я хочу получить от схему необходимую мне функциональность, и мне абсолютно феолетово на какие страдания пойдет синтезатор. Признаюсь, чаще я иду по 2 пути, и потому для меня Verilog язык программирования, им я задаю желаемый мне функционал. Иногда я иду и по 1 пути, но только когда по 2 пути мне идти дорого: если я не влезаю в кристалл, или в частоту, тогда начинаю ковыряться что там да как. 1 путь работает всегда, 2 путь раньше практически всегда не работал, мне передавали мучения людей которые создавали схемы на самых первых ПЛИС. Сейчас стоимость ресурса ПЛИС неуклонно падает, и 2 путь начинает работать чаще и чаще. И вот тут самое главное: второй путь абстрактный, написав на нем модуль один раз, я могу переносить его на разные кристаллы. К примеру вот мне тут совершенно случайно стало известно что на современных ПЛИС нет модулей которые выдают Z, но к счастью синтезатор это знал, и опираясь на мое описание функционала сформировал правильную схему. И мне все равно что он там поставил, функционал поддержан, ресурсов хватило. Естественно если бы моей целью было именно создание Z на выходе, я потерпел бы неудачу. Язык С# тоже идет по этому пути. Результатом компиляции являются не конкретные инструкции. Все для того чтобы успевать за сменой процессоров и систем. Программы на С# гораздо более живучие и легче переносятся с одной версии виндов на другую. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
ZASADA 0 25 января, 2014 Опубликовано 25 января, 2014 · Жалоба и в результате 2 пути мы видим проекты с кривой времянкой, с трудом впихиваемые в огромные плис. и программы под винду с 1 кнопкой и 1 менюшкой, безбожно тормозящие на самом мощном железе. конечно хорошо, что мы дожили до плис с миллионами ячеек и нет нужды экономить каждую из них. но и писать абстрактные проекты нельзя, надо представлять что именно мы хотим получить и помогать синтезатору, описывая схему понятными ему конструкциями. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
dxp 58 25 января, 2014 Опубликовано 25 января, 2014 · Жалоба Вряд ли путь 2 можно считать хорошим. Если проект достаточно серьёзный/сложный, путь 2 почти никогда не работает или работает плохо. Это касается не только HDL, ПЛИС, но и любого программирования - для получения достойного результата всегда надо понимать, как это работает. Путь 1 при наличии достаточного уровня владения темой реализуется простым следованием немногочисленному набору правил - например, в области плисоводства это понимание, во что синтезируется та или иная языковая конструкция, синхронный дизайн, соблюдение правил перехода сигналов между разными клоковыми доменами (может, ещё что-то забыл). Это не так сложно запомнить и следовать этому. А вот несоблюдение приведёт к неприятностям, которые избыток ресурсов ПЛИС вряд ли скомпенсирует. Но хочется отметить, что выбор между путь 1 и путь 2 не имеет никакого отношения к тому, является ли HDL языком программирования. Выбор между путь 1 и путь 2 - это тщательный, взвешенный подход vs. экстенсивный путь, это относится практически к любой области. HDL vs ЯП тут ортогонально. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
2inltd 0 25 января, 2014 Опубликовано 25 января, 2014 (изменено) · Жалоба Ну и наконец Вы уже достаточно долго возитесь с этой задачкой про светодиод - не находите?? Вот вам готовая логика зажигания: 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" А вот если сделать счётчик по принципу как я писал выше, то можно условно считать, что он работает по обоим фронтам. Изменено 25 января, 2014 пользователем 2inltd Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 25 января, 2014 Опубликовано 25 января, 2014 · Жалоба Не надо путать абстрактные проекты и проекты с плохой архитектурой. Можно написать класс с функцией сортировки, и ему будет все равно какой тип данных он сортирует. Но в тоже время в этом классе можно реализовать сортировку пузырьком. Сделав первое без второго, можно проиграть в эффективности против класса который сортирует конкретный тип, но в поддержке кода и переносимости будет огромный выигрыш. А теперь представьте что вы делаете не серию на 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% Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
iosifk 3 25 января, 2014 Опубликовано 25 января, 2014 · Жалоба Не надо путать абстрактные проекты и проекты с плохой архитектурой. Кстати интересный факт, если бы я думал о том как это сделано в железе, я бы такое не написал, счетчик на 2 фронтах я по умолчанию не знаю. Но умный синтезатор что-то заменил, и вуаля... Остается только выяснить, реализуются ли MASTER_CLK_task() в железе... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Джеймс 4 25 января, 2014 Опубликовано 25 января, 2014 · Жалоба Я же говорил, что знаю как сделать по другому и что бы работало. вот например: always @ (pin) begin if (pin === 1) begin led = 1; end if (pin === 0) begin led = 0; end end Ничего вы не знаете. Вы хоть понимаете что вы написали?? Вот что: assign led = pin; Синтезатор cделал провод . Про-вод. А не регистр. Да, провод работает без clock-а, это вы верно заметили. Всё, я заканчиваю дискуссию. Зря я время потратил, "2inltd". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 25 января, 2014 Опубликовано 25 января, 2014 · Жалоба Остается только выяснить, реализуются ли MASTER_CLK_task() в железе... хм... вот вы сказали и я подумал... А вдруг я его правда только симулировал... В реальном проекте частота четная, и там по одному фронту все работает. И я вот что-то сейчас не помню запускал ли я в железе на нечетной частоте... Но это корка для микроблайза, я ее имплементил точно до передачи в железо, но на какой частоте блин не помню... буду силы проверю, может чудес то и нет). Ненавистники программистов готовьте дудки, похоже я правда облажался:)... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
2inltd 0 25 января, 2014 Опубликовано 25 января, 2014 · Жалоба Ничего вы не знаете. Вы хоть понимаете что вы написали?? Вот что: assign led = pin; Провод cделал синтезатор. Про-вод. А не регистр. Да, провод работает без clock-а, это вы верно заметили. Всё, я заканчиваю дискуссию. Зря я время потратил, "2inltd". 1. По сути весь пример и является assign led = pin;. И это только пример, сама программа была другая, это только принцип задумки. 2. Первая задумка была почему 2 always не могут выдать разные значения в 1 провод. и как я уже говорил я получил ответ. и как я уже говорил я не знал что always является триггером защёлкой. иначе не задавал бы таких глупых вопросов. 3. Вторая задумка была (она появилась в основном в процессе жизни темы), чтобы программа работала и по нарастанию и по спаду (это только пример, что я написал "led = 1;" и "led = 0;". Здесь могут быть какие-нибудь инструкции выбора, математические функции и другой нормальный код). И условно можно считать, что это будет срабатывать и по переднему и по заднему фронтам. как-то так. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 25 января, 2014 Опубликовано 25 января, 2014 · Жалоба многим тяжело даются абстрактно сформулированные задачи, а потом мы почему то виноваты что они тему читали... Я так понимаю реально работа по 2 фронтам возможно только как в DDR, типа 2 линии защелок, одна защелкивает данные по одному фронту, другая по другому, и какая-то схема потом анализирует оба сигнала по одному из фронтов или же на частоте сильно большей, полученной с ПЛЛ. наверное пора признать что все таки не представляя кухни внутри ПЛИС эффективной разработки пока вести не получится... еще есть варианта сдвинуть клок на четверть периода и поксорить его с исходником, тогда эта штука будет давать на каждый фронт восходящий и все получится...%) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Джеймс 4 25 января, 2014 Опубликовано 25 января, 2014 · Жалоба 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-у. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Golikov 0 26 января, 2014 Опубликовано 26 января, 2014 · Жалоба А давайте я вам в двух словах объясню как task работает при синтезе? Эта конструкция используется чтобы сократить работу (грубо говоря, писанину..) если есть код, который используется в разных местах. Спасибо капитан очевидность, отчасти так он и использовался в примере, только кроме механической писанины, есть еще общая читаемость кода, так он тоже использовался. Ваш фрагмент кода внутри task выше ("выдерживаем паузу") работает вообще не по clock-у. почему? Можно подробнее что имеется ввиду? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться