Как использовать итеративную переменную в кейсе [VHDL] - PullRequest
0 голосов
/ 19 февраля 2019

Я хочу создать свой интерфейс регистра, потому что у меня есть несколько экземпляров (каналов) одного и того же периферийного устройства.

while (I < generic_num_of_instances) loop
  case loc_addr is
    when 0 + I*256 =>
      q_ctrl_reg(I, 31 downto 0) <= s_axi_wdata;
  end case;
  I := I + 1;
end loop;

И он говорит: Ошибка: Выбор варианта должен быть локально статическим выражением.

Как мне создать этот интерфейс регистра?Должен ли я использовать менее описательные операторы if / elseif?

the error message

Ответы [ 3 ]

0 голосов
/ 19 февраля 2019

Да.Или используйте Verilog.

Варианты выбора VHDL должны быть локально статическими - то есть они должны быть литералами , константами или универсальными .Это не относится к Verilog.

Вы также обнаружите, что вам нужна ветка when others, которая сведет на нет все улучшения читаемости, полученные с помощью оператора case.(И учитывая, что такой стиль кодирования в любом случае довольно необычен, я бы усомнился, стал ли он еще более читабельным.)

0 голосов
/ 19 февраля 2019

Мэтью упомянул два важных улучшения: ваша цель case должна быть статическим выражением (тип которого является локально статическим типом), и если вы делаете синтез, вам нужно использовать цикл for.

Далее, вы не можете разрезать многомерный массив, следовательно, q_ctrl_reg (I, 31 до 0) также недопустим.Давайте исправим это, используя массив массива (показанный ниже):

type q_ctrl_reg_type is array (0 to MAX_REG -1) of std_logic_vector(31 downto 0) ; 
signal q_ctrl_reg : q_ctrl_reg_type ; 

Теперь давайте соберем все это вместе, позволим нам использовать цикл for вместо цикла while и оператор if вместо вашего оператора case:

for i in 0 to generic_num_of_instances - 1 loop
  if loc_addr = 0 + I*256 then
      q_ctrl_reg(I) <= s_axi_wdata;
  end if;
end loop;
0 голосов
/ 19 февраля 2019

попробуйте сделать это значение "0 + I * 256" равным переменной, которую вы называете в цикле, т.е.

while (I < generic_num_of_instances) loop
    variable A : integer;
begin
A := 0 + I*256;
  case loc_addr is
    when A =>
      q_ctrl_reg(I, 31 downto 0) <= s_axi_wdata;
  end case;
  I := I + 1;
end loop;

, надеюсь, это должно сработать

...