vleo 0 27 марта, 2007 Опубликовано 27 марта, 2007 · Жалоба Прежде всего, давайте вспомним утверждение, что если поведение кода зависит от точной раскладки по дельта-циклам - это признак плохого кода. Если же код не зависит от детальной раскладки по дельта-циклам - то можно вместо переменной использовать сигнал. В любом VHDL. И это самый правильный путь, соотвествующий естественной структуре железа - сначала будет структура, вычисляющая (state = S1 or state = S2), выход которой (сигнал) будет использоваться дальнейшей логикой. Да уж, вообще, то, что поведение кода в VHDL-е зависит от дельта циклов мне очень не нравится. Вроде бы они как раз и были предложены для того, чтобы результат на конец каждого момента модельного времени был один и тот же. Кстати, VHDL это единственный *истинно* параллельный ходовой язык программирования. Но он скорее ближе к ассемблеру - в плане тесной привязки к железу. А хотелось бы язык высокого уровня, но на тех же подходах.Потому что реальная жизнь она параллельная, и так или иначе все развитие выразительных средств вычислительной техники идет в сторону параллелизма. Это философское отступление :-) Так вот, поэтому не могу согласится с утверждением - "правильный путь, соотвествующий естественной структуре железа". Мне кажется, что программа упаковки нетлиста лучше разберется куда и как собрать термы. По сути меня в данном случае не волнует наличие или отсутствие сигнала "state = S1 or state = S2" Кроме того, можно написать процесс, и уже в нем завести переменную. Конечно, придется внести все используемые сигналы в список чувствительности, если схема асинхронная. Ну или написать процедуру с длинным списком аругментов. Я все-таки не могу понять базы Вашего жизненного опыта - каждая лишняя строка в коде - это стоит, грубо говоря, денег. Каждая строка - это инвестиция. Чем их меньше, при равных возможностях кода - тем лучше. В данном случае многословность ничего не дает - у меня простая задача - нужен способ символически обозначить часто встречающиеся условие, и если я могу это сдалать в несколько строк, в одном месте - с помощью impure function - у меня вышло так в результате: impure function rd_data_state return boolean is begin return state = RD_DATA0_ST or state = RD_DATA1_ST or state = RD_DATA2_ST; end function rd_data_state; Получается эквивалент: #define rd_data_state state = RD_DATA0_ST or state = RD_DATA1_ST or state = RD_DATA2_ST что мне и хотелось. Shared variables - большое зло, не пользуйтесь ими, особенно, не понимая всех последствий. По нескольким причинам. Они предназначены для гораздо более сложных вещей. См. protected types. P.S. Кстати, что Вы ходите добиться записью variable V2 : boolean := (state = S1 or state = S2) ;? Честно сказать, я еще еще не проникся как следует смыслом использования переменных для синтезируемого кода. Что я хотел добиться записью, не знаю, я имел в виду вышеуказанный define. Безусловно variable мне тут никак не помогала, если только она не на уровне процесса, опять же для записи какого-то логического условия для последующего использования, имеется в виде, что state не меняется после присвоения переменной. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Oldring 0 27 марта, 2007 Опубликовано 27 марта, 2007 · Жалоба Да уж, вообще, то, что поведение кода в VHDL-е зависит от дельта циклов мне очень не нравится. Вроде бы они как раз и были предложены для того, чтобы результат на конец каждого момента модельного времени был один и тот же. Кстати, VHDL это единственный *истинно* параллельный ходовой язык программирования. Но он скорее ближе к ассемблеру - в плане тесной привязки к железу. А хотелось бы язык высокого уровня, но на тех же подходах.Потому что реальная жизнь она параллельная, и так или иначе все развитие выразительных средств вычислительной техники идет в сторону параллелизма. Это философское отступление :-) Так вот, поэтому не могу согласится с утверждением - "правильный путь, соотвествующий естественной структуре железа". Мне кажется, что программа упаковки нетлиста лучше разберется куда и как собрать термы. По сути меня в данном случае не волнует наличие или отсутствие сигнала "state = S1 or state = S2" Ну так и напишите промежуточный сигнал вместо переменной - и пусть синтезаторы разбираются. Для синтеза дельта-циклы вообще безразличны. Они имеют значение для симуляции. Дельта-циклы - некоторая, на мой взгляд, неплохая идея разработчиков VHDL. Предложите более простую модель работы симулятора, не приводящую к большим неприятностям - можно будет её обсудить. Я все-таки не могу понять базы Вашего жизненного опыта - каждая лишняя строка в коде - это стоит, грубо говоря, денег. Каждая строка - это инвестиция. Чем их меньше, при равных возможностях кода - тем лучше. В данном случае многословность ничего не дает - у меня простая задача - нужен способ символически обозначить часто встречающиеся условие, и если я могу это сдалать в несколько строк, в одном месте - с помощью impure function - у меня вышло так в результате: impure function rd_data_state return boolean is begin return state = RD_DATA0_ST or state = RD_DATA1_ST or state = RD_DATA2_ST; end function rd_data_state; Получается эквивалент: #define rd_data_state state = RD_DATA0_ST or state = RD_DATA1_ST or state = RD_DATA2_ST что мне и хотелось. Честно сказать, я еще еще не проникся как следует смыслом использования переменных для синтезируемого кода. Что я хотел добиться записью, не знаю, я имел в виду вышеуказанный define. Безусловно variable мне тут никак не помогала, если только она не на уровне процесса, опять же для записи какого-то логического условия для последующего использования, имеется в виде, что state не меняется после присвоения переменной. Мой жизненный опыт - количество строк не имеет практически никакого значения, если только не страдает читаемость кода. Мне никогда не платили за количество строк, на за большое, ни за малое. Штатная альтернатива, про которую я писал: architecture ... signal rd_data_state : boolean; begin rd_data_state <= state = RD_DATA0_ST or state = RD_DATA1_ST or state = RD_DATA2_ST; Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vleo 0 28 марта, 2007 Опубликовано 28 марта, 2007 (изменено) · Жалоба Мой жизненный опыт - количество строк не имеет практически никакого значения, если только не страдает читаемость кода. Мне никогда не платили за количество строк, на за большое, ни за малое.Дело не столько в читаемости, сколько в локальности изменений - если нужно внося правку править автоматически в 5 местах (из-за дупликации кода), то это очень плохо. Хорошо - уточню - не количество строк, а количество строк выросшее за счет cut/paste - это очень плохо и дорого по времени, по надежности, в результате - по деньгам. Вот опять у меня маленький пример разбухания количества строк (+2) - может быть конечно не догадался как лучше - но такое впечатление что прямого cast-ing-а типов нет в VHDL - то есть какой будет эквивалент VHDL для C-шного "(std_logic_vector(2 downt 1)) xyz" ? pciCmdGen: process (mem_rd,mem_wr_reg) variable tmp : std_logic_vector(1 downto 0); begin tmp := mem_rd & mem_wr_reg; case tmp is when "10" => cben <= CMD_RD; when "01" => cben <= CMD_WR; when others => cben <= "0000"; end case; end process; Изменено 28 марта, 2007 пользователем vleo Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vetal 0 28 марта, 2007 Опубликовано 28 марта, 2007 · Жалоба 2 vleo: ваш пример можно сократить до: cmd_decoder:cben<= CMD_RD when mem_rd='1' and mem_wr_reg='0' else CMD_WR when mem_rd='0' and mem_wr_reg='1' else (others=>'0'); !! всего 2 строчки. Можно и в 1 строчку написать. и вариант №2: case conv_integer(std_logic_vector'(mem_rd &mem_wr_reg)) is when 2 => when 1 => when others => case std_logic_vector'(mem_rd &mem_wr_reg) is when "10" => when "01" => when others => тоже должен работать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Oldring 0 28 марта, 2007 Опубликовано 28 марта, 2007 · Жалоба Дело не столько в читаемости, сколько в локальности изменений - если нужно внося правку править автоматически в 5 местах (из-за дупликации кода), то это очень плохо. Хорошо - уточню - не количество строк, а количество строк выросшее за счет cut/paste - это очень плохо и дорого по времени, по надежности, в результате - по деньгам. Вот опять у меня маленький пример разбухания количества строк (+2) - может быть конечно не догадался как лучше - но такое впечатление что прямого cast-ing-а типов нет в VHDL - то есть какой будет эквивалент VHDL для C-шного "(std_logic_vector(2 downt 1)) xyz" ? pciCmdGen: process (mem_rd,mem_wr_reg) variable tmp : std_logic_vector(1 downto 0); begin tmp := mem_rd & mem_wr_reg; case tmp is when "10" => cben <= CMD_RD; when "01" => cben <= CMD_WR; when others => cben <= "0000"; end case; end process; Кастинг типов из чисел в вектора есть. Функциями. Посмотрите стандартные пакеты ieee.numeric_std и ieee.numeric_bit. И встроенный кастинг есть. Разумеется, только между близкими типами. Неявный - только между подтипами одного типа, при этом run-time проверяется соответствие ограничений для подтипа результата. Только при симуляции, разумеется :) При необходимости функции преобразования пишутся для того, для чего их нехватает. Например, для boolean <=> бит. Свои стилистические библиотеки писать никто не запрещает :) И, кстати, зачем писать так, как написали Вы? Не понятнее ли написать if/elsif/else? То есть, конечно, понятно, что тут обрабатывается случай одновременного получения команды записи и чтения :) Только не повод ли это для простого ассерта и последовательного условия опосля? Единственное, что после плюсов напрягает - необходимость описывать все переменные в самом начале процесса или в архитектуры. И отсутствие вложенных блоков в последовательных конструкциях. Но вообще-то и в С почти так же - только можно вложенные блоки писать во множестве. Но эти неудобства вообще-то не слижком существенны так как всегда можно написать иерархию функций. :) Copy/paste я обычно не занимаюсь. Всегда после некоторого размышления можно придумать, как организовать средствами языка код, чтобы не было необходимости в чрезмерном дублировании. Кроме того, такой простой процесс можно легко описать в виде параллельного оператора, как было подсказано выше, или, если он чуть сложнее - как функцию, опять же, вызываемую из паралльного присваивания. Не нужно будет описывать список чувствительности. Да и присваивать начальное значение переменной в процедуре допустимо прямо при определении. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
oval 0 29 марта, 2007 Опубликовано 29 марта, 2007 · Жалоба 2 vleo: ваш пример можно сократить до: cmd_decoder:cben<= CMD_RD when mem_rd='1' and mem_wr_reg='0' else CMD_WR when mem_rd='0' and mem_wr_reg='1' else (others=>'0'); !! всего 2 строчки. Можно и в 1 строчку написать. и вариант №2: case conv_integer(std_logic_vector'(mem_rd &mem_wr_reg)) is when 2 => when 1 => when others => case std_logic_vector'(mem_rd &mem_wr_reg) is when "10" => when "01" => when others => тоже должен работать. Можно также использовать конструкцию with ... select ... , которая является аналогом конструкции case ... . Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vleo 0 4 апреля, 2007 Опубликовано 4 апреля, 2007 · Жалоба 2 vleo: ваш пример можно сократить до: cmd_decoder:cben<= CMD_RD when mem_rd='1' and mem_wr_reg='0' else CMD_WR when mem_rd='0' and mem_wr_reg='1' else (others=>'0'); !! всего 2 строчки. Можно и в 1 строчку написать. и вариант №2: case conv_integer(std_logic_vector'(mem_rd &mem_wr_reg)) is when 2 => when 1 => when others => case std_logic_vector'(mem_rd &mem_wr_reg) is when "10" => when "01" => when others => тоже должен работать. Спасибо, да, я не знал про форму std_logic_vector' - это и есть кастинг. Однако, на такую форму ModelSim говорит вот что: ** Warning: ...local_master.vhd(374): (vcom-1186) Array type case expression must be of a locally static subtype. Вариант с переходом к integer работает без предупреждений. А то, что можно, конечно записать по другому, то это понятно, интересовало именно как из катенации std_logic получить std_logic_vector. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
andrew_b 17 4 апреля, 2007 Опубликовано 4 апреля, 2007 · Жалоба Спасибо, да, я не знал про форму std_logic_vector' - это и есть кастинг. Однако, на такую форму ModelSim говорит вот что: ** Warning: ...local_master.vhd(374): (vcom-1186) Array type case expression must be of a locally static subtype. Ну warning, не error же. Но работает как надо. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Oldring 0 4 апреля, 2007 Опубликовано 4 апреля, 2007 · Жалоба Спасибо, да, я не знал про форму std_logic_vector' - это и есть кастинг. Однако, на такую форму ModelSim говорит вот что: ** Warning: ...local_master.vhd(374): (vcom-1186) Array type case expression must be of a locally static subtype. Вариант с переходом к integer работает без предупреждений. А то, что можно, конечно записать по другому, то это понятно, интересовало именно как из катенации std_logic получить std_logic_vector. std_logic_vector'() - это вообще-то не есть кастинг. Кастинг - это std_logic_vector() ;) std_logic_vector'() - это квалификация типа, просто обозначение типа результата выражения для разрешения неоднозначности при оверлоадинге. В отличие от плюсов, в VHDL при разрешении оверлоадинга учитывается тип результата выражения. Заметьте, что неоднозначность возникает из-за использования именно std_logic как типа аргументов операции конкатенации. Есть два похожих типа: std_logic_vector и std_ulogic_vector. При использовании типа bit такая неоднозначность не возникает. Что касается предупреждения Моделсима - причина его выдачи мне непонятна. На мой взгляд, подтип результата этой конкатенации является именно локально статическим. Возможно, это ошибка Моделсима. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vleo 0 4 апреля, 2007 Опубликовано 4 апреля, 2007 · Жалоба Заметьте, что неоднозначность возникает из-за использования именно std_logic как типа аргументов операции конкатенации. Есть два похожих типа: std_logic_vector и std_ulogic_vector. При использовании типа bit такая неоднозначность не возникает. Что касается предупреждения Моделсима - причина его выдачи мне непонятна. На мой взгляд, подтип результата этой конкатенации является именно локально статическим. Возможно, это ошибка Моделсима. Ну да, ModelSim изначально именно в этом духе и ругался - про logic и ulogic. library ieee; use ieee.std_logic_1164.all; entity E is end; architecture A of E is signal mem_rd,mem_wr : std_logic; signal mCben : std_logic_vector(3 downto 0); begin process (mem_rd,mem_wr) subtype slv2 is std_logic_vector(1 downto 0); begin case std_logic_vector'(mem_rd & mem_wr) is when "10" => mCben <= "0110"; when "01" => mCben <= "0111"; when others => mCben <= "0000"; end case; end process; end; хоть умри, но хочет еще одну строчку чтобы вписали - убрали переменную tmp, но появилось объявление подтипа. Вряд ли это ошибка в ModelSim, напомню его реакцию, ** Warning: z.vhd(14): (vcom-1186) Array type case expression must be of a locally static subtype. так как ghdl еще жестче реагирует на конструкцию case std_logic_vector'(mem_rd & mem_wr) : ghdl -a z.vhd z.vhd:14:11: type mark is not a locally static subtype ghdl: compilation error Ну а gvhdl дает еще больше конкретной ругани и пищи для размышлений: gvhdl --libieee z.vhd gvhdl: FreeHDL root path is '/usr'. gvhdl: executing '/usr/bin/freehdl-v2cc -m z._main_.cc -L /usr/share/freehdl/lib -o z.cc z.vhd' z.vhd:15: error: length of selection array (=-2147483648) does not match length of choice (=2). z.vhd:16: error: length of selection array (=-2147483648) does not match length of choice (=2). z.vhd:14: warning: no choice coverage checking is done due to previous errors. gvhdl: Compilation failed! Died at /usr/bin/gvhdl line 208. И уж коли мы исследовали большую часть VHDL компиляторов, то не обойти и Aldec-AHDL: # Compile... # File: q:\tmp\VHDL\z.vhd # Compile Entity "E" # Compile Architecture "A" of Entity "E" # Error: COMP96_0316: z.vhd : (14, 11): Case expression must be of a locally static subtype. # Compile failure 1 Errors 0 Warnings Analysis time : 0.5 Что наводит на мысли о том, что engine у Aldec-а тянутый/лицензированный от ModelSim-а. Ну и не забудем про Synplify - однако он либерален: @I:: "Q:/tmp/VHDL/z.vhd" VHDL syntax check successful! На десерт спросим QuartusII: Command: quartus_map ... --analyze_file=Q:\tmp\VHDL\z.vhd Info: Quartus II Analyze Current File was successful. 0 errors, 0 warnings Мораль из этого следующая.... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Oldring 0 4 апреля, 2007 Опубликовано 4 апреля, 2007 · Жалоба library ieee; use ieee.std_logic_1164.all; entity E is end; architecture A of E is signal mem_rd,mem_wr : std_logic; signal mCben : std_logic_vector(3 downto 0); begin process (mem_rd,mem_wr) subtype slv2 is std_logic_vector(1 downto 0); begin case std_logic_vector'(mem_rd & mem_wr) is when "10" => mCben <= "0110"; when "01" => mCben <= "0111"; when others => mCben <= "0000"; end case; end process; end; Очевидно, Вы хотели написать case slv2'(mem_rd & mem_wr) is Вряд ли это ошибка в ModelSim, напомню его реакцию, ** Warning: z.vhd(14): (vcom-1186) Array type case expression must be of a locally static subtype. так как ghdl еще жестче реагирует на конструкцию case std_logic_vector'(mem_rd & mem_wr) : ghdl -a z.vhd z.vhd:14:11: type mark is not a locally static subtype ghdl: compilation error Ну а gvhdl дает еще больше конкретной ругани и пищи для размышлений: gvhdl --libieee z.vhd gvhdl: FreeHDL root path is '/usr'. gvhdl: executing '/usr/bin/freehdl-v2cc -m z._main_.cc -L /usr/share/freehdl/lib -o z.cc z.vhd' z.vhd:15: error: length of selection array (=-2147483648) does not match length of choice (=2). z.vhd:16: error: length of selection array (=-2147483648) does not match length of choice (=2). z.vhd:14: warning: no choice coverage checking is done due to previous errors. gvhdl: Compilation failed! Died at /usr/bin/gvhdl line 208. И уж коли мы исследовали большую часть VHDL компиляторов, то не обойти и Aldec-AHDL: # Compile... # File: q:\tmp\VHDL\z.vhd # Compile Entity "E" # Compile Architecture "A" of Entity "E" # Error: COMP96_0316: z.vhd : (14, 11): Case expression must be of a locally static subtype. # Compile failure 1 Errors 0 Warnings Analysis time : 0.5 Что наводит на мысли о том, что engine у Aldec-а тянутый/лицензированный от ModelSim-а. Ну и не забудем про Synplify - однако он либерален: @I:: "Q:/tmp/VHDL/z.vhd" VHDL syntax check successful! На десерт спросим QuartusII: Command: quartus_map ... --analyze_file=Q:\tmp\VHDL\z.vhd Info: Quartus II Analyze Current File was successful. 0 errors, 0 warnings Мораль из этого следующая.... Инсталляция Active HDL у меня когда-то прямо конфликтовала по DLL с моделсимом. Но я им сейчас не пользуюсь. Я, пожалуй, соглашусь. Это как раз сложное место в стандарте. Тип результата квалификации будет только тогда локально статическим, когда индикатор типа локально-статический. Тип std_logic_vector является базовым типом неограниченного массива, поэтому он не локально-статический. Моделсим разруливает выражение, хоть он и не обязан. Поэтому выдает предупреждение. Другие инструменты не разруливают. Вывод - нужно или явно предварительно определять подтип конкатенации, или писать по-другому. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться