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 24

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

powered by: WebSVN 2.1.0

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