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

Subversion Repositories avr_hp

[/] [avr_hp/] [trunk/] [rtl/] [rtl_orig/] [alu_avr.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 tobil
--************************************************************************************************
2
--  ALU(internal module) for AVR core
3
--      Version 1.2
4
--  Designed by Ruslan Lepetenok 
5
--      Modified 02.08.2003 
6
-- (CPC/SBC/SBCI Z-flag bug found)
7
--  H-flag with NEG instruction found
8
--************************************************************************************************
9
 
10
library IEEE;
11
use IEEE.std_logic_1164.all;
12
 
13
 
14
entity alu_avr is port(
15
 
16
              alu_data_r_in   : in std_logic_vector(7 downto 0);
17
              alu_data_d_in   : in std_logic_vector(7 downto 0);
18
 
19
              alu_c_flag_in   : in std_logic;
20
              alu_z_flag_in   : in std_logic;
21
 
22
 
23
-- OPERATION SIGNALS INPUTS
24
              idc_add         :in std_logic;
25
              idc_adc         :in std_logic;
26
              idc_adiw        :in std_logic;
27
              idc_sub         :in std_logic;
28
              idc_subi        :in std_logic;
29
              idc_sbc         :in std_logic;
30
              idc_sbci        :in std_logic;
31
              idc_sbiw        :in std_logic;
32
 
33
              adiw_st         : in std_logic;
34
              sbiw_st         : in std_logic;
35
 
36
              idc_and         :in std_logic;
37
              idc_andi        :in std_logic;
38
              idc_or          :in std_logic;
39
              idc_ori         :in std_logic;
40
              idc_eor         :in std_logic;
41
              idc_com         :in std_logic;
42
              idc_neg         :in std_logic;
43
 
44
              idc_inc         :in std_logic;
45
              idc_dec         :in std_logic;
46
 
47
              idc_cp          :in std_logic;
48
              idc_cpc         :in std_logic;
49
              idc_cpi         :in std_logic;
50
              idc_cpse        :in std_logic;
51
 
52
              idc_lsr         :in std_logic;
53
              idc_ror         :in std_logic;
54
              idc_asr         :in std_logic;
55
              idc_swap        :in std_logic;
56
 
57
 
58
-- DATA OUTPUT
59
              alu_data_out    : out std_logic_vector(7 downto 0);
60
 
61
-- FLAGS OUTPUT
62
              alu_c_flag_out  : out std_logic;
63
              alu_z_flag_out  : out std_logic;
64
              alu_n_flag_out  : out std_logic;
65
              alu_v_flag_out  : out std_logic;
66
              alu_s_flag_out  : out std_logic;
67
              alu_h_flag_out  : out std_logic
68
);
69
 
70
end alu_avr;
71
 
72
architecture rtl of alu_avr is
73
 
74
-- ####################################################
75
-- INTERNAL SIGNALS
76
-- ####################################################
77
 
78
signal alu_data_out_int             : std_logic_vector (7 downto 0);
79
 
80
-- ALU FLAGS (INTERNAL)
81
signal alu_z_flag_out_int       : std_logic;
82
signal alu_c_flag_in_int        : std_logic;            -- INTERNAL CARRY FLAG
83
 
84
signal alu_n_flag_out_int       : std_logic;
85
signal alu_v_flag_out_int       : std_logic;
86
signal alu_c_flag_out_int       : std_logic;
87
 
88
-- ADDER SIGNALS --
89
signal adder_nadd_sub : std_logic;        -- 0 -> ADD ,1 -> SUB
90
signal adder_v_flag_out : std_logic;
91
 
92
signal adder_carry : std_logic_vector(8 downto 0);
93
signal adder_d_in  : std_logic_vector(8 downto 0);
94
signal adder_r_in  : std_logic_vector(8 downto 0);
95
signal adder_out   : std_logic_vector(8 downto 0);
96
 
97
-- NEG OPERATOR SIGNALS 
98
signal neg_op_in    : std_logic_vector(7 downto 0);
99
signal neg_op_carry : std_logic_vector(8 downto 0);
100
signal neg_op_out   : std_logic_vector(8 downto 0);
101
 
102
-- INC, DEC OPERATOR SIGNALS 
103
signal incdec_op_in    : std_logic_vector (7 downto 0);
104
signal incdec_op_carry : std_logic_vector(7 downto 0);
105
signal incdec_op_out   : std_logic_vector(7 downto 0);
106
 
107
 
108
signal com_op_out : std_logic_vector(7 downto 0);
109
signal and_op_out : std_logic_vector(7 downto 0);
110
signal or_op_out : std_logic_vector(7 downto 0);
111
signal eor_op_out : std_logic_vector(7 downto 0);
112
 
113
-- SHIFT SIGNALS
114
signal right_shift_out : std_logic_vector(7 downto 0);
115
 
116
-- SWAP SIGNALS
117
signal swap_out : std_logic_vector(7 downto 0);
118
 
119
begin
120
 
121
 
122
-- ########################################################################
123
-- ###############              ALU
124
-- ########################################################################
125
 
126
adder_nadd_sub <=(idc_sub or idc_subi or idc_sbc or idc_sbci or idc_sbiw or sbiw_st or
127
                  idc_cp or idc_cpc or idc_cpi or idc_cpse ); -- '0' -> '+'; '1' -> '-' 
128
 
129
-- SREG C FLAG (ALU INPUT)
130
alu_c_flag_in_int <= alu_c_flag_in and
131
(idc_adc or adiw_st or idc_sbc or idc_sbci or sbiw_st or
132
idc_cpc or
133
idc_ror);
134
 
135
-- SREG Z FLAG ()
136
-- alu_z_flag_out <= (alu_z_flag_out_int and not(adiw_st or sbiw_st)) or 
137
--                   ((alu_z_flag_in and alu_z_flag_out_int) and (adiw_st or sbiw_st));
138
alu_z_flag_out <= (alu_z_flag_out_int and not(adiw_st or sbiw_st or idc_cpc or idc_sbc or idc_sbci)) or
139
                  ((alu_z_flag_in and alu_z_flag_out_int) and (adiw_st or sbiw_st))or
140
                                  (alu_z_flag_in and alu_z_flag_out_int and(idc_cpc or idc_sbc or idc_sbci));   -- Previous value (for CPC/SBC/SBCI instructions)
141
 
142
-- SREG N FLAG
143
alu_n_flag_out <= alu_n_flag_out_int;
144
 
145
-- SREG V FLAG
146
alu_v_flag_out <= alu_v_flag_out_int;
147
 
148
 
149
alu_c_flag_out <= alu_c_flag_out_int;
150
 
151
alu_data_out <= alu_data_out_int;
152
 
153
-- #########################################################################################
154
 
155
adder_d_in <= '0'&alu_data_d_in;
156
adder_r_in <= '0'&alu_data_r_in;
157
 
158
--########################## ADDEER ###################################
159
 
160
adder_out(0) <= adder_d_in(0) xor adder_r_in(0) xor alu_c_flag_in_int;
161
 
162
summator:for i in 1 to 8 generate
163
adder_out(i) <= adder_d_in(i) xor adder_r_in(i) xor adder_carry(i-1);
164
end generate;
165
 
166
 
167
adder_carry(0) <= ((adder_d_in(0) xor adder_nadd_sub) and adder_r_in(0)) or
168
                (((adder_d_in(0) xor adder_nadd_sub) or adder_r_in(0)) and alu_c_flag_in_int);
169
 
170
summator2:for i in 1 to 8 generate
171
adder_carry(i) <= ((adder_d_in(i) xor adder_nadd_sub) and adder_r_in(i)) or
172
                (((adder_d_in(i) xor adder_nadd_sub) or adder_r_in(i)) and adder_carry(i-1));
173
end generate;
174
 
175
-- FLAGS  FOR ADDER INSTRUCTIONS: 
176
-- CARRY FLAG (C) -> adder_out(8)
177
-- HALF CARRY FLAG (H) -> adder_carry(3)
178
-- TOW'S COMPLEMENT OVERFLOW  (V) -> 
179
 
180
adder_v_flag_out <= (((adder_d_in(7) and adder_r_in(7) and not adder_out(7)) or
181
                    (not adder_d_in(7) and not adder_r_in(7) and adder_out(7))) and not adder_nadd_sub) or -- ADD
182
                    (((adder_d_in(7) and not adder_r_in(7) and not adder_out(7)) or
183
                                        (not adder_d_in(7) and adder_r_in(7) and adder_out(7))) and adder_nadd_sub);
184
                                                                                                                                                                                                                   -- SUB
185
--#####################################################################
186
 
187
 
188
-- LOGICAL OPERATIONS FOR ONE OPERAND
189
 
190
--########################## NEG OPERATION ####################
191
 
192
neg_op_out(0)   <= not alu_data_d_in(0) xor '1';
193
neg_op:for i in 1 to 7 generate
194
neg_op_out(i)   <= not alu_data_d_in(i) xor neg_op_carry(i-1);
195
end generate;
196
neg_op_out(8) <= neg_op_carry(7) xor '1';
197
 
198
 
199
neg_op_carry(0) <= not alu_data_d_in(0) and '1';
200
neg_op2:for i in 1 to 7 generate
201
neg_op_carry(i) <= not alu_data_d_in(i) and neg_op_carry(i-1);
202
end generate;
203
neg_op_carry(8) <= neg_op_carry(7);                            -- ??!!
204
 
205
 
206
-- CARRY FLAGS  FOR NEG INSTRUCTION: 
207
-- CARRY FLAG -> neg_op_out(8)
208
-- HALF CARRY FLAG -> neg_op_carry(3)
209
-- TOW's COMPLEMENT OVERFLOW FLAG -> alu_data_d_in(7) and neg_op_carry(6) 
210
--############################################################################  
211
 
212
 
213
--########################## INC, DEC OPERATIONS ####################
214
 
215
incdec_op_out(0)      <=  alu_data_d_in(0) xor '1';
216
inc_dec:for i in 1 to 7 generate
217
incdec_op_out(i)   <= alu_data_d_in(i) xor incdec_op_carry(i-1);
218
end generate;
219
 
220
 
221
incdec_op_carry(0)    <=  alu_data_d_in(0) xor idc_dec;
222
inc_dec2:for i in 1 to 7 generate
223
incdec_op_carry(i) <= (alu_data_d_in(i) xor idc_dec) and incdec_op_carry(i-1);
224
end generate;
225
 
226
-- TOW's COMPLEMENT OVERFLOW FLAG -> (alu_data_d_in(7) xor idc_dec) and incdec_op_carry(6) 
227
--####################################################################
228
 
229
 
230
--########################## COM OPERATION ###################################
231
com_op_out <= not alu_data_d_in;
232
-- FLAGS 
233
-- TOW's COMPLEMENT OVERFLOW FLAG (V)  -> '0'
234
-- CARRY FLAG (C) -> '1' 
235
--############################################################################
236
 
237
-- LOGICAL OPERATIONS FOR TWO OPERANDS  
238
 
239
--########################## AND OPERATION ###################################
240
and_op_out <= alu_data_d_in and alu_data_r_in;
241
-- FLAGS 
242
-- TOW's COMPLEMENT OVERFLOW FLAG (V)  -> '0'
243
--############################################################################
244
 
245
--########################## OR OPERATION ###################################
246
or_op_out <= alu_data_d_in or alu_data_r_in;
247
-- FLAGS 
248
-- TOW's COMPLEMENT OVERFLOW FLAG (V)  -> '0'
249
--############################################################################
250
 
251
--########################## EOR OPERATION ###################################
252
eor_op_out <= alu_data_d_in xor alu_data_r_in;
253
-- FLAGS 
254
-- TOW's COMPLEMENT OVERFLOW FLAG (V)  -> '0'
255
--############################################################################
256
 
257
-- SHIFT OPERATIONS 
258
 
259
-- ########################## RIGHT(LSR, ROR, ASR) #######################
260
 
261
right_shift_out(7) <= (idc_ror and alu_c_flag_in_int) or (idc_asr and alu_data_d_in(7)); -- right_shift_out(7)
262
shift_right:for i in 6 downto 0 generate
263
right_shift_out(i) <= alu_data_d_in(i+1);
264
end generate;
265
 
266
-- FLAGS 
267
-- CARRY FLAG (C)                      -> alu_data_d_in(0) 
268
-- NEGATIVE FLAG (N)                   -> right_shift_out(7)
269
-- TOW's COMPLEMENT OVERFLOW FLAG (V)  -> N xor C  (left_shift_out(7) xor alu_data_d_in(0))
270
 
271
-- #######################################################################
272
 
273
 
274
-- ################################## SWAP ###############################
275
 
276
swap_h:for i in 7 downto 4 generate
277
swap_out(i) <= alu_data_d_in(i-4);
278
end generate;
279
swap_l:for i in 3 downto 0 generate
280
swap_out(i) <= alu_data_d_in(i+4);
281
end generate;
282
-- #######################################################################
283
 
284
-- ALU OUTPUT MUX
285
 
286
alu_data_out_mux:for i in alu_data_out_int'range generate
287
alu_data_out_int(i) <= (adder_out(i) and (idc_add or idc_adc or (idc_adiw or adiw_st) or    -- !!!!!
288
                                     idc_sub or idc_subi or idc_sbc or idc_sbci or
289
                                     (idc_sbiw or sbiw_st) or    -- !!!!!
290
                                     idc_cpse or idc_cp or idc_cpc or idc_cpi)) or
291
                                     (neg_op_out(i) and idc_neg) or                               -- NEG
292
                                     (incdec_op_out(i) and (idc_inc or idc_dec)) or               -- INC/DEC
293
                                     (com_op_out(i) and idc_com) or                               -- COM
294
                                     (and_op_out(i) and (idc_and or idc_andi)) or                 -- AND/ANDI                                   
295
                                     (or_op_out(i)  and (idc_or or idc_ori)) or                   -- OR/ORI                                   
296
                                     (eor_op_out(i) and idc_eor) or                               -- EOR
297
                                     (right_shift_out(i) and (idc_lsr or idc_ror or idc_asr)) or  -- LSR/ROR/ASR
298
                                     (swap_out(i) and idc_swap);                                  -- SWAP
299
 
300
 
301
end generate;
302
 
303
--@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ALU FLAGS OUTPUTS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
304
 
305
alu_h_flag_out <= (adder_carry(3) and                                                      -- ADDER INSTRUCTIONS
306
             (idc_add or idc_adc or idc_sub or idc_subi or idc_sbc or idc_sbci or idc_cp or idc_cpc or idc_cpi)) or
307
             (not neg_op_carry(3) and idc_neg); -- H-flag problem with NEG instruction fixing                                         -- NEG
308
 
309
 
310
alu_s_flag_out <= alu_n_flag_out_int xor alu_v_flag_out_int;
311
 
312
alu_v_flag_out_int <= (adder_v_flag_out and
313
             (idc_add or idc_adc or idc_sub or idc_subi or idc_sbc or idc_sbci or adiw_st or sbiw_st or idc_cp or idc_cpi or idc_cpc)) or
314
             ((alu_data_d_in(7) and neg_op_carry(6)) and idc_neg) or                                       -- NEG
315
                     (not alu_data_d_in(7) and incdec_op_carry(6) and idc_inc) or -- INC
316
                     (alu_data_d_in(7) and incdec_op_carry(6) and idc_dec) or     -- DEC
317
                         ((alu_n_flag_out_int xor alu_c_flag_out_int) and (idc_lsr or idc_ror or idc_asr));            -- LSR,ROR,ASR
318
 
319
 
320
alu_n_flag_out_int <= alu_data_out_int(7);
321
 
322
alu_z_flag_out_int <= '1' when alu_data_out_int="00000000" else '0';
323
 
324
alu_c_flag_out_int <= (adder_out(8) and
325
                       (idc_add or idc_adc or (idc_adiw or adiw_st) or idc_sub or idc_subi or idc_sbc or idc_sbci or (idc_sbiw or sbiw_st) or idc_cp or idc_cpc or idc_cpi)) or -- ADDER
326
                                           (not alu_z_flag_out_int and idc_neg) or    -- NEG
327
                                           (alu_data_d_in(0) and (idc_lsr or idc_ror or idc_asr)) or idc_com;
328
 
329
-- @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
330
 
331
 
332
end rtl;

powered by: WebSVN 2.1.0

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