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 12

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 [2:0] dec_o_p1_optype; // k_opcode type
53
wire dec_o_use_s; // signals when S should be used instead of U
54 7 ale500
wire dec_o_alu_size; /* size of the result of an alu opcode (destination to be written) */
55 2 ale500
/* ea decoder */
56
wire dec_o_ea_ofs8, dec_o_ea_ofs16, dec_o_ea_wpost, dec_o_ea_ofs0, dec_o_ea_indirect;
57
/* alu k_opcode decoder */
58
wire [4:0] dec_o_alu_opcode;
59
wire [1:0] dec_o_right_path_mod; /* Modifier for alu's right path input */
60
/* register decoder */
61 4 ale500
wire dec_o_wdest, dec_o_source_size, dec_o_write_flags;
62 2 ale500
wire [3:0] dec_o_left_path_addr, dec_o_right_path_addr, dec_o_dest_reg_addr;
63 11 ale500
// latched versions, used for muxes, regs and alu
64
wire [3:0] dec_lo_left_path_addr, dec_lo_right_path_addr, dec_lo_dest_reg_addr;
65 2 ale500
/* test condition */
66
wire dec_o_cond_taken;
67
/* ALU outputs */
68
wire [15:0] alu_o_result;
69
wire [7:0] alu_o_CCR;
70 6 ale500
wire [7:0] alu8_o_result;
71
wire [7:0] alu8_o_CCR;
72 2 ale500
/* 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
        .optype(dec_o_p1_optype),
187
        .use_s(dec_o_use_s)
188
        );
189
 
190
decode_ea dec_ea(
191
        .eapostbyte( k_ind_ea ),
192
        .noofs(dec_o_ea_ofs0),
193
        .ofs8(dec_o_ea_ofs8),
194
        .ofs16(dec_o_ea_ofs16),
195
        .write_post(dec_o_ea_wpost),
196
        .isind(dec_o_ea_indirect)
197
        );
198
 
199
/* Opcodes for the ALU are decoded here
200
 * Write Flags are also decoded here
201
 */
202
decode_alu dec_alu(
203
        .opcode(k_opcode),
204 5 ale500
        .postbyte0(k_postbyte),
205 2 ale500
        .page2_valid(k_p2_valid),
206
        .page3_valid(k_p3_valid),
207
        .alu_opcode(dec_o_alu_opcode),
208
        .dec_alu_right_path_mod(dec_o_right_path_mod),
209
        .dest_flags(dec_o_write_flags)
210
        );
211
/* Condition decoder */
212
test_condition test_cond(
213
        .opcode(k_opcode),
214 5 ale500
        .postbyte0(k_postbyte),
215 2 ale500
        .page2_valid(k_p2_valid),
216
        .CCR(regs_o_CCR),
217
        .cond_taken(dec_o_cond_taken)
218
        );
219
 
220
/* Module IO */
221
 
222
assign cpu_oe_o = k_cpu_oe; // we latch on the rising edge
223
assign cpu_we_o = k_cpu_we;
224
assign cpu_addr_o = k_cpu_addr;
225
assign cpu_data_o = k_cpu_data_o;
226
assign k_reset = cpu_reset;
227
assign cpu_state_o = state;
228
 
229
 
230
/* Left Register read mux
231
 */
232
always @(*)
233 6 ale500
        begin
234
                if (k_pp_active_reg != `RN_INV)
235
                        datamux_o_alu_in_left_path_addr = k_pp_active_reg;
236
                else
237 11 ale500
                        datamux_o_alu_in_left_path_addr = dec_lo_left_path_addr;
238 2 ale500
        end
239
 
240
/* Destination register address MUX
241
 */
242
always @(*)
243 6 ale500
        begin
244
                if (k_pp_active_reg != `RN_INV)
245
                        datamux_o_dest_reg_addr = k_pp_active_reg;
246
                else
247 11 ale500
                        datamux_o_dest_reg_addr = dec_lo_dest_reg_addr;
248 2 ale500
        end
249
 
250
/* Destination register data mux
251
 * selects the source to write to register. 16 bit registers have to be written at once after reading the low byte
252
 *
253
 */
254
always @(*)
255
        begin
256
                datamux_o_dest = alu_o_result;
257
                case (dec_o_p1_optype)
258
                        `OP_PULL, `OP_RTS: // destination register
259
                                datamux_o_dest = { k_memhi, k_memlo };
260
                        `OP_LEA:
261 4 ale500
                                if (dec_o_ea_indirect)// & dec_o_alu_size)
262 2 ale500
                                        datamux_o_dest = { k_memhi, k_memlo };
263
                                else
264
                                        datamux_o_dest = regs_o_eamem_addr;
265
                endcase
266
        end
267
 
268
/* ALU left input mux */
269
 
270
always @(*)
271
        begin
272 11 ale500
                if (dec_lo_left_path_addr == `RN_MEM8)
273 2 ale500
                        datamux_o_alu_in_left_path_data = { k_memhi, k_memlo };
274
                else
275 4 ale500
                case (dec_o_p1_optype)
276
                        `OP_LEA:
277
                                if (dec_o_ea_indirect)// & dec_o_alu_size)
278
                                        datamux_o_alu_in_left_path_data = { k_memhi, k_memlo };
279
                                else
280
                                        datamux_o_alu_in_left_path_data = regs_o_eamem_addr;
281
                        default:
282 2 ale500
                                datamux_o_alu_in_left_path_data = regs_o_left_path_data;
283 4 ale500
                endcase
284
        end
285
/* PC as destination from jmp/bsr mux */
286
always @(*)
287
        begin
288
                k_new_pc = { k_memhi,k_memlo }; // used to fetch reset vector
289 10 ale500
                if (k_mem_dest != `MEMDEST_PC)
290
                        begin
291
                                case (dec_o_p1_mode)
292
                                        `REL16: k_new_pc = regs_o_pc + { k_memhi,k_memlo };
293
                                        `REL8: k_new_pc = regs_o_pc + { {8{k_memlo[7]}}, k_memlo };
294
                                        `EXTENDED: k_new_pc = { k_eahi,k_ealo };
295
                                        `DIRECT: k_new_pc = { regs_o_dp, k_ealo };
296
                                        `INDEXED:
297
                                                if (dec_o_ea_indirect)
298
                                                        k_new_pc = { k_memhi,k_memlo };
299
                                                else
300
                                                        k_new_pc = regs_o_eamem_addr;
301
                                endcase
302
                        end
303 2 ale500
        end
304
/* ALU right input mux */
305
always @(*)
306
        begin
307 11 ale500
                case (dec_lo_right_path_addr)
308 2 ale500
                        `RN_MEM8:
309
                                datamux_o_alu_in_right_path_data = { 8'h00, k_memlo };
310
                        `RN_MEM16:
311
                                datamux_o_alu_in_right_path_data = { k_memhi, k_memlo };
312
                        `RN_IMM8:
313
                                datamux_o_alu_in_right_path_data = { 8'h0, k_memlo };
314
                        `RN_IMM16:
315
                                datamux_o_alu_in_right_path_data = { k_memhi, k_memlo };
316
                        default:
317
                                case (dec_o_right_path_mod)
318
                                        `MOD_DEFAULT: datamux_o_alu_in_right_path_data = regs_o_right_path_data;
319
                                        `MOD_ONE: datamux_o_alu_in_right_path_data = 16'h0001;
320
                                        `MOD_ZERO: datamux_o_alu_in_right_path_data = 16'h0000;
321
                                        `MOD_MINUS1: datamux_o_alu_in_right_path_data = 16'hffff;
322
                                endcase
323
                endcase
324
        end
325
 
326 6 ale500
always @(posedge cpu_clk or posedge k_reset)
327 2 ale500
        begin
328
                if (k_reset == 1'b1)
329
                        begin
330
                                state <= `SEQ_COLDRESET;
331
                                k_reg_nmi <= 0;
332
                                k_reg_firq <= 0;
333
                                k_reg_irq <= 0;
334
                        end
335
                else
336
                        begin
337
                                /* Inrerrupt recognition and acknowledge */
338
                                if (!k_reg_nmi[2])
339
                                        k_reg_nmi <= { k_reg_nmi[1:0], cpu_nmi_n };
340
                                if (!k_reg_irq[2])
341
                                        k_reg_irq <= { k_reg_irq[1:0], cpu_irq_n };
342
                                if (!k_reg_firq[2])
343
                                        k_reg_firq <= { k_reg_firq[1:0], cpu_firq_n };
344
                                /* modifier registers */
345
                                if (k_inc_pc)
346
                                        k_inc_pc <= 0;
347
                                if (k_write_pc)
348
                                        k_write_pc <= 0;
349
                                if (k_cpu_we)
350
                                        k_cpu_we <= 0;
351
                                if (k_cpu_oe)
352
                                        k_cpu_oe <= 0;
353
                                if (k_write_post_incdec)
354
                                        k_write_post_incdec <= 0;
355
                                if (k_dec_su)
356
                                        k_dec_su <= 0;
357
                                if (k_inc_su)
358
                                        k_inc_su <= 0;
359
                                if (k_set_e)
360
                                        k_set_e <= 0;
361
                                if (k_clear_e)
362 4 ale500
                                        k_clear_e <= 0;
363
                                if (k_write_dest)
364 5 ale500
                                        k_write_dest <= 0;
365
                                if (k_write_exg)
366
                                        k_write_exg <= 0;
367
                                if (k_write_tfr)
368
                                        k_write_tfr <= 0;
369 2 ale500
                        case (state)
370
                                `SEQ_COLDRESET:
371 4 ale500
                                        begin
372
                                                k_forced_mem_size <= 1;
373 2 ale500
                                                state <= `SEQ_MEM_READ_H;
374
                                                k_eahi <= 8'hff;
375
                                                k_ealo <= 8'hfe;
376 10 ale500
                                                next_mem_state <= `SEQ_LOADPC;
377
                                                k_mem_dest <= `MEMDEST_PC;
378 2 ale500
                                        end
379
                                `SEQ_NMI:
380
                                        begin
381 4 ale500
                                                k_forced_mem_size <= 1;
382 7 ale500
                                                k_reg_nmi <= 3'h0;
383 2 ale500
                                                { k_eahi, k_ealo } <= 16'hfffc;
384
                                                k_pp_regs <= 8'hff;
385
                                                k_set_e <= 1;
386
                                                state <= `SEQ_PREPUSH; // first stack the registers
387
                                                next_push_state <= `SEQ_MEM_READ_H; // than load new PC
388
                                                next_mem_state <= `SEQ_FETCH; // than continue fetching instructions
389
                                        end
390
                                `SEQ_SWI:
391
                                        begin
392 4 ale500
                                                k_forced_mem_size <= 1;
393 2 ale500
                                                state <= `SEQ_MEM_READ_H;
394
                                                { k_eahi, k_ealo } <= 16'hfffa;
395
                                                k_pp_regs <= 8'hff;
396
                                                state <= `SEQ_PREPUSH; // first stack the registers
397
                                                next_push_state <= `SEQ_MEM_READ_H; // than load new PC
398
                                                next_mem_state <= `SEQ_FETCH; // than continue fetching instructions
399
                                                k_set_e <= 1;
400
                                        end
401
                                `SEQ_IRQ:
402
                                        begin
403 4 ale500
                                                k_forced_mem_size <= 1;
404 7 ale500
                                                k_reg_irq <= 3'h0;
405 2 ale500
                                                state <= `SEQ_MEM_READ_H;
406
                                                { k_eahi, k_ealo } <= 16'hfff8;
407
                                                k_pp_regs <= 8'hff;
408
                                                next_mem_state <= `SEQ_PREPUSH;
409
                                                k_set_e <= 1;
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
                                        end
414
                                `SEQ_FIRQ:
415
                                        begin
416 4 ale500
                                                k_forced_mem_size <= 1;
417 7 ale500
                                                k_reg_firq <= 3'h0;
418 2 ale500
                                                { k_eahi, k_ealo } <= 16'hfff6;
419
                                                k_pp_regs <= 8'h81; // PC & CC
420
                                                k_clear_e <= 1;
421
                                                state <= `SEQ_PREPUSH; // first stack the registers
422
                                                next_push_state <= `SEQ_MEM_READ_H; // than load new PC
423
                                                next_mem_state <= `SEQ_FETCH; // than continue fetching instructions
424
                                        end
425
                                `SEQ_SWI2:
426
                                        begin
427 4 ale500
                                                k_forced_mem_size <= 1;
428 2 ale500
                                                { k_eahi, k_ealo } <= 16'hfff4;
429
                                                k_pp_regs <= 8'hff;
430
                                                k_set_e <= 1;
431
                                                state <= `SEQ_PREPUSH; // first stack the registers
432
                                                next_push_state <= `SEQ_MEM_READ_H; // than load new PC
433
                                                next_mem_state <= `SEQ_FETCH; // than continue fetching instructions
434
                                        end
435
                                `SEQ_SWI3:
436
                                        begin
437 4 ale500
                                                k_forced_mem_size <= 1;
438 2 ale500
                                                { k_eahi, k_ealo } <= 16'hfff2;
439
                                                k_pp_regs <= 8'hff;
440
                                                k_set_e <= 1;
441
                                                state <= `SEQ_PREPUSH; // first stack the registers
442
                                                next_push_state <= `SEQ_MEM_READ_H; // than load new PC
443
                                                next_mem_state <= `SEQ_FETCH; // than continue fetching instructions
444
                                        end
445
                                `SEQ_UNDEF:
446
                                        begin
447 4 ale500
                                                k_forced_mem_size <= 1;
448 2 ale500
                                                { k_eahi, k_ealo } <= 16'hfff0;
449
                                                k_pp_regs <= 8'hff;
450
                                                k_set_e <= 1;
451
                                                state <= `SEQ_PREPUSH; // first stack the registers
452
                                                next_push_state <= `SEQ_MEM_READ_H; // than load new PC
453
                                                next_mem_state <= `SEQ_FETCH; // than continue fetching instructions
454
                                        end
455
                                `SEQ_LOADPC: /* loads the PC with the address taken from the reset vector */
456
                                        begin
457
                                                $display("cpu_data_i %02x %t", cpu_data_i, $time);
458 10 ale500
                                                state <= `SEQ_FETCH;
459
                                                k_mem_dest <= `MEMDEST_MH; // operand to memlo/memhi
460 2 ale500
                                        end
461
                                `SEQ_FETCH: /* execution starts here */
462
                                        begin
463
                                                if (k_nmi_req)
464
                                                        state <= `SEQ_NMI;
465
                                                else
466 7 ale500
                                                if (k_firq_req & `FLAGF)
467 2 ale500
                                                        state <= `SEQ_FIRQ;
468
                                                else
469 7 ale500
                                                if (k_irq_req & `FLAGI)
470 2 ale500
                                                        state <= `SEQ_IRQ;
471
                                                else
472
                                                        begin
473
                                                                state <= `SEQ_FETCH_1;
474
                                                                k_cpu_addr <= regs_o_pc;
475
                                                        end
476
                                        end
477
                                `SEQ_FETCH_1:
478
                                        begin
479
                                                k_cpu_oe <= 1;
480 6 ale500
                                                k_inc_pc <= 1;
481
                                                k_p2_valid <= 0; // set when an k_opcode is page 2
482
                                                k_p3_valid <= 0; // set when an k_opcode is page 3
483
                                                k_pp_active_reg <= `RN_INV; // ensures that only push/pull control the left/dest muxes
484
                                                state <= `SEQ_FETCH_2;
485 2 ale500
                                        end
486
                                `SEQ_FETCH_2:
487
                                        begin
488
                                                k_opcode <= cpu_data_i;
489
                                                case (cpu_data_i[7:0]) /* page 2 & 3 opcodes are recognized here */
490
                                                        8'h10:
491
                                                                begin
492
                                                                        k_p2_valid <= 1;
493
                                                                        state <= `SEQ_FETCH_3;
494
                                                                end
495
                                                        8'h11:
496 6 ale500
                                                                begin
497 7 ale500
                                                                        k_p3_valid <= 1;
498
                                                                        state <= `SEQ_FETCH_3;
499 6 ale500
                                                                end
500 5 ale500
                                                        8'h1e, 8'h1f:
501 6 ale500
                                                                state <= `SEQ_FETCH_3; // tfr, exg, treated separately
502 2 ale500
                                                        default:
503
                                                                state <= `SEQ_DECODE;
504
                                                endcase
505
                                        end
506
                                `SEQ_FETCH_3:
507
                                        begin
508
                                                state <= `SEQ_FETCH_4;
509
                                                k_cpu_addr <= regs_o_pc;
510
                                        end
511
                                `SEQ_FETCH_4:
512
                                        begin
513
                                                k_cpu_oe <= 1;
514
                                                state <= `SEQ_FETCH_5;
515
                                        end
516
                                `SEQ_FETCH_5: /* fetches a page 2 or 3 opcode */
517
                                        begin
518 5 ale500
                                                k_postbyte <= cpu_data_i;
519 2 ale500
                                                k_inc_pc <= 1;
520
                                                state <= `SEQ_DECODE_P23;
521
                                        end
522
                                `SEQ_DECODE:
523
                                        begin
524 10 ale500
                                                /* here we have the first byte of the opcode and should be decided to which state we jump
525 2 ale500
                                                 * inherent means that no extra info is needed
526
                                                 * ALU opcodes need routing of registers to/from the ALU to the registers
527
                                                 */
528
                                                case (dec_o_p1_mode)
529 10 ale500
                                                        `NONE: // unknown opcode or push/pull... refetch ?
530 2 ale500
                                                                begin
531 6 ale500
                                                                        casex (k_opcode)
532
                                                                                8'h13: state <= `SEQ_SYNC;
533 2 ale500
                                                                                8'h39: // RTS
534 4 ale500
                                                                                        begin
535 2 ale500
                                                                                                state <= `SEQ_PREPULL;
536
                                                                                                k_pp_regs <= 8'h80; // Pull PC (RTS)all regs
537
                                                                                        end
538
                                                                                8'b001101x0: // PUSH S&U
539
                                                                                        begin
540
                                                                                                state <= `SEQ_PC_READ_L;
541
                                                                                                next_state <= `SEQ_PREPUSH;
542
                                                                                                next_push_state <= `SEQ_FETCH;
543
                                                                                        end
544
                                                                                8'b001101x1: // PULL S&U
545
                                                                                        begin
546
                                                                                                next_state <= `SEQ_PREPULL;
547
                                                                                                state <= `SEQ_PC_READ_L;
548
                                                                                        end
549 6 ale500
                                                                                8'h3B: // RTI
550
                                                                                        begin
551
                                                                                                state <= `SEQ_PREPULL;
552
                                                                                                k_pp_regs <= 8'hff; // all regs
553
                                                                                        end
554 2 ale500
                                                                                default: /* we ignore unknown opcodes */
555
                                                                                        state <= `SEQ_FETCH;
556
                                                                        endcase
557
                                                                end
558
                                                        `IMMEDIATE:     // 8 or 16 bits as result decides..
559
                                                                begin
560
                                                                        if (dec_o_alu_size)
561
                                                                                state <= `SEQ_PC_READ_H;
562
                                                                        else
563
                                                                                state <= `SEQ_PC_READ_L;
564
                                                                        next_state <= `SEQ_GRAL_ALU;
565
                                                                end
566
                                                        `INHERENT:
567
                                                                begin
568 6 ale500
                                                                        case (k_opcode)
569
                                                                                8'h3d: begin k_mul_cnt <= 1'h1; state <= `SEQ_GRAL_ALU; end // counter for mul
570 2 ale500
                                                                                8'h3f: state <= `SEQ_SWI;
571
                                                                                        default: state <= `SEQ_GRAL_ALU;
572
                                                                        endcase
573
                                                                end
574
                                                        `DIRECT:
575
                                                                begin
576 10 ale500
                                                                        state <= `SEQ_PC_READ_L; // loads address
577 12 ale500
                                                                        case (dec_o_p1_optype)
578
                                                                                `OP_JSR: next_state <= `SEQ_JSR_PUSH;
579
                                                                                `OP_JMP: next_state <= `SEQ_JMP_LOAD_PC;
580
                                                                                default:
581
                                                                                        begin
582
                                                                                                k_mem_dest <= `MEMDEST_MH; // operand to memlo/memhi
583
                                                                                                if ((dec_o_right_path_addr == `RN_MEM8) || (dec_o_right_path_addr == `RN_MEM16) ||
584
                                                                                                        (dec_o_left_path_addr == `RN_MEM8))
585
                                                                                                        begin
586
                                                                                                                next_state <= `SEQ_MEM_READ_H;
587
                                                                                                                next_mem_state <= `SEQ_GRAL_ALU; // read then alu
588
                                                                                                        end
589
                                                                                                else
590
                                                                                                        next_state <= `SEQ_GRAL_ALU; // no read
591
                                                                                                k_eahi <= regs_o_dp;
592
                                                                                        end
593
                                                                        endcase
594 2 ale500
                                                                end
595
                                                        `INDEXED:
596
                                                                state <= `SEQ_IND_READ_EA;
597
                                                        `EXTENDED:
598 10 ale500
                                                                begin
599 2 ale500
                                                                        state <= `SEQ_PC_READ_H; // loads address
600 12 ale500
                                                                        case (dec_o_p1_optype)
601
                                                                                `OP_JSR: next_state <= `SEQ_JSR_PUSH;
602
                                                                                `OP_JMP: next_state <= `SEQ_JMP_LOAD_PC;
603
                                                                                default:
604
                                                                                        begin
605
                                                                                                k_mem_dest <= `MEMDEST_MH; // operand to memlo/memhi
606
                                                                                                if ((dec_o_right_path_addr == `RN_MEM8) || (dec_o_right_path_addr == `RN_MEM16) ||
607
                                                                                                        (dec_o_left_path_addr == `RN_MEM8))
608
                                                                                                        begin
609
                                                                                                                next_state <= `SEQ_MEM_READ_H;
610
                                                                                                                next_mem_state <= `SEQ_GRAL_ALU; // read then alu
611
                                                                                                        end
612
                                                                                                else
613
                                                                                                        next_state <= `SEQ_GRAL_ALU; // no read
614
                                                                                        end
615
                                                                        endcase
616 2 ale500
                                                                end
617
                                                        `REL8:
618
                                                                begin
619
                                                                        state <= `SEQ_PC_READ_L; // loads address
620
                                                                        if (dec_o_p1_optype == `OP_JSR) // bsr
621
                                                                                next_state <= `SEQ_JSR_PUSH;
622
                                                                        else
623
                                                                                next_state <= `SEQ_JMP_LOAD_PC; // offset loaded in this cycle, jump if needed
624
                                                                end
625
                                                        `REL16:
626
                                                                begin
627
                                                                        state <= `SEQ_PC_READ_H; // loads address
628
                                                                        if (dec_o_p1_optype == `OP_JSR) // lbsr
629
                                                                                next_state <= `SEQ_JSR_PUSH;
630
                                                                        else
631
                                                                                next_state <= `SEQ_JMP_LOAD_PC;
632
                                                                end
633
                                                endcase
634
                                        end
635
                                `SEQ_DECODE_P23:
636
                                        begin // has prefix 10 or 11
637
                                                case (dec_o_p1_mode)
638
                                                        `NONE: // unknown k_opcode... re-fetch ?
639
                                                                state <= `SEQ_FETCH;
640
                                                        `IMMEDIATE:     // 8 or 16 bits as result decides..
641 5 ale500
                                                                begin
642
                                                                        case (k_opcode)
643
                                                                                8'h1e: begin k_write_exg <= 1; state <= `SEQ_TFREXG; end
644
                                                                                8'h1f: begin k_write_tfr <= 1; state <= `SEQ_TFREXG; end
645
                                                                                default:
646
                                                                                        begin
647
                                                                                                next_state <= `SEQ_GRAL_ALU;
648
                                                                                                if (dec_o_alu_size)
649
                                                                                                        state <= `SEQ_PC_READ_H;
650
                                                                                                else
651
                                                                                                        state <= `SEQ_PC_READ_L;
652
                                                                                end
653
                                                                        endcase
654 2 ale500
                                                                end
655
                                                        `INHERENT:
656
                                                                case (k_opcode)
657
                                                                        8'h3f: if (k_p2_valid) state <= `SEQ_SWI2;
658
                                                                                   else state <= `SEQ_SWI3;
659
                                                                        default: state <= `SEQ_GRAL_ALU;
660
                                                                endcase
661
                                                        `DIRECT:
662
                                                                begin
663
                                                                        state <= `SEQ_PC_READ_L;
664
                                                                        k_mem_dest <= `MEMDEST_MH; // operand to memlo/memhi
665
                                                                        if ((dec_o_right_path_addr == `RN_MEM8) || (dec_o_right_path_addr == `RN_MEM16) ||
666
                                                                                (dec_o_left_path_addr == `RN_MEM8))
667
                                                                                begin
668 4 ale500
                                                                                        next_state <= `SEQ_MEM_READ_H;
669 2 ale500
                                                                                        next_mem_state <= `SEQ_GRAL_ALU; // read then alu
670
                                                                                end
671
                                                                        else
672
                                                                                next_state <= `SEQ_GRAL_ALU; // no read
673
                                                                        k_eahi <= regs_o_dp;
674
                                                                end
675
                                                        `INDEXED:
676
                                                                state <= `SEQ_IND_READ_EA;
677
                                                        `EXTENDED:
678
                                                                begin
679
                                                                        state <= `SEQ_PC_READ_H; // loads address
680
                                                                        k_mem_dest <= `MEMDEST_MH; // operand to memlo/memhi
681
                                                                        if ((dec_o_right_path_addr == `RN_MEM8) || (dec_o_right_path_addr == `RN_MEM16) ||
682
                                                                                (dec_o_left_path_addr == `RN_MEM8))
683
                                                                                begin
684 4 ale500
                                                                                        next_state <= `SEQ_MEM_READ_H;
685 2 ale500
                                                                                        next_mem_state <= `SEQ_GRAL_ALU; // read then alu
686
                                                                                end
687
                                                                        else
688
                                                                                next_state <= `SEQ_GRAL_ALU; // no read
689
                                                                end
690
                                                        `REL16:
691
                                                                begin // long branches only
692
                                                                        state <= `SEQ_PC_READ_H; // loads address
693
                                                                        next_state <= `SEQ_JMP_LOAD_PC;
694
                                                                end
695
                                                endcase
696
                                        end
697 4 ale500
                                `SEQ_GRAL_ALU:
698 6 ale500
                                        begin
699
                                                if (!k_mul_cnt)
700
                                                        begin
701
                                                                state <= `SEQ_GRAL_WBACK;
702
                                                                k_write_dest <= 1; /* write destination on wback */
703
                                                        end
704 7 ale500
                                                k_mul_cnt <= 1'h0;
705 4 ale500
                                        end
706 2 ale500
                                `SEQ_GRAL_WBACK:
707
                                        begin
708 4 ale500
                                                next_mem_state <= `SEQ_FETCH;
709 6 ale500
                                                casex (k_opcode)
710
                                                        8'h3C: state <= `SEQ_CWAI_STACK; // CWAI
711
                                                        default:
712
                                                                case (dec_o_dest_reg_addr)
713
                                                                        `RN_MEM8: state <= `SEQ_MEM_WRITE_L;
714
                                                                        `RN_MEM16: state <= `SEQ_MEM_WRITE_H;
715
                                                                        default:
716
                                                                                begin
717
                                                                                        state <= `SEQ_FETCH;
718 12 ale500
                                                                                        k_write_post_incdec <= dec_o_ea_wpost & (dec_o_p1_mode == `INDEXED);
719 6 ale500
                                                                                end
720
                                                                endcase
721 2 ale500
                                                endcase
722
                                        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 10 ale500
                                                                if (dec_o_p1_optype == `OP_JSR) // jsr
836
                                                                        begin
837
                                                                                next_state <= `SEQ_JSR_PUSH;
838
                                                                        end
839
                                                                else
840 2 ale500
                                                                        begin // no extra load...
841
                                                                                if ((dec_o_right_path_addr == `RN_MEM8) || (dec_o_right_path_addr == `RN_MEM16) ||
842
                                                                                        (dec_o_left_path_addr == `RN_MEM8))
843
                                                                                        begin
844 12 ale500
                                                                                                k_mem_dest <= `MEMDEST_MH; // operand lands in k_memhi/lo
845 2 ale500
                                                                                                next_mem_state <= `SEQ_GRAL_ALU;
846 4 ale500
                                                                                                state <= `SEQ_MEM_READ_H;
847 12 ale500
                                                                                                if (dec_o_ea_indirect)
848
                                                                                                        k_forced_mem_size <= 1; // to load indirect address
849 2 ale500
                                                                                        end
850
                                                                                else
851
                                                                                        state <= `SEQ_GRAL_ALU; // no load, then store
852
                                                                        end
853
                                        end
854
                                `SEQ_IND_DECODE_OFS: // loads argument if needed
855 10 ale500
                                        begin
856
                                                if (dec_o_p1_optype == `OP_JSR) // jsr
857 2 ale500
                                                        begin
858 10 ale500
                                                                next_state <= `SEQ_JSR_PUSH;
859 2 ale500
                                                        end
860
                                                else
861 10 ale500
                                                        begin
862
                                                                if ((dec_o_right_path_addr == `RN_MEM8) || (dec_o_right_path_addr == `RN_MEM16) ||
863
                                                                        (dec_o_left_path_addr == `RN_MEM8))
864
                                                                        begin
865
                                                                                k_mem_dest <= `MEMDEST_MH; // operand land in k_memhi/lo
866
                                                                                next_mem_state <= `SEQ_GRAL_ALU;
867
                                                                                state <= `SEQ_MEM_READ_H;
868 12 ale500
                                                                                if (dec_o_ea_indirect)
869
                                                                                        k_forced_mem_size <= 1; // to load indirect address
870 10 ale500
                                                                        end
871
                                                                else
872
                                                                        state <= `SEQ_GRAL_ALU; // no load, then store
873
                                                        end
874 2 ale500
                                        end
875
                                `SEQ_JMP_LOAD_PC:
876
                                        begin
877
                                                state <= `SEQ_FETCH;
878
                                        end
879
                                `SEQ_JSR_PUSH:
880
                                        begin
881 9 ale500
                                                k_pp_active_reg <= `RN_PC; // push PC
882 2 ale500
                                                state <= `SEQ_PUSH_WRITE_L;
883
                                                next_state <= `SEQ_JMP_LOAD_PC;
884
                                        end
885
                                `SEQ_PREPUSH:
886
                                        begin
887
                                                next_state <= `SEQ_PREPUSH;
888 4 ale500
                                                if (k_pp_regs > 0)
889
                                                        begin
890
                                                                state <= `SEQ_PUSH_WRITE_L;
891
                                                        end
892 2 ale500
                                                else
893
                                                        state <= next_push_state;
894 6 ale500
                                                if (k_pp_regs[7]) begin k_pp_regs[7] <= 0; k_pp_active_reg <= `RN_PC; end
895 2 ale500
                                                else
896 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
897 2 ale500
                                                else
898 6 ale500
                                                if (k_pp_regs[5]) begin k_pp_regs[5] <= 0; k_pp_active_reg <= `RN_IY; end
899 2 ale500
                                                else
900 6 ale500
                                                if (k_pp_regs[4]) begin k_pp_regs[4] <= 0; k_pp_active_reg <= `RN_IX; end
901 2 ale500
                                                else
902 6 ale500
                                                if (k_pp_regs[3]) begin k_pp_regs[3] <= 0; k_pp_active_reg <= `RN_DP; end
903 2 ale500
                                                else
904 6 ale500
                                                if (k_pp_regs[2]) begin k_pp_regs[2] <= 0; k_pp_active_reg <= `RN_ACCB; end
905 2 ale500
                                                else
906 6 ale500
                                                if (k_pp_regs[1]) begin k_pp_regs[1] <= 0; k_pp_active_reg <= `RN_ACCA; end
907 2 ale500
                                                else
908 6 ale500
                                                if (k_pp_regs[0]) begin k_pp_regs[0] <= 0; k_pp_active_reg <= `RN_CC; end
909 2 ale500
                                        end
910
                                `SEQ_PREPULL:
911 4 ale500
                                        begin
912
                                                if (k_pp_regs != 8'h0)
913
                                                        begin
914
                                                                k_mem_dest <= `MEMDEST_MH;
915
                                                                next_mem_state <= `SEQ_PREPULL;
916
                                                        end
917
                                                else
918
                                                        state <= `SEQ_FETCH; // end of sequence
919 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
920 9 ale500
                                                else
921
                                                if ((k_opcode == 8'h3B) && (!`FLAGE)) // not all registers have to be pulled
922
                                                        begin
923
                                                                k_pp_active_reg <= `RN_PC;  k_pp_regs <= 0; state <= `SEQ_MEM_READ_H;
924
                                                        end
925 2 ale500
                                                else
926 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
927 2 ale500
                                                else
928 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
929 2 ale500
                                                else
930 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
931 2 ale500
                                                else
932 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
933 2 ale500
                                                else
934 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
935 2 ale500
                                                else
936 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
937 2 ale500
                                                else
938 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
939 2 ale500
                                        end
940
                                `SEQ_PUSH_WRITE_L: // first low byte push 
941
                                        begin
942
                                                k_cpu_data_o <= regs_o_left_path_data[7:0];
943
                                                state <= `SEQ_PUSH_WRITE_L_1;
944
                                                k_cpu_we <= 1; // write
945 4 ale500
                                                k_cpu_addr <= regs_o_su - 16'h1;
946
                                                k_dec_su <= 1;
947 2 ale500
                                        end
948
                                `SEQ_PUSH_WRITE_L_1:
949
                                        begin
950 6 ale500
                                                if (k_pp_active_reg < `RN_ACCA)
951 2 ale500
                                                        state <= `SEQ_PUSH_WRITE_H;
952
                                                else
953
                                                        if (k_pp_regs[3:0] > 0)
954
                                                                state <= `SEQ_PREPUSH;
955
                                                        else
956 4 ale500
                                                                state <= next_push_state;
957
                                                k_cpu_addr <= k_cpu_addr - 16'h1; // when pushing 16 bits the second decrement comes too late 
958 2 ale500
                                        end
959
                                `SEQ_PUSH_WRITE_H: // reads high byte
960
                                        begin
961
                                                k_cpu_data_o <= regs_o_left_path_data[15:8];
962
                                                state <= `SEQ_PUSH_WRITE_H_1;
963 4 ale500
                                                k_cpu_we <= 1; // write
964 6 ale500
                                                if (k_pp_active_reg >= `RN_ACCA)
965
                                                        k_cpu_addr <= regs_o_su; // address for 8 bit register
966 2 ale500
                                                k_dec_su <= 1; // decrement stack pointer
967
                                        end
968
                                `SEQ_PUSH_WRITE_H_1:
969 4 ale500
                                        begin
970
                                                if (next_state == `SEQ_JMP_LOAD_PC)
971
                                                        k_write_pc <= 1; // load PC in the next cycle, the mux output will have the right source
972 2 ale500
                                                state <= next_state;
973
                                        end
974
                                `SEQ_PC_READ_H: // reads high byte for [PC], used by IMM, DIR, EXT
975
                                        begin
976
                                                k_cpu_addr <= regs_o_pc;
977
                                                state <= `SEQ_PC_READ_H_1;
978
                                                k_inc_pc <= 1;
979
                                        end
980
                                `SEQ_PC_READ_H_1:
981
                                        begin
982
                                                k_cpu_oe <= 1; // read
983
                                                state <= `SEQ_PC_READ_H_2;
984
                                        end
985
                                `SEQ_PC_READ_H_2:
986
                                        begin
987
                                                case (dec_o_p1_mode)
988
                                                        `REL16, `IMMEDIATE: k_memhi <= cpu_data_i;
989
                                                        `EXTENDED: k_eahi <= cpu_data_i;
990
                                                        `INDEXED: k_ofshi <= cpu_data_i;
991
                                                endcase
992
                                                state <= `SEQ_PC_READ_L;
993
                                        end
994
                                `SEQ_PC_READ_L: // reads low byte [PC]
995
                                        begin
996
                                                k_cpu_addr <= regs_o_pc;
997
                                                state <= `SEQ_PC_READ_L_1;
998
                                                k_inc_pc <= 1;
999
                                        end
1000
                                `SEQ_PC_READ_L_1:
1001
                                        begin
1002
                                                k_cpu_oe <= 1; // read
1003
                                                state <= `SEQ_PC_READ_L_2;
1004
                                        end
1005
                                `SEQ_PC_READ_L_2:
1006
                                        begin
1007
                                                case (dec_o_p1_mode)
1008
                                                        `NONE: k_pp_regs <= cpu_data_i; // push & pull
1009
                                                        `REL8, `REL16, `IMMEDIATE: k_memlo <= cpu_data_i;
1010
                                                        `DIRECT, `EXTENDED: k_ealo <= cpu_data_i;
1011
                                                        `INDEXED: k_ofslo <= cpu_data_i;
1012 4 ale500
                                                endcase
1013
                                                if ((next_state == `SEQ_JMP_LOAD_PC) & (dec_o_cond_taken))
1014
                                                        k_write_pc <= 1; // load PC in the next cycle, the mux output will have the right source
1015 2 ale500
                                                state <= next_state;
1016
                                        end
1017
                                `SEQ_MEM_READ_H: // reads high byte
1018
                                        begin
1019
                                                case (dec_o_p1_mode)
1020
                                                        `NONE: begin k_cpu_addr <= regs_o_su; k_inc_su <= 1; end // pull, rts, rti
1021 12 ale500
                                                        `INDEXED:
1022
                                                                if (k_indirect_loaded)
1023
                                                                        k_cpu_addr <= { k_memhi, k_memlo };
1024
                                                                else
1025
                                                                        k_cpu_addr <= regs_o_eamem_addr;
1026 2 ale500
                                                        default: k_cpu_addr <= { k_eahi, k_ealo };
1027 4 ale500
                                                endcase
1028 6 ale500
                                                if (k_forced_mem_size | dec_o_source_size | (k_pp_active_reg <  `RN_ACCA))
1029 4 ale500
                                                        state <= `SEQ_MEM_READ_H_1;
1030
                                                else
1031
                                                        state <= `SEQ_MEM_READ_L_1;
1032
                                                k_forced_mem_size <= 0; // used for vector fetch
1033 2 ale500
                                        end
1034
                                `SEQ_MEM_READ_H_1:
1035
                                        begin
1036
                                                k_cpu_oe <= 1; // read
1037
                                                state <= `SEQ_MEM_READ_H_2;
1038
                                        end
1039
                                `SEQ_MEM_READ_H_2:
1040
                                        begin
1041
                                                case (k_mem_dest)
1042 4 ale500
                                                        `MEMDEST_PC,//: k_new_pc[15:8] <= cpu_data_i;
1043 2 ale500
                                                        `MEMDEST_MH: k_memhi <= cpu_data_i;
1044
                                                        `MEMDEST_AH: k_eahi <= cpu_data_i;
1045
                                                endcase
1046
                                                state <= `SEQ_MEM_READ_L_1;
1047 4 ale500
                                                k_cpu_addr  <= k_cpu_addr + 16'h1;
1048
                                                case (dec_o_p1_mode)
1049
                                                        `NONE: begin k_inc_su <= 1; end // pull, rts, rti
1050
                                                endcase
1051 2 ale500
                                        end
1052 4 ale500
                                `SEQ_MEM_READ_L: // reads low byte
1053 2 ale500
                                        begin
1054 4 ale500
                                                // falls through from READ_MEM_H with the right address
1055 2 ale500
                                                case (dec_o_p1_mode)
1056 4 ale500
                                                        `NONE: begin k_cpu_addr <= regs_o_su; k_inc_su <= 1; end // pull, rts, rti
1057 2 ale500
                                                endcase
1058
                                                state <= `SEQ_MEM_READ_L_1;
1059
                                        end
1060
                                `SEQ_MEM_READ_L_1:
1061
                                        begin
1062
                                                k_cpu_oe <= 1; // read
1063
                                                state <= `SEQ_MEM_READ_L_2;
1064
                                        end
1065
                                `SEQ_MEM_READ_L_2:
1066
                                        begin
1067
                                                case (k_mem_dest)
1068 10 ale500
                                                        `MEMDEST_PC,
1069 2 ale500
                                                        `MEMDEST_MH: k_memlo <= cpu_data_i;
1070
                                                        `MEMDEST_AH: k_ealo <= cpu_data_i;
1071
                                                endcase
1072
                                                case (dec_o_p1_mode)
1073 4 ale500
                                                        `NONE, `INHERENT: k_write_dest <= 1; // pull, rts, rti
1074 10 ale500
                                                endcase
1075
                                                if (next_mem_state == `SEQ_LOADPC)
1076
                                                        k_write_pc <= 1;
1077 12 ale500
                                                case (dec_o_p1_mode)
1078
                                                        `INDEXED: // address loaded, load argument
1079
                                                                if (k_indirect_loaded | (!dec_o_ea_indirect))
1080
                                                                        state <= next_mem_state;
1081
                                                                else
1082
                                                                        begin
1083
                                                                                state <= `SEQ_MEM_READ_H;
1084
                                                                                k_indirect_loaded <= 1'b1;
1085
                                                                        end
1086
                                                        default:
1087
                                                                state <= next_mem_state;
1088
                                                endcase
1089 2 ale500
                                        end
1090
                                `SEQ_MEM_WRITE_H: // writes high byte
1091
                                        begin
1092
                                                case (dec_o_p1_mode)
1093
                                                        `INDEXED: k_cpu_addr <= regs_o_eamem_addr;
1094
                                                        default: k_cpu_addr <= { k_eahi, k_ealo };
1095
                                                endcase
1096 4 ale500
                                                k_cpu_data_o <= datamux_o_dest[15:8];
1097 2 ale500
                                                state <= `SEQ_MEM_WRITE_H_1;
1098
                                                k_cpu_we <= 1; // read
1099
                                        end
1100
                                `SEQ_MEM_WRITE_H_1:
1101
                                        begin
1102
                                                state <= `SEQ_MEM_WRITE_L;
1103
                                                k_cpu_addr <= k_cpu_addr + 16'h1;
1104
                                        end
1105
                                `SEQ_MEM_WRITE_L: // reads high byte
1106
                                        begin
1107 6 ale500
                                                if (!dec_o_alu_size) // only if it is an 8 bit write
1108 2 ale500
                                                        case (dec_o_p1_mode)
1109
                                                                `INDEXED: k_cpu_addr <= regs_o_eamem_addr;
1110
                                                                default: k_cpu_addr <= { k_eahi, k_ealo };
1111
                                                        endcase
1112
                                                k_cpu_data_o <= datamux_o_dest[7:0];
1113
                                                state <= `SEQ_MEM_WRITE_L_1;
1114
                                                k_cpu_we <= 1; // write
1115
                                        end
1116
                                `SEQ_MEM_WRITE_L_1:
1117
                                        begin
1118
                                                k_write_post_incdec <= dec_o_ea_wpost;
1119
                                                state <= next_mem_state;
1120
                                        end
1121
 
1122
                        endcase
1123
                end
1124
        end
1125
 
1126
initial
1127
        begin
1128
                k_cpu_oe = 0;
1129
                k_cpu_we = 0;
1130
                k_mem_dest = 0;
1131 5 ale500
                k_new_pc = 16'hffff;
1132
                k_write_tfr = 0;
1133 6 ale500
                k_write_exg = 0;
1134
                k_mul_cnt = 0;
1135 10 ale500
                k_write_dest = 0;
1136 12 ale500
                k_indirect_loaded = 0;
1137 2 ale500
        end
1138 10 ale500
endmodule

powered by: WebSVN 2.1.0

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