OpenCores
URL https://opencores.org/ocsvn/tiny64/tiny64/trunk

Subversion Repositories tiny64

[/] [tiny64/] [trunk/] [ALU.vhd] - Rev 4

Compare with Previous | Blame | View Log

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
 
use work.TinyXconfig.ALL;
 
--  Uncomment the following lines to use the declarations that are
--  provided for instantiating Xilinx primitive components.
--library UNISIM;
--use UNISIM.VComponents.all;
 
entity ALU is
    Port ( opa : in cpuWord;
           opb : in cpuWord;
           res : out cpuWord;
           cin : in std_logic;
           cout : out std_logic;
           zero : out std_logic;
           sign : out std_logic;
           over : out std_logic;
           what : in std_logic_vector(3 downto 0));
end ALU;
 
architecture Behavioral of ALU is
 
  constant alu_mov   : std_logic_vector(3 downto 0) := "0000";
  constant alu_and   : std_logic_vector(3 downto 0) := "0001";
  constant alu_or    : std_logic_vector(3 downto 0) := "0010";
  constant alu_xor   : std_logic_vector(3 downto 0) := "0011";
  constant alu_add   : std_logic_vector(3 downto 0) := "0100";
  constant alu_sub   : std_logic_vector(3 downto 0) := "0101";
  constant alu_ror   : std_logic_vector(3 downto 0) := "0110";
  constant alu_lsr   : std_logic_vector(3 downto 0) := "0111";
  constant alu_lsra  : std_logic_vector(3 downto 0) := "1000";
  constant alu_swap  : std_logic_vector(3 downto 0) := "1001";
  constant alu_swapb : std_logic_vector(3 downto 0) := "1010";
  constant alu_inc   : std_logic_vector(3 downto 0) := "1011";
  constant alu_dec   : std_logic_vector(3 downto 0) := "1100";
  constant alu_rorb  : std_logic_vector(3 downto 0) := "1101";
 
begin
 
  assert XLEN > 31 report "XLEN must at least 32 and multiple of 8";
  assert (XLEN rem 8) = 0 report "XLEN must at least 32 and multiple of 8"; 
 
  process(opa, opb, cin, what)
    variable temp   : std_logic_vector(XLEN downto 0);
    variable ctr    : integer;
    variable help   : std_logic_vector((XLEN-1) downto 0);
    variable helper : std_logic_vector(XLEN downto 0);
  begin
    case what is
      when alu_mov =>
        res  <= opb;
        temp := ("0" & opb);
        cout <= cin;
        over <= '0';
      when alu_and =>
        res  <= opa and opb;
        temp := ("0" & opa) and ("0" & opb);
        cout <= cin;
        over <= '0';
      when alu_or  =>
        res  <= opa or opb;
        temp := ("0" & opa) or ("0" & opb);
        cout <= cin;
        over <= '0';
      when alu_xor =>
        res  <= opa xor opb;
        temp := ("0" & opa) xor ("0" & opb);
        cout <= cin;
        over <= '0';
      when alu_add =>
        res  <= opa + opb + (getStdLogicVectorZeroes(XLEN-1) & cin);
        temp := ("0" & opa) + ("0" & opb) + (getStdLogicVectorZeroes(XLEN-1) & cin);
        cout <= temp(XLEN);
        over <= (opa(XLEN-1) and opb(XLEN-1) and  not temp(XLEN-1)) OR (not opa(XLEN-1) and not opb(XLEN-1) and temp(XLEN-1));
      when alu_sub =>
        res  <= opa - opb - (getStdLogicVectorZeroes(XLEN-1) & cin);
        temp := ("0" & opa) - ("0" & opb) - (getStdLogicVectorZeroes(XLEN-1) & cin);
        cout <= temp(XLEN);
        over <= (opa(XLEN-1) and opb(XLEN-1) and not temp(XLEN-1)) OR (not opa(XLEN-1) and not opb(XLEN-1) and temp(XLEN-1));
      when alu_ror =>
        res  <= opa(0) & opa((XLEN-1) downto 1);
        temp := "0" & opa(0) & opa((XLEN-1) downto 1);
        cout <= opa(0);
        over <= '0';
      when alu_lsr =>
        res  <= cin & opa((XLEN-1) downto 1);
        temp := "00" & opa((XLEN-1) downto 1);
        cout <= opa(0);
        over <= '0';
      when alu_lsra =>
        res  <= opa(XLEN-1) & opa((XLEN-1) downto 1);
        temp := "0" & opa(XLEN-1) & opa((XLEN-1) downto 1);
        cout <= opa(0);
        over <= '0';
      when alu_swap =>
        res  <= opa((XLEN/2-1) downto 0) & opa((XLEN-1) downto (XLEN/2));
        temp := "0" & opa((XLEN/2-1) downto 0) & opa((XLEN-1) downto (XLEN/2));
        cout <= cin;
        over <= '0';
      when alu_swapb =>
        ctr := XLEN / 8;
        help := opa(7 downto 0) & getStdLogicVectorZeroes(XLEN-8);
        swb: for index in 1 to ctr-2 loop
          help := help or (getStdLogicVectorZeroes(index*8) & opa(((index+1)*8-1) downto (index*8)) & getStdLogicVectorZeroes((ctr-index-1)*8));
        end loop;
        help := help or (getStdLogicVectorZeroes(XLEN-8) & opa((XLEN-1) downto (XLEN-8)));
        res <= help;
        helper := "0" & opa(7 downto 0) & getStdLogicVectorZeroes(XLEN-8);
        swt: for index in 1 to ctr-2 loop
          helper := helper or ("0" & getStdLogicVectorZeroes(index*8) & opa(((index+1)*8-1) downto (index*8)) & getStdLogicVectorZeroes((ctr-index-1)*8));
        end loop;
        helper := helper or ("0" & getStdLogicVectorZeroes(XLEN-8) & opa((XLEN-1) downto (XLEN-8)));
        temp := helper;
        --res <= opa(7 downto 0) & opa(15 downto 8) & opa(23 downto 16) & opa(31 downto 24);
        --temp := "0" & opa(7 downto 0) & opa(15 downto 8) & opa(23 downto 16) & opa(31 downto 24);
        cout <= cin;
        over <= '0';
      when alu_inc =>
        res  <= opa + "1" + cin;
        temp := opa + "1" + cin;
        cout <= temp(XLEN);
        over <= '0';
      when alu_dec =>
        res  <= opa - "1" - cin;
        temp := opa - "1" - cin;
        cout <= temp(XLEN);
        over <= '0';
      when alu_rorb =>
        res  <= opa(7 downto 0) & opa((XLEN-1) downto 8);
        temp := "0" & opa(7 downto 0) & opa((XLEN-1) downto 8);
        cout <= cin;
        over <= '0';
      when others =>
        res  <= getStdLogicVectorZeroes(XLEN);
        temp := getStdLogicVectorZeroes(XLEN);
        cout <= cin;
        over <= '0';
    end case;
    sign <= temp(XLEN-1);
    if temp((XLEN-1) downto 0) = 0 then
      zero <= '1';
    else
      zero <= '0';
    end if;
  end process;
end Behavioral;
 
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.