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

Subversion Repositories t6507lp

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

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

powered by: WebSVN 2.1.0

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