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 18

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

powered by: WebSVN 2.1.0

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