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

Subversion Repositories light52

[/] [light52/] [trunk/] [vhdl/] [light52_ucode_pkg.vhdl] - Blame information for rev 15

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

Line No. Rev Author Line
1 2 ja_rd
--------------------------------------------------------------------------------
2
-- light52_ucode_pkg.vhdl -- light52 microcode support package.
3
--------------------------------------------------------------------------------
4
-- A description of the microcode can be found in the core design document.
5
--------------------------------------------------------------------------------
6
-- Copyright (C) 2012 Jose A. Ruiz
7
--                                                              
8
-- This source file may be used and distributed without         
9
-- restriction provided that this copyright statement is not    
10
-- removed from the file and that any derivative work contains  
11
-- the original copyright notice and the associated disclaimer. 
12
--                                                              
13
-- This source file is free software; you can redistribute it   
14
-- and/or modify it under the terms of the GNU Lesser General   
15
-- Public License as published by the Free Software Foundation; 
16
-- either version 2.1 of the License, or (at your option) any   
17
-- later version.                                               
18
--                                                              
19
-- This source is distributed in the hope that it will be       
20
-- useful, but WITHOUT ANY WARRANTY; without even the implied   
21
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      
22
-- PURPOSE.  See the GNU Lesser General Public License for more 
23
-- details.                                                     
24
--                                                              
25
-- You should have received a copy of the GNU Lesser General    
26
-- Public License along with this source; if not, download it   
27
-- from http://www.opencores.org/lgpl.shtml
28
--------------------------------------------------------------------------------
29
 
30
library ieee;
31
use ieee.std_logic_1164.all;
32
use ieee.numeric_std.all;
33
 
34
use work.light52_pkg.all;
35
 
36
 
37
package light52_ucode_pkg is
38
 
39
---- Microcode fields ----------------------------------------------------------
40
 
41
subtype t_class is unsigned(5 downto 0);
42
 
43
-- Some encoding details are used by the decoding logic:
44
-- .- 2 LSBs are "10" for @Ri instruction classes.
45
-- .- lsb is 1 for LJMP/LCALL
46
constant F_ALU :                t_class := "000000";  -- Only 2 MSB significant
47
constant F_CJNE_A_IMM :         t_class := "010000";
48
constant F_CJNE_A_DIR :         t_class := "010001";
49
constant F_CJNE_RI_IMM :        t_class := "010010";
50
constant F_CJNE_RN_IMM :        t_class := "010011";
51
constant F_MOVX_DPTR_A :        t_class := "010100";
52
constant F_MOVX_A_DPTR :        t_class := "010101";
53
constant F_MOVX_A_RI :          t_class := "010110";
54
constant F_MOVX_RI_A :          t_class := "101110";
55
constant F_DJNZ_DIR :           t_class := "011000";
56
constant F_DJNZ_RN :            t_class := "011001";
57
constant F_MOVC_PC :            t_class := "011010";
58
constant F_MOVC_DPTR :          t_class := "011011";
59
constant F_BIT :                t_class := "011100";
60
constant F_OPC :                t_class := "011111";
61
constant F_SPECIAL :            t_class := "011101";
62
constant F_AJMP :               t_class := "110000";
63
constant F_LJMP :               t_class := "110001";
64
constant F_ACALL :              t_class := "110010";
65
constant F_LCALL :              t_class := "110011";
66
constant F_MOV_DPTR :           t_class := "110100";
67
constant F_XCH_DIR :            t_class := "110101";
68
constant F_XCH_RI :             t_class := "110110";
69
constant F_XCH_RN :             t_class := "110111";
70
constant F_JR :                 t_class := "101000";
71
constant F_JRB :                t_class := "101100";  -- 
72
constant F_RET :                t_class := "111001";  -- RET and RETI
73
constant F_JMP_ADPTR :          t_class := "111000";
74
constant F_PUSH :               t_class := "111100";
75
constant F_POP :                t_class := "111101";
76
constant F_NOP :                t_class := "100000";
77
constant F_XCHD :               t_class := "111110";
78
constant F_INVALID :            t_class := "111111";
79
 
80
-- Conditional jump condition selection field for F_JR and F_JRB classes.
81
subtype t_cc is unsigned(3 downto 0);
82
 
83
constant CC_Z :                 t_cc := "0000"; -- Check ALU op result
84
constant CC_NZ :                t_cc := "0001"; -- Check ALU op result
85
constant CC_C :                 t_cc := "0010";
86
constant CC_NC :                t_cc := "0011";
87
constant CC_ALWAYS :            t_cc := "0100";
88
constant CC_CJNE :              t_cc := "0101";
89
constant CC_BIT :               t_cc := "1000";
90
constant CC_NOBIT :             t_cc := "1001";
91
constant CC_ACCZ :              t_cc := "1010";
92
constant CC_ACCNZ :             t_cc := "1011";
93
 
94
 
95
-- 'ALU class' is the combination of source and destination operand types used 
96
-- in an ALU instruction. There is a different path in the state machine for
97
-- each of these classes.
98
subtype t_alu_class is unsigned(4 downto 0);
99
 
100
-- Encoding is arbitrary and not optimized.
101
constant AC_A_RI_to_A :         t_alu_class := "00000";
102
constant AC_RI_to_A :           t_alu_class := "00001";
103
constant AC_RI_to_RI :          t_alu_class := "00010";
104
constant AC_RI_to_D :           t_alu_class := "00011";
105
constant AC_D_to_A :            t_alu_class := "00100";
106
constant AC_D1_to_D :           t_alu_class := "00101";
107
constant AC_D_to_RI :           t_alu_class := "00110";
108
 
109
constant AC_D_to_D :            t_alu_class := "00111";
110
constant AC_A_RN_to_A :         t_alu_class := "01000";
111
constant AC_RN_to_RN :          t_alu_class := "01001";
112
constant AC_D_to_RN :           t_alu_class := "01010";
113
constant AC_RN_to_D :           t_alu_class := "01011";
114
constant AC_I_to_D :            t_alu_class := "01100";
115
 
116
constant AC_I_D_to_D :          t_alu_class := "01101";
117
constant AC_I_to_RI :           t_alu_class := "01110";
118
constant AC_I_to_RN :           t_alu_class := "01111";
119
constant AC_I_to_A :            t_alu_class := "10000";
120
constant AC_A_to_RI :           t_alu_class := "10001";
121
constant AC_A_to_D :            t_alu_class := "10010";
122
constant AC_A_D_to_A :          t_alu_class := "10011";
123
constant AC_A_to_RN :           t_alu_class := "10100";
124
constant AC_A_I_to_A :          t_alu_class := "10101";
125
constant AC_A_to_A :            t_alu_class := "10110";
126
constant AC_A_D_to_D :          t_alu_class := "10111";
127
 
128
constant AC_RN_to_A :           t_alu_class := "11000";
129
constant AC_DIV :               t_alu_class := "11010";
130
constant AC_MUL :               t_alu_class := "11011";
131
constant AC_DA :                t_alu_class := "11001";
132
 
133
 
134
-- ALU input operand selection control.
135
subtype t_alu_op_sel is unsigned(3 downto 0);
136
-- NOTE: the encoding of these constants is not arbitrary and is used in the 
137
-- CPU code (2 MSBs and 2 LSBs control separate muxes).
138
constant AI_A_T :               t_alu_op_sel := "0101";
139
constant AI_T_0 :               t_alu_op_sel := "0000";
140
constant AI_V_T :               t_alu_op_sel := "1001";
141
constant AI_A_0 :               t_alu_op_sel := "0100";
142
 
143
-- ALU function selection 
144
subtype t_alu_fns is unsigned(5 downto 0);
145
 
146
-- Arithmetic branch
147
constant A_ADD :        t_alu_fns := "000001";
148
constant A_SUB :        t_alu_fns := "001001"; -- Used by CJNE
149
constant A_ADDC :       t_alu_fns := "010001";
150
constant A_SUBB :       t_alu_fns := "011001";
151
constant A_INC :        t_alu_fns := "110001";
152
constant A_DEC :        t_alu_fns := "111001"; -- Used by DJNZ
153
 
154
-- Logic branch
155
constant A_ORL :        t_alu_fns := "001000";
156
constant A_ANL :        t_alu_fns := "000000";
157
constant A_XRL :        t_alu_fns := "010000";
158
constant A_NOT :        t_alu_fns := "011000";
159
constant A_SWAP :       t_alu_fns := "001100"; -- A or 0
160
-- Shift branch
161
constant A_RR :         t_alu_fns := "000010";
162
constant A_RRC :        t_alu_fns := "001010";
163
constant A_RL :         t_alu_fns := "010010";
164
constant A_RLC :        t_alu_fns := "011010";
165
-- External modules (external to the regular ALU)
166
constant A_DA :         t_alu_fns := "000110";
167
constant A_DIV :        t_alu_fns := "001110";
168
constant A_MUL :        t_alu_fns := "010110";
169
constant A_XCHD :       t_alu_fns := "011110";
170
-- Bit operations -- decoded by LSB = "11" -- ALU byte result unused.
171
-- This constant is not actually used. The initialization code appends the
172
-- 3 LSBs to a t_bit_fns value.
173
constant A_BIT :        t_alu_fns := "000011";
174
 
175
-- ALU input operand selection control. Arbitrary encoding.
176
subtype t_bit_fns is unsigned(3 downto 0);
177
 
178
constant AB_CLR :       t_bit_fns := "0000";
179
constant AB_SET :       t_bit_fns := "0001";
180
constant AB_CPL :       t_bit_fns := "0010";
181
constant AB_CPLC :      t_bit_fns := "0011";
182
constant AB_B :         t_bit_fns := "0100";
183
constant AB_C :         t_bit_fns := "0101";
184
constant AB_ANL :       t_bit_fns := "0110";
185
constant AB_ORL :       t_bit_fns := "0111";
186
constant AB_ANL_NB :    t_bit_fns := "1110";
187
constant AB_ORL_NB :    t_bit_fns := "1111";
188
 
189
 
190
subtype t_flag_mask is unsigned(1 downto 0);
191
 
192
constant FM_NONE :   t_flag_mask := "00";
193
constant FM_C :      t_flag_mask := "01";   -- C 
194
constant FM_C_OV :   t_flag_mask := "10";   -- C and OV
195
constant FM_ALL :    t_flag_mask := "11";   -- C, OV and AC
196
 
197
 
198
function build_decoding_table(bcd : boolean) return t_ucode_table;
199
 
200
end package light52_ucode_pkg;
201
 
202
package body light52_ucode_pkg is
203
 
204
function build_decoding_table(bcd : boolean) return t_ucode_table is
205
variable dt : t_ucode_table;
206
variable code : integer;
207
begin
208
 
209
    -- Initialize the decoding table to an invalid uCode word. This will help
210
    -- catch unimplemented opcodes in the state machine.
211
    for i in 0 to 255 loop
212
        dt(i) := F_INVALID & "0000000000";
213
    end loop;
214
 
215
 
216
    -- AJMP/ACALL --------------------------------------------------------------
217
    code := 16#01#;
218
    for i in 0 to 7 loop
219
        dt(code+16#10#*(i*2+0)) := F_AJMP  & "00" & X"00";
220
        dt(code+16#10#*(i*2+1)) := F_ACALL & "00" & X"00";
221
    end loop;
222
 
223
    -- LJMP/LCALL --------------------------------------------------------------
224
    dt(16#02#) := (F_LJMP ) & "00" & X"00";
225
    dt(16#12#) := (F_LCALL) & "00" & X"00";
226
 
227
    -- SJMP/Jcc ----------------------------------------------------------------
228
    dt(16#40#+16#10#*(0)) := (F_JR) & CC_C      & "00" & X"0";
229
    dt(16#50#+16#10#*(0)) := (F_JR) & CC_NC     & "00" & X"0";
230
    dt(16#60#+16#10#*(0)) := (F_JR) & CC_ACCZ   & "00" & X"0";
231
    dt(16#70#+16#10#*(0)) := (F_JR) & CC_ACCNZ  & "00" & X"0";
232
    dt(16#80#+16#10#*(0)) := (F_JR) & CC_ALWAYS & "00" & X"0";
233
 
234
 
235
    -- MOV *,#data -------------------------------------------------------------
236
 
237
    code := 16#70#;
238
    dt(code+4) := "00" & AC_I_to_A  & FM_NONE & "0" & A_ORL;
239
    dt(code+5) := "00" & AC_I_to_D  & FM_NONE & "0" & A_ORL;
240
    dt(code+6) := "00" & AC_I_to_RI & FM_NONE & "0" & A_ORL;
241
    dt(code+7) := "00" & AC_I_to_RI & FM_NONE & "0" & A_ORL;
242
    for i in 8 to 15 loop
243
        dt(code+i) := "00" & AC_I_to_RN & FM_NONE & "0" & A_ORL;
244
    end loop;
245
 
246
 
247
    -- MOV dir,* ---------------------------------------------------------------
248
 
249
    code := 16#80#;
250
    dt(code+5) := "00" & AC_D1_to_D & FM_NONE & "0" & A_ORL;
251
    dt(code+6) := "00" & AC_RI_to_D & FM_NONE & "0" & A_ORL;
252
    dt(code+7) := "00" & AC_RI_to_D & FM_NONE & "0" & A_ORL;
253
    for i in 8 to 15 loop
254
        dt(code+i) := "00" & AC_RN_to_D & FM_NONE & "0" & A_ORL;
255
    end loop;
256
 
257
    -- MOV *,dir ---------------------------------------------------------------
258
 
259
    code := 16#a0#;
260
    dt(code+6) := "00" & AC_D_to_RI & FM_NONE & "0" & A_ORL;
261
    dt(code+7) := "00" & AC_D_to_RI & FM_NONE & "0" & A_ORL;
262
    for i in 8 to 15 loop
263
        dt(code+i) := "00" & AC_D_to_RN & FM_NONE & "0" & A_ORL;
264
    end loop;
265
 
266
 
267
    -- XRL ---------------------------------------------------------------------
268
 
269
    code := 16#60#;
270
    dt(code+2) := "00" & AC_A_D_to_D  & FM_NONE & "0" & A_XRL;
271
    dt(code+3) := "00" & AC_I_D_to_D  & FM_NONE & "0" & A_XRL;
272
    dt(code+4) := "00" & AC_A_I_to_A  & FM_NONE & "0" & A_XRL;
273
    dt(code+5) := "00" & AC_A_D_to_A  & FM_NONE & "0" & A_XRL;
274
    dt(code+6) := "00" & AC_A_RI_to_A & FM_NONE & "0" & A_XRL;
275
    dt(code+7) := "00" & AC_A_RI_to_A & FM_NONE & "0" & A_XRL;
276
    for i in 8 to 15 loop
277
        dt(code+i) := "00" & AC_RN_to_A & FM_NONE & "0" & A_XRL;
278
    end loop;
279
 
280
    -- ANL ---------------------------------------------------------------------
281
 
282
    code := 16#50#;
283
    dt(code+2) := "00" & AC_A_D_to_D  & FM_NONE & "0" & A_ANL;
284
    dt(code+3) := "00" & AC_I_D_to_D  & FM_NONE & "0" & A_ANL;
285
    dt(code+4) := "00" & AC_A_I_to_A  & FM_NONE & "0" & A_ANL;
286
    dt(code+5) := "00" & AC_A_D_to_A  & FM_NONE & "0" & A_ANL;
287
    dt(code+6) := "00" & AC_A_RI_to_A & FM_NONE & "0" & A_ANL;
288
    dt(code+7) := "00" & AC_A_RI_to_A & FM_NONE & "0" & A_ANL;
289
    for i in 8 to 15 loop
290
        dt(code+i) := "00" & AC_RN_to_A & FM_NONE & "0" & A_ANL;
291
    end loop;
292
 
293
    -- ORL ---------------------------------------------------------------------
294
 
295
    code := 16#40#;
296
    dt(code+2) := "00" & AC_A_D_to_D  & FM_NONE & "0" & A_ORL;
297
    dt(code+3) := "00" & AC_I_D_to_D  & FM_NONE & "0" & A_ORL;
298
    dt(code+4) := "00" & AC_A_I_to_A  & FM_NONE & "0" & A_ORL;
299
    dt(code+5) := "00" & AC_A_D_to_A  & FM_NONE & "0" & A_ORL;
300
    dt(code+6) := "00" & AC_A_RI_to_A & FM_NONE & "0" & A_ORL;
301
    dt(code+7) := "00" & AC_A_RI_to_A & FM_NONE & "0" & A_ORL;
302
    for i in 8 to 15 loop
303
        dt(code+i) := "00" & AC_RN_to_A & FM_NONE & "0" & A_ORL;
304
    end loop;
305
 
306
 
307
    -- INC * -------------------------------------------------------------------
308
 
309
    code := 16#00#;
310
    dt(code+4) := "00" & AC_A_to_A      & FM_NONE & "0" & A_INC;
311
    dt(code+5) := "00" & AC_D_to_D      & FM_NONE & "0" & A_INC;
312
    dt(code+6) := "00" & AC_RI_to_RI    & FM_NONE & "0" & A_INC;
313
    dt(code+7) := "00" & AC_RI_to_RI    & FM_NONE & "0" & A_INC;
314
    for i in 8 to 15 loop
315
        dt(code+i) := "00" & AC_RN_to_RN  & FM_NONE & "0" & A_INC;
316
    end loop;
317
 
318
 
319
    -- DEC * -------------------------------------------------------------------
320
 
321
    code := 16#10#;
322
    dt(code+4) := "00" & AC_A_to_A      & FM_NONE & "0" & A_DEC;
323
    dt(code+5) := "00" & AC_D_to_D      & FM_NONE & "0" & A_DEC;
324
    dt(code+6) := "00" & AC_RI_to_RI    & FM_NONE & "0" & A_DEC;
325
    dt(code+7) := "00" & AC_RI_to_RI    & FM_NONE & "0" & A_DEC;
326
    for i in 8 to 15 loop
327
        dt(code+i) := "00" & AC_RN_to_RN  & FM_NONE & "0" & A_DEC;
328
    end loop;
329
 
330
    -- CJNE --------------------------------------------------------------------
331
 
332
    code := 16#b0#;
333
    dt(code+4) := F_CJNE_A_IMM  & CC_CJNE & A_SUB;
334
    dt(code+5) := F_CJNE_A_DIR  & CC_CJNE & A_SUB;
335
    dt(code+6) := F_CJNE_RI_IMM & CC_CJNE & A_SUB;
336
    dt(code+7) := F_CJNE_RI_IMM & CC_CJNE & A_SUB;
337
    for i in 8 to 15 loop
338
        dt(code+i) := F_CJNE_RN_IMM & CC_CJNE & A_SUB;
339
    end loop;
340
 
341
    -- DJNZ --------------------------------------------------------------------
342
 
343
    code := 16#d0#;
344
    dt(code+5) := F_DJNZ_DIR & CC_NZ & A_DEC;
345
    for i in 8 to 15 loop
346
        dt(code+i) := F_DJNZ_RN & CC_NZ & A_DEC;
347
    end loop;
348
 
349
    -- MOV A, * ----------------------------------------------------------------
350
 
351
    code := 16#e0#;
352
    dt(code+5) := "00" & AC_D_to_A & FM_NONE & "0" & A_ORL;
353
    dt(code+6) := "00" & AC_RI_to_A & FM_NONE & "0" & A_ORL;
354
    dt(code+7) := "00" & AC_RI_to_A & FM_NONE & "0" & A_ORL;
355
    for i in 8 to 15 loop
356
        dt(code+i) := "00" & AC_RN_to_A & FM_NONE & "0" & A_ORL;
357
    end loop;
358
 
359
    -- MOV *, A ----------------------------------------------------------------
360
 
361
    code := 16#f0#;
362
    dt(code+5) := "00" & AC_A_to_D & FM_NONE & "0" & A_ORL;
363
    dt(code+6) := "00" & AC_A_to_RI & FM_NONE & "0" & A_ORL;
364
    dt(code+7) := "00" & AC_A_to_RI & FM_NONE & "0" & A_ORL;
365
    for i in 8 to 15 loop
366
        dt(code+i) := "00" & AC_A_to_RN & FM_NONE & "0" & A_ORL;
367
    end loop;
368
 
369
    -- ADD ---------------------------------------------------------------------
370
 
371
    code := 16#20#;
372
    dt(code+4) := "00" & AC_A_I_to_A  & FM_ALL & "0" & A_ADD;
373
    dt(code+5) := "00" & AC_A_D_to_A  & FM_ALL & "0" & A_ADD;
374
    dt(code+6) := "00" & AC_A_RI_to_A & FM_ALL & "0" & A_ADD;
375
    dt(code+7) := "00" & AC_A_RI_to_A & FM_ALL & "0" & A_ADD;
376
    for i in 8 to 15 loop
377
        dt(code+i) := "00" & AC_RN_to_A & FM_ALL & "0" & A_ADD;
378
    end loop;
379
 
380
    -- ADDC --------------------------------------------------------------------
381
 
382
    code := 16#30#;
383
    dt(code+4) := "00" & AC_A_I_to_A  & FM_ALL & "0" & A_ADDC;
384
    dt(code+5) := "00" & AC_A_D_to_A  & FM_ALL & "0" & A_ADDC;
385
    dt(code+6) := "00" & AC_A_RI_to_A & FM_ALL & "0" & A_ADDC;
386
    dt(code+7) := "00" & AC_A_RI_to_A & FM_ALL & "0" & A_ADDC;
387
    for i in 8 to 15 loop
388
        dt(code+i) := "00" & AC_RN_to_A & FM_ALL & "0" & A_ADDC;
389
    end loop;
390
 
391
    -- SUBB --------------------------------------------------------------------
392
 
393
    code := 16#90#;
394
    dt(code+4) := "00" & AC_A_I_to_A  & FM_ALL & "0" & A_SUBB;
395
    dt(code+5) := "00" & AC_A_D_to_A  & FM_ALL & "0" & A_SUBB;
396
    dt(code+6) := "00" & AC_A_RI_to_A & FM_ALL & "0" & A_SUBB;
397
    dt(code+7) := "00" & AC_A_RI_to_A & FM_ALL & "0" & A_SUBB;
398
    for i in 8 to 15 loop
399
        dt(code+i) := "00" & AC_RN_to_A & FM_ALL & "0" & A_SUBB;
400
    end loop;
401
 
402
 
403
    -- Special ops on ACC ------------------------------------------------------
404
 
405
    dt(16#e4#) := "00" & AC_A_to_A & FM_NONE & "0" & A_ANL;  -- CLR A
406
    dt(16#f4#) := "00" & AC_A_to_A & FM_NONE & "0" & A_NOT;  -- CPL A
407
    dt(16#c4#) := "00" & AC_A_to_A & FM_NONE & "0" & A_SWAP; -- SWAP A
408
 
409
    dt(16#84#) := "00" & AC_DIV & FM_C_OV & "0" & A_DIV;     -- DIV AB
410
    dt(16#a4#) := "00" & AC_MUL & FM_C_OV & "0" & A_MUL;     -- MUL AB
411
 
412
 
413
    -- C and BIT instructions --------------------------------------------------
414
 
415
    -- C-only instructions: C operand, result written to C.
416
    dt(16#b3#) := (F_OPC) & "0" & FM_C & "0" & AB_CPLC & "11";      -- CPL C
417
    dt(16#c3#) := (F_OPC) & "0" & FM_C & "0" & AB_CLR & "11";       -- CLR C
418
    dt(16#d3#) := (F_OPC) & "0" & FM_C & "0" & AB_SET & "11";       -- SETB C
419
 
420
 
421
    -- BIT instructions. 
422
    --                       +---- '1' to write result to C.
423
    --                       |     '0' to write to BIT.
424
    --                       |
425
    dt(16#b2#) := (F_BIT) & "0" & FM_NONE & "0" & AB_CPL & "11";    -- CPL bit
426
    dt(16#c2#) := (F_BIT) & "0" & FM_NONE & "0" & AB_CLR & "11";    -- CLR bit
427
    dt(16#d2#) := (F_BIT) & "0" & FM_NONE & "0" & AB_SET & "11";    -- SETB bit
428
 
429
    dt(16#82#) := (F_BIT) & "1" & FM_C & "0" & AB_ANL & "11";   -- ANL C, bit
430
    dt(16#72#) := (F_BIT) & "1" & FM_C & "0" & AB_ORL & "11";   -- ORL C, bit
431
 
432
    dt(16#b0#) := (F_BIT) & "1" & FM_C & "0" & AB_ANL_NB & "11";-- ANL C, /bit
433
    dt(16#a0#) := (F_BIT) & "1" & FM_C & "0" & AB_ORL_NB & "11";-- ORL C, /bit
434
 
435
    dt(16#92#) := (F_BIT) & "0" & FM_NONE & "0" & AB_C & "11";  -- MOV bit, C
436
    dt(16#a2#) := (F_BIT) & "1" & FM_C & "0" & AB_B & "11";     -- MOV C, bit
437
 
438
 
439
    -- BIT test relative jumps -------------------------------------------------
440
 
441
    dt(16#10#) := (F_JRB) & CC_BIT & AB_CLR & "11";     -- LSBs="11" -> JBC
442
    dt(16#20#) := (F_JRB) & CC_BIT & A_ANL;             -- LSBs="00" -> not JBC
443
    dt(16#30#) := (F_JRB) & CC_NOBIT & A_ANL;           -- LSBs="00" -> not JBC
444
 
445
 
446
    -- Rotate instructions -----------------------------------------------------
447
 
448
    dt(16#33#) := "00" & AC_A_to_A  & FM_C & "0" & A_RLC;
449
    dt(16#23#) := "00" & AC_A_to_A  & FM_NONE & "0" & A_RL;
450
    dt(16#13#) := "00" & AC_A_to_A  & FM_C & "0" & A_RRC;
451
    dt(16#03#) := "00" & AC_A_to_A  & FM_NONE & "0" & A_RR;
452
 
453
    -- Special (or otherwise difficult to classify) instructions ---------------
454
 
455
    dt(16#a3#) := F_SPECIAL  & "0000000000";                -- INC DPTR
456
    dt(16#90#) := F_MOV_DPTR & "0000" & A_ORL;              -- MOV DPTR, #imm16
457
    dt(16#c0#) := F_PUSH & "0" & FM_NONE & "0" & A_ORL;     -- PUSH dir
458
    dt(16#d0#) := F_POP & "0" & FM_NONE & "0" & A_ORL;      -- POP dir
459
    dt(16#73#) := F_JMP_ADPTR & "0000000000";               -- JMP @A+DPTR
460
    dt(16#22#) := F_RET & "0000000000";                     -- RET
461
    dt(16#32#) := F_RET & "0000000001";                     -- RETI
462
 
463
    -- MOVX/MOVC instructions --------------------------------------------------
464
 
465
    dt(16#e0#) := F_MOVX_A_DPTR & "0000000000";     -- MOVX A, @DPTR
466
    dt(16#f0#) := F_MOVX_DPTR_A & "0000000000";     -- MOVX @DPTR, A
467
 
468
    dt(16#e2#) := F_MOVX_A_RI & "0" & "000" & A_ORL;  -- MOVX A, @R0
469
    dt(16#e3#) := F_MOVX_A_RI & "0" & "000" & A_ORL;  -- MOVX A, @R1
470
    dt(16#f2#) := F_MOVX_RI_A & "1" & "000" & A_ORL;  -- MOVX @R0, A
471
    dt(16#f3#) := F_MOVX_RI_A & "1" & "000" & A_ORL;  -- MOVX @R1, A
472
 
473
    dt(16#83#) := F_MOVC_PC   & "0000000000";       -- MOVC A, @A+PC @R1, A
474
    dt(16#93#) := F_MOVC_DPTR & "0000000000";       -- MOVC A, @A+DPTR
475
 
476
    -- XCH instructions --------------------------------------------------------
477
 
478
    code := 16#c0#;
479
    dt(code+5) := F_XCH_DIR & "0000" & A_ORL;       -- XCH A, dir
480
    dt(code+6) := F_XCH_RI & "0000" & A_ORL;        -- XCH A, @R0
481
    dt(code+7) := F_XCH_RI & "0000" & A_ORL;        -- XCH A, @R1
482
 
483
    for i in 8 to 15 loop
484
        dt(code+i) := F_XCH_RN & "0000" & A_ORL;    -- XCH A, Rn
485
    end loop;
486
 
487
    -- BCD instructions --------------------------------------------------------
488
 
489
    if bcd then
490
        -- BCD instructions fully implemented
491
        dt(16#d4#) := "00" & AC_DA & FM_C & "0" & A_DA;         -- DA A
492
        dt(16#d6#) := F_XCHD & "0" & FM_NONE & "0" & A_XCHD;    -- XCHD A, @R0
493
        dt(16#d7#) := F_XCHD & "0" & FM_NONE & "0" & A_XCHD;    -- XCHD A, @R1
494
    else
495
        -- BCD instructions implemented as NOPs
496
        dt(16#d4#) := F_NOP & "0000000000";         -- DA A
497
        dt(16#d6#) := F_NOP & "0000000000";         -- XCHD A, @R0
498
        dt(16#d7#) := F_NOP & "0000000000";         -- XCHD A, @R1
499
    end if;
500
 
501
 
502
    -- NOPs --------------------------------------------------------------------
503
    dt(16#00#) := F_NOP & "0000000000";             -- NOP
504
    dt(16#a5#) := F_NOP & "0000000000";             -- Unused opcode A5h
505
 
506
 
507
    return dt;
508
end function build_decoding_table;
509
 
510
end package body;
511
 
512
 

powered by: WebSVN 2.1.0

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