📄 alu.vhd
字号:
-----------------------------------------------------------------------------
-- Copyright (C) 2005 IMEC -
-- -
-- Redistribution and use in source and binary forms, with or without -
-- modification, are permitted provided that the following conditions -
-- are met: -
-- -
-- 1. Redistributions of source code must retain the above copyright -
-- notice, this list of conditions and the following disclaimer. -
-- -
-- 2. Redistributions in binary form must reproduce the above -
-- copyright notice, this list of conditions and the following -
-- disclaimer in the documentation and/or other materials provided -
-- with the distribution. -
-- -
-- 3. Neither the name of the author nor the names of contributors -
-- may be used to endorse or promote products derived from this -
-- software without specific prior written permission. -
-- -
-- THIS CODE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' -
-- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED -
-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A -
-- PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR -
-- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -
-- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -
-- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF -
-- USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND -
-- ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -
-- OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT -
-- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -
-- SUCH DAMAGE. -
-- -
-- -----------------------------------------------------------------------------
-- Project : Micro6 microprocessor
-- Author : Osman Allam
-- File : alu.vhd
-- Design : ALU
-- -----------------------------------------------------------------------------
-- Description : Arithmetic and logic unit
-- The ALU performs arithmetic and logic operations on two operands A and B. the
-- required operations is specified by the input port "sel". The output shows on
-- the output port "result". The ALU updates the condition flags (neg, ovf, zro)
-- as a result of the computation.
-- -----------------------------------------------------------------------------
-- History :
-- 1/12/06 : vwb : use functions +,- .... from numeric_std instead of micro_pk
--
--------------------------------------------------------------------------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use WORK.micro_pk.all;
entity alu is
port (
a : in std_logic_vector (DATA_WIDTH - 1 downto 0);
b : in std_logic_vector (DATA_WIDTH - 1 downto 0);
sel : in alu_op;
shiftCnt : in std_logic_vector (4 downto 0); -- shift count
shiftCntSrc : in std_logic; -- shift count source (*)
result : out std_logic_vector (DATA_WIDTH - 1 downto 0);
neg : out std_logic; -- negative
ovf : out std_logic; -- overflow
zro : out std_logic -- zero
);
-- (*) shiftCntSrc:
-- when 0, the shift count is the input shiftCnt, otherwise, it is the least
-- significant slice of the input b.
end entity;
architecture behavioral of alu is
signal cnt_i : integer range 0 to 31; -- actual shift count
signal result_i : std_logic_vector(result'range);
function is_neg (arg: signed) return boolean is
begin
return ( not is_pos(arg));
end function;
begin
cnt_i <= to_integer(unsigned(b (4 downto 0))) when (shiftCntSrc = '1') else
to_integer(unsigned(shiftCnt));
computation: process (a,b,sel,cnt_i)
variable result_v : std_logic_vector(result'range);
begin
ovf <='0'; -- default value
case sel is
when ADD_OP =>
result_v := std_logic_vector(signed(a) + signed(b));
if (is_pos(signed(a)) and is_pos(signed(b)) and is_neg(signed(result_v))) or
(is_neg(signed(a)) and is_neg(signed(b)) and is_pos(signed(result_v))) then
ovf <='1';
else
ovf <='0';
end if;
when SUB_OP =>
result_v := std_logic_vector(signed(a) - signed(b));
if (is_pos(signed(a)) and is_neg(signed(b)) and is_neg(signed(result_v))) or
(is_neg(signed(a)) and is_pos(signed(b)) and is_pos(signed(result_v))) then
ovf <='1';
else
ovf <='0';
end if;
when MULT_OP =>
result_v := std_logic_vector(MultL(signed(a),signed(b)));
ovf <= truncated(signed(a), a'length/2) or truncated(signed(b), b'length/2);
-- when DIV_OP => -- not implemented
-- when REM_OP => -- not implemented
when INC_OP =>
result_v := std_logic_vector(signed(a) + 1);
if (is_pos(signed(a)) and is_neg(signed(result_v))) then
ovf <='1';
else
ovf <='0';
end if;
when DEC_OP =>
result_v := std_logic_vector(signed(a) - 1);
if (is_neg(signed(a)) and is_pos(signed(result_v))) then
ovf <='1';
else
ovf <='0';
end if;
when ZRO_OP =>
result_v := (others => '0');
when AND_OP =>
result_v := a and b;
when OR_OP =>
result_v := a or b;
when XOR_OP =>
result_v := a xor b;
when INV_OP =>
result_v := not a;
when PASS_A =>
result_v := a;
when PASS_B =>
result_v := b;
when SHR_ARTH =>
result_v := std_logic_vector(shift_right(signed(a), cnt_i));
when SHR_LGC =>
result_v := std_logic_vector(shift_right(unsigned(a), cnt_i));
when SHL_ARTH =>
result_v := std_logic_vector(shift_left (signed(a), cnt_i));
result_v(result_i'left) := a(a'left);
when SHL_LGC =>
result_v := std_logic_vector(shift_left (unsigned(a), cnt_i));
when ROTR =>
result_v := std_logic_vector(rotate_right(signed(a), cnt_i));
when ROTL =>
result_v := std_logic_vector(rotate_left(signed(a), cnt_i));
when others =>
result_v := a;
end case;
result_i <= result_v;
end process computation;
conditionFlags: process (result_i)
begin
-- zero flag
if (result_i = (result_i'range => '0')) then
zro <= '1';
else
zro <= '0';
end if;
-- negative flag
if (is_neg(signed(result_i))) then
neg <= '1';
else
neg <= '0';
end if;
end process;
end architecture;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -