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 14

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

powered by: WebSVN 2.1.0

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