vleo 0 16 марта, 2007 Опубликовано 16 марта, 2007 · Жалоба Занимаясь созданием модели элемента, где надо проверять, что фронт A приходит раньше B, или же одновременно, я с удивлением обнаружил, что assert смотрит не только на установившиеся значения сигналов, а на все промежуточные в процессе отработки дельта циклов. Вот пример: entity assertTst is end; architecture sim of assertTst is signal A : bit := '0'; signal B : bit := '0'; signal x : bit; begin assert (A='0' and B='0') or (A='1' and B='1') report "A,B not same, no 'stable filter"; assert not (A'stable and B'stable) or (A='0' and B='0') or (A='1' and B='1') report "A,B not same"; x <= '1' after 1 ns; B <= x; A <= x and B; -- time delta x A B -- 0 +0 0 0 0 -- 1 +0 1 0 0 -- 1 +1 1 0 1 -- 1 +2 1 1 1 end; То есть на дельта цикле +1 условие A = B нарушено. Но какая польза от наблюдения за процессом установления значений? В результате я так и не понял как написать assert который проверяет, что два сигнала либо тождественны, либо сигнал A приходит первым. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
oval 0 16 марта, 2007 Опубликовано 16 марта, 2007 · Жалоба Никаких странностей здесь нет, это не feature и не bug. :) Все так и должно быть. Для проверки необходимого вам условия, смотрите в сторону атрибутов сигнала ('event, 'last_event и т.п.). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vleo 0 16 марта, 2007 Опубликовано 16 марта, 2007 · Жалоба Никаких странностей здесь нет, это не feature и не bug. :) Все так и должно быть. Для проверки необходимого вам условия, смотрите в сторону атрибутов сигнала ('event, 'last_event и т.п.). Это замечания по по существу, из них не следует, что Вы знаете ответ на мой вопрос :-) Если Вы считаете, что "так и должно быть", то тогда напишите assert для проверки интуитивно простого условия - фронт сигнала A приходит раньше или одновременно с фронтом сигнала B Повторю, проблема в том, что assert смотрит на значения сигналов НЕ в момент перехода от текущего модельного времени к следующему (Tn не равно Tc), а в процессе дельта циклов, где неустановившиеся значения сигналов могут и нарушать условия - что с того? Кому это, вообще, интересно? Да, так проще раелизовать assert - но тогда это уже не feature, а bug (в спецификации VHDL). Что может дать в этом смысле event? И тем более last_event - который будет равен 0 в конце данного момента модельного времени (Tc) значение сигналов менялось на дельта циклах. Вот значения этих (и других) аттрибутов для моего примера (A и B имеют event 1-->0 в момет времени 0 fs.) Tc delta A B 'event 'last_event 'stable 'delayed 'transaction 'last_value 1 +0 '0' '0' false false 1 ns 1 ns true true '0' '0' '1' '0' '1' '1' 1 +1 '0' '1' false true 1 ns 0 ns true false '0' '0' '0' '1' '1' '0' 1 +2 '1' '1' true false 0 ns 0 ns false true '0' '1' '1' '1' '0' '0' Что дают эти аттрибуты? Как я должен отлавливать тот факт, что и A и B имели фронт 0 --> 1 на модельном времени 1 ns? То есть можно какой-то код для этого придумать и написть - но это как-то сложно ... Также надо учесть, что A и B могут ходить из '0' в '1' и обратно много раз в течении момента модельного времени Tc. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Oldring 0 16 марта, 2007 Опубликовано 16 марта, 2007 · Жалоба Если Вы считаете, что "так и должно быть", то тогда напишите assert для проверки интуитивно простого условия - фронт сигнала A приходит раньше или одновременно с фронтом сигнала B А мне вот, например, это условие совершенно интуитивно непонятно в отрыве от остальной схемы. P.S. Если не хотите проверять условие в каждом дельта-цикле - воспользуйтесь postponed assert. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vleo 0 17 марта, 2007 Опубликовано 17 марта, 2007 (изменено) · Жалоба А мне вот, например, это условие совершенно интуитивно непонятно в отрыве от остальной схемы. P.S. Если не хотите проверять условие в каждом дельта-цикле - воспользуйтесь postponed assert. Да, тут Вы совершенно правы - физического смысла требование одновременности фронтов не имеет. Можно требовать чтобы один фронт был впереди или позади другого - на величину не менее или не более. Требование одновременности - математическая абстракция. И когда я подумал над своим устройством, то понял, что это требование можно просто исключить, как ложное. Что я позавчера и сделал, но, меня сильно смутило то, что assert проверяется на каждом дельта-цикле, и даже такое утверждение как assert A=B приводит к ложному срабатыванию... Можно, конечно, и тут сказать, что без временного "допуска" это требование тоже не много смысла имеет... Замечательный язык VHDL - есть где мозги напрячь :-) Спасибо большое за указание на postponed assert, буду смотреть. Пока я в этом разбирался, то нарисовал код, иллюстрирующий поведение сигналов и всех их атрибутов на нескольких многодельтовых моментах модельного времени, это очень облегчил замечательный пакет, определяющий функцию типа C-шного printf (только под названием fprint :-), пакет этот PCK_FIO - очень рекомендую, все-таки ввод/вывод нативный в VHDL убитый, в духе алгола :-) A с пакетом PCK_FIO можно писать по человечески вот так: library std; use std.textio.all; library printf; use printf.pck_fio.all; architecture ... file output : text open write_mode is "assertTst.lst"; ... process ... variable l : line; ... fprint(output,l, "Tc=%3d ns A=%b B=%b x=%b\n",fo(NOW), fo(A), fo(B),fo(x)); получаем на выдачу: Tc= 0 ns A=U B=U x=U Tc= 0 ns A=U B=U x=0 Tc= 0 ns A=0 B=0 x=0 Tc= 1 ns A=0 B=0 x=1 Tc= 1 ns A=0 B=1 x=1 Tc= 1 ns A=1 B=1 x=1 Tc= 2 ns A=1 B=1 x=0 Tc= 2 ns A=0 B=0 x=0 Если нужно печатать на консоль, то строку "file output ... " исключить (файл output по умолчанию это вывод на консоль). Печатает все ходовые типы, в том числе и std_logic_vector. PCK_FIO_2002.7.tar.gz Изменено 17 марта, 2007 пользователем vleo Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Oldring 0 17 марта, 2007 Опубликовано 17 марта, 2007 · Жалоба Да, тут Вы совершенно правы - физического смысла требование одновременности фронтов не имеет. Можно требовать чтобы один фронт был впереди или позади другого - на величину не менее или не более. Требование одновременности - математическая абстракция. И когда я подумал над своим устройством, то понял, что это требование можно просто исключить, как ложное. Что я позавчера и сделал, но, меня сильно смутило то, что assert проверяется на каждом дельта-цикле, и даже такое утверждение как assert A=B приводит к ложному срабатыванию... Можно, конечно, и тут сказать, что без временного "допуска" это требование тоже не много смысла имеет... Замечательный язык VHDL - есть где мозги напрячь :-) Требование одновременности - это не абстракция. В VHDL время дискретно. "Одновременно" с точки зрения VHDL - это в одном цикле исполнения. Не более и не менее. Ваше утверждение о том, что assert выполняется в каждом цикле, не соответсвует действительности. Как и любой процесс со списком активации, concurent assert выполняется в каждом цикле, в котором активны сигналы, являющиеся аргументами тестового выражения. Если сигналы в данном цикле неактивны - assert не выполняется. Ваши сигналы изменяются не одновременно, а в последовательных дельта-циклах. Поэтому assert также вычисляется несколько раз подряд. VHDL очень строгий и последовательный язык. Напрягаться с ним особо не нужно, если прочитать LRM и понять идеологию языка. Вам как человеку с опытом программирования это должно быть легко. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vleo 0 17 марта, 2007 Опубликовано 17 марта, 2007 · Жалоба Требование одновременности - это не абстракция. В VHDL время дискретно. "Одновременно" с точки зрения VHDL - это в одном цикле исполнения. Не более и не менее. Ваше утверждение о том, что assert выполняется в каждом цикле, не соответсвует действительности. Как и любой процесс со списком активации, concurent assert выполняется в каждом цикле, в котором активны сигналы, являющиеся аргументами тестового выражения. Если сигналы в данном цикле неактивны - assert не выполняется. Ваши сигналы изменяются не одновременно, а в последовательных дельта-циклах. Поэтому assert также вычисляется несколько раз подряд. VHDL очень строгий и последовательный язык. Напрягаться с ним особо не нужно, если прочитать LRM и понять идеологию языка. Вам как человеку с опытом программирования это должно быть легко. Читаю, читаю IEEE 1076, но вот пример - S'DELAYED - что там написано про задержку 0 ns? На самом деле - на один дельта цикл. В стандарте непонятно что имеется в виду. С точки зрения VHDL одновременность, конечно, не абстрактна,но с точки зрения кодирования спецификации конкретной микросхемы - абстрактно, одновременный приход физических сигналов - невозможен. Я понимаю, что assert выполняется не в каждом цикле, но, естественно, только в тех, где меняются сигналы из списка чувствительности, в моем примере в списке чувствительности все сигналы. И вот подходим к главному - " assert также вычисляется несколько раз подряд" - только вот ЗАЧЕМ это может быть нужно с точки зрения проверки? Меня волнуют соотношения только между установившимися сигналами. Тем не менее большое Вам спасибо за указание на postponed assert и postponed process - я переписал все свой проверки на postponed - и мне очень полегчало. Возможно, иногда и могут быть нужны не-postponed проверки, но я придумать не могу такую ситуацию. Все проверки соотношения между фронтами - setup и hold, а также stable по отношению к другому сигналу проще делать на postponed. О да, мой опыт программирования и число языков на которых я писал велико. Поэтому уж если что-то в языке мне непоятно, то это значит, что это либо действительно оригинальная семантика, либо объективный дефект языка :-) А если мне что-то не нравится, хотя и полностью понятно, то это тоже не в пользу языка. Для составления спецификаций и описания железа строгий язык, безусловно, лучше подходит. В VHDL-е есть и оригинальная семантика - и непроцедурность и подлинная параллельность, тот же цикл моделирования. Но это молодой язык, и очень зажатый усилиями по стандартизации - то есть он не вызрел "на воле", а его уже загнали в жесткие рамки. Пример тому - те же postponed - то есть их отсутствие в спецификации 1987 - это вот Вам пример очевидной ОШИБКИ разработчиков. Они упустили жизненно необходимую возможность (то есть посмотреть на сигналы, когда они полностью установились). Вообще, посмотрите на масштабы изменений/дополнений от 87 до 93. По-моему от C K&R до С90 меньше изменений, а от С90 до С99 - и сравнивать нечего. Еще один ляп VHDL - это отсутствие возможности выполнять процедуру в контексте вызывающего процесса, и отсутствие передачи ссылки на сигнал в процедуру - поэтому невозможно написать процедуру, которая будет получать сигнал s в качестве параметра, и использовать, допустим, s'stable, s'quiet, s'transaction s'delayed. Из этого вытекает необходимость дупликации кода. Это уже никакого отношения к строгости не имеет, а есть чистая проблема. Из той же области традиционное для алголо-образных языков отсутствие препроцессора интегрированного с языком. Все же невозможность управлять обработкой кода на лексическом уровня сложно оправдать - например, почему отсутствует возможность включения кода (include)? Отсюда вытекает бесконечное повторение в каждом файле - library ieee; use .... - это что строгость? удобство? Со стандартными библиотеками очень негусто. Вообщем, как-бы все такие косметически вещи, но на самом деле это все время разработчиков, лишние ошибки и т.д. От этого и пользуется популярностью такая вредная вещь как Verilog. Увы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Oldring 0 17 марта, 2007 Опубликовано 17 марта, 2007 · Жалоба Наконец-то появился человек, с которым будет интересно поспорить :) Дело в том, что я не считаю, что большинство изложенных Вами "недостатков", являются именно недостатками. Во-первых, я вижу, как они поистекают из логики устройства VHDL. Наличие очень последовательно проработанной идеи - это, на мой взгляд, как раз сила языка. После прохождения соответствующего процесса понимания и просветления все становится на свои места. К сожалению, эта идеология конструкции языка очень плохо изложена в популярной литературе по VHDL. Во-вторых, излагаемые Вами конструкции, опять же, на мой взгляд, часто являются ошибочными как раз с точки зрения идеологии. То есть, правильно делать по-другому. Конечно, недостатки и ошибки есть и у VHDL - но они несколько другие. В дальнейшем изложении я буду ссылаться на IEEE 1076-2002 Читаю, читаю IEEE 1076, но вот пример - S'DELAYED - что там написано про задержку 0 ns? На самом деле - на один дельта цикл. В стандарте непонятно что имеется в виду. В стандарте описано совершенно четко, что имеется в виду. Значение атрибута DELAYED получается в подразумеваемом процессе, описанном внизу этого пункта. Из этого описания однозначно следует, что будет задержка именно на один дельта-цикл. С точки зрения VHDL одновременность, конечно, не абстрактна, но с точки зрения кодирования спецификации конкретной микросхемы - абстрактно, одновременный приход физических сигналов - невозможен. Дело в том, что дельта-циклы не предназначены для моделирования физики или кодирования спецификации конкретной микросхемы. Любая физическая модель должна кодироваться с указанием физических задержек. Дельта-циклы предназначены для другого. Дельта-циклы вместе с четкой моделью активности сигналов позволяют гарантироать, что результат моделирования не зависит от порядка исполнения процессов внутри одного цикла - который может быть случайным и, тем более, не может быть одинаковым в разных системах моделирования. Так было, по крайней мере, до введения в язык shared variables, которые, кстати, некорректно реализованы в ряде тулзов. Я понимаю, что assert выполняется не в каждом цикле, но, естественно, только в тех, где меняются сигналы из списка чувствительности, в моем примере в списке чувствительности все сигналы. И вот подходим к главному - " assert также вычисляется несколько раз подряд" - только вот ЗАЧЕМ это может быть нужно с точки зрения проверки? Меня волнуют соотношения только между установившимися сигналами. Тем не менее большое Вам спасибо за указание на postponed assert и postponed process - я переписал все свой проверки на postponed - и мне очень полегчало. Возможно, иногда и могут быть нужны не-postponed проверки, но я придумать не могу такую ситуацию. Все проверки соотношения между фронтами - setup и hold, а также stable по отношению к другому сигналу проще делать на postponed. Теперь мы подошли к главному. Использование postponed assert само по себе не может помочь проверить выполнение hold time specification. Потому что сигнал данных может измениться через 100 ps после фронта клока, и postponed assert это не увидит. Как же быть? Нужно написать корректное выражение, которое по нарастающему фронту клока будет проверять выполнение setup time, а по любому фронту данных выполнение hold time. Для этого проверочного условия абсолютно все равно, использован postponed assert или обычный, активируемый и вычисляемый, как и каждый обычный процесс, в каждом цикле, в котором активен хотя-бы один сигнал из его списка чувствительности. О да, мой опыт программирования и число языков на которых я писал велико. Поэтому уж если что-то в языке мне непоятно, то это значит, что это либо действительно оригинальная семантика, либо объективный дефект языка :-) А если мне что-то не нравится, хотя и полностью понятно, то это тоже не в пользу языка. Я тоже так считаю. Про себя ;) Для составления спецификаций и описания железа строгий язык, безусловно, лучше подходит. В VHDL-е есть и оригинальная семантика - и непроцедурность и подлинная параллельность, тот же цикл моделирования. Но это молодой язык, и очень зажатый усилиями по стандартизации - то есть он не вызрел "на воле", а его уже загнали в жесткие рамки. Пример тому - те же postponed - то есть их отсутствие в спецификации 1987 - это вот Вам пример очевидной ОШИБКИ разработчиков. Они упустили жизненно необходимую возможность (то есть посмотреть на сигналы, когда они полностью установились). Вообще, посмотрите на масштабы изменений/дополнений от 87 до 93. По-моему от C K&R до С90 меньше изменений, а от С90 до С99 - и сравнивать нечего. Ну да, конечно. Введение прототипов функций - это очень маленький отход от K&R C. :) От C90 до C99 изменений, конечно, не очень много - наверное, потому что те, кому нужно было что-то большее, давно перешли к тому времени на плюсы. Давайте сравним развитие VHDL с плюсами. В первой версии C++ не было исключений и шаблонов. Да и пример с postponed не очень удачный, как я показал выше. Если код зависит от postponed, он IMHO не очень хорош. Еще один ляп VHDL - это отсутствие возможности выполнять процедуру в контексте вызывающего процесса, и отсутствие передачи ссылки на сигнал в процедуру - поэтому невозможно написать процедуру, которая будет получать сигнал s в качестве параметра, и использовать, допустим, s'stable, s'quiet, s'transaction s'delayed. Это не ляп. Простите, но это опять Ваше непонимание устройства VHDL. Идеология VHDL очень сильно отличается от обычных процедурных языков для архитектуры Фон-Неймана. Во-первых, сигнал можно передавать в процедуру. Более того, процедура может прсваивать ему новое значение. При этом используется именно драйвер сигнала из вызывающего процесса. Что в процедуре делать нельзя - это использовать атрибуты, результат которых является сигналом. Обработка VHDL модели состоит из двух различных этапов: elaboration и, собственно, исполнения. После парсинга исходников, конечно. Все сигналы, в том числе, результаты атрибутов, порождаются на этапе elaboration. Они не могут порождаться динамически. Это, конечно, ограничение языка - но иначе видимо возникнет куча сложных вопросов по поводу непротиворечивой реализации сомулятора. Поэтому и нельзя использовать атрибуты с результатами-сигналами в вызовах процедур. Вызов процедуры еще не существует на этапе elaboration. Таким образом, если нужно использовать внутри иерархии кода сигнальные атрибуты - нужно использовать не процедуры, а компоненты. С другой стороны, для проверки setup/hold time использовать такие атрибуты нет необходимости. Достаточно несигнальных атрибутов EVENT и LAST_EVENT. Кроме того, такое описание будет гораздо эффективнее, так как каждый сигнал отжирает много памяти, гораздо больше, чем связанный с ним простой тип. Обратите внимание на примеры из раздела "Concurrent procedure call statement". Как Вы думаете, как реализуют подобные процедуры? Из этого вытекает необходимость дупликации кода. Это уже никакого отношения к строгости не имеет, а есть чистая проблема. Из той же области традиционное для алголо-образных языков отсутствие препроцессора интегрированного с языком. Все же невозможность управлять обработкой кода на лексическом уровня сложно оправдать - например, почему отсутствует возможность включения кода (include)? Отсюда вытекает бесконечное повторение в каждом файле - library ieee; use .... - это что строгость? удобство? Со стандартными библиотеками очень негусто. Вообщем, как-бы все такие косметически вещи, но на самом деле это все время разработчиков, лишние ошибки и т.д. Стандартные библиотеки... Да, не густо. С другой стороны, лучше бы STL в плюсах не стандартизовали так, как его реализовали. include... А он реально нужен? Дело в том, что в VHDL модулем является не файл. В одном файле может быть несколько модулей - но они независимы. library ieee; use ... - это именно строгость. И не в каждом файле, а перед каждым модулем, которому это нужно. Вы указываете, что инжектируете в пространство имен своего модуля имена из другого нестандартного для языка пакета. Я, кстати, часто использую встроенные типы, вроде bit_vector. Они, в отличие от std_logic, не resolved, поэтому многие ошибки обнаруживаются на этапе elaboration, а не исполнения. #define... Очень сильное средство, которым многие пользуются неправильно. От этого и пользуется популярностью такая вредная вещь как Verilog. Увы. Не думаю. VB ведь тоже пользуется популярностью. И plain C где нужно и где не нужно при наличии более совершенных языков. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vleo 0 19 марта, 2007 Опубликовано 19 марта, 2007 · Жалоба Наконец-то появился человек, с которым будет интересно поспорить :) Однако,надеюсь, не ради самого процесса :-) Почти, как в известном анекдоте - - Скажите, неужели Вы так любите Истину? - Нет, но сам процесс... .... В стандарте описано совершенно четко, что имеется в виду. Значение атрибута DELAYED получается в подразумеваемом процессе, описанном внизу этого пункта. Из этого описания однозначно следует, что будет задержка именно на один дельта-цикл. Тем не менее, я сгрузил замечательный корманный справочник по VHDL-Handbook от hardi.com. Всем он, казалось бы, хорош, но там написано так "S'delayed .... 0 ns то есть тождественно S" (стр. 54). Я когда это прочитал, то уже знал (прочитал в другой книге и кодировал достаточно часто используя это), то на самом деле - задержка в 1 дельта-цикл. То, что стандарт пишет задержка на 0 ns - получается не совсем понятно для многих. Я уже с ними затеял переписку по этой теме. Дело в том, что дельта-циклы не предназначены для моделирования физики или кодирования спецификации конкретной микросхемы. То что они не предназначены для моделрования физики это понятно. Но на них построено все в VHDL, так что и возможность корректно закодировать специйикацию связана с их использованием. Использование postponed assert само по себе не может помочь проверить выполнение hold time specification. Потому что сигнал данных может измениться через 100 ps после фронта клока, и postponed assert это не увидит. Как Догадываюсь :-) что то, что ПОСЛЕ уж никак не увидеть СЕЙЧАС. же быть? Нужно написать корректное выражение, которое по нарастающему фронту клока будет проверять выполнение setup time, а по любому фронту данных выполнение hold time. Для этого проверочного условия абсолютно все равно, использован postponed assert или обычный, активируемый и вычисляемый, как и каждый обычный процесс, в каждом цикле, в котором активен хотя-бы один сигнал из его списка чувствительности. Речь изначально у меня шла о сигналах, где допустимо (по спецификации производителя), наличие переднего фронта сигнала A в момент времени до переднего фронта сигнала B, или же одновременные фронты сигналов A и B. И вот в этом случае, если в процессе дельта-циклов у меня приходил первым фронт сигнала B, а потом фронт сигнала А, то БЕЗ изпользования postponed получалось ложное сробатывание assert. И там речь даже об иголке не шла. Так что может быть лучше не будем спорить, а напишите assert по требованиям в предыдущем параграфе - без использования postponed. Я тоже так считаю. Про себя ;) Лучше публично похвалить себя, чем публично же покритиковать другого человека, не так ли? :-) Ну да, конечно. Введение прототипов функций - это очень маленький отход от K&R C. :) Это все-таки меньшее изменение, чем введение компонентов вида u1: entity XYZ(RTL), так ведь то были 2 человека против комитета, который несколько лет работал, а на первичную VHDL спецификацию грохнули что-ли 100 миллионов долларов? Да и пример с postponed не очень удачный, как я показал выше. Если код зависит от postponed, он IMHO не очень хорош. Если код, зависящий от postponed "не очень хорош", то зачем же добавили postponed в 93? Чтобы было легче писать плохой код? Это не ляп. Простите, но это опять Ваше непонимание устройства VHDL. Идеология VHDL очень сильно отличается от обычных процедурных языков для архитектуры Фон-Неймана. Простите, но это опять попытка переходить на личности, а не отвечать на вопросы. Я вам специально подчеркиваю очень конкретные вопросы, а если Вы не можете ответить, то и Ваши аргументы теряют убедительность. Допустим, я что-то делаю с сигналом в коде. Допустим, что мне нужно совершенно то же самое сделать с другим сигналом, и еще с одним. Что предлагает VHDL, если я использую, например S и S'delayed? Одно единственное - cut & paste - а это страшный грех для кодировшика. Вот простой пример, у меня оператор печати значений сигнала A: fprint(output,l, "%3dns A=%b e,a=%r %r le=%3dns la=%3dns lv=%b d=%b %b st=%r %r q=%r %r T=%b\n", fo(NOW), fo(A), fo(A'event), fo(A'active), fo(A'last_event), fo(A'last_active), fo(A'last_value), fo(A'delayed), fo(A'delayed(1 ns)), fo(A'stable), fo(A'stable(3 ns)), fo(A'quiet), fo(A'quiet(3 ns)), fo(A'transaction) ); а мне еще хотелось бы напечатать B и С и даже D. Ваши предложения? Что будем делать? Покряхтим и скопируем, а потом ручками A поменяем на B и т.д. Потом, вдруг, что-то захотели поменять, и опять идем правим во всех местах одно и то же. Это же классика - детский сад, давно пройденный этап в устоявшихся языках. Какое отношение моя потребность не копировать один и тот же код 3 раза, имеет отношение к Фон-Неймоновской архитектуре, процессу элаборации и не-динамическом порождению сигналов? Почему при вызове процедуры что-то должно порождаться? В Фортране, например, ничего не порождается, кроме адреса возврата на стеке. При вызове inline функции в C совершенно ничего не порождается вообще, равно как и при вызове макроса. Во-первых, сигнал можно передавать в процедуру. Более того, процедура может прсваивать ему новое значение. При этом используется именно драйвер сигнала из вызывающего процесса. Ничего не хочу передавать - хочу, чтобы процедура сдалала что-то в контексте вызвающего процесса. Я это, кстати, сразу написал, но Вы не заметили, наверно. Вызов процедуры еще не существует на этапе elaboration. Вызов определенного класса процедур не существует на этапе элаборации. Но не все вызовы процедур и функций в языках программирования основаны на Лямбда-формализме. Процедуры могут быть чисто лексического уровня. Таким образом, если нужно использовать внутри иерархии кода сигнальные атрибуты - нужно использовать не процедуры, а компоненты. Едва ли использования компонентов в такой ситуации, которую я описал приведт у упрощению кода и улучшению его читаемости. Хотя, конечно, да, это вариант. Но несколько тяжеловесный. С другой стороны, для проверки setup/hold time использовать такие атрибуты нет необходимости. Достаточно несигнальных атрибутов EVENT и LAST_EVENT. Кроме того, такое описание будет гораздо эффективнее, так как каждый сигнал отжирает много памяти, гораздо больше, чем связанный с ним простой тип. Обратите внимание на Да, тут соглашусь, более того если postponed процессы, то для setup/hold кроме одного LAST_EVENT ничего не нужно. include... А он реально нужен? Дело в том, что в VHDL модулем является не файл. В одном файле может быть несколько модулей - но они независимы. Вот размещать несколько модулей в одном файле - это очень скверная практика. Такая путанница начинается. library ieee; use ... - это именно строгость. И не в каждом файле, а перед каждым модулем, которому это нужно. Вы указываете, что инжектируете в пространство имен своего модуля имена из другого нестандартного для языка пакета. Нет, это не строгость.... Потому что если у меня 250 файлов в проекте, и в каждом из них я включаю одни и те же 10 библиотек, и вот у меня одни и те же 20 строчек, повторяются 250 раз - то есть5000 строчек, когда можно было бы обойтись 250. Или вот такой вопрос - у меня 250 файлов. Предположм, что я хочу на этапе моделирования использовать одно определение типа, а на этапе реализации - другое. Я, кстати, часто использую встроенные типы, вроде bit_vector. Они, в отличие от std_logic, не resolved, поэтому многие ошибки обнаруживаются на этапе elaboration, а не исполнения. #define... Очень сильное средство, которым многие пользуются неправильно. Замечательный пример - ну и как же на этапе моделирования сделать так, чтобы все было bit, а на реализацию - уже std_logic? При тотальной борьбе с препроцессингом в VHDL-е? Вот как бы было удобно, в каждом файле: #include "mytypes.vhdh" а в этом самом mytypes.vhdh: library ieee.numeric_bit; use numeric_bit.all; #define mybit bit #define myvector bitvector а при переходе к реализации, поменяли содержимое этого файла - и все уже на std_logic типах. А как добиться такого эффекта (замена bit на std_logic в 250 файлах) в чистом VHDL-е? Бонусный вопрос - как менять код для процесса моделирования и для синтеза? Убрать сигналы, которые не нужны в окончательном продукте? Масса проблем... Одной конфигураций очень мало для вего этого. Не думаю. VB ведь тоже пользуется популярностью. И plain C где нужно и где не нужно при наличии более совершенных языков. С - это один из очень соврешенных языков. C++ ближе к VHDL. Хотя мне приятнее писать на Perl-e. Есть совершенно замечательный язык ML - вот он очень бы очень Вам понравился - чисто функциональный язык. В некотором смысле, VHDL довольно похож на функциональный язык. Я когда-то даже занимался проработками на эту тему, как на ML специфицировать RTL. Ну что же, в результате этой дискуссии я поставил себе наконец ModelSim под Linux, и попытался приделать препроцессор cpp к vcom. Сделать это можно, но то, что язык в себя не включает таких возможностей изначально, очень сразу все запутывает. Классическая проблема - как по номеру строки с ошибкой в обработанном препроцессором коде найти строку, в необработанном коде, к которой относится ошибка? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Oldring 0 19 марта, 2007 Опубликовано 19 марта, 2007 · Жалоба Я уже с ними затеял переписку по этой теме. Надеюсь, не с комиитетом по стандартизации? В LRM написано все совершенно четко. Программисты, считающие, что чтения популярной литературы достаточно для понимания языка, пусть пеняют на себя :) Речь изначально у меня шла о сигналах, где допустимо (по спецификации производителя), наличие переднего фронта сигнала A в момент времени до переднего фронта сигнала B, или же одновременные фронты сигналов A и B. И вот в этом случае, если в процессе дельта-циклов у меня приходил первым фронт сигнала B, а потом фронт сигнала А, то БЕЗ изпользования postponed получалось ложное сробатывание assert. И там речь даже об иголке не шла. Так что может быть лучше не будем спорить, а напишите assert по требованиям в предыдущем параграфе - без использования postponed. Не совсем понял - подозреваю, что речь идет именно про ошибку в VHDL модели от производителя, которую Вы пытаетесь проверять. Так как сигнал A должен прийти не позже сигнала B, а он с точки зрения VHDL приходил именно позже. Как обходить ошибки производителя - это отдельный вопрос. Например: assert not( A'Event and A and B and B'Last_event > 0 ); сигналы типа boolean ;) Это все-таки меньшее изменение, чем введение компонентов вида u1: entity XYZ(RTL), так ведь то были 2 человека против комитета, который несколько лет работал, а на первичную VHDL спецификацию грохнули что-ли 100 миллионов долларов? Да неужели? Приведенный Вами пример с entity - это только сокращение записи. Раньше нужно было явно описывать компонент и конфигурацию, теперь можно написать так как Вы написали, остальное подразумевается. Ничего принципиально нового не введено. В отличие от прототипов для функций в сях. Вот уж где изменение первоначальной идеологии :) Если код, зависящий от postponed "не очень хорош", то зачем же добавили postponed в 93? Чтобы было легче писать плохой код? Подозреваю, что именно так. ;) Простите, но это опять попытка переходить на личности, а не отвечать на вопросы. Я вам специально подчеркиваю очень конкретные вопросы, а если Нет, это не переход на личности. Я тоже не сразу понял идеологию языка. Сейчас у Вас я вижу то же непонимание, которое было у меня когда-то. Чтобы от него избавиться, нужно внимательно прочитать LRM и хорошенько подумать, зачем те или иные вещи сделаны так, а не иначе. Допустим, я что-то делаю с сигналом в коде. Допустим, что мне нужно совершенно то же самое сделать с другим сигналом, и еще с одним. Что предлагает VHDL, если я использую, например S и S'delayed? Одно единственное - cut & paste - а это страшный грех для кодировшика. Вот простой пример, у меня оператор печати значений сигнала A: fprint(output,l, "%3dns A=%b e,a=%r %r le=%3dns la=%3dns lv=%b d=%b %b st=%r %r q=%r %r T=%b\n", fo(NOW), fo(A), fo(A'event), fo(A'active), fo(A'last_event), fo(A'last_active), fo(A'last_value), fo(A'delayed), fo(A'delayed(1 ns)), fo(A'stable), fo(A'stable(3 ns)), fo(A'quiet), fo(A'quiet(3 ns)), fo(A'transaction) ); а мне еще хотелось бы напечатать B и С и даже D. Ваши предложения? Что будем делать? Покряхтим и скопируем, а потом ручками A поменяем на B и т.д. Ключевое слово - сигнал. Более того, важно, что Вы хотите работать именно с атрибутами сигналов, запрещенными для использования в функциях. Подумайте сами хорошенько, почему атрибут DELAYED недопустимо использовать в функции, и во что это вылилось бы при симуляции, если бы можно было его использовать в любой функции. Если хотите печатать в одной конструкции задержанные сигналы - так напишите компонент, который будет печатать. Потом, вдруг, что-то захотели поменять, и опять идем правим во всех местах одно и то же. Это же классика - детский сад, давно пройденный этап в устоявшихся языках. Да, это именно классика. Если захотелось что-то поменять - нужно менять, а не рожать макрос. Иначе очень быстро код станет абсолютно нечитаемым. Какое отношение моя потребность не копировать один и тот же код 3 раза, имеет отношение к Фон-Неймоновской архитектуре, процессу элаборации и не-динамическом порождению сигналов? Почему при вызове процедуры что-то должно порождаться? В Фортране, например, ничего не порождается, кроме адреса возврата на стеке. При вызове inline функции в C совершенно ничего не порождается вообще, равно как и при вызове макроса. Ничего не хочу передавать - хочу, чтобы процедура сдалала что-то в контексте вызвающего процесса. Я это, кстати, сразу написал, но Вы не заметили, наверно. Она и делает что-то именно в контексте вызывающего процесса. Но то, что Вы хотите - процедуры делать не могут. То, что в Фортране ничего не порождается, а в VHDL должно порождаться - это именно следствия не Фон-Неймановской архитектуры. Вы у Фон-Неймана сигналы видели? Вызов определенного класса процедур не существует на этапе элаборации. Но не все вызовы процедур и функций в языках программирования основаны на Лямбда-формализме. Процедуры могут быть чисто лексического уровня. Могут быть. Это обычно называется "препроцессор". Или "шаблоны". Пока без этого можно обойтись - IMHO лучше обходиться. Дженерики позволяют делать многое из того, для чего обычно используются шаблоны, без кошмара полного отсутствия типизации. Вообще говоря, я плохо представляю, где в вызове процедуры могут потребоватся именно атрибуты, результат которых - сигналы. Несигнальных атрибутов как правило достаточно. Нет, это не строгость.... Потому что если у меня 250 файлов в проекте, и в каждом из них я включаю одни и те же 10 библиотек, и вот у меня одни и те же 20 строчек, повторяются 250 раз - то есть5000 строчек, когда можно было бы обойтись 250. Или вот такой вопрос - у меня 250 файлов. Предположм, что я хочу на этапе моделирования использовать одно определение типа, а на этапе реализации - другое. Замечательный пример - ну и как же на этапе моделирования сделать так, чтобы все было bit, а на реализацию - уже std_logic? При тотальной борьбе с препроцессингом в VHDL-е? Откройте секрет: зачем? Зачем в каждый из 250 файлов включать все 10 библиотек? Зачем вообще иметь 10 библиотек? Или Вы имеете в виду пакеты? Все равно - зачем? И по поводу реализации - то же самое. Синтезаторы прекрасно синтезируют встроенные типы. Бонусный вопрос - как менять код для процесса моделирования и для синтеза? Убрать сигналы, которые не нужны в окончательном продукте? Масса проблем... Одной конфигураций очень мало для вего этого. Тут ничего не поделаешь - моделирование и синтез - это часто разные системы. В проект синтезатора добавляешь файлы для синтеза, в проект симулятора - файлы для симуляции. Но не могли бы Вы привести пример, где для различных симуляций было бы недостаточно конфигураций и generic'ов? Вообще говоря, разработчиков синтезаторов убить мало: они почему-то решили, что очень хорошо знают, какие средства языка "лишние", даже если они никак не влияют собственно на синтез. Чем им помешали конфигурации? Или алиасы? С - это один из очень соврешенных языков. C++ ближе к VHDL. Хотя мне приятнее писать на Perl-e. Есть совершенно замечательный язык ML - вот он очень бы очень Вам понравился - чисто функциональный язык. В некотором смысле, VHDL довольно похож на функциональный язык. Я когда-то даже занимался проработками на эту тему, как на ML специфицировать RTL. Про перл... Давайте не будем углубляться в религиозные вопросы... Некоторым он тоже нравится... А еще ходят головоломки на декодирование перла... Что за язык ML? В первый раз слышу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrew_b 17 19 марта, 2007 Опубликовано 19 марта, 2007 · Жалоба Вообще говоря, разработчиков синтезаторов убить мало: они почему-то решили, что очень хорошо знают, какие средства языка "лишние", даже если они никак не влияют собственно на синтез. Чем им помешали конфигурации? Или алиасы? А что с элиасами не так? Synplify, XST, Quartus их поддерживают. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Oldring 0 19 марта, 2007 Опубликовано 19 марта, 2007 · Жалоба А что с элиасами не так? Synplify, XST, Quartus их поддерживают. Примерно год назад попытался воспользоваться. В связке XST + Modelsim. Оказалось, что поддерживать - поддерживают, но из-за глюков этой их поддержки пришлось отказаться. :( Если не лень - попробуйте, например, написать алиас для пакета. Потом написать функцию, имя типа аргумента у которой - полное с использованием этого алиаса. Разумеется, все без использования конструкции USE. Да и сами полняе имена с последнее время поддерживались как-то нестабильно... Похоже, у разработчиков нет достаточно полных тестов поддержки VHDL. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrew_b 17 19 марта, 2007 Опубликовано 19 марта, 2007 · Жалоба Примерно год назад попытался воспользоваться. В связке XST + Modelsim. Оказалось, что поддерживать - поддерживают, но из-за глюков этой их поддержки пришлось отказаться. :( Если не лень - попробуйте, например, написать алиас для пакета. Потом написать функцию, имя типа аргумента у которой - полное с использованием этого алиаса. Разумеется, все без использования конструкции USE. А-а-а... Вона вы про что. Не, я так не делаю. Нужды в этом пока не было. Я имел в виду элиасы для сигналов и переменных в функциях. С этим проблем нет. Да и не должно, если в элиасы используются в очень многих стандартных функциях. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vleo 0 25 марта, 2007 Опубликовано 25 марта, 2007 · Жалоба .... Что за язык ML? В первый раз слышу. К сожалению нет сейчас времени детально и аргументированно ответить. Но отвечу, когда разгребу проект. И вот - опять налетел на отсутствие препроцесоора в VHDL. Опять Вы скажете, что это стргость - но на мой взгляд, либо я не понимаю как это сделать средствами VHDL, либо это опять неоправданная ограниченность языка (глупость то есть): entity .... architecture ... type mystate is (S1,S2,S3,S4); signal state : mystate; signal a,b,c : std_logic; -- Variable declaration 'rd_data_state' not allowed in this region. variable V2 : boolean := (state = S1 or state = S2) ; begin a <= (state = S1 or state = S2) or ....; b<= (state = S1 or state = S2) and ....; c<= (state = S1 or state = S2) or ....; end; То есть у меня есть фрагмент (state = S1 or state = S2) который повторяется много раз. Попытка ввести переменные там или тут (V1 или V2) компилятору не нравятся. Макроопределиний - нет. ----- Написав, порылся в улучшениях 93 года и понял, что мои пожелания были уже услышаны, строгость понесла поражение и в язык ввели impure funcion и shared variable. Так что мои ощущения в отношении 87 совершенно правильные - VHDL 87 это тяжелый язык. 93 уже вменяемый. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Oldring 0 25 марта, 2007 Опубликовано 25 марта, 2007 · Жалоба К сожалению нет сейчас времени детально и аргументированно ответить. Но отвечу, когда разгребу проект. И вот - опять налетел на отсутствие препроцесоора в VHDL. Опять Вы скажете, что это стргость - но на мой взгляд, либо я не понимаю как это сделать средствами VHDL, либо это опять неоправданная ограниченность языка (глупость то есть): entity .... architecture ... type mystate is (S1,S2,S3,S4); signal state : mystate; signal a,b,c : std_logic; -- Variable declaration 'rd_data_state' not allowed in this region. variable V2 : boolean := (state = S1 or state = S2) ; begin a <= (state = S1 or state = S2) or ....; b<= (state = S1 or state = S2) and ....; c<= (state = S1 or state = S2) or ....; end; То есть у меня есть фрагмент (state = S1 or state = S2) который повторяется много раз. Попытка ввести переменные там или тут (V1 или V2) компилятору не нравятся. Макроопределиний - нет. ----- Написав, порылся в улучшениях 93 года и понял, что мои пожелания были уже услышаны, строгость понесла поражение и в язык ввели impure funcion и shared variable. Так что мои ощущения в отношении 87 совершенно правильные - VHDL 87 это тяжелый язык. 93 уже вменяемый. Вариантов есть несколько, даже без impure функций. Честно говоря, я с VHDL'87 не работал, и мне лень копать тот стандарт. Но даже без них можно кое-что сделать. Прежде всего, давайте вспомним утверждение, что если поведение кода зависит от точной раскладки по дельта-циклам - это признак плохого кода. Если же код не зависит от детальной раскладки по дельта-циклам - то можно вместо переменной использовать сигнал. В любом VHDL. И это самый правильный путь, соотвествующий естественной структуре железа - сначала будет структура, вычисляющая (state = S1 or state = S2), выход которой (сигнал) будет использоваться дальнейшей логикой. Кроме того, можно написать процесс, и уже в нем завести переменную. Конечно, придется внести все используемые сигналы в список чувствительности, если схема асинхронная. Ну или написать процедуру с длинным списком аругментов. Shared variables - большое зло, не пользуйтесь ими, особенно, не понимая всех последствий. По нескольким причинам. Они предназначены для гораздо более сложных вещей. См. protected types. P.S. Кстати, что Вы ходите добиться записью variable V2 : boolean := (state = S1 or state = S2) ;? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться