VHDL STD_LOGIC_VECTOR Подстановочные знаки

Я пытался написать конечный автомат в коде VHDL для простого 16-битного процессора, который я реализую на плате Altera DE1. В конечном автомате у меня есть оператор CASE, который обрабатывает различные 16-битные инструкции, которые вводятся в конечный автомат с помощью 16-битного STD_LOGIC_VECTOR. Однако у меня возникли небольшие проблемы в состоянии декодирования, когда конечный автомат декодирует инструкцию. Одна из инструкций - это ADD, которая принимает два регистра как операнды, а третий - как регистр назначения. Однако у меня также есть инструкция ADD, которая принимает регистр и 5-битное непосредственное значение в качестве операндов и второй регистр для назначения. Моя проблема в том, что в операторе CASE мне нужно различать две разные инструкции ADD. Итак, я подумал, что если я использую подстановочные знаки, такие как «-» или «X» в операторе CASE, я смогу различать эти два значения всего в двух случаях вместо того, чтобы перечислять все возможные комбинации регистр / непосредственное значение. Например:

    CASE IR IS --(IR stands for "Instruction Register")
      WHEN "0001------0-----" => (Go to 3-register add);
      WHEN "0001------1-----" => (Go to 2-register/immediate value add);
      WHEN OTHERS => (Do whatever);
    END CASE;

Это не единственные две инструкции, которые у меня есть, я просто поместил их, чтобы сделать этот пост немного короче. Когда я компилирую и запускаю этот код, процессор прекращает выполнение, когда переходит в состояние «декодирования». Кроме того, Quartus выдает много-много предупреждений вроде «Предупреждение о выборе VHDL в LC3FSM.vhd (37): игнорируемый выбор, содержащий мета-значение» «0001 ------ 0 -----» «« Я нахожусь на потеря относительно того, как это сделать. Я ДЕЙСТВИТЕЛЬНО не делаю и, вероятно, не нуждаюсь в определении каждой отдельной 16-битной комбинации, и я надеюсь, что есть способ использовать подстановочные знаки в STD_LOGIC_VECTOR, чтобы минимизировать количество комбинаций, которые мне придется определять.

Кто-нибудь знает, как это сделать?

Спасибо


person Eric Townsend    schedule 09.02.2012    source источник


Ответы (2)


Предполагая, что вам не нужны другие биты в инструкции, вы можете обойти это, замаскировав другие биты с помощью процесса предварительной проверки. (Или просто убедитесь, что другие биты сброшены при написании инструкции?)

Это действительно что-то вроде взлома.

предполагая, что IR хранится как переменная

if IR(15 downto 12) == "0001" then
    IR := IR_in(15 downto 12) & "0000000" & IR_in(5) & "00000";
else
    IR := IR_in
end if;

CASE IR IS --(IR stands for "Instruction Register")
  WHEN "0001000000000000" => (Go to 3-register add);
  WHEN "0001000000100000" => (Go to 2-register/immediate value add);
  WHEN OTHERS => (Do whatever);
END CASE;

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

person Paul Seeb    schedule 09.02.2012
comment
Ага, большое спасибо, Пол Сиб за ваше предложение. После того, как я вчера задал вопрос, я подумал об использовании оператора CASE для каждого кода операции, а затем с помощью оператора IF для других необходимых сравнений. Хотя ваш первый метод делает код немного короче, поэтому я использовал его. Спасибо, а также Марку Томпсону за ваше предложение. - person Eric Townsend; 10.02.2012

К сожалению, это невозможно. Довольно неожиданно для большинства пользователей оператор сравнения = и сравнение case выполняют буквальное сравнение. Это связано с тем, что тип std_logic - это просто набор символов, которые выполняют аналогичные логические значения из-за способа определения других функций (например, and и or).

VHDL-2008 представляет новый оператор case case?, который работает так, как вы ожидаете - вам нужно указать вашему компилятору работать в режиме VHDL 2008. Кроме того, в VHDL 2008 есть оператор ?=, который сравнивает два значения с учетом -s.

Если вы столкнулись с проблемой компилятора, который все еще не поддерживает VHDL 2008, пожаловаться поставщику. Существует также функция std_match, позволяющая выполнять сравнения в более старых версиях VHDL, но я ничего не знаю, чтобы заставить оператор case работать таким образом.

person Martin Thompson    schedule 09.02.2012
comment
К сведению тех, кто, как и я, пришел сюда после того, как наткнулся на ту же проблему с Xilinx ISE: новый случай? Заявление (как и большинство функций VHDL-2008) отсутствует в версии 14.4 (текущий выпуск на момент написания этой статьи), и неясно, когда и будет ли он в будущем. - person MartyMacGyver; 03.03.2013
comment
бета-поддержка VHDL2008 case? находится в Vivado2014.3 см. AR # 62005. Вы определенно не хотите предполагать, что он будет работать (как бета). - person pev.hall; 26.06.2015