Сделать арифметико-логическое устройство в vhdl

Мне нужно сделать арифметико-логическое устройство на VHDL для pic16f684. Итак, инструкции для ALU можно найти в даташите на pic16f684.

Инструкции, которые мне нужно сделать, следующие:

Это инструкции

Это мой код до сих пор, но я получаю, что вполне логично, ошибку, что std_logic_vector не может иметь символ в векторе, но я не знаю, как это сделать по-другому.

LIBRARY IEEE;
USE  IEEE.STD_LOGIC_1164.all;
USE  IEEE.STD_LOGIC_ARITH.all;
USE  IEEE.STD_LOGIC_UNSIGNED.all;

ENTITY AluPIC IS

   PORT(    -- Input Signals    
        Op_code     : in std_logic_vector(6 DOWNTO 0);
        win, fin        : in std_logic_vector(7 DOWNTO 0);
         -- Output Signals
        d,z : out std_logic;
        ALU_output  : out std_logic_vector(7 DOWNTO 0));


END AluPIC;

ARCHITECTURE behavior OF AluPIC IS
        -- declare signal(s) internal to module here
SIGNAL temp_output,wout,fout: std_logic_vector(7 DOWNTO 0);

BEGIN
  PROCESS (Op_code, win, fin)
    BEGIN
        -- Select Arithmetic/Logical Operation
    CASE Op_Code (6 DOWNTO 0) IS
        WHEN "000111d" =>
            if d ='0' then
                wout <= win + fin;
                temp_output <=wout;
            else
                fout <= win + fin;
                temp_output <= fout;
            end if;

        WHEN "000101d" =>
            if d ='0' then
                wout <= win and fin;
                temp_output <= wout;
            else
                fout <= win and fin;
                temp_output <= fout;
            end if;

        WHEN "000001l" =>
             fout <= fin;
             fout <= "00000000";
             z <= '1';
             temp_output <= fout;

        WHEN "001010d" =>
            fout <= fin+1;
             if d = '0' then
                wout <= fout;
                temp_output <=wout;
             else
                fout <= fout;
                temp_output <=fout;
            end if;

        WHEN "001000d" =>
        if d = '0' then
            wout  <= fin;
            temp_output <= wout;
            z <= '1';
        else
            fout <= fin;
            temp_output <= fout;
            z <= '1';
        end if;

        WHEN "0101bbb" =>
            fout <= fin;
             temp_output <= fout;
        WHEN OTHERS =>
            temp_output <= "00000000";
    END CASE;
            -- Select Shift Operation
    IF Op_Code(0) = '1' THEN
            -- Shift bits left with zero fill using concatination operator
            -- can also use VHDL 1076-1993 shift operator such as SLL 
        Alu_output <= temp_output(6 DOWNTO 0) & '0';
    ELSE 
        Alu_output <= temp_output;
    END IF;
  END PROCESS;
END behavior;

Спасибо за ваше время, ребята!


person Faalhaaz    schedule 04.01.2017    source источник


Ответы (1)


Такие строки, как WHEN "000111d" => или WHEN "0101bbb" =>, недействительны, потому что в вашем операторе case используется std_logic_vector, а "000111d" — это строка.

Непонятно, чего вы пытаетесь достичь с помощью ваших символов d и b, но ваши различные строки when должны сравниваться с допустимыми std_logic_vector правильной длины, например WHEN "0000111" =>.

Глядя на изображение вашего кода операции, оно показывает таблицу со строками, содержащими операции, например «ADDWF». В этих операциях только 6 старших битов выбирают операцию, а младший бит помечен b или d. Этот младший бит на самом деле является параметром операции, а не частью кода операции. В таблице не видно, какое влияние оказывает d на работу, но вы, похоже, это проработали. Используя ADDWF в качестве примера, я бы изменил ваш код следующим образом:

CASE Op_Code (6 DOWNTO 1) IS
  WHEN "000111" =>
    if Op_Code(0) ='0' then
      wout <= win + fin;
      temp_output <=wout;
    else
      fout <= win + fin;
      temp_output <= fout;
    end if;
  -- ...
end case;

Операция BSF является исключением, так как в качестве параметра используются младшие 3 бита. Вы можете написать это либо с помощью соответствующего оператора case, либо перечислив все возможности в одном case:

Соответствующий случай, требующий VHDL2008:

CASE? Op_Code (6 DOWNTO 1) IS
  WHEN "0101--" =>
    -- Set a bit based on `op_code (2 downto 0)`
end case?;

Перечислите все возможности:

CASE Op_Code (6 DOWNTO 1) IS
  WHEN "010100" | "010101" | "010110" | "010111" =>
    -- Set a bit based on `op_code (2 downto 0)`
end case;
person scary_jeff    schedule 04.01.2017
comment
До сих пор это было ясно, но как я могу решить это по-другому? Потому что, если вы посмотрите на инструкции, используется 01bb, и как я могу поместить эту инструкцию в std_logic_vector? - person Faalhaaz; 04.01.2017
comment
Вы должны более подробно прочитать руководства по PIC, чтобы понять, что они означают под bb или d, и внести соответствующие изменения. - person user_1818839; 04.01.2017
comment
хорошо @Faalhaaz Думаю, я понял вопрос, пожалуйста, посмотрите мое редактирование. - person scary_jeff; 04.01.2017
comment
Большое спасибо! Это не только дало мне решение, но теперь я понимаю его намного лучше! - person Faalhaaz; 04.01.2017
comment
Кстати, @scary_jeff, ? после утверждения дела, что это значит? - person Faalhaaz; 04.01.2017
comment
@Faalhaaz doulos.com/knowhow/vhdl_designers_guide/vhdl_2008/ - person scary_jeff; 04.01.2017