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 7

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

powered by: WebSVN 2.1.0

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