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

Subversion Repositories tinyvliw8

[/] [tinyvliw8/] [trunk/] [src/] [vhdl/] [proc/] [alu.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 steckol
-----------------------------------------------------------------
2
-- Project: Aeternitas
3
-- Author:  Oliver Stecklina <stecklina@ihp-microelectronics.com
4
-- Date:    13.11.2013 
5
-- File:    alu.vhd
6
-- Design:  AeternitasSWUR
7
-----------------------------------------------------------------
8
-- Description : Arithmetic unit of IHPvliw8 processor
9
-----------------------------------------------------------------
10
-- $Log$
11
-----------------------------------------------------------------
12
 
13
library ieee;
14
 
15
use ieee.std_logic_1164.all;
16
use ieee.std_logic_arith.all;
17
 
18
entity vliwProc_alu is
19
        port (
20
                state      : in std_logic_vector(3 downto 0);
21
 
22
                enable_n   : in std_logic;
23
 
24
                opcode     : in std_logic_vector(2 downto 0);
25
                as         : in std_logic_vector(1 downto 0);
26
                dstRegIn   : in std_logic_vector(2 downto 0);
27
                dataIn     : in std_logic_vector(7 downto 0);
28
 
29
                reg0       : in std_logic_vector(7 downto 0);
30
                reg1       : in std_logic_vector(7 downto 0);
31
                reg2       : in std_logic_vector(7 downto 0);
32
                reg3       : in std_logic_vector(7 downto 0);
33
                reg4       : in std_logic_vector(7 downto 0);
34
                reg5       : in std_logic_vector(7 downto 0);
35
                reg6       : in std_logic_vector(7 downto 0);
36
                reg7       : in std_logic_vector(7 downto 0);
37
 
38
                cIn        : in  std_logic;
39
                cOut       : out std_logic;
40
                zOut       : out std_logic;
41
 
42
                dstRegEn_n : out std_logic;
43
                dstRegOut  : out std_logic_vector(2 downto 0);
44
                dataOut    : out std_logic_vector(7 downto 0);
45
 
46
                rst_n      : in  std_logic
47
        );
48
end vliwProc_alu;
49
 
50
architecture behavior of vliwProc_alu is
51
 
52
        signal cIn_s      : std_logic;
53
        signal as_s       : std_logic_vector(1 downto 0);
54
        signal opcode_s   : std_logic_vector(2 downto 0);
55
        signal dstRegIn_s : std_logic_vector(2 downto 0);
56
 
57
        signal cShift_s : std_logic;
58
        signal cAdd_s   : std_logic;
59
 
60
        signal shift_s  : std_logic;
61
        signal logic_s  : std_logic;
62
        signal arith_s  : std_logic;
63
 
64
        signal dataOut_s : std_logic_vector(7 downto 0);
65
 
66
        signal op0_s    : std_logic_vector(7 downto 0);
67
        signal op1_s    : std_logic_vector(7 downto 0);
68
 
69
        signal aluEn_s  : std_logic;
70
 
71
        signal rst_n_s  : std_logic;
72
 
73
begin
74
 
75
        rst_n_s <= rst_n;
76
 
77
        enable_p : process(rst_n_s, state(2))
78
        begin
79
                if (rst_n_s = '0') then
80
                        aluEn_s <= '0';
81
                else
82
                        if (state(2)'event and state(2) = '1') then
83
                                if (enable_n = '0') then
84
                                        aluEn_s <= '1';
85
                                else
86
                                        aluEn_s <= '0';
87
                                end if;
88
                        end if;
89
                end if;
90
        end process;
91
 
92
        commitIn_proc : process(rst_n_s, state(2))
93
                variable shift_v : std_logic;
94
                variable logic_v : std_logic;
95
                variable arith_v : std_logic;
96
 
97
                variable op0_v : unsigned(8 downto 0);
98
                variable op1_v : unsigned(8 downto 0);
99
        begin
100
                if (rst_n_s = '0') then
101
                        cIn_s <= '0';
102
 
103
                        as_s       <= (others => '0');
104
                        opcode_s   <= (others => '0');
105
                        dstRegIn_s <= (others => '0');
106
 
107
                        op0_v := (others => '0');
108
                        op1_v := (others => '0');
109
 
110
                        shift_v := '0';
111
                        logic_v := '0';
112
                        arith_v := '0';
113
 
114
                        cAdd_s <= '0';
115
                else
116
                        if (state(2)'event and state(2) = '1') then
117
                                shift_v := '0';
118
                                logic_v := '0';
119
                                arith_v := '0';
120
 
121
                        if (enable_n = '0') then
122
                                cIn_s    <= cIn;
123
 
124
                                as_s     <= as;
125
                                opcode_s <= opcode;
126
                                dstRegIn_s <= dstRegIn;
127
 
128
                                case opcode IS
129
                                        when "010" => arith_v := '1';
130
                                   when "011" => shift_v := '1';
131
                                   when "100" => logic_v := '1';
132
                                   when "101" => logic_v := '1';
133
                                   when "110" => logic_v := '1';
134
                                        WHEN others => null;
135
                                end case;
136
 
137
                                if (shift_v = '1') then
138
                                        if (as(0) = '0' or as(1) = '0') then
139
                                                CASE dataIn(2 downto 0) IS
140
                                                        WHEN "000" => op0_v := unsigned('0' & reg0);
141
                                                        WHEN "001" => op0_v := unsigned('0' & reg1);
142
                                                        WHEN "010" => op0_v := unsigned('0' & reg2);
143
                                                        WHEN "011" => op0_v := unsigned('0' & reg3);
144
                                                        WHEN "100" => op0_v := unsigned('0' & reg4);
145
                                                        WHEN "101" => op0_v := unsigned('0' & reg5);
146
                                                        WHEN "110" => op0_v := unsigned('0' & reg6);
147
                                                        WHEN "111" => op0_v := unsigned('0' & reg7);
148
                                                        WHEN others => null;
149
                                                END CASE;
150
 
151
                                                op1_v := unsigned('0' & dataIn);
152
                                        else -- mov Rx, #NUM
153
                                                op0_v := unsigned('0' & dataIn);
154
                                        end if;
155
                                elsif (logic_v = '1') then
156
                                        if (as(0) = '0') then
157
                                                if (dataIn(7) = '0') then
158
                                                        case dataIn(6 downto 4) is
159
                                                                when "000" => op0_v := unsigned('0' & reg0);
160
                                                                when "001" => op0_v := unsigned('0' & reg1);
161
                                                                when "010" => op0_v := unsigned('0' & reg2);
162
                                                                when "011" => op0_v := unsigned('0' & reg3);
163
                                                                when "100" => op0_v := unsigned('0' & reg4);
164
                                                                when "101" => op0_v := unsigned('0' & reg5);
165
                                                                when "110" => op0_v := unsigned('0' & reg6);
166
                                                                when "111" => op0_v := unsigned('0' & reg7);
167
                                                                when others => null;
168
                                                        end case;
169
                                                else
170
                                                        case dataIn(6 downto 4) is
171
                                                                when "000" => op0_v := unsigned(not('0' & reg0));
172
                                                                when "001" => op0_v := unsigned(not('0' & reg1));
173
                                                                when "010" => op0_v := unsigned(not('0' & reg2));
174
                                                                when "011" => op0_v := unsigned(not('0' & reg3));
175
                                                                when "100" => op0_v := unsigned(not('0' & reg4));
176
                                                                when "101" => op0_v := unsigned(not('0' & reg5));
177
                                                                when "110" => op0_v := unsigned(not('0' & reg6));
178
                                                                when "111" => op0_v := unsigned(not('0' & reg7));
179
                                                                when others => null;
180
                                                        end case;
181
                                                end if;
182
 
183
                                                if (dataIn(3) = '0') then
184
                                                        case dataIn(2 downto 0) is
185
                                                                when "000" => op1_v := unsigned('0' & reg0);
186
                                                                when "001" => op1_v := unsigned('0' & reg1);
187
                                                                when "010" => op1_v := unsigned('0' & reg2);
188
                                                                when "011" => op1_v := unsigned('0' & reg3);
189
                                                                when "100" => op1_v := unsigned('0' & reg4);
190
                                                                when "101" => op1_v := unsigned('0' & reg5);
191
                                                                when "110" => op1_v := unsigned('0' & reg6);
192
                                                                when "111" => op1_v := unsigned('0' & reg7);
193
                                                                when others => null;
194
                                                        end case;
195
                                                else
196
                                                        case dataIn(2 downto 0) is
197
                                                                when "000" => op1_v := unsigned(not('0' & reg0));
198
                                                                when "001" => op1_v := unsigned(not('0' & reg1));
199
                                                                when "010" => op1_v := unsigned(not('0' & reg2));
200
                                                                when "011" => op1_v := unsigned(not('0' & reg3));
201
                                                                when "100" => op1_v := unsigned(not('0' & reg4));
202
                                                                when "101" => op1_v := unsigned(not('0' & reg5));
203
                                                                when "110" => op1_v := unsigned(not('0' & reg6));
204
                                                                when "111" => op1_v := unsigned(not('0' & reg7));
205
                                                                when others => null;
206
                                                        end case;
207
                                                end if;
208
                                        else
209
                                                CASE dstRegIn IS
210
                                                        WHEN "000" => op0_v := unsigned('0' & reg0);
211
                                                        WHEN "001" => op0_v := unsigned('0' & reg1);
212
                                                        WHEN "010" => op0_v := unsigned('0' & reg2);
213
                                                        WHEN "011" => op0_v := unsigned('0' & reg3);
214
                                                        WHEN "100" => op0_v := unsigned('0' & reg4);
215
                                                        WHEN "101" => op0_v := unsigned('0' & reg5);
216
                                                        WHEN "110" => op0_v := unsigned('0' & reg6);
217
                                                        WHEN "111" => op0_v := unsigned('0' & reg7);
218
                                                        WHEN others => null;
219
                                                END CASE;
220
 
221
                                                op1_v := unsigned('0' & dataIn);
222
                                        end if;
223
                                elsif (arith_v = '1') then
224
                                        if (as(0) = '0') then
225
                                                if (dataIn(7) = '0') then
226
                                                        case dataIn(6 downto 4) is
227
                                                                when "000" => op0_v := unsigned('0' & reg0);
228
                                                                when "001" => op0_v := unsigned('0' & reg1);
229
                                                                when "010" => op0_v := unsigned('0' & reg2);
230
                                                                when "011" => op0_v := unsigned('0' & reg3);
231
                                                                when "100" => op0_v := unsigned('0' & reg4);
232
                                                                when "101" => op0_v := unsigned('0' & reg5);
233
                                                                when "110" => op0_v := unsigned('0' & reg6);
234
                                                                when "111" => op0_v := unsigned('0' & reg7);
235
                                                                when others => null;
236
                                                        end case;
237
                                                else
238
                                                        case dataIn(6 downto 4) is
239
                                                                when "000" => op0_v := unsigned(not('0' & reg0));
240
                                                                when "001" => op0_v := unsigned(not('0' & reg1));
241
                                                                when "010" => op0_v := unsigned(not('0' & reg2));
242
                                                                when "011" => op0_v := unsigned(not('0' & reg3));
243
                                                                when "100" => op0_v := unsigned(not('0' & reg4));
244
                                                                when "101" => op0_v := unsigned(not('0' & reg5));
245
                                                                when "110" => op0_v := unsigned(not('0' & reg6));
246
                                                                when "111" => op0_v := unsigned(not('0' & reg7));
247
                                                                when others => null;
248
                                                        end case;
249
 
250
                                                        op0_v := op0_v + 1;
251
                                                end if;
252
 
253
                                                if (dataIn(3) = '0') then
254
                                                        case dataIn(2 downto 0) is
255
                                                                when "000" => op1_v := unsigned('0' & reg0);
256
                                                                when "001" => op1_v := unsigned('0' & reg1);
257
                                                                when "010" => op1_v := unsigned('0' & reg2);
258
                                                                when "011" => op1_v := unsigned('0' & reg3);
259
                                                                when "100" => op1_v := unsigned('0' & reg4);
260
                                                                when "101" => op1_v := unsigned('0' & reg5);
261
                                                                when "110" => op1_v := unsigned('0' & reg6);
262
                                                                when "111" => op1_v := unsigned('0' & reg7);
263
                                                                when others => null;
264
                                                        end case;
265
                                                else
266
                                                        -- two's complement
267
                                                        case dataIn(2 downto 0) is
268
                                                                when "000" => op1_v := unsigned(not('0' & reg0));
269
                                                                when "001" => op1_v := unsigned(not('0' & reg1));
270
                                                                when "010" => op1_v := unsigned(not('0' & reg2));
271
                                                                when "011" => op1_v := unsigned(not('0' & reg3));
272
                                                                when "100" => op1_v := unsigned(not('0' & reg4));
273
                                                                when "101" => op1_v := unsigned(not('0' & reg5));
274
                                                                when "110" => op1_v := unsigned(not('0' & reg6));
275
                                                                when "111" => op1_v := unsigned(not('0' & reg7));
276
                                                                when others => null;
277
                                                        end case;
278
 
279
                                                        op1_v := op1_v + 1;
280
                                                end if;
281
                                        else
282
                                                CASE dstRegIn IS
283
                                                        WHEN "000" => op0_v := unsigned('0' & reg0);
284
                                                        WHEN "001" => op0_v := unsigned('0' & reg1);
285
                                                        WHEN "010" => op0_v := unsigned('0' & reg2);
286
                                                        WHEN "011" => op0_v := unsigned('0' & reg3);
287
                                                        WHEN "100" => op0_v := unsigned('0' & reg4);
288
                                                        WHEN "101" => op0_v := unsigned('0' & reg5);
289
                                                        WHEN "110" => op0_v := unsigned('0' & reg6);
290
                                                        WHEN "111" => op0_v := unsigned('0' & reg7);
291
                                                        WHEN others => null;
292
                                                END CASE;
293
 
294
                                                op1_v := unsigned('0' & dataIn);
295
                                        end if;
296
 
297
                                        -- addition
298
                                        op0_v := op0_v + op1_v;
299
 
300
                                        -- carry add
301
                                        if (as(1) = '1' and cIn = '1') then
302
                                                op0_v := op0_v + 1;
303
                                        end if;
304
 
305
                                        cAdd_s <= std_logic(op0_v(8));
306
                                end if;
307
                                end if;
308
                        end if;
309
                end if;
310
 
311
                shift_s <= std_logic(shift_v);
312
                logic_s <= std_logic(logic_v);
313
                arith_s <= std_logic(arith_v);
314
 
315
                op0_s <= std_logic_vector(op0_v(7 downto 0));
316
                op1_s <= std_logic_vector(op1_v(7 downto 0));
317
        end process;
318
 
319
        cShift_s <= op0_s(7) when as_s(0) = '0' and as(1) = '0' else   -- shift left
320
                    op0_s(0) when as_s(0) = '0' and as(1) = '1' else   -- shift right
321
                                        '0';
322
 
323
        dataOut_s <= op0_s(6 downto 0) & '0'      when shift_s = '1' and as_s = "00" and op1_s(3) = '0' else
324
                     op0_s(6 downto 0) & cIn_s    when shift_s = '1' and as_s = "00" and op1_s(3) = '1' else
325
                                    op0_s(7) & op0_s(7 downto 1) when shift_s = '1' and as_s = "01" and op1_s(3) = '0' else
326
                                         cIn_s & op0_s(7 downto 1)    when shift_s = '1' and as_s = "01" and op1_s(3) = '1' else
327
                                    not(op0_s)                   when shift_s = '1' and as_s = "10" and op1_s(3) = '1' else
328
                                         op0_s                        when shift_s = '1' and as_s(0) = '1' else
329
                                    op0_s and op1_s      when logic_s = '1' and opcode_s = "100" and as_s(1) = '0' else
330
                                    not(op0_s and op1_s) when logic_s = '1' and opcode_s = "100" and as_s(1) = '1' else
331
                                    op0_s or op1_s       when logic_s = '1' and opcode_s = "101" and as_s(1) = '0' else
332
                                    not(op0_s or op1_s)  when logic_s = '1' and opcode_s = "101" and as_s(1) = '1' else
333
                                    op0_s xor op1_s      when logic_s = '1' and opcode_s = "110" and as_s(1) = '0' else
334
                                    not(op0_s xor op1_s) when logic_s = '1' and opcode_s = "110" and as_s(1) = '1' else
335
                                         op0_s when arith_s = '1' else
336
                                    (others => '0');
337
 
338
        cOut <= cAdd_s   when aluEn_s = '1' and arith_s = '1' else                   -- arithmetic operations
339
                cShift_s when aluEn_s = '1' and shift_s = '1' and as_s(0) = '0' else -- shift
340
                          '0';
341
 
342
        dataOut <= dataOut_s  when aluEn_s = '1' else
343
                   (others => '0');
344
        zOut <= '1' when aluEn_s = '1' and dataOut_s = "00000000" else
345
                '0';
346
 
347
        dstRegEn_n <= '0' when aluEn_s = '1' else
348
                      '1';
349
        dstRegOut <= dstRegIn_s when aluEn_s = '1' else
350
                     (others => '0');
351
 
352
end behavior;

powered by: WebSVN 2.1.0

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