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 9

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

powered by: WebSVN 2.1.0

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