Перейти к содержанию
    

Прежде всего, давайте вспомним утверждение, что если поведение кода зависит от точной раскладки по дельта-циклам - это признак плохого кода. Если же код не зависит от детальной раскладки по дельта-циклам - то можно вместо переменной использовать сигнал. В любом 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 не меняется после присвоения переменной.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да уж, вообще, то, что поведение кода в 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;

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Мой жизненный опыт - количество строк не имеет практически никакого значения, если только не страдает читаемость кода. Мне никогда не платили за количество строк, на за большое, ни за малое.
Дело не столько в читаемости, сколько в локальности изменений - если нужно внося правку править автоматически в 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;

Изменено пользователем vleo

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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 =>

тоже должен работать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Дело не столько в читаемости, сколько в локальности изменений - если нужно внося правку править автоматически в 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 я обычно не занимаюсь. Всегда после некоторого размышления можно придумать, как организовать средствами языка код, чтобы не было необходимости в чрезмерном дублировании.

 

Кроме того, такой простой процесс можно легко описать в виде параллельного оператора, как было подсказано выше, или, если он чуть сложнее - как функцию, опять же, вызываемую из паралльного присваивания. Не нужно будет описывать список чувствительности. Да и присваивать начальное значение переменной в процедуре допустимо прямо при определении.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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 ... .

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо, да, я не знал про форму std_logic_vector' - это и есть кастинг.

 

Однако, на такую форму ModelSim говорит вот что:

 

** Warning: ...local_master.vhd(374): (vcom-1186) Array type case expression must be of a locally static subtype.

Ну warning, не error же. Но работает как надо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо, да, я не знал про форму 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 такая неоднозначность не возникает.

 

Что касается предупреждения Моделсима - причина его выдачи мне непонятна. На мой взгляд, подтип результата этой конкатенации является именно локально статическим. Возможно, это ошибка Моделсима.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Заметьте, что неоднозначность возникает из-за использования именно 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

 

Мораль из этого следующая....

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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 является базовым типом неограниченного массива, поэтому он не локально-статический. Моделсим разруливает выражение, хоть он и не обязан. Поэтому выдает предупреждение. Другие инструменты не разруливают. Вывод - нужно или явно предварительно определять подтип конкатенации, или писать по-другому.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
К сожалению, ваш контент содержит запрещённые слова. Пожалуйста, отредактируйте контент, чтобы удалить выделенные ниже слова.
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...