OpenCores
URL https://opencores.org/ocsvn/t6507lp/t6507lp/trunk

Subversion Repositories t6507lp

[/] [t6507lp/] [trunk/] [rtl/] [verilog/] [t6507lp_fsm.v] - Blame information for rev 94

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

Line No. Rev Author Line
1 61 creep
////////////////////////////////////////////////////////////////////////////
2
////                                                                    ////
3
//// T6507LP IP Core                                                    ////
4
////                                                                    ////
5
//// This file is part of the T6507LP project                           ////
6
//// http://www.opencores.org/cores/t6507lp/                            ////
7
////                                                                    ////
8
//// Description                                                        ////
9
//// 6507 FSM                                                           ////
10
////                                                                    ////
11
//// TODO:                                                              ////
12
//// - Fix absolute indexed mode                                        ////
13
//// - Code the relative mode                                           ////
14
//// - Code the indexed indirect mode                                   ////
15
//// - Code the indirect indexed mode                                   ////
16
//// - Code the absolute indirect mode                                  ////
17
////                                                                    ////
18
//// Author(s):                                                         ////
19
//// - Gabriel Oshiro Zardo, gabrieloshiro@gmail.com                    ////
20
//// - Samuel Nascimento Pagliarini (creep), snpagliarini@gmail.com     ////
21
////                                                                    ////
22
////////////////////////////////////////////////////////////////////////////
23
////                                                                    ////
24
//// Copyright (C) 2001 Authors and OPENCORES.ORG                       ////
25
////                                                                    ////
26
//// This source file may be used and distributed without               ////
27
//// restriction provided that this copyright statement is not          ////
28
//// removed from the file and that any derivative work contains        ////
29
//// the original copyright notice and the associated disclaimer.       ////
30
////                                                                    ////
31
//// This source file is free software; you can redistribute it         ////
32
//// and/or modify it under the terms of the GNU Lesser General         ////
33
//// Public License as published by the Free Software Foundation;       ////
34
//// either version 2.1 of the License, or (at your option) any         ////
35
//// later version.                                                     ////
36
////                                                                    ////
37
//// This source is distributed in the hope that it will be             ////
38
//// useful, but WITHOUT ANY WARRANTY; without even the implied         ////
39
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR            ////
40
//// PURPOSE. See the GNU Lesser General Public License for more        ////
41
//// details.                                                           ////
42
////                                                                    ////
43
//// You should have received a copy of the GNU Lesser General          ////
44
//// Public License along with this source; if not, download it         ////
45
//// from http://www.opencores.org/lgpl.shtml                           ////
46
////                                                                    ////
47
////////////////////////////////////////////////////////////////////////////
48
 
49
`timescale 1ns / 1ps
50
 
51 86 creep
module t6507lp_fsm(clk, reset_n, alu_result, alu_status, data_in, address, control, data_out, alu_opcode, alu_a, alu_enable, alu_x, alu_y);
52 87 creep
        parameter DATA_SIZE = 8;
53
        parameter ADDR_SIZE = 13;
54 68 creep
 
55 83 creep
        localparam DATA_SIZE_ = DATA_SIZE - 4'b0001;
56
        localparam ADDR_SIZE_ = ADDR_SIZE - 4'b0001;
57 82 creep
 
58 71 creep
        input clk;
59
        input reset_n;
60 82 creep
        input [DATA_SIZE_:0] alu_result;
61
        input [DATA_SIZE_:0] alu_status;
62
        input [DATA_SIZE_:0] data_in;
63
        output reg [ADDR_SIZE_:0] address;
64 61 creep
        output reg control; // one bit is enough? read = 0, write = 1
65 82 creep
        output reg [DATA_SIZE_:0] data_out;
66
        output reg [DATA_SIZE_:0] alu_opcode;
67
        output reg [DATA_SIZE_:0] alu_a;
68 68 creep
        output reg alu_enable;
69 61 creep
 
70 86 creep
        input [DATA_SIZE_:0] alu_x;
71
        input [DATA_SIZE_:0] alu_y;
72 68 creep
 
73 61 creep
        // FSM states
74 63 creep
        localparam FETCH_OP = 4'b0000;
75 68 creep
        localparam FETCH_OP_CALC = 4'b0001;
76
        localparam FETCH_LOW = 4'b0010;
77
        localparam FETCH_HIGH = 4'b0011;
78 71 creep
        localparam READ_MEM = 4'b0100;
79
        localparam DUMMY_WRT_CALC = 4'b0101;
80
        localparam WRITE_MEM = 4'b0110;
81
        localparam FETCH_OP_CALC_PARAM = 4'b0111;
82 86 creep
        localparam READ_MEM_CALC_INDEX = 4'b1000;
83 87 creep
        localparam FETCH_HIGH_CALC_INDEX = 4'b1001;
84
        localparam READ_MEM_FIX_ADDR = 4'b1010;
85 94 creep
        localparam FETCH_OP_EVAL_BRANCH = 4'b1011;
86
        localparam FETCH_OP_FIX_PC = 4'b1100;
87 87 creep
        localparam RESET = 4'b1111;
88 61 creep
 
89
        // OPCODES TODO: verify how this get synthesised
90
        `include "../T6507LP_Package.v"
91
 
92
        // control signals
93
        localparam MEM_READ = 1'b0;
94
        localparam MEM_WRITE = 1'b1;
95
 
96 82 creep
        reg [ADDR_SIZE_:0] pc;           // program counter
97
        reg [DATA_SIZE_:0] sp;           // stack pointer
98
        reg [DATA_SIZE_:0] ir;           // instruction register
99
        reg [ADDR_SIZE_:0] temp_addr;    // temporary address
100
        reg [DATA_SIZE_:0] temp_data;    // temporary data
101 61 creep
 
102
        reg [3:0] state, next_state; // current and next state registers
103
        // TODO: not sure if this will be 4 bits wide. as of march 9th this was 4bit wide.
104
 
105
        // wiring that simplifies the FSM logic
106
        reg absolute;
107
        reg absolute_indexed;
108
        reg accumulator;
109
        reg immediate;
110
        reg implied;
111
        reg indirect;
112
        reg relative;
113
        reg zero_page;
114
        reg zero_page_indexed;
115 86 creep
        reg [DATA_SIZE_:0] index; // will be assigned with either X or Y
116 61 creep
 
117
        // regs that store the type of operation. again, this simplifies the FSM a lot.
118
        reg read;
119
        reg read_modify_write;
120
        reg write;
121
        reg jump;
122
 
123 82 creep
        wire [ADDR_SIZE_:0] next_pc;
124 63 creep
        assign next_pc = pc + 13'b0000000000001;
125 61 creep
 
126 87 creep
        reg [ADDR_SIZE_:0] address_plus_index; // this would update more times than actually needed, consuming power.
127
        reg page_crossed;                       // so the simple assign was changed into a combinational always block
128
 
129 94 creep
        reg branch;
130
 
131 87 creep
        always @(*) begin
132
                address_plus_index = 0;
133
                page_crossed = 0;
134 86 creep
 
135 88 creep
                if (state == READ_MEM_CALC_INDEX || state == READ_MEM_FIX_ADDR || state == FETCH_HIGH_CALC_INDEX) begin
136
                        {page_crossed, address_plus_index[7:0]} = temp_addr[7:0] + index;
137
                        address_plus_index[12:8] = temp_addr[12:8] + page_crossed;
138 87 creep
                end
139 94 creep
                else if (branch) begin
140
                        if (state == FETCH_OP_FIX_PC || state == FETCH_OP_EVAL_BRANCH) begin
141
                                {page_crossed, address_plus_index[7:0]} = pc[7:0] + index;
142
                                address_plus_index[12:8] = pc[12:8] + page_crossed;// warning: pc might feed these lines twice and cause branch failure
143
                        end                                                             // solution: add a temp reg i guess
144
                end
145 87 creep
        end
146
 
147 71 creep
        always @ (posedge clk or negedge reset_n) begin // sequencial always block
148
                if (reset_n == 1'b0) begin
149
                        // all registers must assume default values
150 68 creep
                        pc <= 0; // TODO: this is written somewhere. something about a reset vector. must be checked.
151
                        sp <= 0; // TODO: the default is not 0. maybe $0100 or something like that. must be checked.
152 82 creep
                        ir <= 8'h00;
153 71 creep
                        temp_addr <= 0;
154 82 creep
                        temp_data <= 8'h00;
155 68 creep
                        state <= RESET;
156 71 creep
                        // registered outputs also receive default values
157
                        address <= 0;
158 82 creep
                        control <= MEM_READ;
159
                        data_out <= 8'h00;
160 61 creep
                end
161
                else begin
162
                        state <= next_state;
163 83 creep
 
164 61 creep
                        case (state)
165 68 creep
                                RESET: begin
166 82 creep
                                        // The processor was reset
167
                                        $write("under reset");
168 68 creep
                                end
169 61 creep
                                FETCH_OP: begin // this state is the simplest one. it is a simple fetch that must be done when the cpu was reset or
170
                                                // the last cycle was a memory write.
171
                                        pc <= next_pc;
172 71 creep
                                        address <= next_pc;
173 83 creep
                                        control <= MEM_READ;
174 70 creep
                                        ir <= data_in;
175 61 creep
                                end
176 71 creep
                                FETCH_OP_CALC, FETCH_OP_CALC_PARAM: begin // this is the pipeline happening!
177 61 creep
                                        pc <= next_pc;
178 71 creep
                                        address <= next_pc;
179 83 creep
                                        control <= MEM_READ;
180 70 creep
                                        ir <= data_in;
181 61 creep
                                end
182 68 creep
                                FETCH_LOW: begin // in this state the opcode is already known so truly execution begins
183
                                        if (accumulator || implied) begin
184 70 creep
                                                pc <= pc; // is this better?
185 71 creep
                                                address <= pc;
186 83 creep
                                                control <= MEM_READ;
187 61 creep
                                        end
188 94 creep
                                        else if (immediate || relative) begin
189 68 creep
                                                pc <= next_pc;
190 71 creep
                                                address <= next_pc;
191 83 creep
                                                control <= MEM_READ;
192 70 creep
                                                temp_data <= data_in; // the follow-up byte is saved in temp_data 
193 61 creep
                                        end
194 87 creep
                                        else if (absolute || absolute_indexed) begin
195 71 creep
                                                pc <= next_pc;
196
                                                address <= next_pc;
197 83 creep
                                                control <= MEM_READ;
198 87 creep
                                                temp_addr <= {{5{1'b0}},data_in};
199 71 creep
                                        end
200 77 creep
                                        else if (zero_page) begin
201
                                                pc <= next_pc;
202
                                                address <= {{5{1'b0}},data_in};
203 78 creep
                                                temp_addr <= {{5{1'b0}},data_in};
204
 
205 77 creep
                                                if (write) begin
206
                                                        control <= MEM_WRITE;
207 78 creep
                                                        data_out <= alu_result;
208 77 creep
                                                end
209 83 creep
                                                else begin
210
                                                        control <= MEM_READ;
211
                                                        data_out <= 8'h00;
212
                                                end
213 77 creep
                                        end
214 86 creep
                                        else if (zero_page_indexed) begin
215
                                                pc <= next_pc;
216 94 creep
                                                address <= {{5{1'b0}}, data_in};
217
                                                temp_addr <= {{5{1'b0}}, data_in};
218 86 creep
                                                control <= MEM_READ;
219
                                        end
220 61 creep
                                end
221 87 creep
                                FETCH_HIGH_CALC_INDEX: begin
222
                                        pc <= next_pc;
223
                                        temp_addr[12:8] <= data_in[4:0];
224
                                        address <= {data_in[4:0], address_plus_index[7:0]};
225
                                        control <= MEM_READ;
226
                                        data_out <= 8'h00;
227
                                end
228 94 creep
                                FETCH_OP_EVAL_BRANCH: begin
229
                                        if (branch) begin
230
                                                pc <= {{5{1'b0}}, address_plus_index[7:0]};
231
                                                address <= {{5{1'b0}}, address_plus_index[7:0]};
232
                                                control <= MEM_READ;
233
                                                data_out <= 8'h00;
234
                                        end
235
                                        else begin
236
                                                pc <= next_pc;
237
                                                address <= next_pc;
238
                                                control <= MEM_READ;
239
                                                data_out <= 8'h00;
240
                                        end
241
                                end
242
                                FETCH_OP_FIX_PC: begin
243
                                        if (page_crossed) begin
244
                                                pc[12:8] <= address_plus_index[12:8];
245
                                                address[12:8] <= address_plus_index[12:8];
246
                                        end
247
                                        else begin
248
                                                pc <= next_pc;
249
                                                address <= next_pc;
250
                                                control <= MEM_READ;
251
                                                ir <= data_in;
252
                                        end
253
                                end
254 71 creep
                                FETCH_HIGH: begin
255
                                        if (jump) begin
256 83 creep
                                                pc <= {data_in[4:0], temp_addr[7:0]}; // PCL <= first byte, PCH <= second byte
257
                                                address <= {data_in[4:0], temp_addr[7:0]};
258
                                                control <= MEM_READ;
259
                                                data_out <= 8'h00;
260 71 creep
                                        end
261
                                        else begin
262
                                                if (write) begin
263
                                                        pc <= next_pc;
264
                                                        temp_addr[12:8] <= data_in[4:0];
265
                                                        address <= {data_in[4:0],temp_addr[7:0]};
266
                                                        control <= MEM_WRITE;
267 77 creep
                                                        data_out <= alu_result;
268 71 creep
                                                end
269
                                                else begin // read_modify_write or just read
270
                                                        pc <= next_pc;
271
                                                        temp_addr[12:8] <= data_in[4:0];
272
                                                        address <= {data_in[4:0],temp_addr[7:0]};
273 83 creep
                                                        control <= MEM_READ;
274
                                                        data_out <= 8'h00;
275 71 creep
                                                end
276
                                        end
277
                                        //else begin
278
                                        //      $write("FETCHHIGH PROBLEM"); 
279
                                        //      $finish(0); 
280
                                        //end
281 61 creep
                                end
282 71 creep
                                READ_MEM: begin
283
                                        if (read_modify_write) begin
284
                                                pc <= pc;
285
                                                address <= temp_addr;
286
                                                control <= MEM_WRITE;
287
                                                temp_data <= data_in;
288
                                                data_out <= data_in; // writeback the same value
289
                                        end
290
                                        else begin
291
                                                pc <= pc;
292
                                                address <= pc;
293
                                                temp_data <= data_in;
294 83 creep
                                                control <= MEM_READ;
295
                                                data_out <= 8'h00;
296 71 creep
                                        end
297 70 creep
                                end
298 86 creep
                                READ_MEM_CALC_INDEX: begin
299
                                                //pc <= next_pc; // pc was  already updated in the previous cycle
300
                                                address <= address_plus_index;
301
                                                temp_addr <= address_plus_index;
302
 
303
                                                if (write) begin
304
                                                        control <= MEM_WRITE;
305
                                                        data_out <= alu_result;
306
                                                end
307
                                                else begin
308
                                                        control <= MEM_READ;
309
                                                        data_out <= 8'h00;
310
                                                end
311
 
312
                                end
313 87 creep
                                READ_MEM_FIX_ADDR: begin
314
                                        if (read) begin
315
                                                control <= MEM_READ;
316
                                                data_out <= 8'h00;
317
 
318
                                                if (page_crossed) begin
319
                                                        address <= address_plus_index;
320
                                                        temp_addr <= address_plus_index;
321
                                                end
322
                                                else begin
323
                                                        address <= pc;
324
                                                        temp_data <= data_in;
325
                                                end
326
                                        end
327
                                        else if (write) begin
328
                                                control <= MEM_WRITE;
329
                                                data_out <= alu_result;
330
                                                address <= address_plus_index;
331
                                                temp_addr <= address_plus_index;
332
 
333
                                        end
334
                                        else begin // read modify write
335
                                                control <= MEM_READ;
336
                                                data_out <= 8'h00;
337
                                                address <= address_plus_index;
338
                                                temp_addr <= address_plus_index;
339
                                        end
340
                                end
341 71 creep
                                DUMMY_WRT_CALC: begin
342
                                        pc <= pc;
343
                                        address <= temp_addr;
344
                                        control <= MEM_WRITE;
345
                                        data_out <= alu_result;
346 70 creep
                                end
347 71 creep
                                WRITE_MEM: begin
348
                                        pc <= pc;
349
                                        address <= pc;
350 83 creep
                                        control <= MEM_READ;
351
                                        data_out <= 8'h00;
352 70 creep
                                end
353
                                default: begin
354
                                        $write("unknown state");        // TODO: check if synth really ignores this 2 lines. Otherwise wrap it with a `ifdef 
355
                                        $finish(0);
356
                                end
357
 
358
                        endcase
359
                end
360
        end
361
 
362 71 creep
        always @ (*) begin // this is the next_state logic and the output logic always block
363
                alu_opcode = 8'h00;
364
                alu_a = 8'h00;
365
                alu_enable = 1'b0;
366 70 creep
 
367 71 creep
                next_state = RESET; // this prevents the latch
368 68 creep
 
369 71 creep
                case (state)
370
                        RESET: begin
371
                                next_state = FETCH_OP;
372
                        end
373
                        FETCH_OP: begin
374
                                next_state = FETCH_LOW;
375
                        end
376 82 creep
                        //FETCH_OP_CALC: begin // so far no addressing mode required the use of this state
377
                        //      next_state = FETCH_LOW;
378
                        //      alu_opcode = ir;
379
                        //      alu_enable = 1'b1;
380
                        //end
381 71 creep
                        FETCH_OP_CALC_PARAM: begin
382
                                next_state = FETCH_LOW;
383
                                alu_opcode = ir;
384
                                alu_enable = 1'b1;
385
                                alu_a = temp_data;
386
                        end
387
                        FETCH_LOW: begin
388
                                if (accumulator  || implied) begin
389
                                        alu_opcode = ir;
390
                                        alu_enable = 1'b1;
391
                                        next_state = FETCH_OP;
392
                                end
393
                                else if (immediate) begin
394
                                        next_state = FETCH_OP_CALC_PARAM;
395
                                end
396 77 creep
                                else if (zero_page) begin
397
                                        if (read || read_modify_write) begin
398
                                                next_state = READ_MEM;
399
                                        end
400
                                        else if (write) begin
401
                                                next_state = WRITE_MEM;
402 86 creep
                                                alu_opcode = ir;
403
                                                alu_enable = 1'b1;
404
                                                alu_a = 8'h00;
405 77 creep
                                        end
406
                                        else begin
407
                                                $write("unknown behavior");
408
                                                $finish(0);
409
                                        end
410
                                end
411 86 creep
                                else if (zero_page_indexed) begin
412
                                        next_state = READ_MEM_CALC_INDEX;
413
                                end
414 87 creep
                                else if (absolute) begin // at least the absolute address mode falls here
415 71 creep
                                        next_state = FETCH_HIGH;
416 87 creep
                                        if (write) begin // this is being done one cycle early but i have checked and the ALU will still work properly
417 86 creep
                                                alu_opcode = ir;
418
                                                alu_enable = 1'b1;
419
                                                alu_a = 8'h00;
420
                                        end
421 71 creep
                                end
422 87 creep
                                else if (absolute_indexed) begin
423
                                        next_state = FETCH_HIGH_CALC_INDEX;
424
                                end
425 94 creep
                                else if (relative) begin
426
                                        next_state = FETCH_OP_EVAL_BRANCH;
427
                                end
428 71 creep
                        end
429 94 creep
                        FETCH_OP_EVAL_BRANCH: begin
430
                                if (branch) begin
431
                                        next_state = FETCH_OP_FIX_PC;
432
                                end
433
                                else begin
434
                                        next_state = FETCH_LOW;
435
                                end
436
                        end
437
                        FETCH_OP_FIX_PC: begin
438
                                if (page_crossed) begin
439
                                        next_state = FETCH_OP;
440
                                end
441
                                else begin
442
                                        next_state = FETCH_LOW;
443
                                end
444
                        end
445 87 creep
                        FETCH_HIGH_CALC_INDEX: begin
446
                                next_state = READ_MEM_FIX_ADDR;
447
                        end
448
                        READ_MEM_FIX_ADDR: begin
449
                                if (read) begin
450
                                        if (page_crossed) begin
451
                                                next_state = READ_MEM;
452
                                        end
453
                                        else begin
454
                                                next_state = FETCH_OP_CALC_PARAM;
455
                                        end
456
                                end
457
                                else if (read_modify_write) begin
458
                                        next_state = READ_MEM;
459
                                end
460
                                else if (write) begin
461
                                        next_state = WRITE_MEM;
462
                                end
463
                                else begin
464
                                        $write("unknown behavior");
465
                                        $finish(0);
466
                                end
467
                        end
468 71 creep
                        FETCH_HIGH: begin
469
                                if (jump) begin
470 68 creep
                                        next_state = FETCH_OP;
471 61 creep
                                end
472 71 creep
                                else if (read || read_modify_write) begin
473
                                        next_state = READ_MEM;
474 61 creep
                                end
475 71 creep
                                else if (write) begin
476
                                        next_state = WRITE_MEM;
477 68 creep
                                end
478 71 creep
                                else begin
479
                                        $write("unknown behavior");
480
                                        $finish(0);
481 61 creep
                                end
482 71 creep
                        end
483 86 creep
                        READ_MEM_CALC_INDEX: begin
484
                                if (read || read_modify_write) begin
485
                                        next_state = READ_MEM;
486
                                end
487
                                else if (write) begin
488
                                        alu_opcode = ir;
489
                                        alu_enable = 1'b1;
490
                                        next_state = WRITE_MEM;
491
                                end
492
                                else begin
493
                                        $write("unknown behavior");
494
                                        $finish(0);
495
                                end
496
                        end
497 71 creep
                        READ_MEM: begin
498
                                if (read) begin
499
                                        next_state = FETCH_OP_CALC_PARAM;
500 61 creep
                                end
501 71 creep
                                else if (read_modify_write) begin
502
                                        next_state = DUMMY_WRT_CALC;
503
                                end
504
                        end
505
                        DUMMY_WRT_CALC: begin
506
                                alu_opcode = ir;
507
                                alu_enable = 1'b1;
508
                                alu_a = data_in;
509
                                next_state = WRITE_MEM;
510
                        end
511
                        WRITE_MEM: begin
512
                                next_state = FETCH_OP;
513
                        end
514
                        default: begin
515
                                next_state = RESET;
516
                        end
517
                endcase
518 61 creep
        end
519
 
520 77 creep
        // this always block is responsible for updating the address mode and the type of operation being done
521 68 creep
        always @ (*) begin // 
522 61 creep
                absolute = 1'b0;
523
                absolute_indexed = 1'b0;
524
                accumulator = 1'b0;
525
                immediate = 1'b0;
526
                implied = 1'b0;
527
                indirect = 1'b0;
528
                relative = 1'b0;
529
                zero_page = 1'b0;
530
                zero_page_indexed = 1'b0;
531 86 creep
 
532
                index = 1'b0;
533 61 creep
 
534
                read = 1'b0;
535
                read_modify_write = 1'b0;
536
                write = 1'b0;
537
                jump = 1'b0;
538 94 creep
                branch = 1'b0;
539
 
540
                //$write("trying with %h\n", ir);
541 61 creep
 
542 70 creep
                case (ir)
543
                        BRK_IMP, CLC_IMP, CLD_IMP, CLI_IMP, CLV_IMP, DEX_IMP, DEY_IMP, INX_IMP, INY_IMP, NOP_IMP, PHA_IMP, PHP_IMP, PLA_IMP,
544
                        PLP_IMP, RTI_IMP, RTS_IMP, SEC_IMP, SED_IMP, SEI_IMP, TAX_IMP, TAY_IMP, TSX_IMP, TXA_IMP, TXS_IMP, TYA_IMP: begin
545
                                implied = 1'b1;
546
                        end
547
                        ASL_ACC, LSR_ACC, ROL_ACC, ROR_ACC: begin
548
                                accumulator = 1'b1;
549
                        end
550
                        ADC_IMM, AND_IMM, CMP_IMM, CPX_IMM, CPY_IMM, EOR_IMM, LDA_IMM, LDX_IMM, LDY_IMM, ORA_IMM, SBC_IMM: begin
551
                                immediate = 1'b1;
552
                        end
553
                        ADC_ZPG, AND_ZPG, ASL_ZPG, BIT_ZPG, CMP_ZPG, CPX_ZPG, CPY_ZPG, DEC_ZPG, EOR_ZPG, INC_ZPG, LDA_ZPG, LDX_ZPG, LDY_ZPG,
554
                        LSR_ZPG, ORA_ZPG, ROL_ZPG, ROR_ZPG, SBC_ZPG, STA_ZPG, STX_ZPG, STY_ZPG: begin
555
                                zero_page = 1'b1;
556
                        end
557
                        ADC_ZPX, AND_ZPX, ASL_ZPX, CMP_ZPX, DEC_ZPX, EOR_ZPX, INC_ZPX, LDA_ZPX, LDY_ZPX, LSR_ZPX, ORA_ZPX, ROL_ZPX, ROR_ZPX,
558 86 creep
                        SBC_ZPX, STA_ZPX, STY_ZPX: begin
559 70 creep
                                zero_page_indexed = 1'b1;
560 86 creep
                                index = alu_x;
561 70 creep
                        end
562 86 creep
                        LDX_ZPY, STX_ZPY: begin
563
                                zero_page_indexed = 1'b1;
564
                                index = alu_y;
565
                        end
566 94 creep
                        BCC_REL: begin
567 70 creep
                                relative = 1'b1;
568 94 creep
                                index = temp_data;
569
 
570
                                if (!alu_status[C]) begin
571
                                        branch = 1'b1;
572
                                end
573
                                else begin
574
                                        branch = 1'b0;
575
                                end
576 70 creep
                        end
577 94 creep
                        BCS_REL: begin
578
                                relative = 1'b1;
579
                                index = temp_data;
580
 
581
                                if (alu_status[C]) begin
582
                                        branch = 1'b1;
583
                                end
584
                                else begin
585
                                        branch = 1'b0;
586
                                end
587
                        end
588
                        BEQ_REL: begin
589
                                relative = 1'b1;
590
                                index = temp_data;
591
 
592
                                if (alu_status[Z]) begin
593
                                        branch = 1'b1;
594
                                end
595
                                else begin
596
                                        branch = 1'b0;
597
                                end
598
                        end
599
                        BNE_REL: begin
600
                                relative = 1'b1;
601
                                index = temp_data;
602
 
603
                                if (alu_status[Z] == 1'b0) begin
604
                                        branch = 1'b1;
605
                                end
606
                                else begin
607
                                        branch = 1'b0;
608
                                end
609
                        end
610
                        BPL_REL: begin
611
                                relative = 1'b1;
612
                                index = temp_data;
613
 
614
                                if (!alu_status[N]) begin
615
                                        branch = 1'b1;
616
                                end
617
                                else begin
618
                                        branch = 1'b0;
619
                                end
620
                        end
621
                        BMI_REL: begin
622
                                relative = 1'b1;
623
                                index = temp_data;
624
 
625
                                if (alu_status[N]) begin
626
                                        branch = 1'b1;
627
                                end
628
                                else begin
629
                                        branch = 1'b0;
630
                                end
631
                        end
632
                        BVC_REL: begin
633
                                relative = 1'b1;
634
                                index = temp_data;
635
 
636
                                if (!alu_status[V]) begin
637
                                        branch = 1'b1;
638
                                end
639
                                else begin
640
                                        branch = 1'b0;
641
                                end
642
                        end
643
                        BVS_REL: begin
644
                                relative = 1'b1;
645
                                index = temp_data;
646
 
647
                                if (alu_status[V]) begin
648
                                        branch = 1'b1;
649
                                end
650
                                else begin
651
                                        branch = 1'b0;
652
                                end
653
                        end
654 70 creep
                        ADC_ABS, AND_ABS, ASL_ABS, BIT_ABS, CMP_ABS, CPX_ABS, CPY_ABS, DEC_ABS, EOR_ABS, INC_ABS, JMP_ABS, JSR_ABS, LDA_ABS,
655
                        LDX_ABS, LDY_ABS, LSR_ABS, ORA_ABS, ROL_ABS, ROR_ABS, SBC_ABS, STA_ABS, STX_ABS, STY_ABS: begin
656
                                absolute = 1'b1;
657
                        end
658
                        ADC_ABX, AND_ABX, ASL_ABX, CMP_ABX, DEC_ABX, EOR_ABX, INC_ABX, LDA_ABX, LDY_ABX, LSR_ABX, ORA_ABX, ROL_ABX, ROR_ABX,
659 87 creep
                        SBC_ABX, STA_ABX: begin
660 70 creep
                                absolute_indexed = 1'b1;
661 87 creep
                                index = alu_x;
662 70 creep
                        end
663 87 creep
                        ADC_ABY, AND_ABY, CMP_ABY, EOR_ABY, LDA_ABY, LDX_ABY, ORA_ABY, SBC_ABY, STA_ABY: begin
664
                                absolute_indexed = 1'b1;
665
                                index = alu_y;
666
                        end
667 70 creep
                        ADC_IDX, AND_IDX, CMP_IDX, EOR_IDX, LDA_IDX, ORA_IDX, SBC_IDX, STA_IDX, ADC_IDY, AND_IDY, CMP_IDY, EOR_IDY, LDA_IDY,
668
                        ORA_IDY, SBC_IDY, STA_IDY: begin // all these opcodes are 8'hX1; TODO: optimize this
669
                                indirect = 1'b1;
670
                        end
671 71 creep
                        default: begin
672 94 creep
                                $write("state : %b", state);
673
                                if (reset_n == 1 && state != FETCH_OP_FIX_PC) begin // the processor is NOT being reset neither it is fixing the pc
674 86 creep
                                        $write("\nunknown OPCODE!!!!! 0x%h\n", ir);
675
                                        $finish();
676
                                end
677 71 creep
                        end
678 70 creep
                endcase
679 71 creep
 
680
                case (ir)
681
                        ASL_ACC, ASL_ZPG, ASL_ZPX, ASL_ABS, ASL_ABX, LSR_ACC, LSR_ZPG, LSR_ZPX, LSR_ABS, LSR_ABX, ROL_ACC, ROL_ZPG, ROL_ZPX, ROL_ABS,
682
                        ROL_ABX, ROR_ACC, ROR_ZPG, ROR_ZPX, ROR_ABS, ROR_ABX, INC_ZPG, INC_ZPX, INC_ABS, INC_ABX, DEC_ZPG, DEC_ZPX, DEC_ABS,
683
                        DEC_ABX: begin
684
                                read_modify_write = 1'b1;
685
                        end
686
                        STA_ZPG, STA_ZPX, STA_ABS, STA_ABX, STA_ABY, STA_IDX, STA_IDY, STX_ZPG, STX_ZPY, STX_ABS, STY_ZPG, STY_ZPX, STY_ABS: begin
687
                                write = 1'b1;
688
                        end
689
                        default: begin // this should work fine since the previous case statement will detect the unknown/undocumented/unsupported opcodes
690
                                read = 1'b1;
691
                        end
692
                endcase
693 61 creep
 
694 71 creep
                if (ir == JMP_ABS || ir == JMP_IND) begin // the opcodes are 8'h4C and 8'h6C
695 70 creep
                        jump = 1'b1;
696
                end
697 86 creep
        end
698 61 creep
endmodule
699
 
700
 
701
 

powered by: WebSVN 2.1.0

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