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

Subversion Repositories arm4u

[/] [arm4u/] [trunk/] [hdl/] [alu.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 Bregalad
-- This file is part of ARM4U CPU
2
-- 
3
-- This is a creation of the Laboratory of Processor Architecture
4
-- of Ecole Polytechnique Fédérale de Lausanne ( http://lap.epfl.ch )
5
--
6
-- alu.vhd  --  Hadrware description of the ALU unit (inside Execute pipeline stage)
7
--
8
-- Written By -  Jonathan Masur and Xavier Jimenez (2013)
9
--
10
-- This program is free software; you can redistribute it and/or modify it
11
-- under the terms of the GNU General Public License as published by the
12
-- Free Software Foundation; either version 2, or (at your option) any
13
-- later version.
14
--
15
-- This program is distributed in the hope that it will be useful,
16
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
17
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
-- GNU General Public License for more details.
19
--
20
-- In other words, you are welcome to use, share and improve this program.
21
-- You are forbidden to forbid anyone else to use, share and improve
22
-- what you give them.   Help stamp out software-hoarding!
23
 
24
library ieee;
25
use ieee.std_logic_1164.all;
26
use ieee.numeric_std.all;
27
use work.arm_types.all;
28
 
29
entity alu is
30
        port (
31
                exe_alu_operation : in ALU_OPERATION;
32
                alu_o : out unsigned(31 downto 0);
33
                alu_opb, alu_opa : in unsigned(31 downto 0);
34
                n, z, c, v, barrelshift_c : in std_logic;
35
                lowflags : in std_logic_vector(5 downto 0);
36
                next_n, next_z, next_c, next_v : out std_logic;
37
                next_lowflags : out std_logic_vector(5 downto 0)
38
        );
39
end;
40
 
41
architecture rtl of alu is
42
        signal alu_out : unsigned(31 downto 0);
43
 
44
        signal adder_a, adder_b, adder_out : unsigned(31 downto 0);
45
        signal adder_cout, adder_vout : std_logic;
46
        signal adder_cin : unsigned(0 downto 0);
47
 
48
begin
49
        alu_o <= alu_out;               -- annoying VHDL
50
 
51
        -- 32 bit adder with carry in and carry out
52
        adder : process(adder_a, adder_b, adder_cin, adder_out) is
53
                variable add33 :unsigned(32 downto 0);
54
        begin
55
                add33 := ('0' & adder_a) + ('0' & adder_b) + adder_cin;
56
                adder_out <= add33(31 downto 0);
57
 
58
                -- carry out is bit 32 of the result
59
                adder_cout <= add33(32);
60
 
61
                -- overflow true if both operands were the same sign and the result is not the same sign
62
                adder_vout <= (add33(31) and not adder_a(31) and not adder_b(31)) or (not adder_out(31) and adder_a(31) and adder_b(31));
63
        end process;
64
 
65
        -- 32-bit ALU
66
        alu : process(exe_alu_operation, alu_out, alu_opb, alu_opa, n, z, c, v, lowflags, barrelshift_c, adder_out, adder_cout, adder_vout) is
67
                variable carry : unsigned(0 downto 0);
68
        begin
69
                adder_a <= (others => '-');
70
                adder_b <= (others => '-');
71
                adder_cin <= "-";
72
 
73
                -- annoying VHDL
74
                if c = '1' then carry := "1"; else carry := "0"; end if;
75
 
76
                -- default values for nzvc and low flags (v and lowflags doesn't change by default)
77
                next_n <= alu_out(31);
78
                if alu_out = X"00000000"
79
                then
80
                        next_z <= '1';
81
                else
82
                        next_z <= '0';
83
                end if;
84
                next_v <= v;
85
                next_c <= barrelshift_c;
86
                next_lowflags <= lowflags;
87
 
88
                case exe_alu_operation is
89
                when ALU_NOP =>         -- no ALU operation
90
                        alu_out <= alu_opb;
91
                when ALU_NOT =>         -- one's complement operation
92
                        alu_out <= not alu_opb;
93
                when ALU_ORR =>
94
                        alu_out <= alu_opa or alu_opb;
95
                when ALU_AND =>
96
                        alu_out <= alu_opa and alu_opb;
97
                when ALU_EOR =>
98
                        alu_out <= alu_opa xor alu_opb;
99
                when ALU_BIC =>         -- bit clear
100
                        alu_out <= alu_opa and not alu_opb;
101
 
102
                when ALU_RWF =>         -- read/write flags
103
                        next_n <= alu_opb(31);
104
                        next_z <= alu_opb(30);
105
                        next_c <= alu_opb(29);
106
                        next_v <= alu_opb(28);
107
                        -- I and F flags
108
                        next_lowflags(5 downto 4) <= std_logic_vector(alu_opb(7 downto 6));
109
                        -- mode flags
110
                        next_lowflags(3 downto 0) <= std_logic_vector(alu_opb(3 downto 0));
111
 
112
                        --read (old) flags
113
                        alu_out <= unsigned( n & z & c & v & (27 downto 8 => '0') & lowflags(5 downto 4) & '0' & '1' & lowflags(3 downto 0) );
114
 
115
                when ALU_ADD =>         -- addition without carry
116
                        adder_a <= alu_opa;
117
                        adder_b <= alu_opb;
118
                        adder_cin <= "0";
119
 
120
                        next_v <= adder_vout;
121
                        alu_out <= adder_out;
122
                        next_c <= adder_cout;
123
 
124
                when ALU_ADC =>         -- addition with carry
125
                        adder_a <= alu_opa;
126
                        adder_b <= alu_opb;
127
                        adder_cin <= carry;
128
 
129
                        next_v <= adder_vout;
130
                        alu_out <= adder_out;
131
                        next_c <= adder_cout;
132
 
133
                when ALU_SUB =>         -- substraction without carry
134
                        adder_a <= alu_opa;
135
                        adder_b <= not alu_opb;
136
                        adder_cin <= "1";
137
 
138
                        next_v <= adder_vout;
139
                        alu_out <= adder_out;
140
                        next_c <= adder_cout;
141
 
142
                when ALU_SBC =>         -- substraction with carry
143
                        adder_a <= alu_opa;
144
                        adder_b <= not alu_opb;
145
                        adder_cin <= carry;
146
 
147
                        next_v <= adder_vout;
148
                        alu_out <= adder_out;
149
                        next_c <= adder_cout;
150
 
151
                when ALU_RSB =>         -- reverse substraction without carry
152
                        adder_a <= not alu_opa;
153
                        adder_b <= alu_opb;
154
                        adder_cin <= "1";
155
 
156
                        next_v <= adder_vout;
157
                        alu_out <= adder_out;
158
                        next_c <= adder_cout;
159
 
160
                when ALU_RSC =>         -- reverse substraction with carry
161
                        adder_a <= not alu_opa;
162
                        adder_b <= alu_opb;
163
                        adder_cin <= carry;
164
 
165
                        next_v <= adder_vout;
166
                        alu_out <= adder_out;
167
                        next_c <= adder_cout;
168
                end case;
169
        end process;
170
end;

powered by: WebSVN 2.1.0

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