OpenCores
URL https://opencores.org/ocsvn/6809_6309_compatible_core/6809_6309_compatible_core/trunk

Subversion Repositories 6809_6309_compatible_core

[/] [6809_6309_compatible_core/] [trunk/] [rtl/] [verilog/] [decoders.v] - Blame information for rev 6

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

Line No. Rev Author Line
1 2 ale500
 
2
/*
3
 * Signals which registers have to be read/written for the current opcode
4
 *
5
 *
6
 *
7
 */
8
`include "defs.v"
9
module decode_regs(
10
        input wire [7:0] opcode,
11
        input wire [7:0] postbyte0,
12
        input wire page2_valid, // is 1 when the postbyte0 is a valid opcode (after it was loaded)
13
        input wire page3_valid, // is 1 when the postbyte0 is a valid opcode (after it was loaded)
14
        output reg [3:0] path_left_addr,
15
        output reg [3:0] path_right_addr,
16
        output reg [3:0] dest_reg,
17 4 ale500
        output wire write_dest,
18
        output wire source_size,
19 2 ale500
        output wire result_size
20
        );
21
// for registers, memory writes are handled differently
22 4 ale500
assign write_dest = (dest_reg != `RN_INV);
23
assign source_size = (path_left_addr < `RN_ACCA);
24 2 ale500
assign result_size = (dest_reg < `RN_IMM16) ? 1:0;
25
always @(opcode, postbyte0, page2_valid, page3_valid)
26
        begin
27
                path_left_addr = `RN_INV;
28
                path_right_addr = `RN_INV;
29
                dest_reg = `RN_INV;
30 4 ale500
                if (page2_valid)
31 2 ale500
                        begin
32
                                casex(postbyte0)
33 4 ale500
                                        8'h83, 8'h93, 8'ha3, 8'hb3: path_left_addr = `RN_ACCD; // cmpd
34
                                        8'h8c, 8'h9c, 8'hac, 8'hbc: path_left_addr = `RN_IY; // cmpy
35
                                        8'h8e, 8'h9e, 8'hae, 8'hbe: path_left_addr = `RN_IY; // ldy
36
                                        8'h8f, 8'h9f, 8'haf, 8'hbf: path_left_addr = `RN_IY; // sty
37
                                        8'hdf, 8'hef, 8'hff: path_left_addr = `RN_S; // STS
38 2 ale500
                                endcase
39
                                casex (postbyte0) // right arm
40 4 ale500
                                        8'h83, 8'h8c, 8'h8e, 8'hce: path_right_addr = `RN_IMM16;
41 2 ale500
                                        8'h93, 8'ha3, 8'hb3: path_right_addr = `RN_MEM16;
42
                                        8'h9c, 8'hac, 8'hbc: path_right_addr = `RN_MEM16;
43
                                        8'h9e, 8'hae, 8'hbe: path_right_addr = `RN_MEM16;
44 4 ale500
                                        8'h9f, 8'haf, 8'hbf: path_right_addr = `RN_MEM16;
45
                                        8'hde, 8'hee, 8'hfe: path_right_addr = `RN_MEM16; // lds
46 2 ale500
                                endcase
47
                                casex(postbyte0) // dest
48 4 ale500
                                        8'h83, 8'h93, 8'ha3, 8'hb3: begin end // cmpu/cmpd
49
                                        8'h8c, 8'h9c, 8'hac, 8'hbc: begin end // cmpy/cmps
50 2 ale500
                                        8'h8e, 8'h9e, 8'hae, 8'hbe: dest_reg = `RN_IY;
51 4 ale500
                                        8'hce, 8'hde, 8'hee, 8'hfe: dest_reg = `RN_S; // LDS
52
                                        8'h8f, 8'h9f, 8'haf, 8'hbf: dest_reg = `RN_MEM16; // STY
53
                                        8'h9f, 8'haf, 8'hbf: dest_reg = `RN_MEM16; // STS
54 2 ale500
                                endcase
55 4 ale500
                        end
56
                if (page3_valid)
57
                        begin
58
                                casex(postbyte0)
59
                                        8'h83, 8'h93, 8'ha3, 8'hb3: path_left_addr = `RN_U; // CMPU
60
                                        8'h8c, 8'h9c, 8'hac, 8'hbc: path_left_addr = `RN_S; // CMPS
61
                                endcase
62
                                casex (postbyte0) // right arm
63
                                        8'h83, 8'h8c: path_right_addr = `RN_IMM16;
64
                                        8'h93, 8'ha3, 8'hb3: path_right_addr = `RN_MEM16;
65
                                        8'h9c, 8'hac, 8'hbc: path_right_addr = `RN_MEM16;
66
                                endcase
67
                                casex(postbyte0) // dest
68
                                        8'h83, 8'h93, 8'ha3, 8'hb3: begin end // cmpu
69
                                        8'h8c, 8'h9c, 8'hac, 8'hbc: begin end // cmps
70
                                endcase
71 2 ale500
                        end
72
                // destination
73 5 ale500
                casex(opcode)
74
                        8'h1e, 8'h1f: begin dest_reg = postbyte0[3:0]; path_left_addr = postbyte0[7:4]; path_right_addr = postbyte0[3:0]; end // tfr, exg
75 2 ale500
                        8'h30: dest_reg = `RN_IX;
76
                        8'h31: dest_reg = `RN_IY;
77
                        8'h32: dest_reg = `RN_S;
78
                        8'h33: dest_reg = `RN_U;
79
                        8'h39: dest_reg = `RN_PC; // rts
80
                        8'h3d: begin path_left_addr = `RN_ACCA; path_right_addr = `RN_ACCB; dest_reg = `RN_ACCD; end // mul
81
                        8'h4x: begin path_left_addr = `RN_ACCA; dest_reg = `RN_ACCA; end
82
                        8'h5x: begin path_left_addr = `RN_ACCB; dest_reg = `RN_ACCB; end
83
                        8'h0x, 8'h7x: begin path_left_addr = `RN_MEM8; dest_reg = `RN_MEM8; end
84
                        8'h6x:
85
                                case (opcode[3:0])
86
                                        4'hf: begin dest_reg = `RN_MEM8; end // CLR, only dest
87
                                        default: begin path_left_addr = `RN_MEM8; dest_reg = `RN_MEM8; end
88
                                endcase
89
                        8'h4x, 8'h8x, 8'h9x, 8'hax, 8'hbx:
90 4 ale500
                                case (opcode[3:0])
91
                                        4'h1: path_left_addr = `RN_ACCA; // CMP
92 2 ale500
                                        4'h3: begin path_left_addr = `RN_ACCD; dest_reg = `RN_ACCD; end
93
                                        4'h7: begin path_left_addr = `RN_ACCA; dest_reg = `RN_MEM8; end
94 4 ale500
                                        4'hc: path_left_addr = `RN_IX; // cmpx
95
                                        4'he, 4'hf: begin path_left_addr = `RN_IX; dest_reg = `RN_IX; end
96 2 ale500
                                        4'hd: begin end // nothing active, jsr
97
                                        default: begin path_left_addr = `RN_ACCA; dest_reg = `RN_ACCA; end
98
                                endcase
99
                        8'h5x, 8'hcx, 8'hdx, 8'hex, 8'hfx:
100
                                case (opcode[3:0])
101 4 ale500
                                        4'h1: path_left_addr = `RN_ACCB; // CMP
102 2 ale500
                                        4'h3, 4'hc: begin path_left_addr = `RN_ACCD; dest_reg = `RN_ACCD; end
103
                                        4'h7: begin path_left_addr = `RN_ACCB; dest_reg = `RN_MEM8; end // store to mem
104
                                        4'he: begin path_left_addr = `RN_U; dest_reg = `RN_IX; end
105
                                        4'hf: begin path_left_addr = `RN_IX; dest_reg = `RN_IX; end
106
                                        4'hd: begin path_left_addr = `RN_ACCD; end
107
                                        default: begin path_left_addr = `RN_ACCB; dest_reg = `RN_ACCB; end
108
                                endcase
109
                endcase
110
                casex (opcode) // right arm
111
                        // 8x and Cx
112
                        8'b1x00_000x, 8'b1x00_0010: path_right_addr = `RN_IMM8;
113
                        8'b1x00_0011, 8'b1x00_11x0, 8'b1x00_1111: path_right_addr = `RN_IMM16;
114
                        8'b1x00_010x, 8'b1x00_0110,
115
                        8'b1x00_10xx: path_right_addr = `RN_IMM8;
116
                        // 9, A, B, D, E, F
117
                        8'b1x01_000x, 8'b1x01_0010: path_right_addr = `RN_MEM8;
118
                        8'b1x01_0011, 8'b1x01_11x0, 8'b1x01_1111: path_right_addr = `RN_MEM16;
119
                        8'b1x01_010x, 8'b1x01_0110,
120
                        8'b1x01_10xx: path_right_addr = `RN_MEM8;
121
                        8'b1x1x_000x, 8'b1x1x_0010: path_right_addr = `RN_MEM8;
122
                        8'b1x1x_0011, 8'b1x1x_11x0, 8'b1x1x_1111: path_right_addr = `RN_MEM16;
123
                        8'b1x1x_010x, 8'b1x1x_0110,
124
                        8'b1x1x_10xx: path_right_addr = `RN_MEM8;
125
                endcase
126
        end
127
 
128
endmodule
129
 
130
/* Decodes module and addressing mode for page 1 opcodes */
131
module decode_op(
132
        input wire [7:0] opcode,
133
        input wire [7:0] postbyte0,
134
        input wire page2_valid, // is 1 when the postbyte0 is a valid opcode (after it was loaded)
135
        input wire page3_valid, // is 1 when the postbyte0 is a valid opcode (after it was loaded)
136
        output reg [2:0] mode,
137
        output reg [2:0] optype,
138
        output reg use_s
139
        );
140
 
141
wire [3:0] oplo;
142
reg size;
143
assign oplo = opcode[3:0];
144
 
145
always @(opcode, postbyte0, page2_valid, page3_valid, oplo)
146
        begin
147
                //dsize = `DSZ_8; // data operand size
148
                //msize = `MSZ_8; // memory operand size
149
                optype = `OP_NONE;
150
                use_s = 1;
151
                mode = `NONE;
152
                size = 0;
153
                // Addressing mode
154
                casex(opcode)
155
                        8'h0x: begin mode = `DIRECT; end
156
                        8'h12, 8'h13, 8'h19: mode = `INHERENT;
157
                        8'h14, 8'h15, 8'h18, 8'h1b: mode = `NONE; // undefined opcodes
158
                        8'h16: mode = `REL16;
159
                        8'h17: begin mode = `REL16; optype = `OP_JSR; end
160 5 ale500
                        8'h1a, 8'h1c, 8'h1d, 8'h1e, 8'h1f: mode = `IMMEDIATE; // handled in ALU ORCC, ANDCC, SEX
161 2 ale500
 
162
                        8'h2x: mode = `REL8;
163
                        8'h30, 8'h31, 8'h32, 8'h33: begin mode = `INDEXED;  optype = `OP_LEA; end
164
                        8'h34: begin optype = `OP_PUSH; mode = `NONE; end
165
                        8'h35: begin optype = `OP_PULL; mode = `NONE; end
166
                        8'h36: begin optype = `OP_PUSH; mode = `NONE; use_s = 0; end
167
                        8'h37: begin optype = `OP_PULL; mode = `NONE; use_s = 0; end
168
                        8'h38, 8'h3e: mode = `NONE;
169
                        // don't change to inh because SEQ_MEM_READ_x would not use register S as address
170
                        8'h39, 8'h3b: begin  mode = `NONE; optype = `OP_RTS; end
171
                        8'h3a, 8'h3c, 8'h3d, 8'h3f: mode = `INHERENT;
172
 
173
                        8'h4x: begin mode = `INHERENT; end
174
                        8'h5x: begin mode = `INHERENT; end
175
                        8'h6x: begin mode = `INDEXED; end
176
                        8'h7x: begin mode = `EXTENDED; end
177
                        8'h8x:
178
                                begin
179
                                        case (oplo)
180
                                                4'h3, 4'hc, 4'he: begin mode = `IMMEDIATE; size = 1; end
181
                                                4'hd: mode = `REL8; // bsr
182
                                                default: mode = `IMMEDIATE;
183
                                        endcase
184
                                end
185
                        8'hcx:
186
                                begin
187
                                        case (oplo)
188
                                                4'h3, 4'hc, 4'he: begin mode = `IMMEDIATE; size = 1; end
189
                                                default: mode = `IMMEDIATE;
190
                                        endcase
191
                                end
192
                        8'h9x, 8'hdx: begin mode = `DIRECT; end
193
                        8'hax, 8'hex: begin mode = `INDEXED; end
194
                        8'hbx, 8'hfx: begin mode = `EXTENDED; end
195
                endcase
196
                // Opcode type
197
                casex(opcode)
198
                        8'b1xxx0110: optype = `OP_LD;
199
                        8'b1xxx0111: optype = `OP_ST;
200
                        8'b11xx1100: optype = `OP_LD; // LDD
201
                        8'b10xx1101: begin optype = `OP_JSR; end// bsr & jsr
202
                        8'b1xxx1110: optype = `OP_LD; // LDX, LDU
203
                        8'b1xxx1111, 8'b1xxx1101: optype = `OP_ST;
204
                endcase
205
                if (page2_valid == 1'b1)
206
                        begin
207
                                casex(postbyte0)
208
                                        8'h1x: mode = `REL16;
209
                                        8'h2f: mode = `INHERENT;
210
                                        8'h83: begin  mode = `IMMEDIATE; size = 1; end
211
                                        //8'h93, 8'ha3, 8'hb3: begin mem16 = 1; size = 1; end
212
                                        8'h8c: begin  mode = `IMMEDIATE; size = 1; end
213
                                        //8'h9c, 8'hac, 8'hbc: begin mem16 = 1; size = 1; end
214
                                        8'h8e: begin mode = `IMMEDIATE; size = 1; end
215
                                        //8'h9e, 8'hae, 8'hbe: begin mem16 = 1; size = 1; end
216
                                        //8'h9f, 8'haf, 8'hbf: begin  mem16 = 1; size = 1; end
217
                                        8'hce: begin  mode = `IMMEDIATE; size = 1; end
218
                                        //8'hde, 8'hee, 8'hfe: begin mem16 = 1; size = 1; end
219
                                        //8'hdf, 8'hef, 8'hff: begin mem16 = 1; size = 1; end
220
                                endcase
221
                                casex( postbyte0)
222
                                        8'h9x, 8'hdx: mode = `DIRECT;
223
                                        8'hax, 8'hex: mode = `INDEXED;
224
                                        8'hbx, 8'hfx: mode = `EXTENDED;
225
                                endcase
226
                                casex( postbyte0)
227
                                        8'b1xxx1110: optype = `OP_LD; // LDY, LDS
228
                                        8'b1xxx1111, 8'b1xxx1101: optype = `OP_ST; // STY, STS
229
                                endcase
230
                        end
231
                if (page3_valid == 1'b1)
232
                        begin
233
                                casex(postbyte0)
234
                                        8'h2f: mode = `INHERENT;
235
                                        8'h83: begin mode = `IMMEDIATE; size = 1; end // CMPD
236
                                        //8'h93, 8'ha3, 8'hb3: begin mem16 = 1; size = 1; end // CMPD
237
                                        8'h8c: begin mode = `IMMEDIATE; size = 1; end
238
                                        //8'h9c, 8'hac, 8'hbc: begin mem16 = 1; size = 1; end
239
                                        8'h8e: begin mode = `IMMEDIATE; size = 1; end
240
                                        //8'h9e, 8'hae, 8'hbe: begin mem16 = 1; size = 1; end
241
                                        //8'h9f, 8'haf, 8'hbf: begin mem16 = 1; size = 1; end
242
                                        8'hce: begin mode = `IMMEDIATE; size = 1; end
243
                                        //8'hde, 8'hee, 8'hfe: begin mem16 = 1; size = 1; end
244
                                        //8'hdf, 8'hef, 8'hff: begin mem16 = 1; size = 1; end
245
                                endcase
246
                                casex( postbyte0)
247
                                        8'h9x, 8'hdx: mode = `DIRECT;
248
                                        8'hax, 8'hex: mode = `INDEXED;
249
                                        8'hbx, 8'hfx: mode = `EXTENDED;
250
                                endcase
251
                        end
252
        end
253
 
254
endmodule
255
 
256
/* Decodes the Effective Address postbyte
257
   to recover size of offset to load and post-incr/pre-decr info
258
 */
259
module decode_ea(
260
        input wire [7:0] eapostbyte,
261
        output reg noofs,
262
        output reg ofs8, // needs an 8 bit offset
263
        output reg ofs16, // needs an 16 bit offset
264
        output reg write_post, // needs to write back a predecr or post incr
265
        output wire isind // signals when the mode is indirect, the memory at the address is read to load the real address
266
        );
267
 
268
assign isind = (eapostbyte[7] & eapostbyte[4]) ? 1'b1:1'b0;
269
always @(*)
270
        begin
271
                noofs = 0;
272
                ofs8 = 0;
273
                ofs16 = 0;
274
                write_post = 0;
275
                casex (eapostbyte)
276
                        8'b0xxxxxxx, 8'b1xx00100: noofs = 1;
277
                        8'b1xxx1000, 8'b1xxx1100: ofs8 = 1;
278
                        8'b1xxx1001, 8'b1xxx1101: ofs16 = 1;
279
                        8'b1xx11111: ofs16 = 1; // extended indirect
280
                        8'b1xxx00xx: write_post = 1;
281
                endcase
282
        end
283
endmodule
284
 
285
module decode_alu(
286
        input wire [7:0] opcode,
287
        input wire [7:0] postbyte0,
288
        input wire page2_valid, // is 1 when the postbyte0 was loaded and is page2 opcode
289
        input wire page3_valid, // is 1 when the postbyte0 was loaded and is page3 opcode
290
        output reg [4:0] alu_opcode,
291
        output reg [1:0] dec_alu_right_path_mod,
292
        output wire dest_flags
293
        );
294
 
295
assign dest_flags = alu_opcode != `NOP;
296
always @(*)
297
        begin
298
                alu_opcode = `NOP;
299
                dec_alu_right_path_mod = `MOD_DEFAULT;
300
                casex (opcode)
301
                        8'b1xxx_0000: alu_opcode = `SUB;
302
                        8'b1xxx_0001: alu_opcode = `CMP;
303
                        8'b1xxx_0010: alu_opcode = `SBC;
304
                        8'b10xx_0011: alu_opcode = `SUB;
305
                        8'b11xx_0011: alu_opcode = `ADD;
306
                        8'b1xxx_0100: alu_opcode = `AND;
307
                        8'b1xxx_0101: alu_opcode = `BIT;
308
                        8'b1xxx_0110: alu_opcode = `LD;
309
                        8'b1xxx_0111: alu_opcode = `ST;
310
                        8'b1xxx_1000: alu_opcode = `EOR;
311
                        8'b1xxx_1001: alu_opcode = `ADC;
312
                        8'b1xxx_1010: alu_opcode = `OR;
313
                        8'b1xxx_1011: alu_opcode = `ADD;
314
                        8'b10xx_1100: alu_opcode = `CMP;
315
                        8'b11xx_1100: alu_opcode = `LD;
316
                        8'b11xx_1101: alu_opcode = `LD;
317
                        8'b1xxx_1110: alu_opcode = `LD;
318
                        8'b1xxx_1111: alu_opcode = `ST;
319
 
320
                        8'h00, 8'b01xx_0000: alu_opcode = `NEG;
321
                        8'h03, 8'b01xx_0011: alu_opcode = `COM;
322
                        8'h04, 8'b01xx_0100: alu_opcode = `LSR;
323
                        8'h06, 8'b01xx_0110: alu_opcode = `ROR;
324
                        8'h07, 8'b01xx_0111: alu_opcode = `ASR;
325
                        8'h08, 8'b01xx_1000: alu_opcode = `LSL;
326
                        8'h09, 8'b01xx_1001: alu_opcode = `ROL;
327
                        8'h0a, 8'b01xx_1010: begin alu_opcode = `SUB; dec_alu_right_path_mod = `MOD_MINUS1; end // dec
328
                        8'h0c, 8'b01xx_1100: begin alu_opcode = `ADD; dec_alu_right_path_mod = `MOD_ONE; end // inc
329
                        8'h0d, 8'b01xx_1101: alu_opcode = `AND;
330
                        8'h0f, 8'b01xx_1111: begin alu_opcode = `LD; dec_alu_right_path_mod = `MOD_ZERO; end // CLR
331
 
332
                        8'h19: alu_opcode = `DAA;
333
                        8'h1a: alu_opcode = `ORCC;
334 6 ale500
                        8'h1c, 8'h3c: alu_opcode = `ANDCC;
335 2 ale500
                        8'h1d: alu_opcode = `SEXT;
336 4 ale500
                        8'h1e: alu_opcode = `EXG;
337
                        8'b0011_000x: alu_opcode = `LEA;
338 2 ale500
                        8'h3d: alu_opcode = `MUL;
339
                endcase
340
                if (page2_valid)
341
                        casex (postbyte0)
342
                                8'b10xx_0011,
343
                                8'b10xx_1010: alu_opcode = `CMP;
344
                                8'b1xxx_1110: alu_opcode = `LD;
345
                                8'b1xxx_1111: alu_opcode = `ST;
346
                        endcase
347
                if (page3_valid)
348
                        casex (postbyte0)
349
                                8'b10xx_0011,
350
                                8'b10xx_1010: alu_opcode = `CMP;
351
                                8'b1xxx_1110: alu_opcode = `LD;
352
                                8'b1xxx_1111: alu_opcode = `ST;
353
                        endcase
354
        end
355
 
356
endmodule
357
/* decodes the condition and checks the flags to see if it is met */
358
module test_condition(
359
        input wire [7:0] opcode,
360
        input wire [7:0] postbyte0,
361
        input wire page2_valid,
362
        input wire [7:0] CCR,
363
        output reg cond_taken
364
        );
365
 
366
wire [7:0] op = page2_valid ? postbyte0:opcode;
367
 
368
always @(*)
369
        begin
370
                cond_taken = 1'b0;
371
                if ((op == 8'h16) || (op == 8'h17) || (op == 8'h8D))
372
                        cond_taken = 1'b1; // LBRA/LBSR, BSR
373
                if (op[7:4] == 4'h2)
374
                        case (op[3:0])
375
                                4'h0: cond_taken = 1'b1; // BRA
376
                                4'h1: cond_taken = 0; // BRN
377
                                4'h2: cond_taken = !(`DFLAGC & `DFLAGZ); // BHI
378
                                4'h3: cond_taken = `DFLAGC | `DFLAGZ; // BLS
379
                                4'h4: cond_taken = !`DFLAGC; // BCC, BHS
380
                                4'h5: cond_taken = `DFLAGC; // BCS, BLO
381
                                4'h6: cond_taken = !`DFLAGZ; // BNE
382
                                4'h7: cond_taken = `DFLAGZ; // BEQ
383
                                4'h8: cond_taken = !`DFLAGV; // BVC
384
                                4'h9: cond_taken = `DFLAGV; // BVS
385
                                4'ha: cond_taken = !`DFLAGN; // BPL
386
                                4'hb: cond_taken = `DFLAGN; // BMI
387
                                4'hc: cond_taken = `DFLAGN == `DFLAGV; // BGE
388
                                4'hd: cond_taken = `DFLAGN != `DFLAGV; // BLT
389
                                4'he: cond_taken = (`DFLAGN == `DFLAGV) & (!`DFLAGZ); // BGT
390
                                4'hf: cond_taken = (`DFLAGN != `DFLAGV) | (`DFLAGZ); // BLE
391
                endcase
392
        end
393
 
394
endmodule

powered by: WebSVN 2.1.0

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