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

Subversion Repositories avr_hp

[/] [avr_hp/] [trunk/] [rtl/] [rtl_v5_cm2/] [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_cm2 is port(
15
                cp2_cml_1 : in std_logic;
16
 
17
 
18
              alu_data_r_in   : in std_logic_vector(7 downto 0);
19
              alu_data_d_in   : in std_logic_vector(7 downto 0);
20
 
21
              alu_c_flag_in   : in std_logic;
22
              alu_z_flag_in   : in std_logic;
23
 
24
 
25
-- OPERATION SIGNALS INPUTS
26
              idc_add         :in std_logic;
27
              idc_adc         :in std_logic;
28
              idc_adiw        :in std_logic;
29
              idc_sub         :in std_logic;
30
              idc_subi        :in std_logic;
31
              idc_sbc         :in std_logic;
32
              idc_sbci        :in std_logic;
33
              idc_sbiw        :in std_logic;
34
 
35
              adiw_st         : in std_logic;
36
              sbiw_st         : in std_logic;
37
 
38
              idc_and         :in std_logic;
39
              idc_andi        :in std_logic;
40
              idc_or          :in std_logic;
41
              idc_ori         :in std_logic;
42
              idc_eor         :in std_logic;
43
              idc_com         :in std_logic;
44
              idc_neg         :in std_logic;
45
 
46
              idc_inc         :in std_logic;
47
              idc_dec         :in std_logic;
48
 
49
              idc_cp          :in std_logic;
50
              idc_cpc         :in std_logic;
51
              idc_cpi         :in std_logic;
52
              idc_cpse        :in std_logic;
53
 
54
              idc_lsr         :in std_logic;
55
              idc_ror         :in std_logic;
56
              idc_asr         :in std_logic;
57
              idc_swap        :in std_logic;
58
 
59
 
60
-- DATA OUTPUT
61
              alu_data_out    : out std_logic_vector(7 downto 0);
62
 
63
-- FLAGS OUTPUT
64
              alu_c_flag_out  : out std_logic;
65
              alu_z_flag_out  : out std_logic;
66
              alu_n_flag_out  : out std_logic;
67
              alu_v_flag_out  : out std_logic;
68
              alu_s_flag_out  : out std_logic;
69
              alu_h_flag_out  : out std_logic
70
);
71
 
72
end alu_avr_cm2;
73
 
74
architecture rtl of alu_avr_cm2 is
75
 
76
-- ####################################################
77
-- INTERNAL SIGNALS
78
-- ####################################################
79
 
80
signal alu_data_out_int             : std_logic_vector (7 downto 0);
81
 
82
-- ALU FLAGS (INTERNAL)
83
signal alu_z_flag_out_int       : std_logic;
84
signal alu_c_flag_in_int        : std_logic;            -- INTERNAL CARRY FLAG
85
 
86
signal alu_n_flag_out_int       : std_logic;
87
signal alu_v_flag_out_int       : std_logic;
88
signal alu_c_flag_out_int       : std_logic;
89
 
90
-- ADDER SIGNALS --
91
signal adder_nadd_sub : std_logic;        -- 0 -> ADD ,1 -> SUB
92
signal adder_v_flag_out : std_logic;
93
 
94
signal adder_carry : std_logic_vector(8 downto 0);
95
signal adder_d_in  : std_logic_vector(8 downto 0);
96
signal adder_r_in  : std_logic_vector(8 downto 0);
97
signal adder_out   : std_logic_vector(8 downto 0);
98
 
99
-- NEG OPERATOR SIGNALS 
100
signal neg_op_in    : std_logic_vector(7 downto 0);
101
signal neg_op_carry : std_logic_vector(8 downto 0);
102
signal neg_op_out   : std_logic_vector(8 downto 0);
103
 
104
-- INC, DEC OPERATOR SIGNALS 
105
signal incdec_op_in    : std_logic_vector (7 downto 0);
106
signal incdec_op_carry : std_logic_vector(7 downto 0);
107
signal incdec_op_out   : std_logic_vector(7 downto 0);
108
 
109
 
110
signal com_op_out : std_logic_vector(7 downto 0);
111
signal and_op_out : std_logic_vector(7 downto 0);
112
signal or_op_out : std_logic_vector(7 downto 0);
113
signal eor_op_out : std_logic_vector(7 downto 0);
114
 
115
-- SHIFT SIGNALS
116
signal right_shift_out : std_logic_vector(7 downto 0);
117
 
118
-- SWAP SIGNALS
119
signal swap_out : std_logic_vector(7 downto 0);
120
 
121
signal alu_data_r_in_cml_1 :  std_logic_vector ( 7 downto 0 );
122
signal alu_data_d_in_cml_1 :  std_logic_vector ( 7 downto 0 );
123
signal alu_h_flag_out_cml_out :  std_logic;
124
signal idc_adc_cml_1 :  std_logic;
125
signal idc_sub_cml_1 :  std_logic;
126
signal idc_subi_cml_1 :  std_logic;
127
signal alu_z_flag_out_cml_out :  std_logic;
128
signal idc_sbc_cml_1 :  std_logic;
129
signal idc_sbci_cml_1 :  std_logic;
130
signal idc_sbiw_cml_1 :  std_logic;
131
signal adiw_st_cml_1 :  std_logic;
132
signal sbiw_st_cml_1 :  std_logic;
133
signal idc_cp_cml_1 :  std_logic;
134
signal idc_cpc_cml_1 :  std_logic;
135
signal idc_cpi_cml_1 :  std_logic;
136
signal idc_cpse_cml_1 :  std_logic;
137
signal idc_ror_cml_1 :  std_logic;
138
signal alu_c_flag_in_int_cml_1 :  std_logic;
139
signal adder_nadd_sub_cml_1 :  std_logic;
140
signal adder_r_in_cml_1 :  std_logic_vector ( 8 downto 0 );
141
 
142
begin
143
 
144
 
145
 
146
process(cp2_cml_1) begin
147
if (cp2_cml_1 = '1' and cp2_cml_1'event) then
148
        alu_data_r_in_cml_1 <= alu_data_r_in;
149
        alu_data_d_in_cml_1 <= alu_data_d_in;
150
        idc_adc_cml_1 <= idc_adc;
151
        idc_sub_cml_1 <= idc_sub;
152
        idc_subi_cml_1 <= idc_subi;
153
        idc_sbc_cml_1 <= idc_sbc;
154
        idc_sbci_cml_1 <= idc_sbci;
155
        idc_sbiw_cml_1 <= idc_sbiw;
156
        adiw_st_cml_1 <= adiw_st;
157
        sbiw_st_cml_1 <= sbiw_st;
158
        idc_cp_cml_1 <= idc_cp;
159
        idc_cpc_cml_1 <= idc_cpc;
160
        idc_cpi_cml_1 <= idc_cpi;
161
        idc_cpse_cml_1 <= idc_cpse;
162
        idc_ror_cml_1 <= idc_ror;
163
        alu_c_flag_in_int_cml_1 <= alu_c_flag_in_int;
164
        adder_nadd_sub_cml_1 <= adder_nadd_sub;
165
        adder_r_in_cml_1 <= adder_r_in;
166
end if;
167
end process;
168
alu_h_flag_out <= alu_h_flag_out_cml_out;
169
alu_z_flag_out <= alu_z_flag_out_cml_out;
170
 
171
 
172
 
173
-- ########################################################################
174
-- ###############              ALU
175
-- ########################################################################
176
 
177
adder_nadd_sub <=(idc_sub or idc_subi or idc_sbc or idc_sbci or idc_sbiw or sbiw_st or
178
                  idc_cp or idc_cpc or idc_cpi or idc_cpse ); -- '0' -> '+'; '1' -> '-' 
179
 
180
-- SREG C FLAG (ALU INPUT)
181
alu_c_flag_in_int <= alu_c_flag_in and
182
(idc_adc or adiw_st or idc_sbc or idc_sbci or sbiw_st or
183
idc_cpc or
184
idc_ror);
185
 
186
-- SynEDA CoreMultiplier
187
-- assignment(s): alu_z_flag_out
188
-- replace(s): idc_sbc, idc_sbci, adiw_st, sbiw_st, idc_cpc
189
 
190
-- SREG Z FLAG ()
191
-- alu_z_flag_out <= (alu_z_flag_out_int and not(adiw_st or sbiw_st)) or 
192
--                   ((alu_z_flag_in and alu_z_flag_out_int) and (adiw_st or sbiw_st));
193
alu_z_flag_out_cml_out <= (alu_z_flag_out_int and not(adiw_st_cml_1 or sbiw_st_cml_1 or idc_cpc_cml_1 or idc_sbc_cml_1 or idc_sbci_cml_1)) or
194
                  ((alu_z_flag_in and alu_z_flag_out_int) and (adiw_st_cml_1 or sbiw_st_cml_1))or
195
                                  (alu_z_flag_in and alu_z_flag_out_int and(idc_cpc_cml_1 or idc_sbc_cml_1 or idc_sbci_cml_1));   -- Previous value (for CPC/SBC/SBCI instructions)
196
 
197
-- SREG N FLAG
198
alu_n_flag_out <= alu_n_flag_out_int;
199
 
200
-- SREG V FLAG
201
alu_v_flag_out <= alu_v_flag_out_int;
202
 
203
 
204
alu_c_flag_out <= alu_c_flag_out_int;
205
 
206
alu_data_out <= alu_data_out_int;
207
 
208
-- #########################################################################################
209
 
210
-- SynEDA CoreMultiplier
211
-- assignment(s): adder_d_in
212
-- replace(s): alu_data_d_in
213
 
214
adder_d_in <= '0'&alu_data_d_in_cml_1;
215
adder_r_in <= '0'&alu_data_r_in;
216
 
217
--########################## ADDEER ###################################
218
 
219
adder_out(0) <= adder_d_in(0) xor adder_r_in_cml_1(0) xor alu_c_flag_in_int_cml_1;
220
 
221
summator:for i in 1 to 8 generate
222
-- SynEDA CoreMultiplier
223
-- assignment(s): adder_out
224
-- replace(s): alu_c_flag_in_int, adder_r_in
225
 
226
adder_out(i) <= adder_d_in(i) xor adder_r_in_cml_1(i) xor adder_carry(i-1);
227
end generate;
228
 
229
 
230
adder_carry(0) <= ((adder_d_in(0) xor adder_nadd_sub_cml_1) and adder_r_in_cml_1(0)) or
231
                (((adder_d_in(0) xor adder_nadd_sub_cml_1) or adder_r_in_cml_1(0)) and alu_c_flag_in_int_cml_1);
232
 
233
summator2:for i in 1 to 8 generate
234
-- SynEDA CoreMultiplier
235
-- assignment(s): adder_carry
236
-- replace(s): alu_c_flag_in_int, adder_nadd_sub, adder_r_in
237
 
238
adder_carry(i) <= ((adder_d_in(i) xor adder_nadd_sub_cml_1) and adder_r_in_cml_1(i)) or
239
                (((adder_d_in(i) xor adder_nadd_sub_cml_1) or adder_r_in_cml_1(i)) and adder_carry(i-1));
240
end generate;
241
 
242
-- FLAGS  FOR ADDER INSTRUCTIONS: 
243
-- CARRY FLAG (C) -> adder_out(8)
244
-- HALF CARRY FLAG (H) -> adder_carry(3)
245
-- TOW'S COMPLEMENT OVERFLOW  (V) -> 
246
 
247
-- SynEDA CoreMultiplier
248
-- assignment(s): adder_v_flag_out
249
-- replace(s): adder_nadd_sub, adder_r_in
250
 
251
adder_v_flag_out <= (((adder_d_in(7) and adder_r_in_cml_1(7) and not adder_out(7)) or
252
                    (not adder_d_in(7) and not adder_r_in_cml_1(7) and adder_out(7))) and not adder_nadd_sub_cml_1) or -- ADD
253
                    (((adder_d_in(7) and not adder_r_in_cml_1(7) and not adder_out(7)) or
254
                                        (not adder_d_in(7) and adder_r_in_cml_1(7) and adder_out(7))) and adder_nadd_sub_cml_1);
255
                                                                                                                                                                                                                   -- SUB
256
--#####################################################################
257
 
258
 
259
-- LOGICAL OPERATIONS FOR ONE OPERAND
260
 
261
--########################## NEG OPERATION ####################
262
 
263
neg_op_out(0)   <= not alu_data_d_in_cml_1(0) xor '1';
264
neg_op:for i in 1 to 7 generate
265
neg_op_out(i)   <= not alu_data_d_in_cml_1(i) xor neg_op_carry(i-1);
266
end generate;
267
-- SynEDA CoreMultiplier
268
-- assignment(s): neg_op_out
269
-- replace(s): alu_data_d_in
270
 
271
neg_op_out(8) <= neg_op_carry(7) xor '1';
272
 
273
 
274
neg_op_carry(0) <= not alu_data_d_in_cml_1(0) and '1';
275
neg_op2:for i in 1 to 7 generate
276
neg_op_carry(i) <= not alu_data_d_in_cml_1(i) and neg_op_carry(i-1);
277
end generate;
278
-- SynEDA CoreMultiplier
279
-- assignment(s): neg_op_carry
280
-- replace(s): alu_data_d_in
281
 
282
neg_op_carry(8) <= neg_op_carry(7);                            -- ??!!
283
 
284
 
285
-- CARRY FLAGS  FOR NEG INSTRUCTION: 
286
-- CARRY FLAG -> neg_op_out(8)
287
-- HALF CARRY FLAG -> neg_op_carry(3)
288
-- TOW's COMPLEMENT OVERFLOW FLAG -> alu_data_d_in(7) and neg_op_carry(6) 
289
--############################################################################  
290
 
291
 
292
--########################## INC, DEC OPERATIONS ####################
293
 
294
incdec_op_out(0)      <=  alu_data_d_in_cml_1(0) xor '1';
295
inc_dec:for i in 1 to 7 generate
296
-- SynEDA CoreMultiplier
297
-- assignment(s): incdec_op_out
298
-- replace(s): alu_data_d_in
299
 
300
incdec_op_out(i)   <= alu_data_d_in_cml_1(i) xor incdec_op_carry(i-1);
301
end generate;
302
 
303
 
304
incdec_op_carry(0)    <=  alu_data_d_in_cml_1(0) xor idc_dec;
305
inc_dec2:for i in 1 to 7 generate
306
-- SynEDA CoreMultiplier
307
-- assignment(s): incdec_op_carry
308
-- replace(s): alu_data_d_in
309
 
310
incdec_op_carry(i) <= (alu_data_d_in_cml_1(i) xor idc_dec) and incdec_op_carry(i-1);
311
end generate;
312
 
313
-- TOW's COMPLEMENT OVERFLOW FLAG -> (alu_data_d_in(7) xor idc_dec) and incdec_op_carry(6) 
314
--####################################################################
315
 
316
 
317
-- SynEDA CoreMultiplier
318
-- assignment(s): com_op_out
319
-- replace(s): alu_data_d_in
320
 
321
--########################## COM OPERATION ###################################
322
com_op_out <= not alu_data_d_in_cml_1;
323
-- FLAGS 
324
-- TOW's COMPLEMENT OVERFLOW FLAG (V)  -> '0'
325
-- CARRY FLAG (C) -> '1' 
326
--############################################################################
327
 
328
-- LOGICAL OPERATIONS FOR TWO OPERANDS  
329
 
330
-- SynEDA CoreMultiplier
331
-- assignment(s): and_op_out
332
-- replace(s): alu_data_r_in, alu_data_d_in
333
 
334
--########################## AND OPERATION ###################################
335
and_op_out <= alu_data_d_in_cml_1 and alu_data_r_in_cml_1;
336
-- FLAGS 
337
-- TOW's COMPLEMENT OVERFLOW FLAG (V)  -> '0'
338
--############################################################################
339
 
340
-- SynEDA CoreMultiplier
341
-- assignment(s): or_op_out
342
-- replace(s): alu_data_r_in, alu_data_d_in
343
 
344
--########################## OR OPERATION ###################################
345
or_op_out <= alu_data_d_in_cml_1 or alu_data_r_in_cml_1;
346
-- FLAGS 
347
-- TOW's COMPLEMENT OVERFLOW FLAG (V)  -> '0'
348
--############################################################################
349
 
350
-- SynEDA CoreMultiplier
351
-- assignment(s): eor_op_out
352
-- replace(s): alu_data_r_in, alu_data_d_in
353
 
354
--########################## EOR OPERATION ###################################
355
eor_op_out <= alu_data_d_in_cml_1 xor alu_data_r_in_cml_1;
356
-- FLAGS 
357
-- TOW's COMPLEMENT OVERFLOW FLAG (V)  -> '0'
358
--############################################################################
359
 
360
-- SHIFT OPERATIONS 
361
 
362
-- ########################## RIGHT(LSR, ROR, ASR) #######################
363
 
364
right_shift_out(7) <= (idc_ror_cml_1 and alu_c_flag_in_int_cml_1) or (idc_asr and alu_data_d_in_cml_1(7)); -- right_shift_out(7)
365
shift_right:for i in 6 downto 0 generate
366
-- SynEDA CoreMultiplier
367
-- assignment(s): right_shift_out
368
-- replace(s): alu_data_d_in, idc_ror, alu_c_flag_in_int
369
 
370
right_shift_out(i) <= alu_data_d_in_cml_1(i+1);
371
end generate;
372
 
373
-- FLAGS 
374
-- CARRY FLAG (C)                      -> alu_data_d_in(0) 
375
-- NEGATIVE FLAG (N)                   -> right_shift_out(7)
376
-- TOW's COMPLEMENT OVERFLOW FLAG (V)  -> N xor C  (left_shift_out(7) xor alu_data_d_in(0))
377
 
378
-- #######################################################################
379
 
380
 
381
-- ################################## SWAP ###############################
382
 
383
swap_h:for i in 7 downto 4 generate
384
swap_out(i) <= alu_data_d_in_cml_1(i-4);
385
end generate;
386
swap_l:for i in 3 downto 0 generate
387
-- SynEDA CoreMultiplier
388
-- assignment(s): swap_out
389
-- replace(s): alu_data_d_in
390
 
391
swap_out(i) <= alu_data_d_in_cml_1(i+4);
392
end generate;
393
-- #######################################################################
394
 
395
-- ALU OUTPUT MUX
396
 
397
alu_data_out_mux:for i in alu_data_out_int'range generate
398
-- SynEDA CoreMultiplier
399
-- assignment(s): alu_data_out_int
400
-- replace(s): idc_adc, idc_sub, idc_subi, idc_sbc, idc_sbci, idc_sbiw, adiw_st, sbiw_st, idc_cp, idc_cpc, idc_cpi, idc_cpse, idc_ror
401
 
402
alu_data_out_int(i) <= (adder_out(i) and (idc_add or idc_adc_cml_1 or (idc_adiw or adiw_st_cml_1) or    -- !!!!!
403
                                     idc_sub_cml_1 or idc_subi_cml_1 or idc_sbc_cml_1 or idc_sbci_cml_1 or
404
                                     (idc_sbiw_cml_1 or sbiw_st_cml_1) or    -- !!!!!
405
                                     idc_cpse_cml_1 or idc_cp_cml_1 or idc_cpc_cml_1 or idc_cpi_cml_1)) or
406
                                     (neg_op_out(i) and idc_neg) or                               -- NEG
407
                                     (incdec_op_out(i) and (idc_inc or idc_dec)) or               -- INC/DEC
408
                                     (com_op_out(i) and idc_com) or                               -- COM
409
                                     (and_op_out(i) and (idc_and or idc_andi)) or                 -- AND/ANDI                                   
410
                                     (or_op_out(i)  and (idc_or or idc_ori)) or                   -- OR/ORI                                   
411
                                     (eor_op_out(i) and idc_eor) or                               -- EOR
412
                                     (right_shift_out(i) and (idc_lsr or idc_ror_cml_1 or idc_asr)) or  -- LSR/ROR/ASR
413
                                     (swap_out(i) and idc_swap);                                  -- SWAP
414
 
415
 
416
end generate;
417
 
418
--@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ALU FLAGS OUTPUTS @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
419
 
420
-- SynEDA CoreMultiplier
421
-- assignment(s): alu_h_flag_out
422
-- replace(s): idc_adc, idc_sub, idc_subi, idc_sbc, idc_sbci, idc_cp, idc_cpc, idc_cpi
423
 
424
alu_h_flag_out_cml_out <= (adder_carry(3) and                                                      -- ADDER INSTRUCTIONS
425
             (idc_add or idc_adc_cml_1 or idc_sub_cml_1 or idc_subi_cml_1 or idc_sbc_cml_1 or idc_sbci_cml_1 or idc_cp_cml_1 or idc_cpc_cml_1 or idc_cpi_cml_1)) or
426
             (not neg_op_carry(3) and idc_neg); -- H-flag problem with NEG instruction fixing                                         -- NEG
427
 
428
 
429
alu_s_flag_out <= alu_n_flag_out_int xor alu_v_flag_out_int;
430
 
431
-- SynEDA CoreMultiplier
432
-- assignment(s): alu_v_flag_out_int
433
-- replace(s): alu_data_d_in, idc_adc, idc_sub, idc_subi, idc_sbc, idc_sbci, adiw_st, sbiw_st, idc_cp, idc_cpc, idc_cpi, idc_ror
434
 
435
alu_v_flag_out_int <= (adder_v_flag_out and
436
             (idc_add or idc_adc_cml_1 or idc_sub_cml_1 or idc_subi_cml_1 or idc_sbc_cml_1 or idc_sbci_cml_1 or adiw_st_cml_1 or sbiw_st_cml_1 or idc_cp_cml_1 or idc_cpi_cml_1 or idc_cpc_cml_1)) or
437
             ((alu_data_d_in_cml_1(7) and neg_op_carry(6)) and idc_neg) or                                       -- NEG
438
                     (not alu_data_d_in_cml_1(7) and incdec_op_carry(6) and idc_inc) or -- INC
439
                     (alu_data_d_in_cml_1(7) and incdec_op_carry(6) and idc_dec) or       -- DEC
440
                         ((alu_n_flag_out_int xor alu_c_flag_out_int) and (idc_lsr or idc_ror_cml_1 or idc_asr));            -- LSR,ROR,ASR
441
 
442
 
443
alu_n_flag_out_int <= alu_data_out_int(7);
444
 
445
alu_z_flag_out_int <= '1' when alu_data_out_int="00000000" else '0';
446
 
447
-- SynEDA CoreMultiplier
448
-- assignment(s): alu_c_flag_out_int
449
-- replace(s): alu_data_d_in, idc_adc, idc_sub, idc_subi, idc_sbc, idc_sbci, idc_sbiw, adiw_st, sbiw_st, idc_cp, idc_cpc, idc_cpi, idc_ror
450
 
451
alu_c_flag_out_int <= (adder_out(8) and
452
                       (idc_add or idc_adc_cml_1 or (idc_adiw or adiw_st_cml_1) or idc_sub_cml_1 or idc_subi_cml_1 or idc_sbc_cml_1 or idc_sbci_cml_1 or (idc_sbiw_cml_1 or sbiw_st_cml_1) or idc_cp_cml_1 or idc_cpc_cml_1 or idc_cpi_cml_1)) or -- ADDER
453
                                           (not alu_z_flag_out_int and idc_neg) or    -- NEG
454
                                           (alu_data_d_in_cml_1(0) and (idc_lsr or idc_ror_cml_1 or idc_asr)) or idc_com;
455
 
456
-- @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
457
 
458
 
459
end rtl;

powered by: WebSVN 2.1.0

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