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

Subversion Repositories cpu_lecture

[/] [cpu_lecture/] [trunk/] [html/] [18_Listing_of_opc_deco.vhd.html] - Blame information for rev 2

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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