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 13

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

powered by: WebSVN 2.1.0

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