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

Subversion Repositories tg68kc

[/] [tg68kc/] [trunk/] [TG68K_ALU.vhd] - Blame information for rev 2

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 tobiflex
------------------------------------------------------------------------------
2
------------------------------------------------------------------------------
3
--                                                                          --
4
-- Copyright (c) 2009-2018 Tobias Gubener                                   -- 
5
-- Subdesign fAMpIGA by TobiFlex                                            --
6
-- Patches by MikeJ, Till Harbaum, Rok Krajnk, ...                          --
7
--                                                                          --
8
-- This source file is free software: you can redistribute it and/or modify --
9
-- it under the terms of the GNU Lesser General Public License as published --
10
-- by the Free Software Foundation, either version 3 of the License, or     --
11
-- (at your option) any later version.                                      --
12
--                                                                          --
13
-- This source file is distributed in the hope that it will be useful,      --
14
-- but WITHOUT ANY WARRANTY; without even the implied warranty of           --
15
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            --
16
-- GNU General Public License for more details.                             --
17
--                                                                          --
18
-- You should have received a copy of the GNU General Public License        --
19
-- along with this program.  If not, see <http://www.gnu.org/licenses/>.    --
20
--                                                                          --
21
------------------------------------------------------------------------------
22
------------------------------------------------------------------------------
23
 
24
library ieee;
25
use ieee.std_logic_1164.all;
26
use ieee.std_logic_unsigned.all;
27
use IEEE.numeric_std.all;
28
use work.TG68K_Pack.all;
29
 
30
entity TG68K_ALU is
31
generic(
32
                MUL_Mode : integer;     --0=>16Bit,  1=>32Bit,  2=>switchable with CPU(1),  3=>no MUL,  
33
                MUL_Hardware : integer;   --0=>no,      1=>yes,  
34
                DIV_Mode : integer;             --0=>16Bit,  1=>32Bit,  2=>switchable with CPU(1),  3=>no DIV,  
35
                BarrelShifter :integer   --0=>no,     1=>yes,    2=>switchable with CPU(1)  
36
                );
37
           port(clk             : in std_logic;
38
        Reset                   : in std_logic;
39
        clkena_lw               : in std_logic:='1';
40
        execOPC                 : in bit;
41
        decodeOPC               : in bit;
42
        exe_condition      : in std_logic;
43
        exec_tas                        : in std_logic;
44
        long_start                      : in bit;
45
                  non_aligned    : in  std_logic;
46
        movem_presub            : in bit;
47
        set_stop                        : in bit;
48
        Z_error                 : in bit;
49
        rot_bits                : in std_logic_vector(1 downto 0);
50
                  exec                : in bit_vector(lastOpcBit downto 0);
51
        OP1out                  : in std_logic_vector(31 downto 0);
52
        OP2out                  : in std_logic_vector(31 downto 0);
53
        reg_QA                  : in std_logic_vector(31 downto 0);
54
        reg_QB                  : in std_logic_vector(31 downto 0);
55
        opcode                  : in std_logic_vector(15 downto 0);
56
--        datatype              : in std_logic_vector(1 downto 0);
57
        exe_opcode              : in std_logic_vector(15 downto 0);
58
        exe_datatype            : in std_logic_vector(1 downto 0);
59
        sndOPC                  : in std_logic_vector(15 downto 0);
60
        last_data_read          : in std_logic_vector(15 downto 0);
61
        data_read                       : in std_logic_vector(15 downto 0);
62
        FlagsSR                 : in std_logic_vector(7 downto 0);
63
                micro_state                     : in micro_states;
64
                bf_ext_in               : in std_logic_vector(7 downto 0);
65
                bf_ext_out              : out std_logic_vector(7 downto 0);
66
                bf_shift                : in std_logic_vector(5 downto 0);
67
                bf_width                : in std_logic_vector(5 downto 0);
68
                bf_ffo_offset           : in std_logic_vector(31 downto 0);
69
                bf_loffset              : in std_logic_vector(4 downto 0);
70
 
71
        set_V_Flag              : buffer bit;
72
        Flags                   : buffer std_logic_vector(7 downto 0);
73
        c_out                   : buffer std_logic_vector(2 downto 0);
74
        addsub_q                : buffer std_logic_vector(31 downto 0);
75
        ALUout                  : out std_logic_vector(31 downto 0)
76
        );
77
end TG68K_ALU;
78
 
79
architecture logic of TG68K_ALU is
80
-----------------------------------------------------------------------------
81
-----------------------------------------------------------------------------
82
-- ALU and more
83
-----------------------------------------------------------------------------
84
-----------------------------------------------------------------------------
85
    signal OP1in          : std_logic_vector(31 downto 0);
86
    signal addsub_a       : std_logic_vector(31 downto 0);
87
    signal addsub_b       : std_logic_vector(31 downto 0);
88
    signal notaddsub_b    : std_logic_vector(33 downto 0);
89
    signal add_result     : std_logic_vector(33 downto 0);
90
    signal addsub_ofl     : std_logic_vector(2 downto 0);
91
    signal opaddsub           : bit;
92
    signal c_in           : std_logic_vector(3 downto 0);
93
    signal flag_z         : std_logic_vector(2 downto 0);
94
         signal set_Flags      : std_logic_vector(3 downto 0);   --NZVC
95
         signal CCRin          : std_logic_vector(7 downto 0);
96
 
97
--BCD
98
    signal bcd_pur                : std_logic_vector(9 downto 0);
99
    signal bcd_kor                : std_logic_vector(8 downto 0);
100
    signal halve_carry    : std_logic;
101
    signal Vflag_a                : std_logic;
102
    signal bcd_a_carry    : std_logic;
103
    signal bcd_a                  : std_logic_vector(8 downto 0);
104
    signal result_mulu    : std_logic_vector(127 downto 0);
105
    signal result_div     : std_logic_vector(63 downto 0);
106
    signal set_mV_Flag    : std_logic;
107
    signal V_Flag             : bit;
108
 
109
         signal rot_rot        : std_logic;
110
         signal rot_lsb        : std_logic;
111
         signal rot_msb        : std_logic;
112
         signal rot_X          : std_logic;
113
         signal rot_C          : std_logic;
114
    signal rot_out        : std_logic_vector(31 downto 0);
115
         signal asl_VFlag      : std_logic;
116
    signal bit_bits       : std_logic_vector(1 downto 0);
117
    signal bit_number     : std_logic_vector(4 downto 0);
118
    signal bits_out       : std_logic_vector(31 downto 0);
119
    signal one_bit_in     : std_logic;
120
    signal bchg                   : std_logic;
121
    signal bset                   : std_logic;
122
 
123
    signal mulu_sign      : std_logic;
124
    signal mulu_signext   : std_logic_vector(16 downto 0);
125
    signal muls_msb               : std_logic;
126
    signal mulu_reg       : std_logic_vector(63 downto 0);
127
    signal FAsign                 : std_logic;
128
    signal faktorA        : std_logic_vector(31 downto 0);
129
    signal faktorB        : std_logic_vector(31 downto 0);
130
 
131
    signal div_reg        : std_logic_vector(63 downto 0);
132
    signal div_quot       : std_logic_vector(63 downto 0);
133
    signal div_ovl            : std_logic;
134
    signal div_neg            : std_logic;
135
    signal div_bit            : std_logic;
136
    signal div_sub        : std_logic_vector(32 downto 0);
137
    signal div_over       : std_logic_vector(32 downto 0);
138
    signal nozero         : std_logic;
139
    signal div_qsign      : std_logic;
140
    signal divisor        : std_logic_vector(63 downto 0);
141
    signal divs                   : std_logic;
142
    signal signedOP       : std_logic;
143
    signal OP1_sign               : std_logic;
144
    signal OP2_sign       : std_logic;
145
    signal OP2outext      : std_logic_vector(15 downto 0);
146
 
147
    signal in_offset        : std_logic_vector(5 downto 0);
148
    signal datareg       : std_logic_vector(31 downto 0);
149
    signal insert       : std_logic_vector(31 downto 0);
150
    signal bf_datareg       : std_logic_vector(31 downto 0);
151
    signal result           : std_logic_vector(39 downto 0);
152
    signal result_tmp           : std_logic_vector(39 downto 0);
153
    signal unshifted_bitmask    : std_logic_vector(31 downto 0);
154
    signal bf_set1          : std_logic_vector(39 downto 0);
155
    signal inmux0           : std_logic_vector(39 downto 0);
156
    signal inmux1           : std_logic_vector(39 downto 0);
157
    signal inmux2           : std_logic_vector(39 downto 0);
158
    signal inmux3           : std_logic_vector(31 downto 0);
159
    signal shifted_bitmask            : std_logic_vector(39 downto 0);
160
    signal bitmaskmux0           : std_logic_vector(37 downto 0);
161
    signal bitmaskmux1           : std_logic_vector(35 downto 0);
162
    signal bitmaskmux2           : std_logic_vector(31 downto 0);
163
    signal bitmaskmux3           : std_logic_vector(31 downto 0);
164
    signal bf_set2          : std_logic_vector(31 downto 0);
165
    signal shift            : std_logic_vector(39 downto 0);
166
    signal bf_firstbit      : std_logic_vector(5 downto 0);
167
         signal mux     : std_logic_vector(3 downto 0);
168
    signal bitnr  : std_logic_vector(4 downto 0);
169
    signal mask     : std_logic_vector(31 downto 0);
170
    signal mask_not_zero  : std_logic;
171
    signal bf_bset  : std_logic;
172
    signal bf_NFlag  : std_logic;
173
    signal bf_bchg  : std_logic;
174
    signal bf_ins  : std_logic;
175
    signal bf_exts  : std_logic;
176
    signal bf_fffo  : std_logic;
177
    signal bf_d32  : std_logic;
178
    signal bf_s32  : std_logic;
179
    signal index  : std_logic_vector(4 downto 0);
180
--    signal i  : integer range 0 to 31;
181
--    signal i  : integer range 0 to 31;
182
--    signal i  : std_logic_vector(5 downto 0);
183
 
184
--  signal hot_bit      : std_logic_vector(33 downto 0); simulation error =>
185
  signal hot_bit      : std_logic_vector(63 downto 0);
186
  signal hot_msb      : std_logic_vector(32 downto 0);
187
  signal vector       : std_logic_vector(32 downto 0);
188
  signal result_bs    : std_logic_vector(65 downto 0);
189
  signal bit_nr       : std_logic_vector(5 downto 0);
190
  signal bit_nr7       : std_logic_vector(6 downto 0);
191
  signal bit_msb      : std_logic_vector(5 downto 0);
192
  signal bs_shift     : std_logic_vector(5 downto 0);
193
  signal bs_shift_mod : std_logic_vector(5 downto 0);
194
  signal asl_over     : std_logic_vector(32 downto 0);
195
  signal asr_sign     : std_logic_vector(32 downto 0);
196
  signal msb          : std_logic;
197
  signal ring               : std_logic_vector(5 downto 0);
198
  signal ALU          : std_logic_vector(31 downto 0);
199
  signal BSout        : std_logic_vector(31 downto 0);
200
  signal bs_V         : std_logic;
201
  signal bs_C         : std_logic;
202
  signal bs_X         : std_logic;
203
 
204
 
205
BEGIN
206
-----------------------------------------------------------------------------
207
-- set OP1in
208
-----------------------------------------------------------------------------
209
PROCESS (OP2out, reg_QB, opcode, OP1out, OP1in, exe_datatype, addsub_q, execOPC, exec,
210
             bcd_a, result_mulu, result_div, exe_condition, bf_shift, bf_ffo_offset, mulu_reg, BSout,
211
             Flags, FlagsSR, bits_out, exec_tas, rot_out, exe_opcode, result, bf_fffo, bf_firstbit, bf_datareg)
212
        BEGIN
213
                ALUout <= OP1in;
214
                ALUout(7) <= OP1in(7) OR exec_tas;
215
                IF exec(opcBFwb)='1' THEN
216
                        ALUout <= result(31 downto 0);
217
--                      ALUout <= bf_datareg(31 downto 0);
218
                        IF bf_fffo='1' THEN
219
--                              ALUout <= (OTHERS =>'0');
220
--                              ALUout(5 downto 0) <= bf_firstbit + bf_shift;
221
--                              ALUout(5 downto 0) <= bf_firstbit;
222
                                ALUout <= bf_ffo_offset - bf_firstbit;
223
                        END IF;
224
                END IF;
225
 
226
                OP1in <= addsub_q;
227
                IF exec(opcABCD)='1' OR exec(opcSBCD)='1' THEN
228
                        OP1in(7 downto 0) <= bcd_a(7 downto 0);
229
                ELSIF exec(opcMULU)='1' AND MUL_Mode/=3 THEN
230
                        IF MUL_Hardware=0 THEN
231
                                IF exec(write_lowlong)='1' AND (MUL_Mode=1 OR MUL_Mode=2) THEN
232
                                        OP1in <= result_mulu(31 downto 0);
233
                                ELSE
234
                                        OP1in <= result_mulu(63 downto 32);
235
                                END IF;
236
                        ELSE
237
                                IF exec(write_lowlong)='1' THEN --AND (MUL_Mode=1 OR MUL_Mode=2) THEN
238
                                        OP1in <= result_mulu(31 downto 0);
239
                                ELSE
240
--                                      OP1in <= result_mulu(63 downto 32);
241
                                        OP1in <= mulu_reg(31 downto 0);
242
                                END IF;
243
                        END IF;
244
                ELSIF exec(opcDIVU)='1' AND DIV_Mode/=3 THEN
245
                        IF exe_opcode(15)='1' OR DIV_Mode=0 THEN
246
--                      IF exe_opcode(15)='1' THEN
247
                                OP1in <= result_div(47 downto 32)&result_div(15 downto 0);
248
                        ELSE            --64bit
249
                                IF exec(write_reminder)='1' THEN
250
                                        OP1in <= result_div(63 downto 32);
251
                                ELSE
252
                                        OP1in <= result_div(31 downto 0);
253
                                END IF;
254
                        END IF;
255
                ELSIF exec(opcOR)='1' THEN
256
                        OP1in <= OP2out OR OP1out;
257
                ELSIF exec(opcAND)='1' THEN
258
                        OP1in <= OP2out AND OP1out;
259
                ELSIF exec(opcScc)='1' THEN
260
                        OP1in(7 downto 0) <= (others=>exe_condition);
261
                ELSIF exec(opcEOR)='1' THEN
262
                        OP1in <= OP2out XOR OP1out;
263
                ELSIF exec(opcMOVE)='1' OR exec(exg)='1' THEN
264
--                      OP1in <= OP2out(31 downto 8)&(OP2out(7)OR exec_tas)&OP2out(6 downto 0);
265
                        OP1in <= OP2out;
266
                ELSIF exec(opcROT)='1' THEN
267
                        OP1in <= rot_out;
268
                ELSIF exec(exec_BS)='1' THEN
269
                        OP1in <= BSout;
270
                ELSIF exec(opcSWAP)='1' THEN
271
                        OP1in <= OP1out(15 downto 0)& OP1out(31 downto 16);
272
                ELSIF exec(opcBITS)='1' THEN
273
                        OP1in <= bits_out;
274
                ELSIF exec(opcBF)='1' THEN
275
                        OP1in <= bf_datareg;            --new bitfieldvector for bfins - for others the old bitfieldvector
276
                ELSIF exec(opcMOVESR)='1' THEN
277
                        OP1in(7 downto 0) <= Flags;
278
--                      IF exe_datatype="00" THEN
279
                        IF exe_opcode(9)='1' THEN
280
                                OP1in(15 downto 8) <= "00000000";
281
                        ELSE
282
                                OP1in(15 downto 8) <= FlagsSR;
283
                        END IF;
284
                ELSIF exec(opcPACK)='1' THEN
285
                        OP1in(7 downto 0) <= addsub_q(11 downto 8) & addsub_q(3 downto 0);
286
                END IF;
287
        END PROCESS;
288
 
289
-----------------------------------------------------------------------------
290
-- addsub
291
-----------------------------------------------------------------------------
292
PROCESS (OP1out, OP2out, execOPC, Flags, long_start, movem_presub, exe_datatype, exec, addsub_a, addsub_b, opaddsub,
293
             notaddsub_b, add_result, c_in, sndOPC, non_aligned)
294
        BEGIN
295
                addsub_a <= OP1out;
296
                IF exec(get_bfoffset)='1' THEN
297
                        IF sndOPC(11)='1' THEN
298
                                addsub_a <= OP1out(31)&OP1out(31)&OP1out(31)&OP1out(31 downto 3);
299
                        ELSE
300
                                addsub_a <= "000000000000000000000000000000"&sndOPC(10 downto 9);
301
                        END IF;
302
                END IF;
303
 
304
                IF exec(subidx)='1' THEN
305
                        opaddsub <= '1';
306
                ELSE
307
                        opaddsub <= '0';
308
                END IF;
309
 
310
                c_in(0) <='0';
311
                addsub_b <= OP2out;
312
                IF exec(opcUNPACK)='1' THEN
313
                        addsub_b(15 downto 0) <= "0000" & OP2out(7 downto 4) & "0000" & OP2out(3 downto 0);
314
                ELSIF execOPC='0' AND exec(OP2out_one)='0' AND exec(get_bfoffset)='0'THEN
315
                        IF long_start='0' AND exe_datatype="00" AND exec(use_SP)='0' THEN
316
                                addsub_b <= "00000000000000000000000000000001";
317
                        ELSIF long_start='0' AND exe_datatype="10" AND (exec(presub) OR exec(postadd) OR movem_presub)='1' THEN
318
                                IF exec(movem_action)='1' THEN
319
                                        addsub_b <= "00000000000000000000000000000110";
320
                                ELSE
321
                                        addsub_b <= "00000000000000000000000000000100";
322
                                END IF;
323
                        ELSE
324
                                addsub_b <= "00000000000000000000000000000010";
325
                        END IF;
326
                ELSE
327
                        IF (exec(use_XZFlag)='1' AND Flags(4)='1') OR exec(opcCHK)='1' THEN
328
                                c_in(0) <= '1';
329
                        END IF;
330
                        opaddsub <= exec(addsub);
331
                END IF;
332
 
333
                -- patch for un-aligned movem --mikej
334
                if (exec(movem_action) = '1') then
335
                  if (movem_presub = '0') then -- up
336
                        if (non_aligned = '1') and (long_start = '0') then -- hold
337
                          addsub_b <= (others => '0');
338
                        end if;
339
                  else
340
                        if (non_aligned = '1') and (long_start = '0') then
341
                          if (exe_datatype = "10") then
342
                                addsub_b <= "00000000000000000000000000001000";
343
                          else
344
                                addsub_b <= "00000000000000000000000000000100";
345
                          end if;
346
                        end if;
347
                  end if;
348
                end if;
349
 
350
                IF opaddsub='0' OR long_start='1' THEN           --ADD
351
                        notaddsub_b <= '0'&addsub_b&c_in(0);
352
                ELSE                                    --SUB
353
                        notaddsub_b <= NOT ('0'&addsub_b&c_in(0));
354
                END IF;
355
                add_result <= (('0'&addsub_a&notaddsub_b(0))+notaddsub_b);
356
                c_in(1) <= add_result(9) XOR addsub_a(8) XOR addsub_b(8);
357
                c_in(2) <= add_result(17) XOR addsub_a(16) XOR addsub_b(16);
358
                c_in(3) <= add_result(33);
359
                addsub_q <= add_result(32 downto 1);
360
                addsub_ofl(0) <= (c_in(1) XOR add_result(8) XOR addsub_a(7) XOR addsub_b(7));            --V Byte
361
                addsub_ofl(1) <= (c_in(2) XOR add_result(16) XOR addsub_a(15) XOR addsub_b(15));        --V Word
362
                addsub_ofl(2) <= (c_in(3) XOR add_result(32) XOR addsub_a(31) XOR addsub_b(31));        --V Long
363
                c_out <= c_in(3 downto 1);
364
        END PROCESS;
365
 
366
------------------------------------------------------------------------------
367
--ALU
368
------------------------------------------------------------------------------          
369
PROCESS (OP1out, OP2out, exec, add_result, bcd_pur, bcd_a, bcd_kor, halve_carry, c_in)
370
        BEGIN
371
--BCD_ARITH-------------------------------------------------------------------
372
--04.04.2017 by Tobiflex - BCD handling with all undefined behavior!
373
                bcd_pur <= c_in(1)&add_result(8 downto 0);
374
                bcd_kor <= "000000000";
375
                halve_carry <= OP1out(4) XOR OP2out(4) XOR bcd_pur(5);
376
                IF halve_carry='1' THEN
377
                        bcd_kor(3 downto 0) <= "0110"; --  -6
378
                END IF;
379
                IF bcd_pur(9)='1' THEN
380
                        bcd_kor(7 downto 4) <= "0110"; --  -60
381
                END IF;
382
                IF exec(opcABCD)='1' THEN
383
                        Vflag_a <= NOT bcd_pur(8) AND bcd_a(7);
384
--                      bcd_pur <= ('0'&OP1out(7 downto 0)&'1') + ('0'&OP2out(7 downto 0)&Flags(4));
385
                        bcd_a <= bcd_pur(9 downto 1) + bcd_kor;
386
                        IF (bcd_pur(4) AND (bcd_pur(3) OR bcd_pur(2)))='1' THEN
387
                                bcd_kor(3 downto 0) <= "0110"; --  +6
388
                        END IF;
389
                        IF (bcd_pur(8) AND (bcd_pur(7) OR bcd_pur(6) OR (bcd_pur(5) AND bcd_pur(4) AND (bcd_pur(3) OR bcd_pur(2)))))='1' THEN
390
                                bcd_kor(7 downto 4) <= "0110"; --  +60 
391
                        END IF;
392
                ELSE --opcSBCD  
393
                        Vflag_a <= bcd_pur(8) AND NOT bcd_a(7);
394
--                      bcd_pur <= ('0'&OP1out(7 downto 0)&'0') - ('0'&OP2out(7 downto 0)&Flags(4));
395
                        bcd_a <= bcd_pur(9 downto 1) - bcd_kor;
396
                END IF;
397
                bcd_a_carry <= bcd_pur(9) OR bcd_a(8);
398
        END PROCESS;
399
 
400
-----------------------------------------------------------------------------
401
-- Bits
402
-----------------------------------------------------------------------------
403
PROCESS (clk, exe_opcode, OP1out, OP2out, reg_QB, one_bit_in, bchg, bset, bit_Number, sndOPC)
404
        BEGIN
405
                IF rising_edge(clk) THEN
406
                IF  clkena_lw = '1' THEN
407
                                bchg <= '0';
408
                                bset <= '0';
409
                                CASE opcode(7 downto 6) IS
410
                                        WHEN "01" =>                                    --bchg
411
                                                bchg <= '1';
412
                                        WHEN "11" =>                                    --bset
413
                                                bset <= '1';
414
                                        WHEN OTHERS => NULL;
415
                                END CASE;
416
                        END IF;
417
                END IF;
418
 
419
                IF exe_opcode(8)='0' THEN
420
                        IF exe_opcode(5 downto 4)="00" THEN
421
                                bit_number <= sndOPC(4 downto 0);
422
                        ELSE
423
                                bit_number <= "00"&sndOPC(2 downto 0);
424
                        END IF;
425
                ELSE
426
                        IF exe_opcode(5 downto 4)="00" THEN
427
                                bit_number <= reg_QB(4 downto 0);
428
                        ELSE
429
                                bit_number <= "00"&reg_QB(2 downto 0);
430
                        END IF;
431
                END IF;
432
 
433
                one_bit_in <= OP1out(conv_integer(bit_Number));
434
                bits_out <= OP1out;
435
                bits_out(conv_integer(bit_Number)) <= (bchg AND NOT one_bit_in) OR bset ;
436
        END PROCESS;
437
 
438
-----------------------------------------------------------------------------
439
-- Bit Field
440
-----------------------------------------------------------------------------   
441
 
442
PROCESS (clk, mux, mask, bitnr, bf_ins, bf_bchg, bf_bset, bf_exts, bf_shift, inmux0, inmux1, inmux2, inmux3, bf_set2, OP1out, OP2out,
443
                        result_tmp, bf_ext_in, mask_not_zero, exec, shift, datareg, bf_NFlag, result, reg_QB, unshifted_bitmask, bf_d32, bf_s32,
444
                        shifted_bitmask, bf_loffset, bitmaskmux0, bitmaskmux1, bitmaskmux2, bitmaskmux3, bf_width)
445
        BEGIN
446
                IF rising_edge(clk) THEN
447
                IF clkena_lw = '1' THEN
448
                                bf_bset <= '0';
449
                                bf_bchg <= '0';
450
                                bf_ins <= '0';
451
                                bf_exts <= '0';
452
                                bf_fffo <= '0';
453
                                bf_d32 <= '0';
454
                                bf_s32 <= '0';
455
--              000-bftst, 001-bfextu, 010-bfchg, 011-bfexts, 100-bfclr, 101-bfff0, 110-bfset, 111-bfins                                                                
456
                                CASE opcode(10 downto 8) IS
457
                                        WHEN "010" => bf_bchg <= '1';                           --BFCHG
458
                                        WHEN "011" => bf_exts <= '1';                           --BFEXTS
459
--                                      WHEN "100" => insert <= (OTHERS =>'0');         --BFCLR
460
                                        WHEN "101" => bf_fffo <= '1';                           --BFFFO
461
                                        WHEN "110" => bf_bset <= '1';                           --BFSET
462
                                        WHEN "111" => bf_ins <= '1';                                    --BFINS
463
                                                                  bf_s32 <= '1';
464
                                        WHEN OTHERS => NULL;
465
                                END CASE;
466
--                              IF      
467
--                                      bf_ins <= '1';
468
--                              END IF;
469
                                IF opcode(4 downto 3)="00" THEN
470
                                        bf_d32 <= '1';
471
                                END IF;
472
                                bf_ext_out <= result(39 downto 32);
473
                        END IF;
474
                END IF;
475
 
476
                IF bf_ins='1' THEN
477
                        datareg <= reg_QB;
478
                ELSE
479
                        datareg <= bf_set2;
480
                END IF;
481
 
482
 
483
-- create bitmask for operation
484
-- unshifted bitmask '0' => bit is in the Bitfieldvector
485
--                                       '1' => bit isn't in the Bitfieldvector
486
-- Example bf_with=11    => "11111111 11111111 11111000 00000000"
487
-- datareg 
488
                unshifted_bitmask <= (OTHERS => '0');
489
                FOR i in 0 to 31 LOOP
490
                        IF i>bf_width(4 downto 0) THEN
491
                                datareg(i) <= '0';
492
                                unshifted_bitmask(i) <= '1';
493
                        END IF;
494
                END LOOP;
495
 
496
                bf_NFlag <= datareg(conv_integer(bf_width));
497
                IF bf_exts='1' AND bf_NFlag='1' THEN
498
                        bf_datareg <= datareg OR unshifted_bitmask;
499
                ELSE
500
                        bf_datareg <= datareg;
501
                END IF;
502
--      bf_datareg <= shifted_bitmask(31 downto 4)&"0000";
503
--      result(31 downto 0)<=datareg;
504
 
505
-- shift bitmask for operation
506
                IF bf_loffset(4)='1' THEN
507
                        bitmaskmux3 <= unshifted_bitmask(15 downto 0)&unshifted_bitmask(31 downto 16);
508
                ELSE
509
                        bitmaskmux3 <= unshifted_bitmask;
510
                END IF;
511
                IF bf_loffset(3)='1' THEN
512
                        bitmaskmux2(31 downto 0) <= bitmaskmux3(23 downto 0)&bitmaskmux3(31 downto 24);
513
                ELSE
514
                        bitmaskmux2(31 downto 0) <= bitmaskmux3;
515
                END IF;
516
                IF bf_loffset(2)='1' THEN
517
                        bitmaskmux1 <= bitmaskmux2&"1111";
518
                        IF bf_d32='1' THEN
519
                                bitmaskmux1(3 downto 0) <= bitmaskmux2(31 downto 28);
520
                        END IF;
521
                ELSE
522
                        bitmaskmux1 <= "1111"&bitmaskmux2;
523
                END IF;
524
                IF bf_loffset(1)='1' THEN
525
                        bitmaskmux0 <= bitmaskmux1&"11";
526
                        IF bf_d32='1' THEN
527
                                bitmaskmux0(1 downto 0) <= bitmaskmux1(31 downto 30);
528
                        END IF;
529
                ELSE
530
                        bitmaskmux0 <= "11"&bitmaskmux1;
531
                END IF;
532
                IF bf_loffset(0)='1' THEN
533
                        shifted_bitmask <= '1'&bitmaskmux0&'1';
534
                        IF bf_d32='1' THEN
535
                                shifted_bitmask(0) <= bitmaskmux0(31);
536
                        END IF;
537
                ELSE
538
                        shifted_bitmask <= "11"&bitmaskmux0;
539
                END IF;
540
 
541
 
542
-- shift for ins 
543
                shift <= bf_ext_in&OP2out;
544
                IF bf_s32='1' THEN
545
                        shift(39 downto 32) <= OP2out(7 downto 0);
546
                END IF;
547
 
548
                IF bf_shift(0)='1' THEN
549
                        inmux0 <= shift(0)&shift(39 downto 1);
550
                ELSE
551
                        inmux0 <= shift;
552
                END IF;
553
                IF bf_shift(1)='1' THEN
554
                        inmux1 <= inmux0(1 downto 0)&inmux0(39 downto 2);
555
                ELSE
556
                        inmux1 <= inmux0;
557
                END IF;
558
                IF bf_shift(2)='1' THEN
559
                        inmux2 <= inmux1(3 downto 0)&inmux1(39 downto 4);
560
                ELSE
561
                        inmux2 <= inmux1;
562
                END IF;
563
                IF bf_shift(3)='1' THEN
564
                        inmux3 <= inmux2(7 downto 0)&inmux2(31 downto 8);
565
                ELSE
566
                        inmux3 <= inmux2(31 downto 0);
567
                END IF;
568
                IF bf_shift(4)='1' THEN
569
                        bf_set2(31 downto 0) <= inmux3(15 downto 0)&inmux3(31 downto 16);
570
                ELSE
571
                        bf_set2(31 downto 0) <= inmux3;
572
                END IF;
573
 
574
                IF bf_ins='1' THEN
575
                        result(31 downto 0) <= bf_set2;
576
                        result(39 downto 32) <= bf_set2(7 downto 0);
577
                ELSIF bf_bchg='1' THEN
578
                        result(31 downto 0) <= NOT OP2out;
579
                        result(39 downto 32) <= NOT bf_ext_in;
580
                ELSE
581
                        result <= (OTHERS => '0');
582
                END IF;
583
                IF bf_bset='1' THEN
584
                        result <= (OTHERS => '1');
585
                END IF;
586
--              
587
                IF bf_ins='1' THEN
588
                        result_tmp <= bf_ext_in&OP1out;
589
                ELSE
590
                        result_tmp <= bf_ext_in&OP2out;
591
                END IF;
592
                FOR i in 0 to 39 LOOP
593
                        IF shifted_bitmask(i)='1' THEN
594
                                result(i) <= result_tmp(i);   --restore old data
595
                        END IF;
596
                END LOOP;
597
 
598
--BFFFO 
599
                mask <= datareg;
600
                bf_firstbit <= ('0'&bitnr)+mask_not_zero;
601
                bitnr <= "11111";
602
                mask_not_zero <= '1';
603
                IF mask(31 downto 28)="0000" THEN
604
                        IF mask(27 downto 24)="0000" THEN
605
                                IF mask(23 downto 20)="0000" THEN
606
                                        IF mask(19 downto 16)="0000" THEN
607
                                                bitnr(4) <= '0';
608
                                                IF mask(15 downto 12)="0000" THEN
609
                                                        IF mask(11 downto 8)="0000" THEN
610
                                                                bitnr(3) <= '0';
611
                                                                IF mask(7 downto 4)="0000" THEN
612
                                                                        bitnr(2) <= '0';
613
                                                                        mux <= mask(3 downto 0);
614
                                                                ELSE
615
                                                                        mux <= mask(7 downto 4);
616
                                                                END IF;
617
                                                        ELSE
618
                                                                mux <= mask(11 downto 8);
619
                                                                bitnr(2) <= '0';
620
                                                        END IF;
621
                                                ELSE
622
                                                        mux <= mask(15 downto 12);
623
                                                END IF;
624
                                        ELSE
625
                                                mux <= mask(19 downto 16);
626
                                                bitnr(3) <= '0';
627
                                                bitnr(2) <= '0';
628
                                        END IF;
629
                                ELSE
630
                                        mux <= mask(23 downto 20);
631
                                        bitnr(3) <= '0';
632
                                END IF;
633
                        ELSE
634
                                mux <= mask(27 downto 24);
635
                                bitnr(2) <= '0';
636
                        END IF;
637
                ELSE
638
                        mux <= mask(31 downto 28);
639
                END IF;
640
 
641
                IF mux(3 downto 2)="00" THEN
642
                        bitnr(1) <= '0';
643
                        IF mux(1)='0' THEN
644
                                bitnr(0) <= '0';
645
                                IF mux(0)='0' THEN
646
                                        mask_not_zero <= '0';
647
                                END IF;
648
                        END IF;
649
                ELSE
650
                        IF mux(3)='0' THEN
651
                                bitnr(0) <= '0';
652
                        END IF;
653
                END  IF;
654
        END PROCESS;
655
 
656
-----------------------------------------------------------------------------
657
-- Rotation
658
-----------------------------------------------------------------------------
659
PROCESS (exe_opcode, OP1out, Flags, rot_bits, rot_msb, rot_lsb, rot_rot, exec, BSout)
660
        BEGIN
661
                CASE exe_opcode(7 downto 6) IS
662
                        WHEN "00" =>                                    --Byte
663
                                                rot_rot <= OP1out(7);
664
                        WHEN "01"|"11" =>                               --Word
665
                                                rot_rot <= OP1out(15);
666
                        WHEN "10" =>                                    --Long
667
                                                rot_rot <= OP1out(31);
668
                        WHEN OTHERS => NULL;
669
                END CASE;
670
 
671
                CASE rot_bits IS
672
                        WHEN "00" =>                                    --ASL, ASR
673
                                                rot_lsb <= '0';
674
                                                rot_msb <= rot_rot;
675
                        WHEN "01" =>                                    --LSL, LSR
676
                                                rot_lsb <= '0';
677
                                                rot_msb <= '0';
678
                        WHEN "10" =>                                    --ROXL, ROXR
679
                                                rot_lsb <= Flags(4);
680
                                                rot_msb <= Flags(4);
681
                        WHEN "11" =>                                    --ROL, ROR
682
                                                rot_lsb <= rot_rot;
683
                                                rot_msb <= OP1out(0);
684
                        WHEN OTHERS => NULL;
685
                END CASE;
686
 
687
                IF exec(rot_nop)='1' THEN
688
                        rot_out <= OP1out;
689
                        rot_X <= Flags(4);
690
                        IF rot_bits="10" THEN   --ROXL, ROXR
691
                                rot_C <= Flags(4);
692
                        ELSE
693
                                rot_C <= '0';
694
                        END IF;
695
                ELSE
696
                        IF exe_opcode(8)='1' THEN               --left
697
                                rot_out <= OP1out(30 downto 0)&rot_lsb;
698
                                rot_X <= rot_rot;
699
                                rot_C <= rot_rot;
700
                        ELSE                                            --right
701
                                rot_X <= OP1out(0);
702
                                rot_C <= OP1out(0);
703
                                rot_out <= rot_msb&OP1out(31 downto 1);
704
                                CASE exe_opcode(7 downto 6) IS
705
                                        WHEN "00" =>                                    --Byte
706
                                                rot_out(7) <= rot_msb;
707
                                        WHEN "01"|"11" =>                               --Word
708
                                                rot_out(15) <= rot_msb;
709
                                        WHEN OTHERS => NULL;
710
                                END CASE;
711
                        END IF;
712
                        IF BarrelShifter/=0 THEN
713
                           rot_out <= BSout;
714
                        END IF;
715
                END IF;
716
        END PROCESS;
717
 
718
-----------------------------------------------------------------------------
719
-- Barrel Shifter
720
-----------------------------------------------------------------------------   
721
process (OP1out, OP2out, opcode, bit_nr, bit_nr7, bit_msb, hot_bit, bs_shift, bs_shift_mod, ring, result_bs, exe_opcode, vector,
722
         rot_bits, Flags, msb, hot_msb, asl_over, ALU, asr_sign, exec)
723
        begin
724
                ring <= "100000";
725
                IF rot_bits="10" THEN --ROX L/R
726
                        CASE exe_opcode(7 downto 6) IS
727
                                WHEN "00" =>                                    --Byte
728
                                                        ring <= "001001";
729
                                WHEN "01"|"11" =>                               --Word
730
                                                        ring <= "010001";
731
                                WHEN "10" =>                                    --Long
732
                                                        ring <= "100001";
733
                                WHEN OTHERS => NULL;
734
                        END CASE;
735
                ELSE
736
                        CASE exe_opcode(7 downto 6) IS
737
                                WHEN "00" =>                                    --Byte
738
                                                        ring <= "001000";
739
                                WHEN "01"|"11" =>                               --Word
740
                                                        ring <= "010000";
741
                                WHEN "10" =>                                    --Long
742
                                                        ring <= "100000";
743
                                WHEN OTHERS => NULL;
744
                        END CASE;
745
                END IF;
746
 
747
                IF exe_opcode(7 downto 6)="11" OR exec(exec_BS)='0' THEN
748
                        bs_shift <="000001";
749
                ELSIF exe_opcode(5)='1' THEN
750
                        bs_shift <= OP2out(5 downto 0);
751
                ELSE
752
                        bs_shift(2 downto 0) <= exe_opcode(11 downto 9);
753
                        IF exe_opcode(11 downto 9)="000" THEN
754
                                bs_shift(5 downto 3) <="001";
755
                        ELSE
756
                                bs_shift(5 downto 3) <="000";
757
                        END IF;
758
                END IF;
759
 
760
                bs_shift_mod <= std_logic_vector(unsigned(bs_shift) rem unsigned(ring));
761
 
762
                bit_nr <= bs_shift_mod(5 downto 0);
763
                bit_nr7 <= ('1'&ring)-('0'&bs_shift_mod);
764
                IF exe_opcode(8)='0' THEN  --right shift
765
                        bit_nr <= bit_nr7(5 downto 0);
766
                END IF;
767
                IF rot_bits(1)='0' THEN --only shift
768
                        IF unsigned(bs_shift)<33 THEN
769
                                IF exe_opcode(8)='0' THEN  --right shift
770
                                        bit_nr <= 32-bs_shift;
771
                                ELSE
772
                                        bit_nr <= bs_shift;
773
                                END IF;
774
                        ELSE
775
                                bit_nr <= "100001";
776
                                bit_msb <= "000000";
777
                        END IF;
778
                END IF;
779
 
780
 
781
-- calc V-Flag by ASL           
782
                hot_msb <= (OTHERS =>'0');
783
                hot_msb(conv_integer(bit_msb)) <= '1';
784
                if bs_shift > ring then
785
                   bit_msb <= "000000";
786
                else
787
                        bit_msb <= ring-bs_shift;
788
                end if;
789
                asl_over <= ((('0'&vector(30 downto 0)) XOR ('0'&vector(31 downto 1)))&'0') - ('0'&hot_msb(31 downto 0));
790
                bs_V <= '0';
791
                IF rot_bits="00" AND exe_opcode(8)='1' THEN --ASL
792
                        bs_V <= not asl_over(32);
793
                END IF;
794
 
795
                IF exe_opcode(8)='0' THEN --right shift
796
                        bs_C <= result_bs(31);
797
                        bs_X <= result_bs(31);
798
                ELSE                  --left shift
799
                        CASE exe_opcode(7 downto 6) IS
800
                                WHEN "00" =>                                    --Byte
801
                                        bs_C <= result_bs(8);
802
                                        bs_X <= result_bs(8);
803
                                WHEN "01"|"11" =>                               --Word
804
                                        bs_C <= result_bs(16);
805
                                        bs_X <= result_bs(16);
806
                                WHEN "10" =>                                    --Long
807
                                        bs_C <= result_bs(32);
808
                                        bs_X <= result_bs(32);
809
                                WHEN OTHERS => NULL;
810
                        END CASE;
811
                END IF;
812
 
813
                ALU <= (others=>'-');
814
                IF rot_bits="11" THEN --RO L/R
815
                        bs_X <= Flags(4);
816
                        CASE exe_opcode(7 downto 6) IS
817
                                WHEN "00" =>                                    --Byte
818
                                        ALU(7 downto 0) <= result_bs(7 downto 0) OR result_bs(15 downto 8);
819
                              bs_C <= ALU(7);
820
                                WHEN "01"|"11" =>                               --Word
821
                                        ALU(15 downto 0) <= result_bs(15 downto 0) OR result_bs(31 downto 16);
822
                              bs_C <= ALU(15);
823
                                WHEN "10" =>                                    --Long
824
                                        ALU <= result_bs(31 downto 0) OR result_bs(63 downto 32);
825
                              bs_C <= ALU(31);
826
                                WHEN OTHERS => NULL;
827
                        END CASE;
828
                        IF exe_opcode(0)='1' THEN --left shift
829
                                bs_C <= ALU(0);
830
                        END IF;
831
                ELSIF rot_bits="10" THEN --ROX L/R
832
                        CASE exe_opcode(7 downto 6) IS
833
                                WHEN "00" =>                                    --Byte
834
                                        ALU(7 downto 0) <= result_bs(7 downto 0) OR result_bs(16 downto 9);
835
                                        bs_C <= result_bs(8) OR result_bs(17);
836
                                        bs_X <= result_bs(8) OR result_bs(17);
837
                                WHEN "01"|"11" =>                               --Word
838
                                        ALU(15 downto 0) <= result_bs(15 downto 0) OR result_bs(32 downto 17);
839
                                        bs_C <= result_bs(16) OR result_bs(33);
840
                                        bs_X <= result_bs(16) OR result_bs(33);
841
                                WHEN "10" =>                                    --Long
842
                                        ALU <= result_bs(31 downto 0) OR result_bs(64 downto 33);
843
                                        bs_C <= result_bs(32) OR result_bs(65);
844
                                        bs_X <= result_bs(32) OR result_bs(65);
845
                                WHEN OTHERS => NULL;
846
                        END CASE;
847
                ELSE
848
                        IF exe_opcode(8)='0' THEN --right shift
849
                                ALU <= result_bs(63 downto 32);
850
                        ELSE                  --left shift
851
                                ALU <= result_bs(31 downto 0);
852
                        END IF;
853
                END IF;
854
 
855
                IF(bs_shift = "000000") THEN
856
                        IF rot_bits="10" THEN --ROX L/R
857
                          bs_C <= Flags(4);
858
                        ELSE
859
                          bs_C <= '0';
860
                        END IF;
861
                        bs_X <= Flags(4);
862
                        bs_V <= '0';
863
                END IF;
864
 
865
-- calc ASR sign                
866
                BSout <= ALU;
867
                asr_sign <= (OTHERS =>'0');
868
                asr_sign(32 downto 1) <= asr_sign(31 downto 0) OR hot_msb(31 downto 0);
869
--              IF opcode(2 downto 0)="000" AND msb='1' THEN --ASR
870
                IF rot_bits="00" AND exe_opcode(8)='0' AND msb='1' THEN --ASR
871
                        BSout <= ALU or asr_sign(32 downto 1);
872
                        IF bs_shift > ring THEN
873
                                bs_C <= '1';
874
                                bs_X <= '1';
875
                        END IF;
876
                END IF;
877
 
878
                vector(32 downto 0) <= '0'&OP1out;
879
                CASE exe_opcode(7 downto 6) IS
880
                        WHEN "00" =>                                    --Byte
881
                                msb <= OP1out(7);
882
                                vector(31 downto 8) <= X"000000";
883
                                BSout(31 downto 8) <= X"000000";
884
                                IF rot_bits="10" THEN --ROX L/R
885
                                        vector(8) <= Flags(4);
886
                                END IF;
887
                        WHEN "01"|"11" =>                               --Word
888
                                msb <= OP1out(15);
889
                                vector(31 downto 16) <= X"0000";
890
                                BSout(31 downto 16) <= X"0000";
891
                                IF rot_bits="10" THEN --ROX L/R
892
                                        vector(16) <= Flags(4);
893
                                END IF;
894
                        WHEN "10" =>                                    --Long
895
                                msb <= OP1out(31);
896
                                IF rot_bits="10" THEN --ROX L/R
897
                                        vector(32) <= Flags(4);
898
                                END IF;
899
                        WHEN OTHERS => NULL;
900
                END CASE;
901
 
902
                hot_bit <= (OTHERS =>'0');
903
                hot_bit(conv_integer(bit_nr(5 downto 0))) <= '1';
904
                result_bs <= vector * hot_bit(32 downto 0);
905
-- if you don't like to use the multiplier -> uncommend next line       and commend the lines before    
906
--              result_bs <= std_logic_vector(unsigned('0'&X"00000000"&vector) sll to_integer(unsigned(bit_nr(5 downto 0)))); 
907
 
908
  end process;
909
 
910
 
911
------------------------------------------------------------------------------
912
--CCR op
913
------------------------------------------------------------------------------          
914
PROCESS (clk, Reset, exe_opcode, exe_datatype, Flags, last_data_read, OP2out, flag_z, OP1IN, c_out, addsub_ofl,
915
             bcd_a, bcd_a_carry, Vflag_a, exec)
916
        BEGIN
917
                IF exec(andiSR)='1' THEN
918
                        CCRin <= Flags AND last_data_read(7 downto 0);
919
                ELSIF exec(eoriSR)='1' THEN
920
                        CCRin <= Flags XOR last_data_read(7 downto 0);
921
                ELSIF exec(oriSR)='1' THEN
922
                        CCRin <= Flags OR last_data_read(7 downto 0);
923
                ELSE
924
                        CCRin <= OP2out(7 downto 0);
925
                END IF;
926
 
927
------------------------------------------------------------------------------
928
--Flags
929
------------------------------------------------------------------------------          
930
                flag_z <= "000";
931
                IF exec(use_XZFlag)='1' AND flags(2)='0' THEN
932
                        flag_z <= "000";
933
                ELSIF OP1in(7 downto 0)="00000000" THEN
934
                        flag_z(0) <= '1';
935
                        IF OP1in(15 downto 8)="00000000" THEN
936
                                flag_z(1) <= '1';
937
                                IF OP1in(31 downto 16)="0000000000000000" THEN
938
                                        flag_z(2) <= '1';
939
                                END IF;
940
                        END IF;
941
                END IF;
942
 
943
--                                      --Flags NZVC
944
                IF exe_datatype="00" THEN                                               --Byte
945
                        set_flags <= OP1IN(7)&flag_z(0)&addsub_ofl(0)&c_out(0);
946
                        IF exec(opcABCD)='1' OR exec(opcSBCD)='1' THEN
947
                                set_flags(0) <= bcd_a_carry;
948
                                set_flags(1) <= Vflag_a;
949
                        END IF;
950
                ELSIF exe_datatype="10" OR exec(opcCPMAW)='1' THEN                                              --Long
951
                        set_flags <= OP1IN(31)&flag_z(2)&addsub_ofl(2)&c_out(2);
952
                ELSE                                            --Word
953
                        set_flags <= OP1IN(15)&flag_z(1)&addsub_ofl(1)&c_out(1);
954
                END IF;
955
 
956
                IF rising_edge(clk) THEN
957
                IF clkena_lw = '1' THEN
958
                                IF exec(directSR)='1' OR set_stop='1' THEN
959
                                        Flags(7 downto 0) <= data_read(7 downto 0);
960
                                END IF;
961
                                IF exec(directCCR)='1' THEN
962
                                        Flags(7 downto 0) <= data_read(7 downto 0);
963
                                END IF;
964
 
965
                                IF exec(opcROT)='1' AND decodeOPC='0' THEN
966
                                        asl_VFlag <= ((set_flags(3) XOR rot_rot) OR asl_VFlag);
967
                                ELSE
968
                                        asl_VFlag <= '0';
969
                                END IF;
970
                                IF exec(to_CCR)='1' THEN
971
                                        Flags(7 downto 0) <= CCRin(7 downto 0);                   --CCR
972
                                ELSIF Z_error='1' THEN
973
                                        IF exe_opcode(8)='0' THEN
974
--                                              Flags(3 downto 0) <= reg_QA(31)&"000";
975
                                                Flags(3 downto 0) <= '0'&NOT reg_QA(31)&"00";
976
                                        ELSE
977
                                                Flags(3 downto 0) <= "0100";
978
                                        END IF;
979
                                ELSIF exec(no_Flags)='0' THEN
980
                                        IF exec(opcADD)='1' THEN
981
                                                Flags(4) <= set_flags(0);
982
                                        ELSIF exec(opcROT)='1' AND rot_bits/="11" AND exec(rot_nop)='0' THEN
983
                                                Flags(4) <= rot_X;
984
                                        ELSIF exec(exec_BS)='1' THEN
985
                                                Flags(4) <= BS_X;
986
                                        END IF;
987
 
988
                                        IF (exec(opcADD) OR exec(opcCMP))='1' THEN
989
                                                Flags(3 downto 0) <= set_flags;
990
                                        ELSIF exec(opcDIVU)='1' AND DIV_Mode/=3 THEN
991
                                                IF V_Flag='1' THEN
992
                                                        Flags(3 downto 0) <= "1010";
993
                                                ELSE
994
                                                        Flags(3 downto 0) <= OP1IN(15)&flag_z(1)&"00";
995
                                                END IF;
996
                                        ELSIF exec(write_reminder)='1' AND MUL_Mode/=3 THEN -- z-flag MULU.l
997
                                                Flags(3) <= set_flags(3);
998
                                                Flags(2) <= set_flags(2) AND Flags(2);
999
                                                Flags(1) <= '0';
1000
                                                Flags(0) <= '0';
1001
                                        ELSIF exec(write_lowlong)='1' AND (MUL_Mode=1 OR MUL_Mode=2) THEN  -- flag MULU.l
1002
                                                Flags(3) <= set_flags(3);
1003
                                                Flags(2) <= set_flags(2);
1004
                                                Flags(1) <= set_mV_Flag;        --V
1005
                                                Flags(0) <= '0';
1006
                                        ELSIF exec(opcOR)='1' OR exec(opcAND)='1' OR exec(opcEOR)='1' OR exec(opcMOVE)='1' OR exec(opcMOVEQ)='1' OR exec(opcSWAP)='1' OR exec(opcBF)='1' OR (exec(opcMULU)='1' AND MUL_Mode/=3) THEN
1007
                                                Flags(1 downto 0) <= "00";
1008
                                                Flags(3 downto 2) <= set_flags(3 downto 2);
1009
                                                IF exec(opcBF)='1' THEN
1010
                                                        Flags(3) <= bf_NFlag;
1011
                                                END IF;
1012
                                        ELSIF exec(opcROT)='1' THEN
1013
                                                Flags(3 downto 2) <= set_flags(3 downto 2);
1014
                                                Flags(0) <= rot_C;
1015
                                                IF rot_bits="00" AND ((set_flags(3) XOR rot_rot) OR asl_VFlag)='1' THEN         --ASL/ASR
1016
                                                        Flags(1) <= '1';
1017
                                                ELSE
1018
                                                        Flags(1) <= '0';
1019
                                                END IF;
1020
                                        ELSIF exec(exec_BS)='1' THEN
1021
                                                Flags(3 downto 2) <= set_flags(3 downto 2);
1022
                                                Flags(0) <= BS_C;
1023
                                                Flags(1) <= BS_V;
1024
                                        ELSIF exec(opcBITS)='1' THEN
1025
                                                Flags(2) <= NOT one_bit_in;
1026
                                        ELSIF exec(opcCHK)='1' THEN
1027
                                                IF exe_datatype="01" THEN                                               --Word
1028
                                                        Flags(3) <= OP1out(15);
1029
                                                ELSE
1030
                                                        Flags(3) <= OP1out(31);
1031
                                                END IF;
1032
                                                IF OP1out(15 downto 0)=X"0000" AND (exe_datatype="01" OR OP1out(31 downto 16)=X"0000") THEN
1033
                                                        Flags(2) <='1';
1034
                                                ELSE
1035
                                                        Flags(2) <='0';
1036
                                                END IF;
1037
                                                Flags(1 downto 0) <= "00";
1038
                                        END IF;
1039
                                END IF;
1040
                        END IF;
1041
                        Flags(7 downto 5) <= "000";
1042
                END IF;
1043
        END PROCESS;
1044
 
1045
---------------------------------------------------------------------------------
1046
------ MULU/MULS
1047
---------------------------------------------------------------------------------       
1048
PROCESS (exe_opcode, OP2out, muls_msb, mulu_reg, FAsign, mulu_sign, reg_QA, faktorA, faktorB, result_mulu, signedOP)
1049
--PROCESS (exec, reg_QA, OP2out, faktorA, faktorB, signedOP)
1050
        BEGIN
1051
        IF MUL_Hardware=1 THEN
1052
--              IF exe_opcode(15)='1' OR MUL_Mode=0 THEN        -- 16 Bit
1053
                IF MUL_Mode=0 THEN       -- 16 Bit
1054
                        IF signedOP='1' AND reg_QA(15)='1' THEN
1055
                                faktorA <= X"FFFFFFFF";
1056
                        ELSE
1057
                                faktorA <= X"00000000";
1058
                        END IF;
1059
                        IF signedOP='1' AND OP2out(15)='1' THEN
1060
                                faktorB <= X"FFFFFFFF";
1061
                        ELSE
1062
                                faktorB <= X"00000000";
1063
                        END IF;
1064
                        result_mulu(63 downto 0) <= (faktorA(15 downto 0) & reg_QA(15 downto 0)) * (faktorB(15 downto 0) & OP2out(15 downto 0));
1065
                ELSE
1066
                        IF exe_opcode(15)='1' THEN      -- 16 Bit
1067
                                IF signedOP='1' AND reg_QA(15)='1' THEN
1068
                                        faktorA <= X"FFFFFFFF";
1069
                                ELSE
1070
                                        faktorA <= X"00000000";
1071
                                END IF;
1072
                                IF signedOP='1' AND OP2out(15)='1' THEN
1073
                                        faktorB <= X"FFFFFFFF";
1074
                                ELSE
1075
                                        faktorB <= X"00000000";
1076
                                END IF;
1077
                        ELSE
1078
                                faktorA(15 downto 0) <= reg_QA(31 downto 16);
1079
                                faktorB(15 downto 0) <= OP2out(31 downto 16);
1080
                                IF signedOP='1' AND reg_QA(31)='1' THEN
1081
                                        faktorA(31 downto 16) <= X"FFFF";
1082
                                ELSE
1083
                                        faktorA(31 downto 16) <= X"0000";
1084
                                END IF;
1085
                                IF signedOP='1' AND OP2out(31)='1' THEN
1086
                                        faktorB(31 downto 16) <= X"FFFF";
1087
                                ELSE
1088
                                        faktorB(31 downto 16) <= X"0000";
1089
                                END IF;
1090
                        END IF;
1091
                        result_mulu(127 downto 0) <= (faktorA(31 downto 16) & faktorA(31 downto 0) & reg_QA(15 downto 0)) * (faktorB(31 downto 16) & faktorB(31 downto 0) & OP2out(15 downto 0));
1092
                END IF;
1093
--      END PROCESS;
1094
-------------------------------------------------------------------------------
1095
---- MULU/MULS
1096
------------------------------------------------------------------------------- 
1097
--PROCESS (exe_opcode, OP2out, muls_msb, mulu_reg, FAsign, mulu_sign, reg_QA, faktorB, result_mulu, signedOP)
1098
--      BEGIN
1099
        ELSE
1100
                IF (signedOP='1' AND faktorB(31)='1') OR FAsign='1' THEN
1101
                        muls_msb <= mulu_reg(63);
1102
                ELSE
1103
                        muls_msb <= '0';
1104
                END IF;
1105
 
1106
                IF signedOP='1' AND faktorB(31)='1' THEN
1107
                        mulu_sign <= '1';
1108
                ELSE
1109
                        mulu_sign <= '0';
1110
                END IF;
1111
 
1112
                IF MUL_Mode=0 THEN       -- 16 Bit
1113
                        result_mulu(63 downto 32) <= muls_msb&mulu_reg(63 downto 33);
1114
                        result_mulu(15 downto 0) <= 'X'&mulu_reg(15 downto 1);
1115
                        IF mulu_reg(0)='1' THEN
1116
                                IF FAsign='1' THEN
1117
                                        result_mulu(63 downto 47) <= (muls_msb&mulu_reg(63 downto 48)-(mulu_sign&faktorB(31 downto 16)));
1118
                                ELSE
1119
                                        result_mulu(63 downto 47) <= (muls_msb&mulu_reg(63 downto 48)+(mulu_sign&faktorB(31 downto 16)));
1120
                                END IF;
1121
                        END IF;
1122
                ELSE                            -- 32 Bit
1123
                        result_mulu(63 downto 0) <= muls_msb&mulu_reg(63 downto 1);
1124
                        IF mulu_reg(0)='1' THEN
1125
                                IF FAsign='1' THEN
1126
                                        result_mulu(63 downto 31) <= (muls_msb&mulu_reg(63 downto 32)-(mulu_sign&faktorB));
1127
                                ELSE
1128
                                        result_mulu(63 downto 31) <= (muls_msb&mulu_reg(63 downto 32)+(mulu_sign&faktorB));
1129
                                END IF;
1130
                        END IF;
1131
                END IF;
1132
                IF exe_opcode(15)='1' OR MUL_Mode=0 THEN
1133
                        faktorB(31 downto 16) <= OP2out(15 downto 0);
1134
                        faktorB(15 downto 0) <= (OTHERS=>'0');
1135
                ELSE
1136
                        faktorB <= OP2out;
1137
                END IF;
1138
        END IF;
1139
                IF (result_mulu(63 downto 32)=X"00000000" AND (signedOP='0' OR result_mulu(31)='0')) OR
1140
                        (result_mulu(63 downto 32)=X"FFFFFFFF" AND signedOP='1' AND result_mulu(31)='1') THEN
1141
                        set_mV_Flag <= '0';
1142
                ELSE
1143
                        set_mV_Flag <= '1';
1144
                END IF;
1145
        END PROCESS;
1146
 
1147
PROCESS (clk)
1148
        BEGIN
1149
                IF rising_edge(clk) THEN
1150
                        IF clkena_lw='1' THEN
1151
                                IF MUL_Hardware=0 THEN
1152
                                        IF micro_state=mul1 THEN
1153
                                                mulu_reg(63 downto 32) <= (OTHERS=>'0');
1154
                                                IF divs='1' AND ((exe_opcode(15)='1' AND reg_QA(15)='1') OR (exe_opcode(15)='0' AND reg_QA(31)='1')) THEN                                --MULS Neg faktor
1155
                                                        FAsign <= '1';
1156
                                                        mulu_reg(31 downto 0) <= 0-reg_QA;
1157
                                                ELSE
1158
                                                        FAsign <= '0';
1159
                                                        mulu_reg(31 downto 0) <= reg_QA;
1160
                                                END IF;
1161
                                        ELSIF exec(opcMULU)='0' THEN
1162
                                                mulu_reg(63 downto 32) <= (OTHERS=>'-');
1163
                                                mulu_reg <= result_mulu(63 downto 0);
1164
                                        END IF;
1165
                                ELSE
1166
                                        mulu_reg(31 downto 0) <= result_mulu(63 downto 32);
1167
                                END IF;
1168
                        END IF;
1169
                END IF;
1170
        END PROCESS;
1171
 
1172
-------------------------------------------------------------------------------
1173
---- DIVU/DIVS
1174
-------------------------------------------------------------------------------
1175
 
1176
PROCESS (execOPC, OP1out, OP2out, div_reg, div_neg, div_bit, div_sub, div_quot, OP1_sign, div_over, result_div, reg_QA, opcode, sndOPC, divs, exe_opcode, reg_QB,
1177
             signedOP, nozero, div_qsign, OP2outext)
1178
        BEGIN
1179
                divs <= (opcode(15) AND opcode(8)) OR (NOT opcode(15) AND sndOPC(11));
1180
                divisor(15 downto 0) <= (OTHERS=> '0');
1181
                divisor(63 downto 32) <= (OTHERS=> divs AND reg_QA(31));
1182
                IF exe_opcode(15)='1' OR DIV_Mode=0 THEN
1183
                        divisor(47 downto 16) <= reg_QA;
1184
                ELSE
1185
                        divisor(31 downto 0) <= reg_QA;
1186
                        IF exe_opcode(14)='1' AND sndOPC(10)='1' THEN
1187
                                divisor(63 downto 32) <= reg_QB;
1188
                        END IF;
1189
                END IF;
1190
                IF signedOP='1' OR opcode(15)='0' THEN
1191
                        OP2outext <= OP2out(31 downto 16);
1192
                ELSE
1193
                        OP2outext <= (OTHERS=> '0');
1194
                END IF;
1195
                IF signedOP='1' AND OP2out(31) ='1' THEN
1196
                        div_sub <= (div_reg(63 downto 31))+('1'&OP2out(31 downto 0));
1197
                ELSE
1198
                        div_sub <= (div_reg(63 downto 31))-('0'&OP2outext(15 downto 0)&OP2out(15 downto 0));
1199
                END IF;
1200
                IF DIV_Mode=0 THEN
1201
                        div_bit <= div_sub(16);
1202
                ELSE
1203
                        div_bit <= div_sub(32);
1204
                END IF;
1205
                IF div_bit='1' THEN
1206
                        div_quot(63 downto 32) <= div_reg(62 downto 31);
1207
                ELSE
1208
                        div_quot(63 downto 32) <= div_sub(31 downto 0);
1209
                END IF;
1210
                div_quot(31 downto 0) <= div_reg(30 downto 0)&NOT div_bit;
1211
 
1212
 
1213
                IF ((nozero='1' AND signedOP='1' AND (OP2out(31) XOR OP1_sign XOR div_neg XOR div_qsign)='1' )  --Overflow DIVS
1214
                        OR (signedOP='0' AND div_over(32)='0')) AND DIV_Mode/=3 THEN      --Overflow DIVU
1215
                        set_V_Flag <= '1';
1216
                ELSE
1217
                        set_V_Flag <= '0';
1218
                END IF;
1219
        END PROCESS;
1220
 
1221
PROCESS (clk)
1222
        BEGIN
1223
                IF rising_edge(clk) THEN
1224
                        IF clkena_lw='1' THEN
1225
                                V_Flag <= set_V_Flag;
1226
                                signedOP <= divs;
1227
                                IF micro_state=div1 THEN
1228
                                        nozero <= '0';
1229
                                        IF divs='1' AND divisor(63)='1' THEN                            -- Neg divisor
1230
                                                OP1_sign <= '1';
1231
                                                div_reg <= 0-divisor;
1232
                                        ELSE
1233
                                                OP1_sign <= '0';
1234
                                                div_reg <= divisor;
1235
                                        END IF;
1236
                                ELSE
1237
                                        div_reg <= div_quot;
1238
                                        nozero <= NOT div_bit OR nozero;
1239
                                END IF;
1240
                                IF micro_state=div2 THEN
1241
                                        div_qsign <= NOT div_bit;
1242
                                        div_neg <= signedOP AND (OP2out(31) XOR OP1_sign);
1243
                                        IF DIV_Mode=0 THEN
1244
                                                div_over(32 downto 16) <= ('0'&div_reg(47 downto 32))-('0'&OP2out(15 downto 0));
1245
                                        ELSE
1246
                                                div_over <= ('0'&div_reg(63 downto 32))-('0'&OP2out);
1247
                                        END IF;
1248
                                END IF;
1249
                                IF exec(write_reminder)='0' THEN
1250
--                              IF exec_DIVU='0' THEN
1251
                                        IF div_neg='1' THEN
1252
                                                result_div(31 downto 0) <= 0-div_quot(31 downto 0);
1253
                                        ELSE
1254
                                                result_div(31 downto 0) <= div_quot(31 downto 0);
1255
                                        END IF;
1256
 
1257
                                        IF OP1_sign='1' THEN
1258
                                                result_div(63 downto 32) <= 0-div_quot(63 downto 32);
1259
                                        ELSE
1260
                                                result_div(63 downto 32) <= div_quot(63 downto 32);
1261
                                        END IF;
1262
                                END IF;
1263
                        END IF;
1264
                END IF;
1265
        END PROCESS;
1266
END;

powered by: WebSVN 2.1.0

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