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 17

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

powered by: WebSVN 2.1.0

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