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

Noran

Новичок
  • Постов

    1
  • Зарегистрирован

  • Посещение

Репутация

0 Обычный
  1. Добрый день, необходимо написать два кода Алу. Вот один из них: -- реализация простейшего АЛУ library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; use ieee.std_logic_unsigned.all; -- порты АЛУ -- reset - сброс -- op_code - код операции -- in1 - первый операнд -- in2 - второй операнд -- out1 - результат -- flag_z - флаг нулевого результата -- flag_cy - флаг переноса -- flag_ov - флаг переполнения entity alu is port( reset : in std_logic; op_code : in std_logic_vector (3 downto 0); in1 : in std_logic_vector (7 downto 0); in2 : in std_logic_vector (7 downto 0); out1 : out std_logic_vector (7 downto 0); flag_z : out std_logic; flag_cy : out std_logic; flag_ov : out std_logic); end alu; architecture behaviour of alu is --Коды операций, которые выполняет АЛУ constant alu_op_add : std_logic_vector (3 downto 0) := "0001"; constant alu_op_sub : std_logic_vector (3 downto 0) := "0010"; constant alu_op_mul : std_logic_vector (3 downto 0) := "0011"; constant alu_op_and : std_logic_vector (3 downto 0) := "0100"; constant alu_op_or : std_logic_vector (3 downto 0) := "0101"; constant alu_op_xor : std_logic_vector (3 downto 0) := "0110"; constant alu_op_ror : std_logic_vector (3 downto 0) := "0111"; constant alu_op_rol : std_logic_vector (3 downto 0) := "1000"; constant alu_op_not : std_logic_vector (3 downto 0) := "1001"; -- Процедура вычисляющая по значению результата значение флага OV procedure calc_overflow_flag ( result : in std_logic_vector (15 downto 0); overflow_flag : out std_logic ) is begin -- Проверяются старшие 8 бит результата if( result( 15 downto 8 ) /= "00000000" ) then -- Если они не нулевые, то установить флаг переполнения overflow_flag := '1'; else -- Если они нулевые, то сбросить флаг переполнения overflow_flag := '0'; end if; end calc_overflow_flag; procedure z_flag ( result : in std_logic_vector (15 downto 0); zero_flag : out std_logic ) is begin if( result = "00000000" ) then zero_flag := '1'; else zero_flag := '0'; end if; end z_flag; procedure c_flag ( result : in std_logic_vector (15 downto 0); carry_flag : out std_logic ) is begin if( result( 15 downto 8 ) /= "00000000" ) then carry_flag := '1'; else carry_flag := '0'; end if; end c_flag; begin process( reset, op_code, in1, in2 ) -- Временные переменные для хранения значений внутри процесса variable tmp_in1, tmp_in2 : std_logic_vector (15 downto 0); variable res : std_logic_vector (15 downto 0); variable res_z, res_cy, res_ov : std_logic; begin if reset = '0' then -- Обнуляем внутренние переменные и записываем в них -- входные значения -- Внутренние переменные имеют вдвое большую разрядность, чем -- входные, для того, что бы иметь возможность устанавливать -- флаги tmp_in1 := "0000000000000000"; tmp_in2 := "0000000000000000"; tmp_in1( 7 downto 0 ) := in1; tmp_in2( 7 downto 0 ) := in2; -- Определяем какой код операции установлен case op_code is when alu_op_add => res := tmp_in1 + tmp_in2; c_flag(res,res_cy); when alu_op_sub => res := tmp_in1 - tmp_in2; z_flag(res,res_z); when alu_op_mul => res := in1 * in2; calc_overflow_flag(res,res_ov); when alu_op_and => res := tmp_in1 and tmp_in2; z_flag(res,res_z); when alu_op_or => res := tmp_in1 or tmp_in2; z_flag(res,res_z); when alu_op_not => res := not tmp_in1; z_flag(res,res_z); when alu_op_xor => res := tmp_in1 xor tmp_in2; z_flag(res,res_z); when alu_op_rol => -- Циклический сдвиг влево res( 0 ) := tmp_in1( 7 ); res( 7 downto 1 ) := tmp_in1( 6 downto 0 ); when alu_op_ror => -- Циклический сдвиг вправо res( 7 ) := tmp_in1( 0 ); res( 1 to 7 ) := tmp_in1( 0 to 6 ); when others => -- Неизвестный код операции res := "ZZZZZZZZZZZZZZZZ"; end case; end if; -- Выдаем в порты 8 младших бит результата и -- значения флагов out1 <= res( 7 downto 0 ); flag_z <= res_z; flag_cy <= res_cy; flag_ov <= res_ov; end process; end behaviour; Тест - код:
×
×
  • Создать...