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

Subversion Repositories t6507lp

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

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

powered by: WebSVN 2.1.0

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