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/] [MC6809_cpu.v] - Blame information for rev 2

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

Line No. Rev Author Line
1 2 ale500
/*
2
 *
3
 * MC6809/HD6309 Compatible code
4
 * (c) 2013 R.A. Paz Schmidt
5
 * distributed under the terms of the Lesser GPL, see LICENSE.TXT
6
 *
7
 */
8
 
9
`include "defs.v"
10
module MC6809_cpu(
11
        input  wire cpu_clk,
12
        input  wire cpu_reset,
13
        input  wire cpu_nmi_n,
14
        input  wire cpu_irq_n,
15
        input  wire cpu_firq_n,
16
        output wire [5:0] cpu_state_o,
17
        output wire cpu_we_o,
18
        output wire cpu_oe_o,
19
        output wire [15:0] cpu_addr_o,
20
        input  wire [7:0] cpu_data_i,
21
        output wire [7:0] cpu_data_o
22
        );
23
 
24
wire k_reset;
25
wire k_clk;
26
assign k_clk = cpu_clk;
27
 
28
reg [7:0] k_opcode, k_postbyte0, k_ind_ea; /* all bytes of an instruction */
29
reg [7:0] k_pp_regs, k_pp_active_reg; // push/pull mask 
30
reg [7:0] k_memhi, k_memlo, k_cpu_data_o; /* operand read from memory */
31
reg [7:0] k_ofslo, k_ofshi, k_eahi, k_ealo;
32
reg [5:0] state, // state of the main state machine
33
          next_state, // next state to exit to from the read from [PC] state machine
34
                  next_mem_state, // next state to exit to from the read from memory state machine
35
                  next_push_state; // next state to exit to from push multiple state machine
36
reg k_cpu_oe, k_cpu_we, k_inc_pc, k_pull_reg_write;
37
reg [15:0] k_cpu_addr, k_new_pc;
38
reg k_write_pc, k_inc_su, k_dec_su, k_set_e, k_clear_e;
39
reg [1:0] k_mem_dest;
40
reg k_write_post_incdec; // asserted when in the last write cycle or in write back for loads
41
/****
42
 * Decoder outputs
43
 */
44
wire [2:0] dec_o_p1_mode; // addressing mode
45
wire [2:0] dec_o_p1_optype; // k_opcode type
46
wire dec_o_use_s; // signals when S should be used instead of U
47
wire dec_o_alu_size;
48
/* ea decoder */
49
wire dec_o_ea_ofs8, dec_o_ea_ofs16, dec_o_ea_wpost, dec_o_ea_ofs0, dec_o_ea_indirect;
50
/* alu k_opcode decoder */
51
wire [4:0] dec_o_alu_opcode;
52
wire [1:0] dec_o_right_path_mod; /* Modifier for alu's right path input */
53
/* register decoder */
54
wire dec_o_wdest_8, dec_o_wdest_16, dec_o_write_flags;
55
wire [3:0] dec_o_left_path_addr, dec_o_right_path_addr, dec_o_dest_reg_addr;
56
/* test condition */
57
wire dec_o_cond_taken;
58
/* ALU outputs */
59
wire [15:0] alu_o_result;
60
wire [7:0] alu_o_CCR;
61
/* Register Module outputs */
62
wire [15:0] regs_o_left_path_data, regs_o_right_path_data, regs_o_eamem_addr, regs_o_su;
63
wire [7:0] regs_o_dp;
64
wire [15:0] regs_o_pc;
65
wire [7:0] regs_o_CCR;
66
/* Data Muxes */
67
reg [3:0] datamux_o_dest_reg_addr, datamux_o_alu_in_left_path_addr;
68
reg [15:0] datamux_o_alu_in_left_path_data, datamux_o_alu_in_right_path_data, datamux_o_dest;
69
 
70
reg k_p2_valid, k_p3_valid; /* 1 when k_postbyte0 has been loaded for page 2 or page 3 */
71
 
72
/* Interrupt sync registers */
73
 
74
reg [2:0] k_reg_nmi, k_reg_irq, k_reg_firq;
75
wire k_nmi_req, k_firq_req, k_irq_req;
76
 
77
assign k_nmi_req = k_reg_nmi[2] & k_reg_nmi[1];
78
assign k_firq_req = k_reg_firq[2] & k_reg_firq[1];
79
assign k_irq_req = k_reg_irq[2] & k_reg_irq[1];
80
 
81
alu16 alu(
82
        .clk(k_clk),
83
        .a_in(datamux_o_alu_in_left_path_data),
84
        .b_in(datamux_o_alu_in_right_path_data),
85
        .CCR(regs_o_CCR), /* flags */
86
        .opcode_in(dec_o_alu_opcode), /* ALU k_opcode */
87
        .sz_in(dec_o_alu_size), /* size, low 8 bit, high 16 bit */
88
        .q_out(alu_o_result), /* ALU result */
89
        .CCRo(alu_o_CCR)
90
        );
91
 
92
regblock regs(
93
        .clk_in(k_clk),
94
        .path_left_addr(datamux_o_alu_in_left_path_addr),
95
        .path_right_addr(dec_o_right_path_addr),
96
        .write_reg_addr(datamux_o_dest_reg_addr),
97
        .eapostbyte( k_ind_ea ),
98
        .offset16({ k_ofshi, k_ofslo }),
99
        .write_reg_8(dec_o_wdest_8 & (state == `SEQ_GRAL_WBACK)),
100
        .write_reg_16(dec_o_wdest_16 & (state == `SEQ_GRAL_WBACK)),
101
        .write_pull_reg(k_pull_reg_write),
102
        .write_post(k_write_post_incdec),
103
        .write_pc(k_write_pc),
104
        .inc_pc(k_inc_pc),
105
        .inc_su(k_inc_su),
106
        .dec_su(k_dec_su),
107
        .use_s(dec_o_use_s),
108
        .data_w(datamux_o_dest),
109
        .new_pc(k_new_pc),
110
        .CCR_in(alu_o_CCR),
111
        .write_flags(dec_o_write_flags & (state == `SEQ_GRAL_WBACK)),
112
        .set_e(k_set_e),
113
        .clear_e(k_clear_e),
114
        .CCR_o(regs_o_CCR),
115
        .path_left_data(regs_o_left_path_data),
116
        .path_right_data(regs_o_right_path_data),
117
        .eamem_addr(regs_o_eamem_addr),
118
        .reg_pc(regs_o_pc),
119
        .reg_dp(regs_o_dp),
120
        .reg_su(regs_o_su)
121
);
122
 
123
decode_regs dec_regs(
124
        .opcode(k_opcode),
125
        .postbyte0(k_postbyte0),
126
        .page2_valid(k_p2_valid),
127
        .page3_valid(k_p3_valid),
128
        .path_left_addr(dec_o_left_path_addr),
129
        .path_right_addr(dec_o_right_path_addr),
130
        .dest_reg(dec_o_dest_reg_addr),
131
        .write_dest_8(dec_o_wdest_8),
132
        .write_dest_16(dec_o_wdest_16),
133
        .result_size(dec_o_alu_size)
134
        );
135
 
136
decode_op dec_op(
137
        .opcode(k_opcode),
138
        .postbyte0(k_postbyte0),
139
        .page2_valid(k_p2_valid),
140
        .page3_valid(k_p3_valid),
141
        .mode(dec_o_p1_mode),
142
        .optype(dec_o_p1_optype),
143
        .use_s(dec_o_use_s)
144
        );
145
 
146
decode_ea dec_ea(
147
        .eapostbyte( k_ind_ea ),
148
        .noofs(dec_o_ea_ofs0),
149
        .ofs8(dec_o_ea_ofs8),
150
        .ofs16(dec_o_ea_ofs16),
151
        .write_post(dec_o_ea_wpost),
152
        .isind(dec_o_ea_indirect)
153
        );
154
 
155
/* Opcodes for the ALU are decoded here
156
 * Write Flags are also decoded here
157
 */
158
decode_alu dec_alu(
159
        .opcode(k_opcode),
160
        .postbyte0(k_postbyte0),
161
        .page2_valid(k_p2_valid),
162
        .page3_valid(k_p3_valid),
163
        .alu_opcode(dec_o_alu_opcode),
164
        .dec_alu_right_path_mod(dec_o_right_path_mod),
165
        .dest_flags(dec_o_write_flags)
166
        );
167
/* Condition decoder */
168
test_condition test_cond(
169
        .opcode(k_opcode),
170
        .postbyte0(k_postbyte0),
171
        .page2_valid(k_p2_valid),
172
        .CCR(regs_o_CCR),
173
        .cond_taken(dec_o_cond_taken)
174
        );
175
 
176
/* Module IO */
177
 
178
assign cpu_oe_o = k_cpu_oe; // we latch on the rising edge
179
assign cpu_we_o = k_cpu_we;
180
assign cpu_addr_o = k_cpu_addr;
181
assign cpu_data_o = k_cpu_data_o;
182
assign k_reset = cpu_reset;
183
assign cpu_state_o = state;
184
 
185
 
186
/* Left Register read mux
187
 */
188
always @(*)
189
        begin
190
                datamux_o_alu_in_left_path_addr = dec_o_left_path_addr;
191
                case (k_pp_active_reg)
192
                        8'h80: datamux_o_alu_in_left_path_addr = `RN_PC;
193
                        8'h40: datamux_o_alu_in_left_path_addr = (dec_o_use_s) ? `RN_U:`RN_S;
194
                        8'h20: datamux_o_alu_in_left_path_addr = `RN_IY;
195
                        8'h10: datamux_o_alu_in_left_path_addr = `RN_IX;
196
                        8'h08: datamux_o_alu_in_left_path_addr = `RN_DP;
197
                        8'h04: datamux_o_alu_in_left_path_addr = `RN_ACCB;
198
                        8'h02: datamux_o_alu_in_left_path_addr = `RN_ACCA;
199
                        8'h01: datamux_o_alu_in_left_path_addr = `RN_CC;
200
                        endcase
201
        end
202
 
203
/* Destination register address MUX
204
 */
205
always @(*)
206
        begin
207
                datamux_o_dest_reg_addr = dec_o_dest_reg_addr;
208
                case (k_pp_active_reg)
209
                        8'h80: datamux_o_dest_reg_addr = `RN_PC;
210
                        8'h40: datamux_o_dest_reg_addr = (dec_o_use_s) ? `RN_U:`RN_S;
211
                        8'h20: datamux_o_dest_reg_addr = `RN_IY;
212
                        8'h10: datamux_o_dest_reg_addr = `RN_IX;
213
                        8'h08: datamux_o_dest_reg_addr = `RN_DP;
214
                        8'h04: datamux_o_dest_reg_addr = `RN_ACCB;
215
                        8'h02: datamux_o_dest_reg_addr = `RN_ACCA;
216
                        8'h01: datamux_o_dest_reg_addr = `RN_CC;
217
                endcase
218
        end
219
 
220
/* Destination register data mux
221
 * selects the source to write to register. 16 bit registers have to be written at once after reading the low byte
222
 *
223
 */
224
always @(*)
225
        begin
226
                datamux_o_dest = alu_o_result;
227
                case (dec_o_p1_optype)
228
                        `OP_PULL, `OP_RTS: // destination register
229
                                datamux_o_dest = { k_memhi, k_memlo };
230
                        `OP_LEA:
231
                                if (dec_o_ea_indirect & dec_o_alu_size)
232
                                        datamux_o_dest = { k_memhi, k_memlo };
233
                                else
234
                                        datamux_o_dest = regs_o_eamem_addr;
235
                endcase
236
        end
237
 
238
/* ALU left input mux */
239
 
240
always @(*)
241
        begin
242
                if (dec_o_left_path_addr == `RN_MEM8)
243
                        datamux_o_alu_in_left_path_data = { k_memhi, k_memlo };
244
                else
245
                        begin
246
                                datamux_o_alu_in_left_path_data = regs_o_left_path_data;
247
                        end
248
        end
249
 
250
/* ALU right input mux */
251
always @(*)
252
        begin
253
                case (dec_o_right_path_addr)
254
                        `RN_MEM8:
255
                                datamux_o_alu_in_right_path_data = { 8'h00, k_memlo };
256
                        `RN_MEM16:
257
                                datamux_o_alu_in_right_path_data = { k_memhi, k_memlo };
258
                        `RN_IMM8:
259
                                datamux_o_alu_in_right_path_data = { 8'h0, k_memlo };
260
                        `RN_IMM16:
261
                                datamux_o_alu_in_right_path_data = { k_memhi, k_memlo };
262
                        default:
263
                                case (dec_o_right_path_mod)
264
                                        `MOD_DEFAULT: datamux_o_alu_in_right_path_data = regs_o_right_path_data;
265
                                        `MOD_ONE: datamux_o_alu_in_right_path_data = 16'h0001;
266
                                        `MOD_ZERO: datamux_o_alu_in_right_path_data = 16'h0000;
267
                                        `MOD_MINUS1: datamux_o_alu_in_right_path_data = 16'hffff;
268
                                endcase
269
                endcase
270
        end
271
 
272
always @(posedge k_clk or posedge k_reset)
273
        begin
274
                if (k_reset == 1'b1)
275
                        begin
276
                                state <= `SEQ_COLDRESET;
277
                                k_reg_nmi <= 0;
278
                                k_reg_firq <= 0;
279
                                k_reg_irq <= 0;
280
                        end
281
                else
282
                        begin
283
                                /* Inrerrupt recognition and acknowledge */
284
                                if (!k_reg_nmi[2])
285
                                        k_reg_nmi <= { k_reg_nmi[1:0], cpu_nmi_n };
286
                                if (!k_reg_irq[2])
287
                                        k_reg_irq <= { k_reg_irq[1:0], cpu_irq_n };
288
                                if (!k_reg_firq[2])
289
                                        k_reg_firq <= { k_reg_firq[1:0], cpu_firq_n };
290
                                /* modifier registers */
291
                                if (k_inc_pc)
292
                                        k_inc_pc <= 0;
293
                                if (k_write_pc)
294
                                        k_write_pc <= 0;
295
                                if (k_cpu_we)
296
                                        k_cpu_we <= 0;
297
                                if (k_cpu_oe)
298
                                        k_cpu_oe <= 0;
299
                                if (k_write_post_incdec)
300
                                        k_write_post_incdec <= 0;
301
                                if (k_dec_su)
302
                                        k_dec_su <= 0;
303
                                if (k_inc_su)
304
                                        k_inc_su <= 0;
305
                                if (k_pull_reg_write)
306
                                        k_pull_reg_write <= 0;
307
                                if (k_set_e)
308
                                        k_set_e <= 0;
309
                                if (k_clear_e)
310
                                        k_clear_e <= 0;
311
                        case (state)
312
                                `SEQ_COLDRESET:
313
                                        begin
314
                                                state <= `SEQ_MEM_READ_H;
315
                                                k_eahi <= 8'hff;
316
                                                k_ealo <= 8'hfe;
317
                                                next_mem_state <= `SEQ_LOADPC;
318
                                        end
319
                                `SEQ_NMI:
320
                                        begin
321
                                                k_reg_nmi <= 2'h0;
322
                                                { k_eahi, k_ealo } <= 16'hfffc;
323
                                                k_pp_regs <= 8'hff;
324
                                                k_set_e <= 1;
325
                                                state <= `SEQ_PREPUSH; // first stack the registers
326
                                                next_push_state <= `SEQ_MEM_READ_H; // than load new PC
327
                                                next_mem_state <= `SEQ_FETCH; // than continue fetching instructions
328
                                        end
329
                                `SEQ_SWI:
330
                                        begin
331
                                                state <= `SEQ_MEM_READ_H;
332
                                                { k_eahi, k_ealo } <= 16'hfffa;
333
                                                k_pp_regs <= 8'hff;
334
                                                state <= `SEQ_PREPUSH; // first stack the registers
335
                                                next_push_state <= `SEQ_MEM_READ_H; // than load new PC
336
                                                next_mem_state <= `SEQ_FETCH; // than continue fetching instructions
337
                                                k_set_e <= 1;
338
                                        end
339
                                `SEQ_IRQ:
340
                                        begin
341
                                                k_reg_irq <= 2'h0;
342
                                                state <= `SEQ_MEM_READ_H;
343
                                                { k_eahi, k_ealo } <= 16'hfff8;
344
                                                k_pp_regs <= 8'hff;
345
                                                next_mem_state <= `SEQ_PREPUSH;
346
                                                k_set_e <= 1;
347
                                                state <= `SEQ_PREPUSH; // first stack the registers
348
                                                next_push_state <= `SEQ_MEM_READ_H; // than load new PC
349
                                                next_mem_state <= `SEQ_FETCH; // than continue fetching instructions
350
                                        end
351
                                `SEQ_FIRQ:
352
                                        begin
353
                                                k_reg_firq <= 2'h0;
354
                                                { k_eahi, k_ealo } <= 16'hfff6;
355
                                                k_pp_regs <= 8'h81; // PC & CC
356
                                                k_clear_e <= 1;
357
                                                state <= `SEQ_PREPUSH; // first stack the registers
358
                                                next_push_state <= `SEQ_MEM_READ_H; // than load new PC
359
                                                next_mem_state <= `SEQ_FETCH; // than continue fetching instructions
360
                                        end
361
                                `SEQ_SWI2:
362
                                        begin
363
                                                { k_eahi, k_ealo } <= 16'hfff4;
364
                                                k_pp_regs <= 8'hff;
365
                                                k_set_e <= 1;
366
                                                state <= `SEQ_PREPUSH; // first stack the registers
367
                                                next_push_state <= `SEQ_MEM_READ_H; // than load new PC
368
                                                next_mem_state <= `SEQ_FETCH; // than continue fetching instructions
369
                                        end
370
                                `SEQ_SWI3:
371
                                        begin
372
                                                { k_eahi, k_ealo } <= 16'hfff2;
373
                                                k_pp_regs <= 8'hff;
374
                                                k_set_e <= 1;
375
                                                state <= `SEQ_PREPUSH; // first stack the registers
376
                                                next_push_state <= `SEQ_MEM_READ_H; // than load new PC
377
                                                next_mem_state <= `SEQ_FETCH; // than continue fetching instructions
378
                                        end
379
                                `SEQ_UNDEF:
380
                                        begin
381
                                                { k_eahi, k_ealo } <= 16'hfff0;
382
                                                k_pp_regs <= 8'hff;
383
                                                k_set_e <= 1;
384
                                                state <= `SEQ_PREPUSH; // first stack the registers
385
                                                next_push_state <= `SEQ_MEM_READ_H; // than load new PC
386
                                                next_mem_state <= `SEQ_FETCH; // than continue fetching instructions
387
                                        end
388
                                `SEQ_LOADPC: /* loads the PC with the address taken from the reset vector */
389
                                        begin
390
                                                $display("cpu_data_i %02x %t", cpu_data_i, $time);
391
                                                state <= `SEQ_FETCH;
392
                                        end
393
                                `SEQ_FETCH: /* execution starts here */
394
                                        begin
395
                                                if (k_nmi_req)
396
                                                        state <= `SEQ_NMI;
397
                                                else
398
                                                if (k_firq_req)
399
                                                        state <= `SEQ_FIRQ;
400
                                                else
401
                                                if (k_irq_req)
402
                                                        state <= `SEQ_IRQ;
403
                                                else
404
                                                        begin
405
                                                                state <= `SEQ_FETCH_1;
406
                                                                k_cpu_addr <= regs_o_pc;
407
                                                        end
408
                                        end
409
                                `SEQ_FETCH_1:
410
                                        begin
411
                                                k_cpu_oe <= 1;
412
                                                state <= `SEQ_FETCH_2;
413
                                        end
414
                                `SEQ_FETCH_2:
415
                                        begin
416
                                                k_opcode <= cpu_data_i;
417
                                                case (cpu_data_i[7:0]) /* page 2 & 3 opcodes are recognized here */
418
                                                        8'h10:
419
                                                                begin
420
                                                                        k_p2_valid <= 1;
421
                                                                        k_p3_valid <= 0;
422
                                                                        state <= `SEQ_FETCH_3;
423
                                                                end
424
                                                        8'h11:
425
                                                        begin
426
                                                                k_p2_valid <= 0;
427
                                                                k_p3_valid <= 1;
428
                                                                state <= `SEQ_FETCH_3;
429
                                                        end
430
                                                        default:
431
                                                        begin
432
                                                                state <= `SEQ_DECODE;
433
                                                                k_p2_valid <= 0; // set when an k_opcode is page 2
434
                                                                k_p3_valid <= 0; // set when an k_opcode is page 3
435
                                                        end
436
                                                endcase
437
                                                k_pp_active_reg <= 8'h00; // prevents wrong register in left/dest data muxes
438
                                                k_inc_pc <= 1;
439
                                        end
440
                                `SEQ_FETCH_3:
441
                                        begin
442
                                                state <= `SEQ_FETCH_4;
443
                                                k_cpu_addr <= regs_o_pc;
444
                                        end
445
                                `SEQ_FETCH_4:
446
                                        begin
447
                                                k_cpu_oe <= 1;
448
                                                state <= `SEQ_FETCH_5;
449
                                        end
450
                                `SEQ_FETCH_5: /* fetches a page 2 or 3 opcode */
451
                                        begin
452
                                                k_postbyte0 <= cpu_data_i;
453
                                                k_inc_pc <= 1;
454
                                                state <= `SEQ_DECODE_P23;
455
                                        end
456
                                `SEQ_DECODE:
457
                                        begin
458
                                                /* here we have the first byte of the k_opcode and should be decided to which state we jump
459
                                                 * inherent means that no extra info is needed
460
                                                 * ALU opcodes need routing of registers to/from the ALU to the registers
461
                                                 */
462
                                                case (dec_o_p1_mode)
463
                                                        `NONE: // unknown k_opcode and push/pull... refetch ?
464
                                                                begin
465
                                                                        casex (k_opcode)
466
                                                                                8'h39: // RTS
467
                                                                                        begin
468
                                                                                                state <= `SEQ_PREPULL;
469
                                                                                                k_pp_regs <= 8'h80; // Pull PC (RTS)all regs
470
                                                                                        end
471
                                                                                8'h3B: // RTI
472
                                                                                        begin
473
                                                                                                state <= `SEQ_PREPULL;
474
                                                                                                k_pp_regs <= 8'hff; // all regs
475
                                                                                        end
476
                                                                                8'b001101x0: // PUSH S&U
477
                                                                                        begin
478
                                                                                                state <= `SEQ_PC_READ_L;
479
                                                                                                next_state <= `SEQ_PREPUSH;
480
                                                                                                next_push_state <= `SEQ_FETCH;
481
                                                                                        end
482
                                                                                8'b001101x1: // PULL S&U
483
                                                                                        begin
484
                                                                                                next_state <= `SEQ_PREPULL;
485
                                                                                                state <= `SEQ_PC_READ_L;
486
                                                                                        end
487
                                                                                default: /* we ignore unknown opcodes */
488
                                                                                        state <= `SEQ_FETCH;
489
                                                                        endcase
490
                                                                end
491
                                                        `IMMEDIATE:     // 8 or 16 bits as result decides..
492
                                                                begin
493
                                                                        if (dec_o_alu_size)
494
                                                                                state <= `SEQ_PC_READ_H;
495
                                                                        else
496
                                                                                state <= `SEQ_PC_READ_L;
497
                                                                        next_state <= `SEQ_GRAL_ALU;
498
                                                                end
499
                                                        `INHERENT:
500
                                                                begin
501
                                                                        case (k_opcode)
502
                                                                                8'h3f: state <= `SEQ_SWI;
503
                                                                                        default: state <= `SEQ_GRAL_ALU;
504
                                                                        endcase
505
                                                                end
506
                                                        `DIRECT:
507
                                                                begin
508
                                                                        state <= `SEQ_PC_READ_L;
509
                                                                        k_mem_dest <= `MEMDEST_MH; // operand to memlo/memhi
510
                                                                        if ((dec_o_right_path_addr == `RN_MEM8) || (dec_o_right_path_addr == `RN_MEM16) ||
511
                                                                                (dec_o_left_path_addr == `RN_MEM8))
512
                                                                                begin
513
                                                                                        if (dec_o_alu_size)
514
                                                                                                next_state <= `SEQ_MEM_READ_H;
515
                                                                                        else
516
                                                                                                next_state <= `SEQ_MEM_READ_L;
517
                                                                                        next_mem_state <= `SEQ_GRAL_ALU; // read then alu
518
                                                                                end
519
                                                                        else
520
                                                                                next_state <= `SEQ_GRAL_ALU; // no read
521
                                                                        k_eahi <= regs_o_dp;
522
                                                                end
523
                                                        `INDEXED:
524
                                                                state <= `SEQ_IND_READ_EA;
525
                                                        `EXTENDED:
526
                                                                begin
527
                                                                        state <= `SEQ_PC_READ_H; // loads address
528
                                                                        k_mem_dest <= `MEMDEST_MH; // operand to memlo/memhi
529
                                                                        if ((dec_o_right_path_addr == `RN_MEM8) || (dec_o_right_path_addr == `RN_MEM16) ||
530
                                                                                (dec_o_left_path_addr == `RN_MEM8))
531
                                                                                begin
532
                                                                                        if (dec_o_alu_size)
533
                                                                                                next_state <= `SEQ_MEM_READ_H;
534
                                                                                        else
535
                                                                                                next_state <= `SEQ_MEM_READ_L;
536
                                                                                        next_mem_state <= `SEQ_GRAL_ALU; // read then alu
537
                                                                                end
538
                                                                        else
539
                                                                                next_state <= `SEQ_GRAL_ALU; // no read
540
                                                                end
541
                                                        `REL8:
542
                                                                begin
543
                                                                        state <= `SEQ_PC_READ_L; // loads address
544
                                                                        if (dec_o_p1_optype == `OP_JSR) // bsr
545
                                                                                next_state <= `SEQ_JSR_PUSH;
546
                                                                        else
547
                                                                                next_state <= `SEQ_JMP_LOAD_PC; // offset loaded in this cycle, jump if needed
548
                                                                end
549
                                                        `REL16:
550
                                                                begin
551
                                                                        state <= `SEQ_PC_READ_H; // loads address
552
                                                                        if (dec_o_p1_optype == `OP_JSR) // lbsr
553
                                                                                next_state <= `SEQ_JSR_PUSH;
554
                                                                        else
555
                                                                                next_state <= `SEQ_JMP_LOAD_PC;
556
                                                                end
557
                                                endcase
558
                                        end
559
                                `SEQ_DECODE_P23:
560
                                        begin // has prefix 10 or 11
561
                                                k_inc_pc <= 0;
562
                                                case (dec_o_p1_mode)
563
                                                        `NONE: // unknown k_opcode... re-fetch ?
564
                                                                state <= `SEQ_FETCH;
565
                                                        `IMMEDIATE:     // 8 or 16 bits as result decides..
566
                                                                begin
567
                                                                        if (dec_o_alu_size)
568
                                                                                state <= `SEQ_PC_READ_H;
569
                                                                        else
570
                                                                                state <= `SEQ_PC_READ_L;
571
                                                                        next_state <= `SEQ_GRAL_ALU;
572
                                                                end
573
                                                        `INHERENT:
574
                                                                case (k_opcode)
575
                                                                        8'h3f: if (k_p2_valid) state <= `SEQ_SWI2;
576
                                                                                   else state <= `SEQ_SWI3;
577
                                                                        default: state <= `SEQ_GRAL_ALU;
578
                                                                endcase
579
                                                        `DIRECT:
580
                                                                begin
581
                                                                        state <= `SEQ_PC_READ_L;
582
                                                                        k_mem_dest <= `MEMDEST_MH; // operand to memlo/memhi
583
                                                                        if ((dec_o_right_path_addr == `RN_MEM8) || (dec_o_right_path_addr == `RN_MEM16) ||
584
                                                                                (dec_o_left_path_addr == `RN_MEM8))
585
                                                                                begin
586
                                                                                        if (dec_o_alu_size)
587
                                                                                                next_state <= `SEQ_MEM_READ_H;
588
                                                                                        else
589
                                                                                                next_state <= `SEQ_MEM_READ_L;
590
                                                                                        next_mem_state <= `SEQ_GRAL_ALU; // read then alu
591
                                                                                end
592
                                                                        else
593
                                                                                next_state <= `SEQ_GRAL_ALU; // no read
594
                                                                        k_eahi <= regs_o_dp;
595
                                                                end
596
                                                        `INDEXED:
597
                                                                state <= `SEQ_IND_READ_EA;
598
                                                        `EXTENDED:
599
                                                                begin
600
                                                                        state <= `SEQ_PC_READ_H; // loads address
601
                                                                        k_mem_dest <= `MEMDEST_MH; // operand to memlo/memhi
602
                                                                        if ((dec_o_right_path_addr == `RN_MEM8) || (dec_o_right_path_addr == `RN_MEM16) ||
603
                                                                                (dec_o_left_path_addr == `RN_MEM8))
604
                                                                                begin
605
                                                                                        if (dec_o_alu_size)
606
                                                                                                next_state <= `SEQ_MEM_READ_H;
607
                                                                                        else
608
                                                                                                next_state <= `SEQ_MEM_READ_L;
609
                                                                                        next_mem_state <= `SEQ_GRAL_ALU; // read then alu
610
                                                                                end
611
                                                                        else
612
                                                                                next_state <= `SEQ_GRAL_ALU; // no read
613
                                                                end
614
                                                        `REL16:
615
                                                                begin // long branches only
616
                                                                        state <= `SEQ_PC_READ_H; // loads address
617
                                                                        next_state <= `SEQ_JMP_LOAD_PC;
618
                                                                end
619
                                                endcase
620
                                        end
621
                                `SEQ_GRAL_ALU:
622
                                        state <= `SEQ_GRAL_WBACK;
623
                                `SEQ_GRAL_WBACK:
624
                                        begin
625
                                                next_mem_state <= `SEQ_FETCH;
626
                                                case (dec_o_dest_reg_addr)
627
                                                        `RN_MEM8: state <= `SEQ_MEM_WRITE_L;
628
                                                        `RN_MEM16: state <= `SEQ_MEM_WRITE_H;
629
                                                        default:
630
                                                                begin
631
                                                                        state <= `SEQ_FETCH;
632
                                                                        k_write_post_incdec <= dec_o_ea_wpost;
633
                                                                end
634
                                                endcase
635
                                        end
636
                                `SEQ_INH_ALU:
637
                                        state <= `SEQ_GRAL_WBACK;
638
                                `SEQ_IND_READ_EA: // reads EA byte
639
                                        begin
640
                                                k_cpu_addr <= regs_o_pc;
641
                                                state <= `SEQ_IND_READ_EA_1;
642
                                                k_inc_pc <= 1;
643
                                        end
644
                                `SEQ_IND_READ_EA_1:
645
                                        begin
646
                                                k_cpu_oe <= 1; // read
647
                                                state <= `SEQ_IND_READ_EA_2;
648
                                        end
649
                                `SEQ_IND_READ_EA_2:
650
                                        begin
651
                                                k_ind_ea <= cpu_data_i;
652
                                                state <= `SEQ_IND_DECODE;
653
                                        end
654
                                `SEQ_IND_DECODE: // here we have to see what we need for indexed...
655
                                        begin
656
                                                if (dec_o_ea_ofs8)
657
                                                        begin // load 1 byte offset
658
                                                                state <= `SEQ_PC_READ_L;
659
                                                                next_state <= `SEQ_IND_DECODE_OFS; // has some offset, load arg
660
                                                        end
661
                                                else
662
                                                        if (dec_o_ea_ofs16)
663
                                                                begin // load 2 bytes offset
664
                                                                        state <= `SEQ_PC_READ_H;
665
                                                                        next_state <= `SEQ_IND_DECODE_OFS; // has some offset, load arg
666
                                                                end
667
                                                        else
668
                                                                //if (dec_o_ea_ofs0)
669
                                                                        begin // no extra load...
670
                                                                                if ((dec_o_right_path_addr == `RN_MEM8) || (dec_o_right_path_addr == `RN_MEM16) ||
671
                                                                                        (dec_o_left_path_addr == `RN_MEM8))
672
                                                                                        begin
673
                                                                                                k_mem_dest <= `MEMDEST_MH; // operand land in k_memhi/lo
674
                                                                                                next_mem_state <= `SEQ_GRAL_ALU;
675
                                                                                                if (dec_o_alu_size)
676
                                                                                                        state <= `SEQ_MEM_READ_H;
677
                                                                                                else
678
                                                                                                        state <= `SEQ_MEM_READ_L;
679
                                                                                        end
680
                                                                                else
681
                                                                                        state <= `SEQ_GRAL_ALU; // no load, then store
682
                                                                        end
683
                                        end
684
                                `SEQ_IND_DECODE_OFS: // loads argument if needed
685
                                        begin
686
                                                if ((dec_o_right_path_addr == `RN_MEM8) || (dec_o_right_path_addr == `RN_MEM16) ||
687
                                                        (dec_o_left_path_addr == `RN_MEM8))
688
                                                        begin
689
                                                                k_mem_dest <= `MEMDEST_MH; // operand land in k_memhi/lo
690
                                                                next_mem_state <= `SEQ_GRAL_ALU;
691
                                                                if (dec_o_alu_size)
692
                                                                        state <= `SEQ_MEM_READ_H;
693
                                                                else
694
                                                                        state <= `SEQ_MEM_READ_L;
695
                                                        end
696
                                                else
697
                                                        state <= `SEQ_GRAL_ALU; // no load, then store
698
                                        end
699
                                `SEQ_JMP_LOAD_PC:
700
                                        begin
701
                                                case (dec_o_p1_mode)
702
                                                        `REL16:
703
                                                                begin
704
                                                                        k_new_pc <= regs_o_pc + { k_memhi,k_memlo };
705
                                                                        if (dec_o_cond_taken)
706
                                                                                k_write_pc <= 1;
707
                                                                end
708
                                                        `REL8:
709
                                                                begin
710
                                                                        k_new_pc <= regs_o_pc + { {8{k_memlo[7]}}, k_memlo };
711
                                                                        if (dec_o_cond_taken)
712
                                                                                k_write_pc <= 1;
713
                                                                end
714
                                                        `EXTENDED:
715
                                                                begin
716
                                                                        k_new_pc <= { k_eahi,k_ealo };
717
                                                                        k_write_pc <= 1;
718
                                                                end
719
                                                        `DIRECT:
720
                                                                begin
721
                                                                        k_new_pc <= { regs_o_dp, k_ealo };
722
                                                                        k_write_pc <= 1;
723
                                                                end
724
                                                        `INDEXED:
725
                                                                begin
726
                                                                        if (dec_o_ea_indirect)
727
                                                                                k_new_pc <= { k_memhi,k_memlo };
728
                                                                        else
729
                                                                                k_new_pc <= regs_o_eamem_addr;
730
                                                                        k_write_pc <= 1;
731
                                                                end
732
                                                endcase
733
                                                state <= `SEQ_FETCH;
734
 
735
                                        end
736
                                `SEQ_JSR_PUSH:
737
                                        begin
738
                                                k_pp_active_reg <= 8'h80; // push PC
739
                                                state <= `SEQ_PUSH_WRITE_L;
740
                                                next_state <= `SEQ_JMP_LOAD_PC;
741
                                        end
742
                                `SEQ_PREPUSH:
743
                                        begin
744
                                                next_state <= `SEQ_PREPUSH;
745
                                                if (k_pp_regs > 0)
746
                                                        state <= `SEQ_PUSH_WRITE_L;
747
                                                else
748
                                                        state <= next_push_state;
749
                                                if (k_pp_regs[7]) begin k_pp_regs[7] <= 0; k_pp_active_reg <= 8'h80; end
750
                                                else
751
                                                if (k_pp_regs[6]) begin k_pp_regs[6] <= 0; k_pp_active_reg <= 8'h40; end
752
                                                else
753
                                                if (k_pp_regs[5]) begin k_pp_regs[5] <= 0; k_pp_active_reg <= 8'h20; end
754
                                                else
755
                                                if (k_pp_regs[4]) begin k_pp_regs[4] <= 0; k_pp_active_reg <= 8'h10; end
756
                                                else
757
                                                if (k_pp_regs[3]) begin k_pp_regs[3] <= 0; k_pp_active_reg <= 8'h08; end
758
                                                else
759
                                                if (k_pp_regs[2]) begin k_pp_regs[2] <= 0; k_pp_active_reg <= 8'h04; end
760
                                                else
761
                                                if (k_pp_regs[1]) begin k_pp_regs[1] <= 0; k_pp_active_reg <= 8'h02; end
762
                                                else
763
                                                if (k_pp_regs[0]) begin k_pp_regs[0] <= 0; k_pp_active_reg <= 8'h01; end
764
                                        end
765
                                `SEQ_PREPULL:
766
                                        begin
767
                                                k_inc_su <= 1;
768
                                                k_mem_dest <= `MEMDEST_MH;
769
                                                next_mem_state <= `SEQ_PREPULL;
770
                                                if (k_pp_regs[0]) begin k_pp_active_reg <= 8'h01; k_pp_regs[0] <= 0; state <= `SEQ_MEM_READ_L; end
771
                                                else
772
                                                if (k_pp_regs[1]) begin k_pp_active_reg <= 8'h02; k_pp_regs[1] <= 0; state <= `SEQ_MEM_READ_L; end
773
                                                else
774
                                                if (k_pp_regs[2]) begin k_pp_active_reg <= 8'h04; k_pp_regs[2] <= 0; state <= `SEQ_MEM_READ_L; end
775
                                                else
776
                                                if (k_pp_regs[3]) begin k_pp_active_reg <= 8'h08; k_pp_regs[3] <= 0; state <= `SEQ_MEM_READ_L; end
777
                                                else
778
                                                if (k_pp_regs[4]) begin k_pp_active_reg <= 8'h10; k_pp_regs[4] <= 0; state <= `SEQ_MEM_READ_H;end
779
                                                else
780
                                                if (k_pp_regs[5]) begin k_pp_active_reg <= 8'h20; k_pp_regs[5] <= 0; state <= `SEQ_MEM_READ_H;end
781
                                                else
782
                                                if (k_pp_regs[6]) begin k_pp_active_reg <= 8'h40; k_pp_regs[6] <= 0; state <= `SEQ_MEM_READ_H; end
783
                                                else
784
                                                        begin
785
                                                                next_mem_state <= `SEQ_FETCH; // end of sequence
786
                                                                if (k_pp_regs[7]) begin k_pp_active_reg <= 8'h80;  k_pp_regs[7] <= 0; state <= `SEQ_MEM_READ_H; end
787
                                                        end
788
                                        end
789
                                `SEQ_PUSH_WRITE_L: // first low byte push 
790
                                        begin
791
                                                k_cpu_data_o <= regs_o_left_path_data[7:0];
792
                                                state <= `SEQ_PUSH_WRITE_L_1;
793
                                                k_cpu_we <= 1; // write
794
                                                k_cpu_addr <= regs_o_su;
795
                                                k_dec_su <= 1; // decrement stack pointer
796
                                        end
797
                                `SEQ_PUSH_WRITE_L_1:
798
                                        begin
799
                                                if (k_pp_active_reg[7:4] > 0)
800
                                                        state <= `SEQ_PUSH_WRITE_H;
801
                                                else
802
                                                        if (k_pp_regs[3:0] > 0)
803
                                                                state <= `SEQ_PREPUSH;
804
                                                        else
805
                                                                state <= next_push_state;
806
                                        end
807
                                `SEQ_PUSH_WRITE_H: // reads high byte
808
                                        begin
809
                                                k_cpu_data_o <= regs_o_left_path_data[15:8];
810
                                                state <= `SEQ_PUSH_WRITE_H_1;
811
                                                k_cpu_we <= 1; // write
812
                                                k_cpu_addr <= regs_o_su;
813
                                                k_dec_su <= 1; // decrement stack pointer
814
                                        end
815
                                `SEQ_PUSH_WRITE_H_1:
816
                                        begin
817
                                                state <= next_state;
818
                                        end
819
                                `SEQ_PC_READ_H: // reads high byte for [PC], used by IMM, DIR, EXT
820
                                        begin
821
                                                k_cpu_addr <= regs_o_pc;
822
                                                state <= `SEQ_PC_READ_H_1;
823
                                                k_inc_pc <= 1;
824
                                        end
825
                                `SEQ_PC_READ_H_1:
826
                                        begin
827
                                                k_cpu_oe <= 1; // read
828
                                                state <= `SEQ_PC_READ_H_2;
829
                                        end
830
                                `SEQ_PC_READ_H_2:
831
                                        begin
832
                                                case (dec_o_p1_mode)
833
                                                        `REL16, `IMMEDIATE: k_memhi <= cpu_data_i;
834
                                                        `EXTENDED: k_eahi <= cpu_data_i;
835
                                                        `INDEXED: k_ofshi <= cpu_data_i;
836
                                                endcase
837
                                                state <= `SEQ_PC_READ_L;
838
                                        end
839
                                `SEQ_PC_READ_L: // reads low byte [PC]
840
                                        begin
841
                                                k_cpu_addr <= regs_o_pc;
842
                                                state <= `SEQ_PC_READ_L_1;
843
                                                k_inc_pc <= 1;
844
                                        end
845
                                `SEQ_PC_READ_L_1:
846
                                        begin
847
                                                k_cpu_oe <= 1; // read
848
                                                state <= `SEQ_PC_READ_L_2;
849
                                        end
850
                                `SEQ_PC_READ_L_2:
851
                                        begin
852
                                                case (dec_o_p1_mode)
853
                                                        `NONE: k_pp_regs <= cpu_data_i; // push & pull
854
                                                        `REL8, `REL16, `IMMEDIATE: k_memlo <= cpu_data_i;
855
                                                        `DIRECT, `EXTENDED: k_ealo <= cpu_data_i;
856
                                                        `INDEXED: k_ofslo <= cpu_data_i;
857
                                                endcase
858
                                                state <= next_state;
859
                                        end
860
                                `SEQ_MEM_READ_H: // reads high byte
861
                                        begin
862
                                                case (dec_o_p1_mode)
863
                                                        `NONE: begin k_cpu_addr <= regs_o_su; k_inc_su <= 1; end // pull, rts, rti
864
                                                        `INDEXED: k_cpu_addr <= regs_o_eamem_addr;
865
                                                        default: k_cpu_addr <= { k_eahi, k_ealo };
866
                                                endcase
867
                                                state <= `SEQ_MEM_READ_H_1;
868
                                        end
869
                                `SEQ_MEM_READ_H_1:
870
                                        begin
871
                                                k_cpu_oe <= 1; // read
872
                                                state <= `SEQ_MEM_READ_H_2;
873
                                        end
874
                                `SEQ_MEM_READ_H_2:
875
                                        begin
876
                                                case (k_mem_dest)
877
                                                        `MEMDEST_PC: k_new_pc[15:8] <= cpu_data_i;
878
                                                        `MEMDEST_MH: k_memhi <= cpu_data_i;
879
                                                        `MEMDEST_AH: k_eahi <= cpu_data_i;
880
                                                endcase
881
                                                state <= `SEQ_MEM_READ_L_1;
882
                                                k_cpu_addr  <= k_cpu_addr + 16'h1;
883
                                        end
884
                                `SEQ_MEM_READ_L: // reads high byte
885
                                        begin
886
                                                case (dec_o_p1_mode)
887
                                                        `NONE: k_cpu_addr <= regs_o_su; // pull, rts, rti
888
                                                        `INDEXED: k_cpu_addr <= regs_o_eamem_addr;
889
                                                        default: k_cpu_addr <= { k_eahi, k_ealo };
890
                                                endcase
891
                                                state <= `SEQ_MEM_READ_L_1;
892
                                        end
893
                                `SEQ_MEM_READ_L_1:
894
                                        begin
895
                                                k_cpu_oe <= 1; // read
896
                                                state <= `SEQ_MEM_READ_L_2;
897
                                        end
898
                                `SEQ_MEM_READ_L_2:
899
                                        begin
900
                                                case (k_mem_dest)
901
                                                        `MEMDEST_PC: begin k_new_pc[7:0] <= cpu_data_i; k_write_pc <= 1; end
902
                                                        `MEMDEST_MH: k_memlo <= cpu_data_i;
903
                                                        `MEMDEST_AH: k_ealo <= cpu_data_i;
904
                                                endcase
905
                                                case (dec_o_p1_mode)
906
                                                        `NONE, `INHERENT: k_pull_reg_write <= 1; // pull, rts, rti
907
                                                endcase
908
                                                state <= next_mem_state;
909
                                        end
910
                                `SEQ_MEM_WRITE_H: // writes high byte
911
                                        begin
912
                                                case (dec_o_p1_mode)
913
                                                        `INDEXED: k_cpu_addr <= regs_o_eamem_addr;
914
                                                        default: k_cpu_addr <= { k_eahi, k_ealo };
915
                                                endcase
916
                                                k_cpu_data_o <= datamux_o_dest[7:0];
917
                                                state <= `SEQ_MEM_WRITE_H_1;
918
                                                k_cpu_we <= 1; // read
919
                                        end
920
                                `SEQ_MEM_WRITE_H_1:
921
                                        begin
922
                                                state <= `SEQ_MEM_WRITE_L;
923
                                                k_cpu_addr <= k_cpu_addr + 16'h1;
924
                                        end
925
                                `SEQ_MEM_WRITE_L: // reads high byte
926
                                        begin
927
                                                if (!dec_o_alu_size)
928
                                                        case (dec_o_p1_mode)
929
                                                                `INDEXED: k_cpu_addr <= regs_o_eamem_addr;
930
                                                                default: k_cpu_addr <= { k_eahi, k_ealo };
931
                                                        endcase
932
                                                k_cpu_data_o <= datamux_o_dest[7:0];
933
                                                state <= `SEQ_MEM_WRITE_L_1;
934
                                                k_cpu_we <= 1; // write
935
                                        end
936
                                `SEQ_MEM_WRITE_L_1:
937
                                        begin
938
                                                k_write_post_incdec <= dec_o_ea_wpost;
939
                                                state <= next_mem_state;
940
                                        end
941
 
942
                        endcase
943
                end
944
        end
945
 
946
initial
947
        begin
948
                k_cpu_oe = 0;
949
                k_cpu_we = 0;
950
                k_mem_dest = 0;
951
                k_new_pc = 16'hffff;
952
        end
953
endmodule

powered by: WebSVN 2.1.0

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