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 4

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

powered by: WebSVN 2.1.0

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