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

Subversion Repositories t6507lp

[/] [t6507lp/] [trunk/] [fv/] [alu_chk.e] - Blame information for rev 177

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

Line No. Rev Author Line
1 131 creep
alu_chk.e
2
<'
3
import alu_components;
4
 
5
unit alu_chk_u {
6
        reg_a : byte;
7
        reg_x : byte;
8
        reg_y : byte;
9
        reg_status : byte;
10 135 creep
        reg_result : byte;
11 131 creep
 
12 159 creep
        !inst : alu_input_s;
13
        !next_inst : alu_input_s;
14 132 creep
 
15 131 creep
        count_cycles : int;
16
        first_cycle : bool;
17 159 creep
        last_a : byte;
18
        last_status : byte;
19
        last_result : byte;
20 131 creep
 
21
        keep first_cycle == TRUE;
22
        keep count_cycles == 0;
23
 
24
        store(input : alu_input_s) is {
25 134 creep
                count_cycles = count_cycles + 1;
26
 
27 153 creep
                //out ("CYCLE ", count_cycles, " STORE:");
28
                //print input;
29 132 creep
 
30 159 creep
                last_a = reg_a;
31
                last_status = reg_status;
32
                last_result = reg_result;
33
 
34 132 creep
                if (first_cycle) {
35
                        inst = input;
36
                        next_inst = input;
37
                }
38
                else {
39
                        inst = next_inst;
40
                        next_inst = input;
41
                };
42
 
43 131 creep
        };
44
 
45
        compare(alu_result:byte, alu_status:byte, alu_x:byte, alu_y:byte ) is {
46
                if (first_cycle) {
47
                        first_cycle = FALSE;
48 143 creep
                        reg_x = 0;
49
                        reg_y = 0;
50
                        reg_status = 8'b00100010;
51 132 creep
                        reg_a = 0; // TODO: check this
52 135 creep
                        reg_result = 0;
53 131 creep
                }
54 132 creep
                else {
55 153 creep
                        //out ("CYCLE ", count_cycles, " COMPARE:");
56
                        //print inst;
57 134 creep
 
58 159 creep
                        if (count_cycles == 99999) {
59
                                out("ENOUGH!");
60
                                stop_run();
61
                        };
62
 
63 132 creep
                        case inst.input_kind {
64
                                ENABLED_VALID: {
65 153 creep
                                        //out("CYCLE ", count_cycles, ": executing and comparing");
66 132 creep
                                        execute();
67
                                };
68
                                DISABLED_VALID: {
69 153 creep
                                        //out("CYCLE ", count_cycles, ": just comparing");
70 132 creep
                                };
71 143 creep
                                RESET: {
72 146 creep
                                        reg_x = 0;
73
                                        reg_y = 0;
74
                                        reg_status = 8'b00100010;
75
                                        reg_a = 0; // TODO: check this
76
                                        reg_result = 0;
77
 
78 143 creep
                                        return;
79
                                };
80 132 creep
                                default: {
81
                                        dut_error("error at e code");
82
                                };
83
                        };
84
 
85 133 creep
                        // here i have already calculated. must compare!
86 143 creep
 
87 146 creep
                        if ((reg_result != alu_result) || (reg_x != alu_x) or (reg_y != alu_y) or (reg_status != alu_status)) {
88 153 creep
                                out("#########################################################");
89 135 creep
                                print me;
90 155 creep
                                print me.inst;
91 153 creep
                                out("#########################################################");
92 134 creep
                                print alu_result;
93 135 creep
                                print alu_status;
94
                                print alu_x;
95
                                print alu_y;
96
 
97 133 creep
                                dut_error("WRONG!");
98
                        };
99 146 creep
                };
100 131 creep
        };
101 132 creep
 
102
        execute() is {
103
                case inst.alu_opcode {
104
                        ADC_IMM: { exec_sum(); }; // A,Z,C,N = A+M+C
105
                        ADC_ZPG: { exec_sum(); };
106
                        ADC_ZPX: { exec_sum(); };
107
                        ADC_ABS: { exec_sum(); };
108
                        ADC_ABX: { exec_sum(); };
109
                        ADC_ABY: { exec_sum(); };
110
                        ADC_IDX: { exec_sum(); };
111
                        ADC_IDY: { exec_sum(); };
112
 
113 133 creep
                        AND_IMM: { exec_and(); }; // A,Z,N = A&M
114 132 creep
                        AND_ZPG: { exec_and(); };
115
                        AND_ZPX: { exec_and(); };
116
                        AND_ABS: { exec_and(); };
117
                        AND_ABX: { exec_and(); };
118
                        AND_ABY: { exec_and(); };
119
                        AND_IDX: { exec_and(); };
120
                        AND_IDY: { exec_and(); };
121
 
122 135 creep
                        ASL_ACC: { exec_asl_acc(); }; // A,Z,C,N = M*2
123 132 creep
 
124 135 creep
                        ASL_ZPG: { exec_asl_mem(); }; // M,Z,C,N = M*2
125
                        ASL_ZPX: { exec_asl_mem(); };
126
                        ASL_ABS: { exec_asl_mem(); };
127
                        ASL_ABX: { exec_asl_mem(); };
128
 
129 155 creep
                        BCC_REL: {}; // nothing is done. these are all branches.
130 153 creep
                        BCS_REL: {};
131
                        BEQ_REL: {};
132 155 creep
                        BMI_REL: {};
133
                        BNE_REL: {};
134
                        BPL_REL: {};
135
                        BVC_REL: {};
136
                        BVS_REL: {};
137 153 creep
 
138 155 creep
                        BIT_ZPG: { exec_bit(); }; // Z = A & M, N = M7, V = M6
139
                        BIT_ABS: { exec_bit(); };
140
 
141
                        BRK_IMP: { reg_status[4:4] = 1; };
142
 
143
                        CLC_IMP: { reg_status[0:0] = 0; };
144
                        CLD_IMP: { reg_status[3:3] = 0; };
145
                        CLI_IMP: { reg_status[2:2] = 0; };
146
                        CLV_IMP: { reg_status[6:6] = 0; };
147
 
148 159 creep
                        CMP_IMM: { exec_cmp(reg_a); }; // Z,C,N = A-M
149
                        CMP_ZPG: { exec_cmp(reg_a); };
150
                        CMP_ZPX: { exec_cmp(reg_a); };
151
                        CMP_ABS: { exec_cmp(reg_a); };
152
                        CMP_ABX: { exec_cmp(reg_a); };
153
                        CMP_ABY: { exec_cmp(reg_a); };
154
                        CMP_IDX: { exec_cmp(reg_a); };
155
                        CMP_IDY: { exec_cmp(reg_a); };
156
 
157
                        CPX_IMM: { exec_cmp(reg_x); }; // Z,C,N = X-M
158
                        CPX_ZPG: { exec_cmp(reg_x); };
159
                        CPX_ABS: { exec_cmp(reg_x); };
160
 
161
                        CPY_IMM: { exec_cmp(reg_y); }; //Z,C,N = Y-M
162
                        CPY_ZPG: { exec_cmp(reg_y); };
163
                        CPY_ABS: { exec_cmp(reg_y); };
164
 
165
                        DEC_ZPG: { exec_dec(inst.alu_a, TRUE); }; // M,Z,N = M-1
166
                        DEC_ZPX: { exec_dec(inst.alu_a, TRUE); };
167
                        DEC_ABS: { exec_dec(inst.alu_a, TRUE); };
168
                        DEC_ABX: { exec_dec(inst.alu_a, TRUE); };
169
 
170
                        DEX_IMP: { exec_dec(reg_x, FALSE); };  // X,Z,N = X-1
171
                        DEY_IMP: { exec_dec(reg_y, FALSE); };  // Y,Z,N = Y-1
172
 
173
                        EOR_IMM: { exec_eor(); }; // A,Z,N = A^M
174
                        EOR_ZPG: { exec_eor(); };
175
                        EOR_ZPX: { exec_eor(); };
176
                        EOR_ABS: { exec_eor(); };
177
                        EOR_ABX: { exec_eor(); };
178
                        EOR_ABY: { exec_eor(); };
179
                        EOR_IDX: { exec_eor(); };
180
                        EOR_IDY: { exec_eor(); };
181
 
182
                        INC_ZPG: { exec_inc(inst.alu_a, TRUE); };
183
                        INC_ZPX: { exec_inc(inst.alu_a, TRUE); };
184
                        INC_ABS: { exec_inc(inst.alu_a, TRUE); };
185
                        INC_ABX: { exec_inc(inst.alu_a, TRUE); };
186
 
187
                        INX_IMP: { exec_inc(reg_x, FALSE); };
188
                        INY_IMP: { exec_inc(reg_y, FALSE); };
189
 
190
                        JMP_ABS: {};
191
                        JMP_IND: {};
192
                        JSR_ABS: {};
193
 
194
                        LDA_IMM: { exec_load(reg_a, TRUE); }; // A,Z,N = M
195
                        LDA_ZPG: { exec_load(reg_a, TRUE); };
196
                        LDA_ZPX: { exec_load(reg_a, TRUE); };
197
                        LDA_ABS: { exec_load(reg_a, TRUE); };
198
                        LDA_ABX: { exec_load(reg_a, TRUE); };
199
                        LDA_ABY: { exec_load(reg_a, TRUE); };
200
                        LDA_IDX: { exec_load(reg_a, TRUE); };
201
                        LDA_IDY: { exec_load(reg_a, TRUE); };
202
 
203
                        LDX_IMM: { exec_load(reg_x, FALSE); };
204
                        LDX_ZPG: { exec_load(reg_x, FALSE); };
205
                        LDX_ZPY: { exec_load(reg_x, FALSE); };
206
                        LDX_ABS: { exec_load(reg_x, FALSE); };
207
                        LDX_ABY: { exec_load(reg_x, FALSE); };
208
 
209
                        LDY_IMM: { exec_load(reg_y, FALSE); };
210
                        LDY_ZPG: { exec_load(reg_y, FALSE); };
211
                        LDY_ZPX: { exec_load(reg_y, FALSE); };
212
                        LDY_ABS: { exec_load(reg_y, FALSE); };
213
                        LDY_ABX: { exec_load(reg_y, FALSE); };
214
 
215
                        LSR_ACC: { exec_lsr(reg_a); }; // A,C,Z,N = A/2 or M,C,Z,N = M/2
216
                        LSR_ZPG: { exec_lsr(inst.alu_a); };
217
                        LSR_ZPX: { exec_lsr(inst.alu_a); };
218
                        LSR_ABS: { exec_lsr(inst.alu_a); };
219
                        LSR_ABX: { exec_lsr(inst.alu_a); };
220
 
221
                        NOP_IMP: {};
222
 
223
                        ORA_IMM: { exec_or(); }; // A,Z,N = A|M
224
                        ORA_ZPG: { exec_or(); };
225
                        ORA_ZPX: { exec_or(); };
226
                        ORA_ABS: { exec_or(); };
227
                        ORA_ABX: { exec_or(); };
228
                        ORA_ABY: { exec_or(); };
229
                        ORA_IDX: { exec_or(); };
230
                        ORA_IDY: { exec_or(); };
231
 
232
                        PHA_IMP: { reg_result = reg_a; };
233
                        PHP_IMP: {}; // P is always connected and the result is not updated
234
                        PLA_IMP: {
235
                                reg_a = inst.alu_a;
236
                                reg_result = inst.alu_a;
237
                                update_z(reg_a);
238
                                update_n(reg_a);
239
                        };
240
                        PLP_IMP: {
241
                                reg_status = inst.alu_a;
242
                                reg_status[5:5] = 1; // this is always one
243
                        };
244
 
245 177 creep
                        ROL_ACC: { exec_rot(TRUE, reg_a); };
246
                        ROL_ZPG: { exec_rot(TRUE, inst.alu_a); };
247
                        ROL_ZPX: { exec_rot(TRUE, inst.alu_a); };
248
                        ROL_ABS: { exec_rot(TRUE, inst.alu_a); };
249
                        ROL_ABX: { exec_rot(TRUE, inst.alu_a); };
250
                        ROR_ACC: { exec_rot(FALSE, reg_a); };
251
                        ROR_ZPG: { exec_rot(FALSE, inst.alu_a); };
252
                        ROR_ZPX: { exec_rot(FALSE, inst.alu_a); };
253
                        ROR_ABS: { exec_rot(FALSE, inst.alu_a); };
254
                        ROR_ABX: { exec_rot(FALSE, inst.alu_a); };
255 160 creep
 
256 177 creep
                        RTI_IMP: { reg_status = inst.alu_a; reg_status[5:5] = 1; };
257
                        RTS_IMP: { };
258
 
259
                        SBC_IMM: { exec_sub(); }; // A,Z,C,N = A-M-(1-C)
260
                        SBC_ZPG: { exec_sub(); };
261
                        SBC_ZPX: { exec_sub(); };
262
                        SBC_ABS: { exec_sub(); };
263
                        SBC_ABX: { exec_sub(); };
264
                        SBC_ABY: { exec_sub(); };
265
                        SBC_IDX: { exec_sub(); };
266
                        SBC_IDY: { exec_sub(); };
267
 
268
                        SEC_IMP: { reg_status[0:0] = 1; };
269
                        SED_IMP: { reg_status[3:3] = 1; };
270
                        SEI_IMP: { reg_status[2:2] = 1; };
271
 
272
                        STA_ZPG: { reg_result = reg_a; };
273
                        STA_ZPX: { reg_result = reg_a; };
274
                        STA_ABS: { reg_result = reg_a; };
275
                        STA_ABX: { reg_result = reg_a; };
276
                        STA_ABY: { reg_result = reg_a; };
277
                        STA_IDX: { reg_result = reg_a; };
278
                        STA_IDY: { reg_result = reg_a; };
279
                        //STX_ZPG: { reg_result = reg_x; };
280
                        //STX_ZPY: { reg_result = reg_x; };
281
                        //STX_ABS: { reg_result = reg_x; };
282
                        //STY_ZPG: { reg_result = reg_y; };
283
                        //STY_ZPX: { reg_result = reg_y; };
284
                        //STY_ABS: { reg_result = reg_y; };
285
 
286
                        //TAX_IMP: { exec_transfer(reg_a, reg_x); };
287
                        //TAY_IMP: { exec_transfer(reg_a, reg_y); };
288
                        //TSX_IMP: { exec_transfer(inst.alu_a, reg_x); };
289
                        //TXA_IMP: { exec_transfer(reg_x, reg_a); };
290
                        //TXS_IMP: { };
291
                        //TYA_IMP: { exec_transfer(reg_y, reg_a); };
292
 
293 132 creep
                        default: {
294 155 creep
                                out(inst.alu_opcode);
295
                                dut_error("unknown opcode");
296 132 creep
                        }
297
                };
298
        };
299
 
300 177 creep
        exec_transfer(source : byte, dest : *byte) is {
301
                dest = source;
302
                update_z(dest);
303
                update_n(dest);
304
        };
305
 
306
        exec_sub() is {
307
                if (reg_status[3:3] == 1) {
308
                        var op1 : int;
309
                        var op2 : int;
310
 
311
                        //out("i am subtracting ", reg_a, " and ", inst.alu_a, " carry is ", reg_status[0:0]);
312
 
313
                        op1 = inst.alu_a[3:0];
314
                        op2 = inst.alu_a[7:4];
315
 
316
                        op1 = reg_a[3:0] - op1 -1 + reg_status[0:0];
317
                        op2 = reg_a[7:4] - op2;
318
 
319
                        if (op1 >= 10) {
320
                                op2 = op2  + op1/10;
321
                                op1 = op1 % 10;
322
                        } else if (op1 < 0) {
323
                                op2 = op2 - op1/10;
324
                                op1 = -(op1 % 10);
325
                        };
326
 
327
                        if (op2 >= 10) {
328
                                op2 = op2 % 10;
329
                                reg_status[0:0] = 1;
330
                        }
331
                        else if (op2 < 0) {
332
                                op2 = op2 + 10;
333
                                reg_status[0:0] = 0;
334
                        };
335
 
336
                        reg_result[3:0] = op1;
337
                        reg_result[7:4] = op2;
338
                }
339
                else {
340
                        reg_result = reg_a - inst.alu_a - 1 + reg_status[0:0];
341
                        if (reg_result[7:7] == 1) {
342
                                reg_status[0:0] = 0;
343
                        }
344
                        else {
345
                                reg_status[0:0] = 1;
346
                        };
347
                };
348
 
349
                update_z(reg_result);
350
                update_n(reg_result);
351
                update_v(reg_a, inst.alu_a, reg_result);
352
 
353
 
354
                reg_a = reg_result;
355
 
356
        };
357
 
358
        exec_rot(left : bool, arg1 : *byte) is {
359 160 creep
                var oldcarry : bit;
360
 
361 177 creep
                if (left) {
362
                        oldcarry = reg_status[0:0];
363
                        reg_status[0:0] = arg1[7:7];
364
                        arg1 = arg1 << 1;
365
                        arg1[0:0] = oldcarry;
366
                }
367
                else {
368
                        oldcarry = reg_status[0:0];
369
                        reg_status[0:0] = arg1[0:0];
370
                        arg1 = arg1 >> 1;
371
                        arg1[7:7] = oldcarry;
372
                };
373 160 creep
 
374 170 creep
                reg_result = arg1;
375
                update_z(arg1);
376
                update_n(arg1);
377 160 creep
        };
378
 
379 159 creep
        exec_or() is {
380
                reg_a = reg_a | inst.alu_a;
381
                reg_result = reg_a;
382
                update_z(reg_a);
383
                update_n(reg_a);
384
        };
385
 
386
        exec_lsr(arg1 : *byte) is {
387
                reg_status[0:0] = arg1[0:0];
388
                arg1 = arg1 >> 1;
389
                update_z(arg1);
390
                update_n(arg1);
391
                reg_result = arg1;
392
        };
393
 
394
        exec_load(arg1 : *byte, update_result : bool) is {
395
                arg1 = inst.alu_a;
396
 
397
                if (update_result) { //
398
                        reg_result = inst.alu_a; // no need for this but...
399
                };
400
                update_z(arg1);
401
                update_n(arg1);
402
        };
403
 
404
        exec_inc(arg1 : *byte, update_result : bool) is {
405
                arg1 = arg1 + 1;
406
                update_z(arg1);
407
                update_n(arg1);
408
 
409
                if (update_result) { //
410
                        reg_result = arg1;
411
                };
412
        };
413
 
414
        exec_eor() is {
415
                reg_a = reg_a ^ inst.alu_a;
416
                reg_result = reg_a;
417
                update_z(reg_a);
418
                update_n(reg_a);
419
        };
420
 
421
        exec_dec(arg1 : *byte, update_result : bool) is {
422
                arg1 = arg1 - 1;
423
                update_z(arg1);
424
                update_n(arg1);
425
 
426
                if (update_result) { // DEX and DEY do not output the result
427
                        reg_result = arg1;
428
                };
429
        };
430
 
431
        exec_cmp(arg1 : byte) is {
432
                update_z(arg1 - inst.alu_a);
433
                update_n(arg1 - inst.alu_a);
434
 
435
                if (arg1 >= inst.alu_a) {
436
                        reg_status[0:0] = 1;
437
                }
438
                else {
439
                        reg_status[0:0] = 0;
440
                };
441
        };
442
 
443 155 creep
        exec_bit() is {
444
                update_z(reg_a & inst.alu_a);
445
                reg_status[7:7] = inst.alu_a[7:7];
446
                reg_status[6:6] = inst.alu_a[6:6];
447
        };
448
 
449 135 creep
        exec_asl_acc() is {
450
                reg_status[0:0] = reg_a[7:7];
451
                reg_a = reg_a * 2;
452
                update_z(reg_a);
453
                update_n(reg_a);
454
                reg_result = reg_a;
455
        };
456
 
457
        exec_asl_mem() is {
458
                reg_status[0:0] = inst.alu_a[7:7];
459
                reg_result = inst.alu_a * 2;
460
                update_z(reg_result);
461
                update_n(reg_result);
462
        };
463
 
464 132 creep
        exec_and() is {
465 133 creep
                reg_a = reg_a & inst.alu_a; // TODO: this is probably wrong
466
                update_z(reg_a);
467
                update_n(reg_a);
468 135 creep
                reg_result = reg_a;
469 132 creep
        };
470
 
471
        exec_sum() is {
472 153 creep
                //out("adding: ", reg_a, " + ", inst.alu_a, " + ", reg_status[0:0]);
473 160 creep
                if (reg_status[3:3] == 1) {
474
                        var op1 : byte;
475
                        var op2 : byte;
476
 
477 177 creep
                        //out("i am adding ", reg_a, " and ", inst.alu_a, " carry is ", reg_status[0:0]);
478 170 creep
 
479 160 creep
                        op1 = inst.alu_a[3:0];
480
                        op2 = inst.alu_a[7:4];
481
 
482
                        op1 = reg_a[3:0] + op1 + reg_status[0:0];
483
                        op2 = reg_a[7:4] + op2;
484
 
485
                        if (op1 >= 10) {
486 170 creep
                                op2 = op2  + op1/ 10;
487 160 creep
                                op1 = op1 % 10;
488
                        };
489 170 creep
 
490 160 creep
                        if (op2 >= 10) {
491
                                op2 = op2 % 10;
492
                                reg_status[0:0] = 1;
493
                        }
494
                        else {
495
                                reg_status[0:0] = 0;
496
                        };
497
 
498
                        reg_result[3:0] = op1;
499
                        reg_result[7:4] = op2;
500
                        update_z(reg_result);
501
                        update_n(reg_result);
502 177 creep
                        update_v(reg_a, inst.alu_a, reg_result);
503 160 creep
                        reg_a = reg_result;
504
                }
505
                else {
506
                        reg_result = reg_a + inst.alu_a + reg_status[0:0];
507
                        update_c(reg_a, inst.alu_a, reg_status[0:0]);
508
                        update_v(reg_a, inst.alu_a, reg_result);
509
                        update_z(reg_result);
510
                        update_n(reg_result);
511
                        reg_a = reg_result;
512
                };
513 132 creep
        };
514
 
515 143 creep
        update_c(arg1 : byte, arg2 : byte, arg3: bit) is {
516 153 creep
                if (arg1 + arg2 + arg3 > 255) {
517 132 creep
                        reg_status[0:0] = 1;
518
                }
519
                else {
520
                        reg_status[0:0] = 0;
521
                }
522
        };
523
 
524 146 creep
        update_v(op1 : byte, op2 : byte, res : byte) is {
525
                if ((op1[7:7] == op2[7:7]) && (op1[7:7] != res[7:7])) {
526
                        reg_status[6:6] = 1;
527
                }
528
                else {
529
                        reg_status[6:6] = 0;
530
                };
531
        };
532
 
533
        update_z(arg : byte) is {
534
                if (arg == 0) {
535
                        reg_status[1:1] = 1;
536
                }
537
                else {
538
                        reg_status[1:1] = 0;
539
                }
540
        };
541
 
542
 
543 132 creep
        update_n(arg : byte) is {
544
                if (arg[7:7] == 1) {
545
                        reg_status[7:7] = 1;
546
                }
547
                else {
548
                        reg_status[7:7] = 0;
549
                }
550
        };
551 131 creep
};
552
'>

powered by: WebSVN 2.1.0

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