⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 alu.vhd

📁 16位RISC CPU的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 + -