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 10

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

powered by: WebSVN 2.1.0

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