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

Subversion Repositories cpu_lecture

[/] [cpu_lecture/] [trunk/] [src/] [opc_deco.vhd] - Blame information for rev 20

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

Line No. Rev Author Line
1 2 jsauermann
-------------------------------------------------------------------------------
2
-- 
3
-- Copyright (C) 2009, 2010 Dr. Juergen Sauermann
4
-- 
5
--  This code is free software: you can redistribute it and/or modify
6
--  it under the terms of the GNU General Public License as published by
7
--  the Free Software Foundation, either version 3 of the License, or
8
--  (at your option) any later version.
9
--
10
--  This code is distributed in the hope that it will be useful,
11
--  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
--  GNU General Public License for more details.
14
--
15
--  You should have received a copy of the GNU General Public License
16
--  along with this code (see the file named COPYING).
17
--  If not, see http://www.gnu.org/licenses/.
18
--
19
-------------------------------------------------------------------------------
20
-------------------------------------------------------------------------------
21
--
22
-- Module Name:    opc_deco - Behavioral 
23
-- Create Date:    16:05:16 10/29/2009 
24
-- Description:    the opcode decoder of a CPU.
25
--
26
-------------------------------------------------------------------------------
27
--
28
library IEEE;
29
use IEEE.STD_LOGIC_1164.ALL;
30
use IEEE.STD_LOGIC_ARITH.ALL;
31
use IEEE.STD_LOGIC_UNSIGNED.ALL;
32
 
33
use work.common.ALL;
34
 
35
entity opc_deco is
36
    port (  I_CLK       : in  std_logic;
37
 
38
            I_OPC       : in  std_logic_vector(31 downto 0);
39
            I_PC        : in  std_logic_vector(15 downto 0);
40
            I_T0        : in  std_logic;
41
 
42
            Q_ALU_OP    : out std_logic_vector( 4 downto 0);
43
            Q_AMOD      : out std_logic_vector( 5 downto 0);
44
            Q_BIT       : out std_logic_vector( 3 downto 0);
45
            Q_DDDDD     : out std_logic_vector( 4 downto 0);
46
            Q_IMM       : out std_logic_vector(15 downto 0);
47
            Q_JADR      : out std_logic_vector(15 downto 0);
48
            Q_OPC       : out std_logic_vector(15 downto 0);
49
            Q_PC        : out std_logic_vector(15 downto 0);
50
            Q_PC_OP     : out std_logic_vector( 2 downto 0);
51
            Q_PMS       : out std_logic;  -- program memory select
52
            Q_RD_M      : out std_logic;
53
            Q_RRRRR     : out std_logic_vector( 4 downto 0);
54
            Q_RSEL      : out std_logic_vector( 1 downto 0);
55
            Q_WE_01     : out std_logic;
56
            Q_WE_D      : out std_logic_vector( 1 downto 0);
57
            Q_WE_F      : out std_logic;
58
            Q_WE_M      : out std_logic_vector( 1 downto 0);
59
            Q_WE_XYZS   : out std_logic);
60
end opc_deco;
61
 
62
architecture Behavioral of opc_deco is
63
 
64
begin
65
 
66
    process(I_CLK)
67
    begin
68
    if (rising_edge(I_CLK)) then
69
        --
70
        -- set the most common settings as default.
71
        --
72
        Q_ALU_OP  <= ALU_D_MV_Q;
73
        Q_AMOD    <= AMOD_ABS;
74
        Q_BIT     <= I_OPC(10) & I_OPC(2 downto 0);
75
        Q_DDDDD   <= I_OPC(8 downto 4);
76
        Q_IMM     <= X"0000";
77
        Q_JADR    <= I_OPC(31 downto 16);
78
        Q_OPC     <= I_OPC(15 downto  0);
79
        Q_PC      <= I_PC;
80
        Q_PC_OP   <= PC_NEXT;
81
        Q_PMS     <= '0';
82
        Q_RD_M    <= '0';
83
        Q_RRRRR   <= I_OPC(9) & I_OPC(3 downto 0);
84
        Q_RSEL    <= RS_REG;
85
        Q_WE_D    <= "00";
86
        Q_WE_01   <= '0';
87
        Q_WE_F    <= '0';
88
        Q_WE_M    <= "00";
89
        Q_WE_XYZS <= '0';
90
 
91
        case I_OPC(15 downto 10) is
92 10 jsauermann
            when "000000" =>                            -- 0000 00xx xxxx xxxx
93 2 jsauermann
                case I_OPC(9 downto 8) is
94
                    when "00" =>
95
                        --
96
                        -- 0000 0000 0000 0000 - NOP
97
                        -- 0000 0000 001v vvvv - INTERRUPT
98
                        --
99
                        if (I_OPC(5)) = '1' then   -- interrupt
100
                            Q_ALU_OP <= ALU_INTR;
101 15 jsauermann
                            Q_AMOD <= AMOD_SPdd;
102 2 jsauermann
                            Q_JADR <= "0000000000" & I_OPC(4 downto 0) & "0";
103
                            Q_PC_OP <= PC_LD_I;
104
                            Q_WE_F <= '1';
105
                            Q_WE_M <= "11";
106
                        end if;
107
 
108
                    when "01" =>
109
                        --
110
                        -- 0000 0001 dddd rrrr - MOVW
111
                        --
112
                        Q_DDDDD <= I_OPC(7 downto 4) & "0";
113
                        Q_RRRRR <= I_OPC(3 downto 0) & "0";
114
                        Q_ALU_OP <= ALU_MV_16;
115
                        Q_WE_D <= "11";
116
 
117
                    when "10" =>
118
                        --
119
                        -- 0000 0010 dddd rrrr - MULS
120
                        --
121
                        Q_DDDDD <= "1" & I_OPC(7 downto 4);
122
                        Q_RRRRR <= "1" & I_OPC(3 downto 0);
123
                        Q_ALU_OP <= ALU_MULT;
124
                        Q_IMM(7 downto 5) <= MULT_SS;
125
                        Q_WE_01 <= '1';
126
                        Q_WE_F <= '1';
127
 
128
                    when others =>
129
                        --
130
                        -- 0000 0011 0ddd 0rrr - _MULSU  SU "010"
131
                        -- 0000 0011 0ddd 1rrr - FMUL    UU "100"
132
                        -- 0000 0011 1ddd 0rrr - FMULS   SS "111"
133
                        -- 0000 0011 1ddd 1rrr - FMULSU  SU "110"
134
                        --
135
                        Q_DDDDD(4 downto 3) <= "10";    -- regs 16 to 23
136
                        Q_RRRRR(4 downto 3) <= "10";    -- regs 16 to 23
137
                        Q_ALU_OP <= ALU_MULT;
138
                        if I_OPC(7) = '0' then
139
                            if I_OPC(3) = '0' then
140
                                Q_IMM(7 downto 5) <= MULT_SU;
141
                            else
142
                                Q_IMM(7 downto 5) <= MULT_FUU;
143
                            end if;
144
                        else
145
                            if I_OPC(3) = '0' then
146
                                Q_IMM(7 downto 5) <= MULT_FSS;
147
                            else
148
                                Q_IMM(7 downto 5) <= MULT_FSU;
149
                            end if;
150
                        end if;
151
                        Q_WE_01 <= '1';
152
                        Q_WE_F <= '1';
153
                end case;
154
 
155
            when "000001" | "000010" =>
156
                --
157
                -- 0000 01rd dddd rrrr - CPC = SBC without Q_WE_D
158
                -- 0000 10rd dddd rrrr - SBC
159
                --
160
                Q_ALU_OP <= ALU_SBC;
161
                Q_WE_D <= '0' & I_OPC(11);  -- write Rd if SBC.
162
                Q_WE_F <= '1';
163
 
164 10 jsauermann
            when "000011" =>                            -- 0000 11xx xxxx xxxx
165 2 jsauermann
                --
166
                -- 0000 11rd dddd rrrr - ADD
167
                --
168
                Q_ALU_OP <= ALU_ADD;
169
                Q_WE_D <= "01";
170
                Q_WE_F <= '1';
171
 
172 10 jsauermann
            when "000100" =>                            -- 0001 00xx xxxx xxxx
173 20 jsauermann
                --
174
                -- 0001 00rd dddd rrrr - CPSE
175
                --
176 2 jsauermann
                Q_ALU_OP <= ALU_SUB;
177
                if (I_T0 = '0') then        -- second cycle.
178
                    Q_PC_OP <= PC_SKIP_Z;
179
                end if;
180
 
181
            when "000101" | "000110" =>
182
                --
183
                -- 0001 01rd dddd rrrr - CP = SUB without Q_WE_D
184
                -- 0000 10rd dddd rrrr - SUB
185
                --
186
                Q_ALU_OP <= ALU_SUB;
187
                Q_WE_D <= '0' & I_OPC(11);  -- write Rd if SUB.
188
                Q_WE_F <= '1';
189
 
190 10 jsauermann
            when "000111" =>                            -- 0001 11xx xxxx xxxx
191 2 jsauermann
                --
192
                -- 0001 11rd dddd rrrr - ADC
193
                --
194
                Q_ALU_OP <= ALU_ADC;
195
                Q_WE_D <= "01";
196
                Q_WE_F <= '1';
197
 
198 10 jsauermann
            when "001000" =>                            -- 0010 00xx xxxx xxxx
199 2 jsauermann
                --
200
                -- 0010 00rd dddd rrrr - AND
201
                --
202
                Q_ALU_OP <= ALU_AND;
203
                Q_WE_D <= "01";
204
                Q_WE_F <= '1';
205
 
206 10 jsauermann
            when "001001" =>                            -- 0010 01xx xxxx xxxx
207 2 jsauermann
                --
208
                -- 0010 01rd dddd rrrr - EOR
209
                --
210
                Q_ALU_OP <= ALU_EOR;
211
                Q_WE_D <= "01";
212
                Q_WE_F <= '1';
213
 
214 10 jsauermann
            when "001010" =>                            -- 0010 10xx xxxx xxxx
215 2 jsauermann
                --
216
                -- 0010 10rd dddd rrrr - OR
217
                --
218
                Q_ALU_OP <= ALU_OR;
219
                Q_WE_D <= "01";
220
                Q_WE_F <= '1';
221
 
222 10 jsauermann
            when "001011" =>                            -- 0010 11xx xxxx xxxx
223 2 jsauermann
                --
224
                -- 0010 11rd dddd rrrr - MOV
225
                --
226
                Q_ALU_OP <= ALU_R_MV_Q;
227
                Q_WE_D <= "01";
228
 
229
            when "001100" | "001101" | "001110" | "001111"
230
               | "010100" | "010101" | "010110" | "010111" =>
231
                --
232
                -- 0011 KKKK dddd KKKK - CPI
233
                -- 0101 KKKK dddd KKKK - SUBI
234
                --
235
                Q_ALU_OP <= ALU_SUB;
236
                Q_IMM(7 downto 0) <= I_OPC(11 downto 8) & I_OPC(3 downto 0);
237
                Q_RSEL <= RS_IMM;
238
                Q_DDDDD(4) <= '1';    -- Rd = 16...31
239
                Q_WE_D <= '0' & I_OPC(14);
240
                Q_WE_F <= '1';
241
 
242
            when "010000" | "010001" | "010010" | "010011" =>
243
                --
244
                -- 0100 KKKK dddd KKKK - SBCI
245
                --
246
                Q_ALU_OP <= ALU_SBC;
247
                Q_IMM(7 downto 0) <= I_OPC(11 downto 8) & I_OPC(3 downto 0);
248
                Q_RSEL <= RS_IMM;
249
                Q_DDDDD(4) <= '1';    -- Rd = 16...31
250
                Q_WE_D <= "01";
251
                Q_WE_F <= '1';
252
 
253
            when "011000" | "011001" | "011010" | "011011" =>
254
                --
255
                -- 0110 KKKK dddd KKKK - ORI
256
                --
257
                Q_ALU_OP <= ALU_OR;
258
                Q_IMM(7 downto 0) <= I_OPC(11 downto 8) & I_OPC(3 downto 0);
259
                Q_RSEL <= RS_IMM;
260
                Q_DDDDD(4) <= '1';    -- Rd = 16...31
261
                Q_WE_D <= "01";
262
                Q_WE_F <= '1';
263
 
264
            when "011100" | "011101" | "011110" | "011111" =>
265
                --
266
                -- 0111 KKKK dddd KKKK - ANDI
267
                --
268
                Q_ALU_OP <= ALU_AND;
269
                Q_IMM(7 downto 0) <= I_OPC(11 downto 8) & I_OPC(3 downto 0);
270
                Q_RSEL <= RS_IMM;
271
                Q_DDDDD(4) <= '1';    -- Rd = 16...31
272
                Q_WE_D <= "01";
273
                Q_WE_F <= '1';
274
 
275
            when "100000" | "100001" | "100010" | "100011"
276
               | "101000" | "101001" | "101010" | "101011" =>
277
                --
278
                -- LDD (Y + q) == LD (y) if q == 0
279
                --
280
                -- 10q0 qq0d dddd 1qqq  LDD (Y + q)
281
                -- 10q0 qq0d dddd 0qqq  LDD (Z + q)
282
                -- 10q0 qq1d dddd 1qqq  SDD (Y + q)
283
                -- 10q0 qq1d dddd 0qqq  SDD (Z + q)
284
                --        L/      Z/
285
                --        S       Y
286
                --
287
                Q_IMM(5) <= I_OPC(13);
288
                Q_IMM(4 downto 3) <= I_OPC(11 downto 10);
289
                Q_IMM(2 downto 0) <= I_OPC( 2 downto  0);
290
 
291
                if (I_OPC(3) = '0') then    Q_AMOD <= AMOD_Zq;
292
                else                        Q_AMOD <= AMOD_Yq;
293
                end if;
294
 
295 13 jsauermann
                if (I_OPC(9) = '0') then            -- LDD
296 14 jsauermann
                    Q_RSEL <= RS_DIN;
297 20 jsauermann
                    Q_RD_M <= I_T0;
298 13 jsauermann
                    Q_WE_D <= '0' & not I_T0;
299
                else                                -- STD
300
                    Q_WE_M <= '0' & I_OPC(9);
301
                end if;
302 2 jsauermann
 
303 10 jsauermann
            when "100100" =>                            -- 1001 00xx xxxx xxxx
304 2 jsauermann
                Q_IMM <= I_OPC(31 downto 16);   -- absolute address for LDS/STS
305
                if (I_OPC(9) = '0') then        -- LDD / POP
306
                    --
307
                    -- 1001 00-0d dddd 0000 - LDS
308 20 jsauermann
                    -- 1001 00-0d dddd 0001 - LD   Rd, Z+
309
                    -- 1001 00-0d dddd 0010 - LD   Rd, -Z
310
                    -- 1001 00-0d dddd 0100 - LPM  Rd, (Z)      (ii)
311
                    -- 1001 00-0d dddd 0101 - LPM  Rd, (Z+)     (iii)
312
                    -- 1001 00-0d dddd 0110 - ELPM Z            --- not mega8
313
                    -- 1001 00-0d dddd 0111 - ELPM Z+           --- not mega8
314
                    -- 1001 00-0d dddd 1001 - LD   Rd, Y+
315
                    -- 1001 00-0d dddd 1010 - LD   Rd, -Y
316
                    -- 1001 00-0d dddd 1100 - LD   Rd, X
317
                    -- 1001 00-0d dddd 1101 - LD   Rd, X+
318
                    -- 1001 00-0d dddd 1110 - LD   Rd, -X
319
                    -- 1001 00-0d dddd 1111 - POP  Rd
320 2 jsauermann
                    --
321
                    Q_RSEL <= RS_DIN;
322
                    Q_RD_M <= I_T0;
323
                    Q_WE_D <= '0' & not I_T0;
324
                    Q_WE_XYZS <= not I_T0;
325
                    Q_PMS <= (not I_OPC(3)) and I_OPC(2) and (not I_OPC(1));
326
                    case I_OPC(3 downto 0) is
327
                        when "0000" => Q_AMOD <= AMOD_ABS;  Q_WE_XYZS <= '0';
328
                        when "0001" => Q_AMOD <= AMOD_Zi;
329
                        when "0100" => Q_AMOD <= AMOD_Z;    Q_WE_XYZS <= '0';
330
                        when "0101" => Q_AMOD <= AMOD_Zi;
331
                        when "1001" => Q_AMOD <= AMOD_Yi;
332
                        when "1010" => Q_AMOD <= AMOD_dY;
333
                        when "1100" => Q_AMOD <= AMOD_X;    Q_WE_XYZS <= '0';
334
                        when "1101" => Q_AMOD <= AMOD_Xi;
335
                        when "1110" => Q_AMOD <= AMOD_dX;
336 15 jsauermann
                        when "1111" => Q_AMOD <= AMOD_iSP;
337 2 jsauermann
                        when others =>                      Q_WE_XYZS <= '0';
338
                    end case;
339
                else                        -- STD / PUSH
340
                    --
341
                    -- 1001 00-1r rrrr 0000 - STS
342
                    -- 1001 00-1r rrrr 0001 - ST Z+. Rr
343
                    -- 1001 00-1r rrrr 0010 - ST -Z. Rr
344
                    -- 1001 00-1r rrrr 1000 - ST Y. Rr
345
                    -- 1001 00-1r rrrr 1001 - ST Y+. Rr
346
                    -- 1001 00-1r rrrr 1010 - ST -Y. Rr
347
                    -- 1001 00-1r rrrr 1100 - ST X. Rr
348
                    -- 1001 00-1r rrrr 1101 - ST X+. Rr
349
                    -- 1001 00-1r rrrr 1110 - ST -X. Rr
350
                    -- 1001 00-1r rrrr 1111 - PUSH Rr
351
                    --
352
                    Q_ALU_OP <= ALU_D_MV_Q;
353
                    Q_WE_M <= "01";
354
                    Q_WE_XYZS <= '1';
355
                    case I_OPC(3 downto 0) is
356
                        when "0000" => Q_AMOD <= AMOD_ABS;  Q_WE_XYZS <= '0';
357
                        when "0001" => Q_AMOD <= AMOD_Zi;
358
                        when "0010" => Q_AMOD <= AMOD_dZ;
359
                        when "1001" => Q_AMOD <= AMOD_Yi;
360
                        when "1010" => Q_AMOD <= AMOD_dY;
361
                        when "1100" => Q_AMOD <= AMOD_X;    Q_WE_XYZS <= '0';
362
                        when "1101" => Q_AMOD <= AMOD_Xi;
363
                        when "1110" => Q_AMOD <= AMOD_dX;
364 15 jsauermann
                        when "1111" => Q_AMOD <= AMOD_SPd;
365 2 jsauermann
                        when others =>
366
                    end case;
367
                end if;
368
 
369 10 jsauermann
            when "100101" =>                            -- 1001 01xx xxxx xxxx
370
                if (I_OPC(9) = '0') then                -- 1001 010
371 20 jsauermann
                    case I_OPC(3 downto 0) is
372
                        when "0000" =>
373
                            --
374
                            --  1001 010d dddd 0000 - COM Rd
375
                            --
376
                            Q_ALU_OP <= ALU_COM;
377
                            Q_WE_D <= "01";
378
                            Q_WE_F <= '1';
379
 
380
                        when "0001" =>
381
                            --
382
                            --  1001 010d dddd 0001 - NEG Rd
383
                            --
384
                            Q_ALU_OP <= ALU_NEG;
385
                            Q_WE_D <= "01";
386
                            Q_WE_F <= '1';
387
 
388
                        when "0010" =>
389
                            --
390
                            --  1001 010d dddd 0010 - SWAP Rd
391
                            --
392
                            Q_ALU_OP <= ALU_SWAP;
393
                            Q_WE_D <= "01";
394
                            Q_WE_F <= '1';
395
 
396
                        when "0011" =>
397
                            --
398
                            --  1001 010d dddd 0011 - INC Rd
399
                            --
400
                            Q_ALU_OP <= ALU_INC;
401
                            Q_WE_D <= "01";
402
                            Q_WE_F <= '1';
403
 
404
                        when "0101" =>
405
                            --
406
                            --  1001 010d dddd 0101 - ASR Rd
407
                            --
408
                            Q_ALU_OP <= ALU_ASR;
409
                            Q_WE_D <= "01";
410
                            Q_WE_F <= '1';
411
 
412
                        when "0110" =>
413
                            --
414
                            --  1001 010d dddd 0110 - LSR Rd
415
                            --
416
                            Q_ALU_OP <= ALU_LSR;
417
                            Q_WE_D <= "01";
418
                            Q_WE_F <= '1';
419
 
420
                        when "0111" =>
421
                            --
422
                            --  1001 010d dddd 0111 - ROR Rd
423
                            --
424
                            Q_ALU_OP <= ALU_ROR;
425
                                        Q_WE_D <= "01";
426
                                        Q_WE_F <= '1';
427
 
428
                        when "1000"  =>             -- 1001 010x xxxx 1000
429
                            if I_OPC(8) = '0' then  -- 1001 0100 xxxx 1000
430
                                --
431
                                --  1001 0100 0sss 1000 - BSET
432
                                --  1001 0100 1sss 1000 - BCLR
433
                                --
434 2 jsauermann
                                    Q_BIT(3 downto 0) <= I_OPC(7 downto 4);
435
                                    Q_ALU_OP <= ALU_SREG;
436
                                    Q_WE_F <= '1';
437 20 jsauermann
                            else                    -- 1001 0101 xxxx 1000
438
                                --
439
                                --  1001 0101 0000 1000 - RET
440
                                --  1001 0101 0001 1000 - RETI
441
                                --  1001 0101 1000 1000 - SLEEP
442
                                --  1001 0101 1001 1000 - BREAK
443
                                --  1001 0101 1100 1000 - LPM     [ R0,(Z) ]
444
                                --  1001 0101 1101 1000 - ELPM    not mega8
445
                                --  1001 0101 1110 1000 - SPM
446
                                --  1001 0101 1111 1000 - SPM #2
447
                                --  1001 0101 1010 1000 - WDR
448
                                --
449
                                case I_OPC(7 downto 4) is
450
                                    when "0000" =>  -- RET
451
                                        Q_AMOD <= AMOD_iiSP;
452
                                        Q_RD_M <= I_T0;
453
                                        Q_WE_XYZS <= not I_T0;
454
                                        if (I_T0 = '0') then
455
                                            Q_PC_OP <= PC_LD_S;
456
                                        end if;
457 2 jsauermann
 
458 20 jsauermann
                                    when "0001" =>  -- RETI
459
                                        Q_ALU_OP <= ALU_INTR;
460
                                        Q_IMM(6) <= '1';
461
                                        Q_AMOD <= AMOD_iiSP;
462
                                        Q_RD_M <= I_T0;
463
                                        Q_WE_XYZS <= not I_T0;
464
                                        if (I_T0 = '0') then
465
                                            Q_PC_OP <= PC_LD_S;
466
                                        end if;
467 2 jsauermann
 
468 20 jsauermann
                                    when "1100" =>  -- (i) LPM R0, (Z)
469
                                        Q_DDDDD <= "00000";
470
                                        Q_AMOD <= AMOD_Z;
471
                                        Q_PMS <= '1';
472
                                        Q_WE_D <= '0' & not I_T0;
473 2 jsauermann
 
474 20 jsauermann
                                    when "1110" =>  -- SPM
475
                                        Q_ALU_OP <= ALU_D_MV_Q;
476
                                        Q_DDDDD <= "00000";
477
                                        Q_AMOD <= AMOD_Z;
478
                                        Q_PMS <= '1';
479
                                        Q_WE_M <= "01";
480 2 jsauermann
 
481 20 jsauermann
                                    when "1111" =>  -- SPM #2
482
                                        -- page write: not supported
483 2 jsauermann
 
484 20 jsauermann
                                    when others =>
485
                                end case;
486
                            end if;
487 2 jsauermann
 
488 20 jsauermann
                        when "1001" =>               -- 1001 010x xxxx 1001
489
                            --
490
                            --  1001 0100 0000 1001 IJMP
491
                            --  1001 0100 0001 1001 EIJMP   -- not mega8
492
                            --  1001 0101 0000 1001 ICALL
493
                            --  1001 0101 0001 1001 EICALL   -- not mega8
494
                            --
495
                            Q_PC_OP <= PC_LD_Z;
496
                            if (I_OPC(8) = '1') then        -- ICALL
497
                                Q_ALU_OP <= ALU_PC_1;
498
                                Q_AMOD <= AMOD_SPdd;
499
                                Q_WE_M <= "11";
500
                                Q_WE_XYZS <= '1';
501
                            end if;
502 2 jsauermann
 
503 20 jsauermann
                        when "1010"  =>              -- 1001 010x xxxx 1010
504
                            --
505
                            --  1001 010d dddd 1010 - DEC Rd
506
                            --
507
                            Q_ALU_OP <= ALU_DEC;
508
                            Q_WE_D <= "01";
509
                            Q_WE_F <= '1';
510 2 jsauermann
 
511 20 jsauermann
                        when "1011"  =>              -- 1001 010x xxxx 1011
512
                            --
513
                            --  1001 0100 KKKK 1011 - DES   -- not mega8
514
                            --
515 2 jsauermann
 
516 20 jsauermann
                        when "1100" | "1101"  =>
517
                            --
518
                            --  1001 010k kkkk 110k - JMP (k = 0 for 16 bit)
519
                            --  kkkk kkkk kkkk kkkk
520
                            --
521
                            Q_PC_OP <= PC_LD_I;
522 2 jsauermann
 
523 20 jsauermann
                        when "1110" | "1111"  =>      -- 1001 010x xxxx 111x
524
                            --
525
                            --  1001 010k kkkk 111k - CALL (k = 0)
526
                            --  kkkk kkkk kkkk kkkk
527
                            --
528
                            Q_ALU_OP <= ALU_PC_2;
529
                            Q_AMOD <= AMOD_SPdd;
530
                            Q_PC_OP <= PC_LD_I;
531
                            Q_WE_M <= "11";     -- both PC bytes
532
                            Q_WE_XYZS <= '1';
533 2 jsauermann
 
534 20 jsauermann
                        when others =>
535
                    end case;
536 10 jsauermann
                else            -- 1001 011
537 2 jsauermann
                    --
538
                    --  1001 0110 KKdd KKKK - ADIW
539
                    --  1001 0111 KKdd KKKK - SBIW
540
                    --
541
                    if (I_OPC(8) = '0') then    Q_ALU_OP <= ALU_ADIW;
542
                    else                        Q_ALU_OP <= ALU_SBIW;
543
                    end if;
544
                    Q_IMM(5 downto 4) <= I_OPC(7 downto 6);
545
                    Q_IMM(3 downto 0) <= I_OPC(3 downto 0);
546
                    Q_RSEL <= RS_IMM;
547
                    Q_DDDDD <= "11" & I_OPC(5 downto 4) & "0";
548
 
549
                    Q_WE_D <= "11";
550
                    Q_WE_F <= '1';
551
                end if; -- I_OPC(9) = 0/1
552
 
553 10 jsauermann
            when "100110" =>                            -- 1001 10xx xxxx xxxx
554 2 jsauermann
                --
555
                --  1001 1000 AAAA Abbb - CBI
556
                --  1001 1001 AAAA Abbb - SBIC
557
                --  1001 1010 AAAA Abbb - SBI
558
                --  1001 1011 AAAA Abbb - SBIS
559
                --
560
                Q_ALU_OP <= ALU_BIT_CS;
561
                Q_AMOD <= AMOD_ABS;
562
                Q_BIT(3) <= I_OPC(9);   -- set/clear
563
 
564
                -- IMM = AAAAAA + 0x20
565
                --
566
                Q_IMM(4 downto 0) <= I_OPC(7 downto 3);
567
                Q_IMM(6 downto 5) <= "01";
568
 
569
                Q_RD_M <= I_T0;
570
                if ((I_OPC(8) = '0') ) then     -- CBI or SBI
571
                    Q_WE_M(0) <= '1';
572
                else                            -- SBIC or SBIS
573
                    if (I_T0 = '0') then        -- second cycle.
574
                        Q_PC_OP <= PC_SKIP_T;
575
                    end if;
576
                end if;
577
 
578 10 jsauermann
            when "100111" =>                            -- 1001 11xx xxxx xxxx
579 2 jsauermann
                --
580
                --  1001 11rd dddd rrrr - MUL
581
                --
582
                 Q_ALU_OP <= ALU_MULT;
583
                 Q_IMM(7 downto 5) <= "000"; --  -MUL UU;
584
                 Q_WE_01 <= '1';
585
                 Q_WE_F <= '1';
586
 
587 10 jsauermann
            when "101100" | "101101" =>                 -- 1011 0xxx xxxx xxxx
588 2 jsauermann
                --
589
                -- 1011 0AAd dddd AAAA - IN
590
                --
591
                Q_RSEL <= RS_DIN;
592
                Q_AMOD <= AMOD_ABS;
593
 
594
                -- IMM = AAAAAA
595
                --     + 010000 (0x20)
596
                Q_IMM(3 downto 0) <= I_OPC(3 downto 0);
597
                Q_IMM(4) <= I_OPC(9);
598
                Q_IMM(6 downto 5) <= "01" + ('0' & I_OPC(10 downto 10));
599
 
600 16 jsauermann
                Q_RD_M <= '1';
601 2 jsauermann
                Q_WE_D <= "01";
602
 
603 10 jsauermann
            when "101110" | "101111" =>                 -- 1011 1xxx xxxx xxxx
604 2 jsauermann
                --
605
                -- 1011 1AAr rrrr AAAA - OUT
606
                --
607
                Q_ALU_OP <= ALU_D_MV_Q;
608
                Q_AMOD <= AMOD_ABS;
609
 
610
                -- IMM = AAAAAA
611
                --     + 010000 (0x20)
612
                --
613
                Q_IMM(3 downto 0) <= I_OPC(3 downto 0);
614
                Q_IMM(4) <= I_OPC(9);
615
                Q_IMM(6 downto 5) <= "01" + ('0' & I_OPC(10 downto 10));
616
                Q_WE_M <= "01";
617
 
618
            when "110000" | "110001" | "110010" | "110011" =>
619
                --
620
                -- 1100 kkkk kkkk kkkk - RJMP
621
                --
622
                Q_JADR <= I_PC + (I_OPC(11) & I_OPC(11) & I_OPC(11) & I_OPC(11)
623
                                & I_OPC(11 downto 0)) + X"0001";
624
                Q_PC_OP <= PC_LD_I;
625
 
626
            when "110100" | "110101" | "110110" | "110111" =>
627
                --
628
                -- 1101 kkkk kkkk kkkk - RCALL
629
                --
630
                Q_JADR <= I_PC + (I_OPC(11) & I_OPC(11) & I_OPC(11) & I_OPC(11)
631
                                & I_OPC(11 downto 0)) + X"0001";
632
                Q_ALU_OP <= ALU_PC_1;
633 15 jsauermann
                Q_AMOD <= AMOD_SPdd;
634 2 jsauermann
                Q_PC_OP <= PC_LD_I;
635
                Q_WE_M <= "11";     -- both PC bytes
636
                Q_WE_XYZS <= '1';
637
 
638
            when "111000" | "111001" | "111010" | "111011" => -- LDI
639
                --
640
                -- 1110 KKKK dddd KKKK - LDI Rd, K
641
                --
642
                Q_ALU_OP <= ALU_R_MV_Q;
643
                Q_RSEL <= RS_IMM;
644
                Q_DDDDD <= '1' & I_OPC(7 downto 4);     -- 16..31
645
                Q_IMM(7 downto 0) <= I_OPC(11 downto 8) & I_OPC(3 downto 0);
646
                Q_WE_D <= "01";
647
 
648 10 jsauermann
            when "111100" | "111101" =>                 -- 1111 0xxx xxxx xxxx
649 2 jsauermann
                --
650
                -- 1111 00kk kkkk kbbb - BRBS
651
                -- 1111 01kk kkkk kbbb - BRBC
652
                --       v
653
                -- bbb: status register bit
654
                -- v: value (set/cleared) of status register bit
655
                --
656
                Q_JADR <= I_PC + (I_OPC(9) & I_OPC(9) & I_OPC(9) & I_OPC(9)
657
                                & I_OPC(9) & I_OPC(9) & I_OPC(9) & I_OPC(9)
658
                                & I_OPC(9) & I_OPC(9 downto 3)) + X"0001";
659
                Q_PC_OP <= PC_BCC;
660
 
661 10 jsauermann
            when "111110" =>                            -- 1111 10xx xxxx xxxx
662 2 jsauermann
                --
663
                -- 1111 100d dddd 0bbb - BLD
664
                -- 1111 101d dddd 0bbb - BST
665
                --
666
                if I_OPC(9) = '0' then  -- BLD: T flag to register
667
                    Q_ALU_OP <= ALU_BLD;
668
                    Q_WE_D <= "01";
669
                else                    -- BST: register to T flag
670
                    Q_AMOD <= AMOD_ABS;
671
                    Q_BIT(3) <= I_OPC(10);
672
                    Q_IMM(4 downto 0) <= I_OPC(8 downto 4);
673
                    Q_ALU_OP <= ALU_BIT_CS;
674
                    Q_WE_F <= '1';
675
                end if;
676
 
677 10 jsauermann
            when "111111" =>                            -- 1111 11xx xxxx xxxx
678 2 jsauermann
                --
679
                -- 1111 110r rrrr 0bbb - SBRC
680
                -- 1111 111r rrrr 0bbb - SBRS
681
                --
682
                -- like SBIC, but and general purpose regs instead of I/O regs.
683
                --
684
                Q_ALU_OP <= ALU_BIT_CS;
685
                Q_AMOD <= AMOD_ABS;
686
                Q_BIT(3) <= I_OPC(9);   -- set/clear bit
687
                Q_IMM(4 downto 0) <= I_OPC(8 downto 4);
688
                if (I_T0 = '0') then
689
                    Q_PC_OP <= PC_SKIP_T;
690
                end if;
691
 
692
            when others =>
693
        end case;
694
    end if;
695
    end process;
696
 
697
end Behavioral;
698
 

powered by: WebSVN 2.1.0

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