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

Subversion Repositories tiny64

[/] [tiny64/] [trunk/] [ALU.vhd] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 riedelx
library IEEE;
2
use IEEE.STD_LOGIC_1164.ALL;
3
use IEEE.STD_LOGIC_ARITH.ALL;
4
use IEEE.STD_LOGIC_UNSIGNED.ALL;
5
 
6
use work.TinyXconfig.ALL;
7
 
8
--  Uncomment the following lines to use the declarations that are
9
--  provided for instantiating Xilinx primitive components.
10
--library UNISIM;
11
--use UNISIM.VComponents.all;
12
 
13
entity ALU is
14
    Port ( opa : in cpuWord;
15
           opb : in cpuWord;
16
           res : out cpuWord;
17
           cin : in std_logic;
18
           cout : out std_logic;
19
           zero : out std_logic;
20
           sign : out std_logic;
21
           over : out std_logic;
22
           what : in std_logic_vector(3 downto 0));
23
end ALU;
24
 
25
architecture Behavioral of ALU is
26
 
27
  constant alu_mov   : std_logic_vector(3 downto 0) := "0000";
28
  constant alu_and   : std_logic_vector(3 downto 0) := "0001";
29
  constant alu_or    : std_logic_vector(3 downto 0) := "0010";
30
  constant alu_xor   : std_logic_vector(3 downto 0) := "0011";
31
  constant alu_add   : std_logic_vector(3 downto 0) := "0100";
32
  constant alu_sub   : std_logic_vector(3 downto 0) := "0101";
33
  constant alu_ror   : std_logic_vector(3 downto 0) := "0110";
34
  constant alu_lsr   : std_logic_vector(3 downto 0) := "0111";
35
  constant alu_lsra  : std_logic_vector(3 downto 0) := "1000";
36
  constant alu_swap  : std_logic_vector(3 downto 0) := "1001";
37
  constant alu_swapb : std_logic_vector(3 downto 0) := "1010";
38
  constant alu_inc   : std_logic_vector(3 downto 0) := "1011";
39
  constant alu_dec   : std_logic_vector(3 downto 0) := "1100";
40
  constant alu_rorb  : std_logic_vector(3 downto 0) := "1101";
41
 
42
begin
43
 
44
  assert XLEN > 31 report "XLEN must at least 32 and multiple of 8";
45
  assert (XLEN rem 8) = 0 report "XLEN must at least 32 and multiple of 8";
46
 
47
  process(opa, opb, cin, what)
48
    variable temp   : std_logic_vector(XLEN downto 0);
49
    variable ctr    : integer;
50
    variable help   : std_logic_vector((XLEN-1) downto 0);
51
    variable helper : std_logic_vector(XLEN downto 0);
52
  begin
53
    case what is
54
      when alu_mov =>
55
        res  <= opb;
56
        temp := ("0" & opb);
57
        cout <= cin;
58
        over <= '0';
59
      when alu_and =>
60
        res  <= opa and opb;
61
        temp := ("0" & opa) and ("0" & opb);
62
        cout <= cin;
63
        over <= '0';
64
      when alu_or  =>
65
        res  <= opa or opb;
66
        temp := ("0" & opa) or ("0" & opb);
67
        cout <= cin;
68
        over <= '0';
69
      when alu_xor =>
70
        res  <= opa xor opb;
71
        temp := ("0" & opa) xor ("0" & opb);
72
        cout <= cin;
73
        over <= '0';
74
      when alu_add =>
75
        res  <= opa + opb + (getStdLogicVectorZeroes(XLEN-1) & cin);
76
        temp := ("0" & opa) + ("0" & opb) + (getStdLogicVectorZeroes(XLEN-1) & cin);
77
        cout <= temp(XLEN);
78
        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));
79
      when alu_sub =>
80
        res  <= opa - opb - (getStdLogicVectorZeroes(XLEN-1) & cin);
81
        temp := ("0" & opa) - ("0" & opb) - (getStdLogicVectorZeroes(XLEN-1) & cin);
82
        cout <= temp(XLEN);
83
        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));
84
      when alu_ror =>
85
        res  <= opa(0) & opa((XLEN-1) downto 1);
86
        temp := "0" & opa(0) & opa((XLEN-1) downto 1);
87
        cout <= opa(0);
88
        over <= '0';
89
      when alu_lsr =>
90
        res  <= cin & opa((XLEN-1) downto 1);
91
        temp := "00" & opa((XLEN-1) downto 1);
92
        cout <= opa(0);
93
        over <= '0';
94
      when alu_lsra =>
95
        res  <= opa(XLEN-1) & opa((XLEN-1) downto 1);
96
        temp := "0" & opa(XLEN-1) & opa((XLEN-1) downto 1);
97
        cout <= opa(0);
98
        over <= '0';
99
      when alu_swap =>
100
        res  <= opa((XLEN/2-1) downto 0) & opa((XLEN-1) downto (XLEN/2));
101
        temp := "0" & opa((XLEN/2-1) downto 0) & opa((XLEN-1) downto (XLEN/2));
102
        cout <= cin;
103
        over <= '0';
104
      when alu_swapb =>
105
        ctr := XLEN / 8;
106
        help := opa(7 downto 0) & getStdLogicVectorZeroes(XLEN-8);
107
        swb: for index in 1 to ctr-2 loop
108
          help := help or (getStdLogicVectorZeroes(index*8) & opa(((index+1)*8-1) downto (index*8)) & getStdLogicVectorZeroes((ctr-index-1)*8));
109
        end loop;
110
        help := help or (getStdLogicVectorZeroes(XLEN-8) & opa((XLEN-1) downto (XLEN-8)));
111
        res <= help;
112
        helper := "0" & opa(7 downto 0) & getStdLogicVectorZeroes(XLEN-8);
113
        swt: for index in 1 to ctr-2 loop
114
          helper := helper or ("0" & getStdLogicVectorZeroes(index*8) & opa(((index+1)*8-1) downto (index*8)) & getStdLogicVectorZeroes((ctr-index-1)*8));
115
        end loop;
116
        helper := helper or ("0" & getStdLogicVectorZeroes(XLEN-8) & opa((XLEN-1) downto (XLEN-8)));
117
        temp := helper;
118
        --res <= opa(7 downto 0) & opa(15 downto 8) & opa(23 downto 16) & opa(31 downto 24);
119
        --temp := "0" & opa(7 downto 0) & opa(15 downto 8) & opa(23 downto 16) & opa(31 downto 24);
120
        cout <= cin;
121
        over <= '0';
122
      when alu_inc =>
123
        res  <= opa + "1" + cin;
124
        temp := opa + "1" + cin;
125
        cout <= temp(XLEN);
126
        over <= '0';
127
      when alu_dec =>
128
        res  <= opa - "1" - cin;
129
        temp := opa - "1" - cin;
130
        cout <= temp(XLEN);
131
        over <= '0';
132
      when alu_rorb =>
133
        res  <= opa(7 downto 0) & opa((XLEN-1) downto 8);
134
        temp := "0" & opa(7 downto 0) & opa((XLEN-1) downto 8);
135
        cout <= cin;
136
        over <= '0';
137
      when others =>
138
        res  <= getStdLogicVectorZeroes(XLEN);
139
        temp := getStdLogicVectorZeroes(XLEN);
140
        cout <= cin;
141
        over <= '0';
142
    end case;
143
    sign <= temp(XLEN-1);
144
    if temp((XLEN-1) downto 0) = 0 then
145
      zero <= '1';
146
    else
147
      zero <= '0';
148
    end if;
149
  end process;
150
end Behavioral;
151
 

powered by: WebSVN 2.1.0

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