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 9

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

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

powered by: WebSVN 2.1.0

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