VHDL STD_LOGIC_VECTOR Значения подстановочных знаков - PullRequest
5 голосов
/ 09 февраля 2012

Я пытался написать конечный автомат в коде VHDL для простого 16-разрядного процессора, который я реализую на плате Altera DE1. В Finite State Machine у ​​меня есть оператор CASE, который обрабатывает различные 16-битные инструкции, которые вводятся в FSM 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 есть способ использовать подстановочные знаки, чтобы минимизировать количество комбинаций, которые мне придется определять.

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

Спасибо

Ответы [ 2 ]

5 голосов
/ 09 февраля 2012

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

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

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

1 голос
/ 09 февраля 2012

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

Это действительно немного хака.

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

...