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 11

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

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

powered by: WebSVN 2.1.0

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